@zenstackhq/orm 3.4.0-beta.2 → 3.4.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -409,6 +409,7 @@ type toKyselyFieldType<Schema extends SchemaDef, Model extends GetModels<Schema>
409
409
  declare class InputValidator<Schema extends SchemaDef> {
410
410
  private readonly client;
411
411
  private readonly schemaCache;
412
+ private readonly allFilterKinds;
412
413
  constructor(client: ClientContract<Schema>);
413
414
  private get schema();
414
415
  private get options();
@@ -502,7 +503,7 @@ declare class InputValidator<Schema extends SchemaDef> {
502
503
  private get providerSupportsCaseSensitivity();
503
504
  /**
504
505
  * Gets the effective set of allowed FilterKind values for a specific model and field.
505
- * Respects the precedence: field-level > model-level $all > global $all.
506
+ * Respects the precedence: model[field] > model.$all > $all[field] > $all.$all.
506
507
  */
507
508
  private getEffectiveFilterKinds;
508
509
  /**
@@ -829,7 +830,7 @@ type SlicingOptions<Schema extends SchemaDef> = {
829
830
  * Model slicing options.
830
831
  */
831
832
  models?: {
832
- [Model in GetModels<Schema>]?: ModelSlicingOptions<Schema, Model>;
833
+ [Model in GetModels<Schema> as Uncapitalize<Model>]?: ModelSlicingOptions<Schema, Model>;
833
834
  } & {
834
835
  /**
835
836
  * Slicing options that apply to all models. Model-specific options will override these general
@@ -994,9 +995,9 @@ type GetSlicedModels<Schema extends SchemaDef, Options extends QueryOptions<Sche
994
995
  type GetSlicedOperations<Schema extends SchemaDef, Model extends GetModels<Schema>, Options extends QueryOptions<Schema>> = Options['slicing'] extends infer Slicing ? Slicing extends SlicingOptions<Schema> ? GetIncludedOperations<Slicing, Model> extends infer IO ? GetExcludedOperations<Slicing, Model> extends infer EO ? IO extends '_none_' ? never : IsNever<IO> extends false ? Exclude<IO, EO> : Exclude<AllCrudOperations, EO> : AllCrudOperations : AllCrudOperations : AllCrudOperations : AllCrudOperations;
995
996
  type GetIncludedOperations<Slicing extends SlicingOptions<any>, Model extends string> = 'models' extends keyof Slicing ? Slicing extends {
996
997
  models: infer Config;
997
- } ? Model extends keyof Config ? 'includedOperations' extends keyof Config[Model] ? Config[Model] extends {
998
+ } ? Uncapitalize<Model> extends keyof Config ? 'includedOperations' extends keyof Config[Uncapitalize<Model>] ? Config[Uncapitalize<Model>] extends {
998
999
  includedOperations: readonly [];
999
- } ? '_none_' : Config[Model] extends {
1000
+ } ? '_none_' : Config[Uncapitalize<Model>] extends {
1000
1001
  includedOperations: readonly (infer IO)[];
1001
1002
  } ? IO : never : GetAllIncludedOperations<Slicing> : GetAllIncludedOperations<Slicing> : AllCrudOperations : AllCrudOperations;
1002
1003
  type GetAllIncludedOperations<Slicing extends SlicingOptions<any>> = 'models' extends keyof Slicing ? Slicing extends {
@@ -1008,7 +1009,7 @@ type GetAllIncludedOperations<Slicing extends SlicingOptions<any>> = 'models' ex
1008
1009
  } ? IO : AllCrudOperations : AllCrudOperations : AllCrudOperations : AllCrudOperations;
1009
1010
  type GetExcludedOperations<Slicing extends SlicingOptions<any>, Model extends string> = 'models' extends keyof Slicing ? Slicing extends {
1010
1011
  models: infer Config;
1011
- } ? Model extends keyof Config ? Config[Model] extends {
1012
+ } ? Uncapitalize<Model> extends keyof Config ? Config[Uncapitalize<Model>] extends {
1012
1013
  excludedOperations: readonly (infer EO)[];
1013
1014
  } ? EO : GetAllExcludedOperations<Slicing> : GetAllExcludedOperations<Slicing> : never : never;
1014
1015
  type GetAllExcludedOperations<Slicing extends SlicingOptions<any>> = 'models' extends keyof Slicing ? Slicing extends {
@@ -1035,7 +1036,7 @@ type GetIncludedFilterKindsFromModelConfig<ModelConfig, Field extends string> =
1035
1036
  } ? IFK : never : GetAllFieldsIncludedFilterKinds<FieldsConfig> : GetAllFieldsIncludedFilterKinds<FieldsConfig> : never : never;
1036
1037
  type GetFieldIncludedFilterKinds<S extends SlicingOptions<any>, Model extends string, Field extends string> = S extends {
1037
1038
  models?: infer Config;
1038
- } ? Model extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config[Model], Field> : '$all' extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1039
+ } ? Uncapitalize<Model> extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config[Uncapitalize<Model>], Field> : '$all' extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1039
1040
  type GetAllFieldsIncludedFilterKinds<FieldsConfig> = '$all' extends keyof FieldsConfig ? FieldsConfig['$all'] extends {
1040
1041
  includedFilterKinds: readonly [];
1041
1042
  } ? '_none_' : FieldsConfig['$all'] extends {
@@ -1046,7 +1047,7 @@ type GetExcludedFilterKindsFromModelConfig<ModelConfig, Field extends string> =
1046
1047
  } ? EFK : GetAllFieldsExcludedFilterKinds<FieldsConfig> : GetAllFieldsExcludedFilterKinds<FieldsConfig> : never : never;
1047
1048
  type GetFieldExcludedFilterKinds<S extends SlicingOptions<any>, Model extends string, Field extends string> = S extends {
1048
1049
  models?: infer Config;
1049
- } ? Model extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config[Model], Field> : '$all' extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1050
+ } ? Uncapitalize<Model> extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config[Uncapitalize<Model>], Field> : '$all' extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1050
1051
  type GetAllFieldsExcludedFilterKinds<FieldsConfig> = '$all' extends keyof FieldsConfig ? FieldsConfig['$all'] extends {
1051
1052
  excludedFilterKinds: readonly (infer EFK)[];
1052
1053
  } ? EFK : never : never;
package/dist/index.d.ts CHANGED
@@ -409,6 +409,7 @@ type toKyselyFieldType<Schema extends SchemaDef, Model extends GetModels<Schema>
409
409
  declare class InputValidator<Schema extends SchemaDef> {
410
410
  private readonly client;
411
411
  private readonly schemaCache;
412
+ private readonly allFilterKinds;
412
413
  constructor(client: ClientContract<Schema>);
413
414
  private get schema();
414
415
  private get options();
@@ -502,7 +503,7 @@ declare class InputValidator<Schema extends SchemaDef> {
502
503
  private get providerSupportsCaseSensitivity();
503
504
  /**
504
505
  * Gets the effective set of allowed FilterKind values for a specific model and field.
505
- * Respects the precedence: field-level > model-level $all > global $all.
506
+ * Respects the precedence: model[field] > model.$all > $all[field] > $all.$all.
506
507
  */
507
508
  private getEffectiveFilterKinds;
508
509
  /**
@@ -829,7 +830,7 @@ type SlicingOptions<Schema extends SchemaDef> = {
829
830
  * Model slicing options.
830
831
  */
831
832
  models?: {
832
- [Model in GetModels<Schema>]?: ModelSlicingOptions<Schema, Model>;
833
+ [Model in GetModels<Schema> as Uncapitalize<Model>]?: ModelSlicingOptions<Schema, Model>;
833
834
  } & {
834
835
  /**
835
836
  * Slicing options that apply to all models. Model-specific options will override these general
@@ -994,9 +995,9 @@ type GetSlicedModels<Schema extends SchemaDef, Options extends QueryOptions<Sche
994
995
  type GetSlicedOperations<Schema extends SchemaDef, Model extends GetModels<Schema>, Options extends QueryOptions<Schema>> = Options['slicing'] extends infer Slicing ? Slicing extends SlicingOptions<Schema> ? GetIncludedOperations<Slicing, Model> extends infer IO ? GetExcludedOperations<Slicing, Model> extends infer EO ? IO extends '_none_' ? never : IsNever<IO> extends false ? Exclude<IO, EO> : Exclude<AllCrudOperations, EO> : AllCrudOperations : AllCrudOperations : AllCrudOperations : AllCrudOperations;
995
996
  type GetIncludedOperations<Slicing extends SlicingOptions<any>, Model extends string> = 'models' extends keyof Slicing ? Slicing extends {
996
997
  models: infer Config;
997
- } ? Model extends keyof Config ? 'includedOperations' extends keyof Config[Model] ? Config[Model] extends {
998
+ } ? Uncapitalize<Model> extends keyof Config ? 'includedOperations' extends keyof Config[Uncapitalize<Model>] ? Config[Uncapitalize<Model>] extends {
998
999
  includedOperations: readonly [];
999
- } ? '_none_' : Config[Model] extends {
1000
+ } ? '_none_' : Config[Uncapitalize<Model>] extends {
1000
1001
  includedOperations: readonly (infer IO)[];
1001
1002
  } ? IO : never : GetAllIncludedOperations<Slicing> : GetAllIncludedOperations<Slicing> : AllCrudOperations : AllCrudOperations;
1002
1003
  type GetAllIncludedOperations<Slicing extends SlicingOptions<any>> = 'models' extends keyof Slicing ? Slicing extends {
@@ -1008,7 +1009,7 @@ type GetAllIncludedOperations<Slicing extends SlicingOptions<any>> = 'models' ex
1008
1009
  } ? IO : AllCrudOperations : AllCrudOperations : AllCrudOperations : AllCrudOperations;
1009
1010
  type GetExcludedOperations<Slicing extends SlicingOptions<any>, Model extends string> = 'models' extends keyof Slicing ? Slicing extends {
1010
1011
  models: infer Config;
1011
- } ? Model extends keyof Config ? Config[Model] extends {
1012
+ } ? Uncapitalize<Model> extends keyof Config ? Config[Uncapitalize<Model>] extends {
1012
1013
  excludedOperations: readonly (infer EO)[];
1013
1014
  } ? EO : GetAllExcludedOperations<Slicing> : GetAllExcludedOperations<Slicing> : never : never;
1014
1015
  type GetAllExcludedOperations<Slicing extends SlicingOptions<any>> = 'models' extends keyof Slicing ? Slicing extends {
@@ -1035,7 +1036,7 @@ type GetIncludedFilterKindsFromModelConfig<ModelConfig, Field extends string> =
1035
1036
  } ? IFK : never : GetAllFieldsIncludedFilterKinds<FieldsConfig> : GetAllFieldsIncludedFilterKinds<FieldsConfig> : never : never;
1036
1037
  type GetFieldIncludedFilterKinds<S extends SlicingOptions<any>, Model extends string, Field extends string> = S extends {
1037
1038
  models?: infer Config;
1038
- } ? Model extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config[Model], Field> : '$all' extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1039
+ } ? Uncapitalize<Model> extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config[Uncapitalize<Model>], Field> : '$all' extends keyof Config ? GetIncludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1039
1040
  type GetAllFieldsIncludedFilterKinds<FieldsConfig> = '$all' extends keyof FieldsConfig ? FieldsConfig['$all'] extends {
1040
1041
  includedFilterKinds: readonly [];
1041
1042
  } ? '_none_' : FieldsConfig['$all'] extends {
@@ -1046,7 +1047,7 @@ type GetExcludedFilterKindsFromModelConfig<ModelConfig, Field extends string> =
1046
1047
  } ? EFK : GetAllFieldsExcludedFilterKinds<FieldsConfig> : GetAllFieldsExcludedFilterKinds<FieldsConfig> : never : never;
1047
1048
  type GetFieldExcludedFilterKinds<S extends SlicingOptions<any>, Model extends string, Field extends string> = S extends {
1048
1049
  models?: infer Config;
1049
- } ? Model extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config[Model], Field> : '$all' extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1050
+ } ? Uncapitalize<Model> extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config[Uncapitalize<Model>], Field> : '$all' extends keyof Config ? GetExcludedFilterKindsFromModelConfig<Config['$all'], Field> : never : never;
1050
1051
  type GetAllFieldsExcludedFilterKinds<FieldsConfig> = '$all' extends keyof FieldsConfig ? FieldsConfig['$all'] extends {
1051
1052
  excludedFilterKinds: readonly (infer EFK)[];
1052
1053
  } ? EFK : never : never;
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
19
 
20
20
  // src/client/client-impl.ts
21
- import { invariant as invariant14 } from "@zenstackhq/common-helpers";
21
+ import { invariant as invariant14, lowerCaseFirst as lowerCaseFirst3 } from "@zenstackhq/common-helpers";
22
22
  import { CompiledQuery, DefaultConnectionProvider, DefaultQueryExecutor as DefaultQueryExecutor2, Kysely, Log, sql as sql8, Transaction } from "kysely";
23
23
 
24
24
  // src/client/crud/operations/aggregate.ts
@@ -4591,7 +4591,7 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4591
4591
  };
4592
4592
 
4593
4593
  // src/client/crud/validator/index.ts
4594
- import { enumerate as enumerate3, invariant as invariant9 } from "@zenstackhq/common-helpers";
4594
+ import { enumerate as enumerate3, invariant as invariant9, lowerCaseFirst } from "@zenstackhq/common-helpers";
4595
4595
  import Decimal5 from "decimal.js";
4596
4596
  import { match as match14, P as P3 } from "ts-pattern";
4597
4597
  import { z as z2, ZodType } from "zod";
@@ -5017,6 +5017,9 @@ var InputValidator = class {
5017
5017
  }
5018
5018
  client;
5019
5019
  schemaCache = /* @__PURE__ */ new Map();
5020
+ allFilterKinds = [
5021
+ ...new Set(Object.values(FILTER_PROPERTY_TO_KIND))
5022
+ ];
5020
5023
  constructor(client) {
5021
5024
  this.client = client;
5022
5025
  }
@@ -5301,7 +5304,7 @@ var InputValidator = class {
5301
5304
  continue;
5302
5305
  }
5303
5306
  const allowedFilterKinds = this.getEffectiveFilterKinds(model, field);
5304
- if (allowedFilterKinds && !allowedFilterKinds.has("Relation")) {
5307
+ if (allowedFilterKinds && !allowedFilterKinds.includes("Relation")) {
5305
5308
  fieldSchema = z2.never();
5306
5309
  } else {
5307
5310
  fieldSchema = z2.lazy(() => this.makeWhereSchema(fieldDef.type, false).optional());
@@ -5523,7 +5526,7 @@ var InputValidator = class {
5523
5526
  }
5524
5527
  makeJsonFilterSchema(contextModel, field, optional) {
5525
5528
  const allowedFilterKinds = this.getEffectiveFilterKinds(contextModel, field);
5526
- if (allowedFilterKinds && !allowedFilterKinds.has("Json")) {
5529
+ if (allowedFilterKinds && !allowedFilterKinds.includes("Json")) {
5527
5530
  return z2.never();
5528
5531
  }
5529
5532
  const valueSchema = this.makeJsonValueSchema(optional, true);
@@ -6384,7 +6387,7 @@ var InputValidator = class {
6384
6387
  }
6385
6388
  /**
6386
6389
  * Gets the effective set of allowed FilterKind values for a specific model and field.
6387
- * Respects the precedence: field-level > model-level $all > global $all.
6390
+ * Respects the precedence: model[field] > model.$all > $all[field] > $all.$all.
6388
6391
  */
6389
6392
  getEffectiveFilterKinds(model, field) {
6390
6393
  if (!model) {
@@ -6394,21 +6397,27 @@ var InputValidator = class {
6394
6397
  if (!slicing?.models) {
6395
6398
  return void 0;
6396
6399
  }
6397
- const modelConfig = slicing.models[model];
6400
+ const modelsRecord = slicing.models;
6401
+ const modelConfig = modelsRecord[lowerCaseFirst(model)];
6398
6402
  if (modelConfig?.fields) {
6399
6403
  const fieldConfig = modelConfig.fields[field];
6400
6404
  if (fieldConfig) {
6401
6405
  return this.computeFilterKinds(fieldConfig.includedFilterKinds, fieldConfig.excludedFilterKinds);
6402
6406
  }
6403
- const allFieldsConfig = modelConfig.fields.$all;
6407
+ const allFieldsConfig = modelConfig.fields["$all"];
6404
6408
  if (allFieldsConfig) {
6405
6409
  return this.computeFilterKinds(allFieldsConfig.includedFilterKinds, allFieldsConfig.excludedFilterKinds);
6406
6410
  }
6407
6411
  }
6408
- const allModelsConfig = slicing.models.$all;
6412
+ const allModelsConfig = modelsRecord["$all"];
6409
6413
  if (allModelsConfig?.fields) {
6410
- if (allModelsConfig.fields.$all) {
6411
- return this.computeFilterKinds(allModelsConfig.fields.$all.includedFilterKinds, allModelsConfig.fields.$all.excludedFilterKinds);
6414
+ const allModelsFieldConfig = allModelsConfig.fields[field];
6415
+ if (allModelsFieldConfig) {
6416
+ return this.computeFilterKinds(allModelsFieldConfig.includedFilterKinds, allModelsFieldConfig.excludedFilterKinds);
6417
+ }
6418
+ const allModelsAllFieldsConfig = allModelsConfig.fields["$all"];
6419
+ if (allModelsAllFieldsConfig) {
6420
+ return this.computeFilterKinds(allModelsAllFieldsConfig.includedFilterKinds, allModelsAllFieldsConfig.excludedFilterKinds);
6412
6421
  }
6413
6422
  }
6414
6423
  return void 0;
@@ -6419,21 +6428,18 @@ var InputValidator = class {
6419
6428
  computeFilterKinds(included, excluded) {
6420
6429
  let result;
6421
6430
  if (included !== void 0) {
6422
- result = new Set(included);
6431
+ result = [
6432
+ ...included
6433
+ ];
6423
6434
  }
6424
6435
  if (excluded !== void 0) {
6425
6436
  if (!result) {
6426
- result = /* @__PURE__ */ new Set([
6427
- "Equality",
6428
- "Range",
6429
- "Like",
6430
- "Json",
6431
- "List",
6432
- "Relation"
6433
- ]);
6437
+ result = [
6438
+ ...this.allFilterKinds
6439
+ ];
6434
6440
  }
6435
6441
  for (const kind of excluded) {
6436
- result.delete(kind);
6442
+ result = result.filter((k) => k !== kind);
6437
6443
  }
6438
6444
  }
6439
6445
  return result;
@@ -6446,17 +6452,17 @@ var InputValidator = class {
6446
6452
  return operators;
6447
6453
  }
6448
6454
  return Object.fromEntries(Object.entries(operators).filter(([key, _]) => {
6449
- return !(key in FILTER_PROPERTY_TO_KIND) || allowedKinds.has(FILTER_PROPERTY_TO_KIND[key]);
6455
+ return !(key in FILTER_PROPERTY_TO_KIND) || allowedKinds.includes(FILTER_PROPERTY_TO_KIND[key]);
6450
6456
  }));
6451
6457
  }
6452
6458
  createUnionFilterSchema(valueSchema, optional, components, allowedFilterKinds) {
6453
6459
  if (Object.keys(components).length === 0) {
6454
- if (!allowedFilterKinds || allowedFilterKinds.has("Equality")) {
6460
+ if (!allowedFilterKinds || allowedFilterKinds.includes("Equality")) {
6455
6461
  return this.nullableIf(valueSchema, optional);
6456
6462
  }
6457
6463
  return z2.never();
6458
6464
  }
6459
- if (!allowedFilterKinds || allowedFilterKinds.has("Equality")) {
6465
+ if (!allowedFilterKinds || allowedFilterKinds.includes("Equality")) {
6460
6466
  return z2.union([
6461
6467
  this.nullableIf(valueSchema, optional),
6462
6468
  z2.strictObject(components)
@@ -8141,7 +8147,7 @@ __export(functions_exports, {
8141
8147
  search: () => search,
8142
8148
  startsWith: () => startsWith
8143
8149
  });
8144
- import { invariant as invariant12, lowerCaseFirst, upperCaseFirst } from "@zenstackhq/common-helpers";
8150
+ import { invariant as invariant12, lowerCaseFirst as lowerCaseFirst2, upperCaseFirst } from "@zenstackhq/common-helpers";
8145
8151
  import { sql as sql6, ValueNode as ValueNode3 } from "kysely";
8146
8152
  import { match as match16 } from "ts-pattern";
8147
8153
  var contains = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "contains"), "contains");
@@ -8252,7 +8258,7 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
8252
8258
  function processCasing(casing, result, model) {
8253
8259
  const opNode = casing.toOperationNode();
8254
8260
  invariant12(ValueNode3.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
8255
- result = match16(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst(result)).otherwise(() => {
8261
+ result = match16(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst2(result)).otherwise(() => {
8256
8262
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
8257
8263
  });
8258
8264
  return result;
@@ -9208,7 +9214,7 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
9208
9214
  };
9209
9215
  const slicing = client.$options.slicing;
9210
9216
  if (slicing?.models) {
9211
- const modelSlicing = slicing.models[model];
9217
+ const modelSlicing = slicing.models[lowerCaseFirst3(model)];
9212
9218
  const allSlicing = slicing.models.$all;
9213
9219
  const includedOperations = modelSlicing?.includedOperations ?? allSlicing?.includedOperations;
9214
9220
  const excludedOperations = modelSlicing?.excludedOperations ?? allSlicing?.excludedOperations;