Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions packages/clients/client-helpers/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ClientContract, QueryOptions } from '@zenstackhq/orm';
import { ExtQueryArgsMarker, ExtResultMarker, type QueryOptions } from '@zenstackhq/orm';
import type { SchemaDef } from '@zenstackhq/schema';

/**
Expand All @@ -11,10 +11,15 @@ export type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;
*/
export type InferSchema<T> = T extends { $schema: infer S extends SchemaDef } ? S : T extends SchemaDef ? T : never;

/**
* Extracts the ExtQueryArgs type from a client contract, or defaults to `{}`.
*/
export type InferExtQueryArgs<T> = T extends { [ExtQueryArgsMarker]?: infer E } ? (unknown extends E ? {} : E) : {};

/**
* Extracts the ExtResult type from a client contract, or defaults to `{}`.
*/
export type InferExtResult<T> = T extends ClientContract<any, any, any, any, infer E> ? E : {};
export type InferExtResult<T> = T extends { [ExtResultMarker]?: infer E } ? (unknown extends E ? {} : E) : {};

/**
* Infers query options from a client contract type, or defaults to `QueryOptions<Schema>`.
Expand Down
2 changes: 1 addition & 1 deletion packages/clients/tanstack-query/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@zenstackhq/client-helpers": "workspace:*",
"@zenstackhq/common-helpers": "workspace:*",
"@zenstackhq/schema": "workspace:*",
"@zenstackhq/orm": "workspace:*",
"decimal.js": "catalog:"
},
"devDependencies": {
Expand All @@ -71,7 +72,6 @@
"@zenstackhq/cli": "workspace:*",
"@zenstackhq/eslint-config": "workspace:*",
"@zenstackhq/language": "workspace:*",
"@zenstackhq/orm": "workspace:*",
"@zenstackhq/sdk": "workspace:*",
"@zenstackhq/typescript-config": "workspace:*",
"@zenstackhq/vitest-config": "workspace:*",
Expand Down
99 changes: 50 additions & 49 deletions packages/clients/tanstack-query/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
import type { Logger, OptimisticDataProvider } from '@zenstackhq/client-helpers';
import type { FetchFn } from '@zenstackhq/client-helpers/fetch';
import type {
AggregateArgs,
CountArgs,
CreateArgs,
CreateManyAndReturnArgs,
CreateManyArgs,
DeleteArgs,
DeleteManyArgs,
ExistsArgs,
FindFirstArgs,
FindManyArgs,
FindUniqueArgs,
CoreCrudOperations,
CrudArgsMap,
CrudReturnMap,
ExtQueryArgsBase,
ExtResultBase,
GetProcedureNames,
GetSlicedOperations,
GroupByArgs,
ModelAllowsCreate,
OperationsRequiringCreate,
ProcedureFunc,
QueryOptions,
UpdateArgs,
UpdateManyAndReturnArgs,
UpdateManyArgs,
UpsertArgs,
} from '@zenstackhq/orm';
import type { GetModels, SchemaDef } from '@zenstackhq/schema';

Expand Down Expand Up @@ -118,46 +107,58 @@ export type ProcedureReturn<Schema extends SchemaDef, Name extends GetProcedureN
>;

/**
* Maps each core CRUD operation to its argument type for a given model.
* Operations available in a sequential transaction.
*/
type CrudArgsMap<Schema extends SchemaDef, Model extends GetModels<Schema>> = {
findMany: FindManyArgs<Schema, Model>;
findUnique: FindUniqueArgs<Schema, Model>;
findFirst: FindFirstArgs<Schema, Model>;
create: CreateArgs<Schema, Model>;
createMany: CreateManyArgs<Schema, Model>;
createManyAndReturn: CreateManyAndReturnArgs<Schema, Model>;
update: UpdateArgs<Schema, Model>;
updateMany: UpdateManyArgs<Schema, Model>;
updateManyAndReturn: UpdateManyAndReturnArgs<Schema, Model>;
upsert: UpsertArgs<Schema, Model>;
delete: DeleteArgs<Schema, Model>;
deleteMany: DeleteManyArgs<Schema, Model>;
count: CountArgs<Schema, Model>;
aggregate: AggregateArgs<Schema, Model>;
groupBy: GroupByArgs<Schema, Model>;
exists: ExistsArgs<Schema, Model>;
};

/**
* Operations available for a given model, omitting create-style operations
* for models that don't allow them (e.g. delegate models).
*/
type AllowedTransactionOps<Schema extends SchemaDef, Model extends GetModels<Schema>> =
type AllowedTransactionOps<
Schema extends SchemaDef,
Model extends GetModels<Schema>,
Options extends QueryOptions<Schema> = QueryOptions<Schema>,
> =
ModelAllowsCreate<Schema, Model> extends true
? keyof CrudArgsMap<Schema, Model>
: Exclude<keyof CrudArgsMap<Schema, Model>, OperationsRequiringCreate>;
? GetSlicedOperations<Schema, Model, Options> & CoreCrudOperations
: Exclude<GetSlicedOperations<Schema, Model, Options> & CoreCrudOperations, OperationsRequiringCreate>;

/**
* Represents a single operation to execute within a sequential transaction.
*
* The `model`, `op`, and `args` fields are correlated: `op` is constrained to
* the CRUD operations available on `model`, and `args` is typed accordingly.
* the CRUD operations available on `model` (respecting `Options['slicing']`), and
* `args` is typed accordingly.
*/
export type TransactionOperation<Schema extends SchemaDef> = {
export type TransactionOperation<
Schema extends SchemaDef,
Options extends QueryOptions<Schema> = QueryOptions<Schema>,
ExtQueryArgs extends ExtQueryArgsBase = {},
ExtResult extends ExtResultBase<Schema> = {},
> = {
[Model in GetModels<Schema>]: {
[Op in AllowedTransactionOps<Schema, Model>]: {} extends CrudArgsMap<Schema, Model>[Op]
? { model: Model; op: Op; args?: CrudArgsMap<Schema, Model>[Op] }
: { model: Model; op: Op; args: CrudArgsMap<Schema, Model>[Op] };
}[AllowedTransactionOps<Schema, Model>];
[Op in AllowedTransactionOps<Schema, Model, Options>]: {} extends CrudArgsMap<
Schema,
Model,
Options,
ExtQueryArgs,
ExtResult
>[Op]
? { model: Model; op: Op; args?: CrudArgsMap<Schema, Model, Options, ExtQueryArgs, ExtResult>[Op] }
: { model: Model; op: Op; args: CrudArgsMap<Schema, Model, Options, ExtQueryArgs, ExtResult>[Op] };
}[AllowedTransactionOps<Schema, Model, Options>];
}[GetModels<Schema>];

/**
* Maps each operation in a transaction tuple to its precise result type, preserving
* per-position typing.
*/
export type TransactionResults<
Schema extends SchemaDef,
Ops extends readonly TransactionOperation<Schema, any, any, any>[],
Options extends QueryOptions<Schema> = QueryOptions<Schema>,
ExtResult extends ExtResultBase<Schema> = {},
> = {
[K in keyof Ops]: Ops[K] extends { model: infer M; op: infer O; args?: infer A }
? M extends GetModels<Schema>
? O extends keyof CrudReturnMap<Schema, M, A, Options, ExtResult>
? CrudReturnMap<Schema, M, A, Options, ExtResult>[O]
: never
: never
: never;
};
Loading
Loading