diff --git a/packages/runtime/src/client/contract.ts b/packages/runtime/src/client/contract.ts index 531f3fa7..53c8a36f 100644 --- a/packages/runtime/src/client/contract.ts +++ b/packages/runtime/src/client/contract.ts @@ -1,7 +1,7 @@ import type { Decimal } from 'decimal.js'; import { type GetModels, type ProcedureDef, type SchemaDef } from '../schema'; import type { AuthType } from '../schema/auth'; -import type { OrUndefinedIf, UnwrapTuplePromises } from '../utils/type-utils'; +import type { OrUndefinedIf, Simplify, UnwrapTuplePromises } from '../utils/type-utils'; import type { TRANSACTION_UNSUPPORTED_METHODS } from './constants'; import type { AggregateArgs, @@ -299,7 +299,7 @@ export interface ModelOperations>( args?: SelectSubset>, - ): ZenStackPromise[]>; + ): ZenStackPromise>[]>; /** * Returns a uniquely identified entity. @@ -309,7 +309,7 @@ export interface ModelOperations>( args?: SelectSubset>, - ): ZenStackPromise | null>; + ): ZenStackPromise> | null>; /** * Returns a uniquely identified entity or throws `NotFoundError` if not found. @@ -319,7 +319,7 @@ export interface ModelOperations>( args?: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Returns the first entity. @@ -329,7 +329,7 @@ export interface ModelOperations>( args?: SelectSubset>, - ): ZenStackPromise | null>; + ): ZenStackPromise> | null>; /** * Returns the first entity or throws `NotFoundError` if not found. @@ -339,7 +339,7 @@ export interface ModelOperations>( args?: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Creates a new entity. @@ -395,7 +395,7 @@ export interface ModelOperations>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Creates multiple entities. Only scalar fields are allowed. @@ -446,7 +446,7 @@ export interface ModelOperations>( args?: SelectSubset>, - ): ZenStackPromise[]>; + ): ZenStackPromise>[]>; /** * Updates a uniquely identified entity. @@ -567,7 +567,7 @@ export interface ModelOperations>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Updates multiple entities. @@ -617,7 +617,7 @@ export interface ModelOperations>( args: Subset>, - ): ZenStackPromise[]>; + ): ZenStackPromise>[]>; /** * Creates or updates an entity. @@ -641,7 +641,7 @@ export interface ModelOperations>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Deletes a uniquely identifiable entity. @@ -664,7 +664,7 @@ export interface ModelOperations>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Deletes multiple entities. @@ -709,7 +709,7 @@ export interface ModelOperations>( args?: Subset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Aggregates rows. @@ -730,7 +730,7 @@ export interface ModelOperations>( args: Subset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; /** * Groups rows by columns. @@ -766,7 +766,7 @@ export interface ModelOperations>( args: Subset>, - ): ZenStackPromise>; + ): ZenStackPromise>>; } //#endregion diff --git a/packages/runtime/src/client/crud-types.ts b/packages/runtime/src/client/crud-types.ts index 4643991d..259e1023 100644 --- a/packages/runtime/src/client/crud-types.ts +++ b/packages/runtime/src/client/crud-types.ts @@ -77,13 +77,21 @@ type ModelSelectResult RelationFieldType, FieldIsArray > - ? ModelResult< - Schema, - RelationFieldType, - Select[Key], - FieldIsOptional, - FieldIsArray - > + ? 'select' extends keyof Select[Key] + ? ModelResult< + Schema, + RelationFieldType, + Pick, + FieldIsOptional, + FieldIsArray + > + : ModelResult< + Schema, + RelationFieldType, + Pick, + FieldIsOptional, + FieldIsArray + > : DefaultModelResult< Schema, RelationFieldType, diff --git a/packages/runtime/src/utils/type-utils.ts b/packages/runtime/src/utils/type-utils.ts index abd963a5..6769f177 100644 --- a/packages/runtime/src/utils/type-utils.ts +++ b/packages/runtime/src/utils/type-utils.ts @@ -6,6 +6,16 @@ export type NullableIf = Condition extends true ? export type PartialRecord = Partial>; +type _Preserve = Date | Function | Decimal | Uint8Array; +type _Depth = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; +export type Simplify = D extends 0 + ? T + : T extends object + ? T extends _Preserve + ? T + : { [K in keyof T]: Simplify } & {} + : T; + export type WrapType = Optional extends true ? T | null : Array extends true @@ -24,17 +34,17 @@ export type MapBaseType = T extends 'String' ? Decimal : T extends 'DateTime' ? Date - : T extends 'Json' - ? JsonValue - : unknown; + : T extends 'Bytes' + ? Uint8Array + : T extends 'Json' + ? JsonValue + : unknown; export type JsonValue = string | number | boolean | null | JsonObject | JsonArray; export type JsonObject = { [key: string]: JsonValue }; export type JsonArray = Array; -export type Simplify = { [Key in keyof T]: T[Key] } & {}; - export function call(code: string) { return { code }; } diff --git a/packages/runtime/test/typing/verify-typing.ts b/packages/runtime/test/typing/verify-typing.ts index e616140e..86389616 100644 --- a/packages/runtime/test/typing/verify-typing.ts +++ b/packages/runtime/test/typing/verify-typing.ts @@ -1,7 +1,7 @@ +import SQLite from 'better-sqlite3'; import { ZenStackClient } from '../../dist'; import { Role } from './models'; import { schema } from './schema'; -import SQLite from 'better-sqlite3'; const client = new ZenStackClient(schema, { dialectConfig: { @@ -147,6 +147,45 @@ async function find() { }, }) ).profile?.region?.city; + + ( + await client.user.findFirstOrThrow({ + select: { + posts: { + where: { title: 'Foo' }, + select: { + author: { + select: { + id: true, + }, + }, + }, + }, + }, + }) + ).posts[0]?.author?.id; + + const u = await client.user.findFirstOrThrow({ + select: { + posts: { + where: { title: 'Foo' }, + select: { + author: { + include: { + profile: true, + }, + omit: { + email: true, + }, + }, + }, + }, + }, + }); + console.log(u.posts[0]?.author?.profile?.age); + console.log(u.posts[0]?.author?.role); + // @ts-expect-error + console.log(u.posts[0]?.author?.email); } async function create() {