From 8f6b8f4b3b4341e7459e43db6e46e13d87e7ac3f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Tue, 5 May 2026 19:15:09 -0700 Subject: [PATCH] refactor(orm): make ZenStackPromise compatible with standard Promise signature Drop the `Schema` type parameter from `ZenStackPromise` and remove the public `cb` property from its type, so the type is structurally assignable to a standard `Promise`. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/orm/src/client/client-impl.ts | 14 +++++-- packages/orm/src/client/contract.ts | 57 +++++++++++--------------- packages/orm/src/client/promise.ts | 15 +++---- 3 files changed, 40 insertions(+), 46 deletions(-) diff --git a/packages/orm/src/client/client-impl.ts b/packages/orm/src/client/client-impl.ts index d96984aef..0fb4e4dbd 100644 --- a/packages/orm/src/client/client-impl.ts +++ b/packages/orm/src/client/client-impl.ts @@ -223,7 +223,7 @@ export class ClientImpl { ): Promise; // overload for sequential transaction - $transaction

[]>( + $transaction

[]>( arg: [...P], options?: { isolationLevel?: TransactionIsolationLevel }, ): Promise>; @@ -268,8 +268,15 @@ export class ClientImpl { } } + private getPromiseCallback(promise: ZenStackPromise) { + invariant((promise as any).cb, 'Invalid ZenStackPromise, missing cb property'); + const cb = (promise as any).cb; + invariant(typeof cb === 'function', 'Invalid ZenStackPromise, cb property is not a function'); + return (promise as any).cb; + } + private async sequentialTransaction( - arg: ZenStackPromise[], + arg: ZenStackPromise[], options?: { isolationLevel?: TransactionIsolationLevel }, ) { const execute = async (tx: AnyKysely) => { @@ -277,7 +284,8 @@ export class ClientImpl { txClient.kysely = tx; const result: any[] = []; for (const promise of arg) { - result.push(await promise.cb(txClient as unknown as ClientContract)); + const cb = this.getPromiseCallback(promise); + result.push(await cb(txClient as unknown as ClientContract)); } return result; }; diff --git a/packages/orm/src/client/contract.ts b/packages/orm/src/client/contract.ts index 3f9fb493a..f9a8aeae4 100644 --- a/packages/orm/src/client/contract.ts +++ b/packages/orm/src/client/contract.ts @@ -94,7 +94,7 @@ export type ClientContract< * const result = await db.$executeRaw`UPDATE User SET cool = ${true} WHERE email = ${'user@email.com'};` * ``` */ - $executeRaw(query: TemplateStringsArray, ...values: any[]): ZenStackPromise; + $executeRaw(query: TemplateStringsArray, ...values: any[]): ZenStackPromise; /** * Executes a raw query and returns the number of affected rows. @@ -104,7 +104,7 @@ export type ClientContract< * const result = await db.$executeRawUnsafe('UPDATE User SET cool = $1 WHERE email = $2 ;', true, 'user@email.com') * ``` */ - $executeRawUnsafe(query: string, ...values: any[]): ZenStackPromise; + $executeRawUnsafe(query: string, ...values: any[]): ZenStackPromise; /** * Performs a prepared raw query and returns the `SELECT` data. @@ -113,7 +113,7 @@ export type ClientContract< * const result = await db.$queryRaw`SELECT * FROM User WHERE id = ${1} OR email = ${'user@email.com'};` * ``` */ - $queryRaw(query: TemplateStringsArray, ...values: any[]): ZenStackPromise; + $queryRaw(query: TemplateStringsArray, ...values: any[]): ZenStackPromise; /** * Performs a raw query and returns the `SELECT` data. @@ -123,7 +123,7 @@ export type ClientContract< * const result = await db.$queryRawUnsafe('SELECT * FROM User WHERE id = $1 OR email = $2;', 1, 'user@email.com') * ``` */ - $queryRawUnsafe(query: string, ...values: any[]): ZenStackPromise; + $queryRawUnsafe(query: string, ...values: any[]): ZenStackPromise; /** * The current user identity. If the client is not bound to any user context, returns `undefined`. @@ -205,7 +205,7 @@ export type ClientContract< * db.post.create({ data: { title: 'Hello World', authorId: 1 } }), * ]); */ - $transaction

[]>( + $transaction

[]>( arg: [...P], options?: { isolationLevel?: TransactionIsolationLevel }, ): Promise>; @@ -388,10 +388,7 @@ export type AllModelOperations< T, CrudArgsType >, - ): ZenStackPromise< - Schema, - CrudReturnType - >; + ): ZenStackPromise>; /** * Updates multiple entities and returns them. @@ -418,14 +415,8 @@ export type AllModelOperations< updateManyAndReturn< T extends CrudArgsType, >( - args: Subset< - T, - CrudArgsType - >, - ): ZenStackPromise< - Schema, - CrudReturnType - >; + args: Subset>, + ): ZenStackPromise>; }); type CommonModelOperations< @@ -518,7 +509,7 @@ type CommonModelOperations< */ findMany>( args?: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Returns a uniquely identified entity. @@ -528,7 +519,7 @@ type CommonModelOperations< */ findUnique>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Returns a uniquely identified entity or throws `NotFoundError` if not found. @@ -538,7 +529,7 @@ type CommonModelOperations< */ findUniqueOrThrow>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Returns the first entity. @@ -548,7 +539,7 @@ type CommonModelOperations< */ findFirst>( args?: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Returns the first entity or throws `NotFoundError` if not found. @@ -558,7 +549,7 @@ type CommonModelOperations< */ findFirstOrThrow>( args?: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Creates a new entity. @@ -614,7 +605,7 @@ type CommonModelOperations< */ create>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Creates multiple entities. Only scalar fields are allowed. @@ -643,7 +634,7 @@ type CommonModelOperations< */ createMany>( args?: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Updates a uniquely identified entity. @@ -764,7 +755,7 @@ type CommonModelOperations< */ update>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Updates multiple entities. @@ -788,7 +779,7 @@ type CommonModelOperations< */ updateMany>( args: Subset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Creates or updates an entity. @@ -812,7 +803,7 @@ type CommonModelOperations< */ upsert>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Deletes a uniquely identifiable entity. @@ -835,7 +826,7 @@ type CommonModelOperations< */ delete>( args: SelectSubset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Deletes multiple entities. @@ -858,7 +849,7 @@ type CommonModelOperations< */ deleteMany>( args?: Subset>, - ): ZenStackPromise>; + ): ZenStackPromise>; /** * Counts rows or field values. @@ -880,7 +871,7 @@ type CommonModelOperations< */ count>( args?: Subset>, - ): ZenStackPromise>>; + ): ZenStackPromise>>; /** * Aggregates rows. @@ -901,7 +892,7 @@ type CommonModelOperations< */ aggregate>( args: Subset>, - ): ZenStackPromise>>; + ): ZenStackPromise>>; /** * Groups rows by columns. @@ -938,7 +929,7 @@ type CommonModelOperations< */ groupBy>( args: Subset>, - ): ZenStackPromise>>; + ): ZenStackPromise>>; /** * Checks if an entity exists. @@ -959,7 +950,7 @@ type CommonModelOperations< */ exists>( args?: Subset>, - ): ZenStackPromise>; + ): ZenStackPromise>; }; export type OperationsRequiringCreate = 'create' | 'createMany' | 'createManyAndReturn' | 'upsert'; diff --git a/packages/orm/src/client/promise.ts b/packages/orm/src/client/promise.ts index 77d9324b9..563e555fa 100644 --- a/packages/orm/src/client/promise.ts +++ b/packages/orm/src/client/promise.ts @@ -1,16 +1,11 @@ -import type { SchemaDef } from '@zenstackhq/schema'; import type { ClientContract } from './contract'; /** * A promise that only executes when it's awaited or .then() is called. */ -export type ZenStackPromise = Promise & { - /** - * @private - * Callable to get a plain promise. - */ - cb: (txClient?: ClientContract) => Promise; -}; +export interface ZenStackPromise extends Promise { + [Symbol.toStringTag]: 'ZenStackPromise'; +} /** * Creates a promise that only executes when it's awaited or .then() is called. @@ -18,7 +13,7 @@ export type ZenStackPromise = Promise & { */ export function createZenStackPromise( callback: (txClient?: ClientContract) => Promise, -): ZenStackPromise { +): ZenStackPromise { let promise: Promise | undefined; const cb = (txClient?: ClientContract) => { try { @@ -41,7 +36,7 @@ export function createZenStackPromise( }, cb, [Symbol.toStringTag]: 'ZenStackPromise', - }; + } as ZenStackPromise; } function valueToPromise(thing: any): Promise {