prisma-arktype 2.4.0 → 2.5.1

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/README.md CHANGED
@@ -132,6 +132,216 @@ const whereResult = UserWhere(whereClause);
132
132
  // ...
133
133
  ```
134
134
 
135
+ ## Where Clause Filters
136
+
137
+ Where clauses support advanced filtering through dedicated filter types. Fields can accept either direct values or filter objects with comparison operators.
138
+
139
+ ### Filter Types
140
+
141
+ #### String Filters
142
+
143
+ String fields can use `StringFilter` for advanced text filtering:
144
+
145
+ ```typescript
146
+ import { UserWhere } from "./generated/validators";
147
+
148
+ // Direct value
149
+ const result1 = UserWhere({ email: "user@example.com" });
150
+
151
+ // Filter object
152
+ const result2 = UserWhere({
153
+ email: {
154
+ contains: "example", // Contains substring
155
+ startsWith: "user", // Starts with prefix
156
+ endsWith: ".com", // Ends with suffix
157
+ equals: "user@example.com", // Exact match
158
+ not: "admin@example.com", // Not equal to
159
+ in: ["user1@example.com", "user2@example.com"], // In array
160
+ notIn: ["banned@example.com"], // Not in array
161
+ gt: "a", // Greater than (lexicographic)
162
+ gte: "a", // Greater than or equal
163
+ lt: "z", // Less than
164
+ lte: "z" // Less than or equal
165
+ }
166
+ });
167
+ ```
168
+
169
+ **Available operations:** `contains`, `startsWith`, `endsWith`, `equals`, `not`, `in`, `notIn`, `gt`, `gte`, `lt`, `lte`
170
+
171
+ #### Number Filters
172
+
173
+ Integer fields (`Int`, `BigInt`) use `IntFilter`, while floating-point fields (`Float`, `Decimal`) use `NumberFilter`:
174
+
175
+ ```typescript
176
+ import { PostWhere } from "./generated/validators";
177
+
178
+ // Direct value
179
+ const result1 = PostWhere({ views: 100 });
180
+
181
+ // Filter object for integers
182
+ const result2 = PostWhere({
183
+ views: {
184
+ equals: 100,
185
+ gt: 50, // Greater than
186
+ gte: 50, // Greater than or equal
187
+ lt: 200, // Less than
188
+ lte: 200, // Less than or equal
189
+ in: [100, 200, 300], // In array
190
+ notIn: [0], // Not in array
191
+ not: 0 // Not equal to
192
+ }
193
+ });
194
+
195
+ // Filter object for floats/decimals
196
+ const result3 = PostWhere({
197
+ rating: {
198
+ gte: 4.5,
199
+ lte: 5.0
200
+ }
201
+ });
202
+ ```
203
+
204
+ **Available operations:** `equals`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `not`
205
+
206
+ #### Boolean Filters
207
+
208
+ Boolean fields use `BooleanFilter`:
209
+
210
+ ```typescript
211
+ import { PostWhere } from "./generated/validators";
212
+
213
+ // Direct value
214
+ const result1 = PostWhere({ published: true });
215
+
216
+ // Filter object
217
+ const result2 = PostWhere({
218
+ published: {
219
+ equals: true,
220
+ not: false
221
+ }
222
+ });
223
+ ```
224
+
225
+ **Available operations:** `equals`, `not`
226
+
227
+ #### Enum Filters
228
+
229
+ Enum fields use the generic `enumFilter`:
230
+
231
+ ```typescript
232
+ import { PaymentWhere } from "./generated/validators";
233
+
234
+ // Direct enum value
235
+ const result1 = PaymentWhere({ currency: "USD" });
236
+
237
+ // Filter object
238
+ const result2 = PaymentWhere({
239
+ currency: {
240
+ equals: "USD",
241
+ in: ["USD", "EUR", "GBP"],
242
+ notIn: ["JPY"],
243
+ not: "CAD"
244
+ }
245
+ });
246
+ ```
247
+
248
+ **Available operations:** `equals`, `in`, `notIn`, `not`
249
+
250
+ #### DateTime Filters
251
+
252
+ DateTime fields use `DateTimeFilter`:
253
+
254
+ ```typescript
255
+ import { PostWhere } from "./generated/validators";
256
+
257
+ // Direct Date value
258
+ const result1 = PostWhere({ createdAt: new Date("2024-01-01") });
259
+
260
+ // Filter object
261
+ const result2 = PostWhere({
262
+ createdAt: {
263
+ equals: new Date("2024-01-01"),
264
+ gt: new Date("2024-01-01"), // After
265
+ gte: new Date("2024-01-01"), // On or after
266
+ lt: new Date("2024-12-31"), // Before
267
+ lte: new Date("2024-12-31"), // On or before
268
+ in: [new Date("2024-01-01"), new Date("2024-06-01")],
269
+ notIn: [new Date("2024-07-04")],
270
+ not: new Date("2024-01-01")
271
+ }
272
+ });
273
+ ```
274
+
275
+ **Available operations:** `equals`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `not`
276
+
277
+ #### Array Filters
278
+
279
+ Array fields use specialized array filters with operations for list matching:
280
+
281
+ ```typescript
282
+ import { TagWhere } from "./generated/validators";
283
+
284
+ // String arrays
285
+ const result1 = TagWhere({
286
+ labels: {
287
+ isEmpty: false, // Array is empty
288
+ has: "important", // Array contains value
289
+ hasEvery: ["tag1", "tag2"], // Array contains all values
290
+ hasSome: ["tag1", "tag2"], // Array contains at least one value
291
+ equals: ["exact", "match"] // Array exactly matches
292
+ }
293
+ });
294
+
295
+ // Number arrays
296
+ const result2 = ScoresWhere({
297
+ values: {
298
+ isEmpty: false,
299
+ has: 100,
300
+ hasEvery: [90, 95, 100],
301
+ hasSome: [100, 200],
302
+ equals: [90, 95, 100]
303
+ }
304
+ });
305
+
306
+ // Enum arrays
307
+ const result3 = PermissionsWhere({
308
+ roles: {
309
+ isEmpty: false,
310
+ has: "ADMIN",
311
+ hasEvery: ["USER", "ADMIN"],
312
+ hasSome: ["ADMIN", "MODERATOR"],
313
+ equals: ["USER"]
314
+ }
315
+ });
316
+ ```
317
+
318
+ **Available array filter types:**
319
+ - `StringArrayFilter` - for `String[]` fields
320
+ - `NumberArrayFilter` - for `Int[]`, `Float[]`, `Decimal[]` fields
321
+ - `BigIntArrayFilter` - for `BigInt[]` fields
322
+ - `arrayFilter(EnumType)` - for enum array fields
323
+
324
+ **Available operations:** `isEmpty`, `has`, `hasEvery`, `hasSome`, `equals`
325
+
326
+ ### Combining Filters
327
+
328
+ You can combine multiple filters in a single where clause:
329
+
330
+ ```typescript
331
+ import { PostWhere } from "./generated/validators";
332
+
333
+ const complexQuery = PostWhere({
334
+ title: { contains: "TypeScript" },
335
+ views: { gte: 100 },
336
+ published: true,
337
+ rating: { gte: 4.0 },
338
+ createdAt: {
339
+ gte: new Date("2024-01-01"),
340
+ lt: new Date("2024-12-31")
341
+ }
342
+ });
343
+ ```
344
+
135
345
  ### Generated Code Examples
136
346
 
137
347
  #### Enum Generation
package/dist/index.js CHANGED
@@ -2,7 +2,9 @@
2
2
  import { writeFile, access, rm, mkdir } from 'node:fs/promises';
3
3
  import generatorHelperPkg from '@prisma/generator-helper';
4
4
  import { type, ArkErrors } from 'arktype';
5
- import { join } from 'node:path';
5
+ import { readFileSync } from 'node:fs';
6
+ import { createRequire } from 'node:module';
7
+ import { dirname, join } from 'node:path';
6
8
 
7
9
  const configSchema = type({
8
10
  output: "string = './prisma/generated/validators'",
@@ -151,6 +153,21 @@ function extractAnnotations(documentation) {
151
153
  };
152
154
  }
153
155
 
156
+ const require = createRequire(import.meta.url);
157
+ function isPrismaV7OrHigher() {
158
+ try {
159
+ const prismaClientPath = require.resolve("@prisma/client");
160
+ const clientDir = dirname(prismaClientPath);
161
+ const packageJsonPath = join(clientDir, "package.json");
162
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
163
+ const version = packageJson.version;
164
+ const majorVersion = Number.parseInt(version.split(".")[0], 10);
165
+ return majorVersion >= 7;
166
+ } catch {
167
+ return false;
168
+ }
169
+ }
170
+ const IS_PRISMA_V7_OR_HIGHER = isPrismaV7OrHigher();
154
171
  const primitiveTypes = [
155
172
  "Int",
156
173
  "BigInt",
@@ -182,7 +199,10 @@ function stringifyPrimitiveType(type, annotations) {
182
199
  case "Boolean":
183
200
  return `"boolean"`;
184
201
  case "Bytes":
185
- return `"instanceof Buffer"`;
202
+ if (IS_PRISMA_V7_OR_HIGHER) {
203
+ return "Uint8ArrayInstance";
204
+ }
205
+ return "BufferInstance";
186
206
  default:
187
207
  throw new Error(`Unsupported primitive type: ${type}`);
188
208
  }
@@ -218,6 +238,7 @@ function stringifyEnum(enumData) {
218
238
  }
219
239
 
220
240
  const processedPlain = [];
241
+ const extRegex$1 = /\.(ts|js)$/;
221
242
  function processPlain(models) {
222
243
  for (const model of models) {
223
244
  const result = stringifyPlain(model);
@@ -226,7 +247,8 @@ function processPlain(models) {
226
247
  name: model.name,
227
248
  stringified: result.stringified,
228
249
  enumDependencies: result.enumDependencies,
229
- externalSchemaDependencies: result.externalSchemaDependencies
250
+ externalSchemaDependencies: result.externalSchemaDependencies,
251
+ runtimeDependencies: result.runtimeDependencies
230
252
  });
231
253
  }
232
254
  }
@@ -234,17 +256,16 @@ function processPlain(models) {
234
256
  }
235
257
  function stringifyPlain(model, isInputCreate = false, isInputUpdate = false) {
236
258
  const config = getConfig();
237
- const { hidden } = extractAnnotations(
238
- model.documentation
239
- );
259
+ const { hidden } = extractAnnotations(model.documentation);
240
260
  if (hidden) {
241
261
  return;
242
262
  }
243
263
  const fields = [];
244
264
  const enumDependencies = [];
245
265
  const externalSchemaDependencies = [];
266
+ const runtimeDependencies = [];
246
267
  function generateUniqueAlias(path, exportName, fieldName) {
247
- const baseName = exportName || path.split("/").pop()?.replace(/\.(ts|js)$/, "") || "Schema";
268
+ const baseName = exportName || path.split("/").pop()?.replace(extRegex$1, "") || "Schema";
248
269
  const suffix = fieldName ? `_${fieldName}` : "";
249
270
  return `${baseName}${suffix}`;
250
271
  }
@@ -309,15 +330,22 @@ function stringifyPlain(model, isInputCreate = false, isInputUpdate = false) {
309
330
  }
310
331
  const isEnumType = field.kind === "enum" && !typeOverwrite && !schemaAnnotation;
311
332
  const isExternalSchema = schemaAnnotation?.isExternal === true;
333
+ const isBytesField = field.type === "Bytes" && !typeOverwrite && !schemaAnnotation;
334
+ if (isBytesField) {
335
+ const runtimeDep = fieldType;
336
+ if (!runtimeDependencies.includes(runtimeDep)) {
337
+ runtimeDependencies.push(runtimeDep);
338
+ }
339
+ }
312
340
  if (field.isList) {
313
- if (isExternalSchema || isEnumType) {
341
+ if (isExternalSchema || isEnumType || isBytesField) {
314
342
  fieldType = `${fieldType}.array()`;
315
343
  } else {
316
344
  fieldType = `"${wrapPrimitiveWithArray(fieldType.slice(1, -1))}"`;
317
345
  }
318
346
  }
319
347
  if (!field.isRequired) {
320
- if (isExternalSchema || isEnumType) {
348
+ if (isExternalSchema || isEnumType || isBytesField) {
321
349
  fieldType = `${fieldType}.or("null")`;
322
350
  } else {
323
351
  const inner = fieldType.slice(1, -1);
@@ -337,7 +365,8 @@ function stringifyPlain(model, isInputCreate = false, isInputUpdate = false) {
337
365
  ${fields.join(",\n ")}
338
366
  }`,
339
367
  enumDependencies,
340
- externalSchemaDependencies
368
+ externalSchemaDependencies,
369
+ runtimeDependencies
341
370
  };
342
371
  }
343
372
  function stringifyPlainInputCreate(model) {
@@ -358,7 +387,8 @@ function processCreate(models) {
358
387
  name: model.name,
359
388
  stringified: result.stringified,
360
389
  enumDependencies: result.enumDependencies,
361
- externalSchemaDependencies: result.externalSchemaDependencies
390
+ externalSchemaDependencies: result.externalSchemaDependencies,
391
+ runtimeDependencies: result.runtimeDependencies
362
392
  });
363
393
  }
364
394
  }
@@ -379,9 +409,7 @@ function processInclude(models) {
379
409
  Object.freeze(processedInclude);
380
410
  }
381
411
  function stringifyInclude(model) {
382
- const { hidden } = extractAnnotations(
383
- model.documentation
384
- );
412
+ const { hidden } = extractAnnotations(model.documentation);
385
413
  if (hidden) {
386
414
  return;
387
415
  }
@@ -415,9 +443,7 @@ function processOrderBy(models) {
415
443
  Object.freeze(processedOrderBy);
416
444
  }
417
445
  function stringifyOrderBy(model) {
418
- const { hidden } = extractAnnotations(
419
- model.documentation
420
- );
446
+ const { hidden } = extractAnnotations(model.documentation);
421
447
  if (hidden) {
422
448
  return;
423
449
  }
@@ -451,9 +477,7 @@ function processRelations(models) {
451
477
  Object.freeze(processedRelations);
452
478
  }
453
479
  function stringifyRelations(model) {
454
- const { hidden } = extractAnnotations(
455
- model.documentation
456
- );
480
+ const { hidden } = extractAnnotations(model.documentation);
457
481
  if (hidden) {
458
482
  return;
459
483
  }
@@ -500,9 +524,7 @@ function processRelationsCreate(models) {
500
524
  Object.freeze(processedRelationsCreate);
501
525
  }
502
526
  function stringifyRelationsInputCreate(model, allModels) {
503
- const { hidden } = extractAnnotations(
504
- model.documentation
505
- );
527
+ const { hidden } = extractAnnotations(model.documentation);
506
528
  if (hidden) {
507
529
  return;
508
530
  }
@@ -547,9 +569,7 @@ function processRelationsUpdate(models) {
547
569
  Object.freeze(processedRelationsUpdate);
548
570
  }
549
571
  function stringifyRelationsInputUpdate(model, allModels) {
550
- const { hidden } = extractAnnotations(
551
- model.documentation
552
- );
572
+ const { hidden } = extractAnnotations(model.documentation);
553
573
  if (hidden) {
554
574
  return;
555
575
  }
@@ -634,7 +654,8 @@ function processUpdate(models) {
634
654
  name: model.name,
635
655
  stringified: result.stringified,
636
656
  enumDependencies: result.enumDependencies,
637
- externalSchemaDependencies: result.externalSchemaDependencies
657
+ externalSchemaDependencies: result.externalSchemaDependencies,
658
+ runtimeDependencies: result.runtimeDependencies
638
659
  });
639
660
  }
640
661
  }
@@ -652,7 +673,8 @@ function processWhere(models) {
652
673
  name: model.name,
653
674
  stringified: result.stringified,
654
675
  enumDependencies: result.enumDependencies,
655
- externalSchemaDependencies: result.externalSchemaDependencies
676
+ externalSchemaDependencies: result.externalSchemaDependencies,
677
+ runtimeDependencies: result.runtimeDependencies
656
678
  });
657
679
  }
658
680
  const uniqueResult = stringifyWhereUnique(model);
@@ -661,7 +683,8 @@ function processWhere(models) {
661
683
  name: model.name,
662
684
  stringified: uniqueResult.stringified,
663
685
  enumDependencies: uniqueResult.enumDependencies,
664
- externalSchemaDependencies: uniqueResult.externalSchemaDependencies
686
+ externalSchemaDependencies: uniqueResult.externalSchemaDependencies,
687
+ runtimeDependencies: uniqueResult.runtimeDependencies
665
688
  });
666
689
  }
667
690
  }
@@ -676,6 +699,7 @@ function stringifyWhere(model) {
676
699
  const fields = [];
677
700
  const enumDependencies = [];
678
701
  const externalSchemaDependencies = [];
702
+ const runtimeDependencies = [];
679
703
  function generateUniqueAlias(path, exportName, fieldName) {
680
704
  const baseName = exportName || path.split("/").pop()?.replace(extRegex, "") || "Schema";
681
705
  const suffix = fieldName ? `_${fieldName}` : "";
@@ -729,14 +753,82 @@ function stringifyWhere(model) {
729
753
  }
730
754
  const isEnumType = field.kind === "enum" && !typeOverwrite && !schemaAnnotation;
731
755
  const isExternalSchema = schemaAnnotation?.isExternal === true;
756
+ const isDateTimeField = field.type === "DateTime" && !typeOverwrite && !schemaAnnotation;
757
+ const isStringField = field.type === "String" && !typeOverwrite && !schemaAnnotation;
758
+ const isIntField = (field.type === "Int" || field.type === "BigInt") && !typeOverwrite && !schemaAnnotation;
759
+ const isFloatField = (field.type === "Float" || field.type === "Decimal") && !typeOverwrite && !schemaAnnotation;
760
+ const isBooleanField = field.type === "Boolean" && !typeOverwrite && !schemaAnnotation;
761
+ const isBytesField = field.type === "Bytes" && !typeOverwrite && !schemaAnnotation;
762
+ if (isBytesField) {
763
+ const runtimeDep = fieldType;
764
+ if (!runtimeDependencies.includes(runtimeDep)) {
765
+ runtimeDependencies.push(runtimeDep);
766
+ }
767
+ }
732
768
  if (field.isList) {
733
- if (isExternalSchema || isEnumType) {
769
+ if (isEnumType) {
770
+ fieldType = `arrayFilter(${fieldType})`;
771
+ if (!runtimeDependencies.includes("arrayFilter")) {
772
+ runtimeDependencies.push("arrayFilter");
773
+ }
774
+ } else if (field.type === "String" && !typeOverwrite && !schemaAnnotation) {
775
+ fieldType = "StringArrayFilter";
776
+ if (!runtimeDependencies.includes("StringArrayFilter")) {
777
+ runtimeDependencies.push("StringArrayFilter");
778
+ }
779
+ } else if ((field.type === "Int" || field.type === "Float" || field.type === "Decimal") && !typeOverwrite && !schemaAnnotation) {
780
+ fieldType = "NumberArrayFilter";
781
+ if (!runtimeDependencies.includes("NumberArrayFilter")) {
782
+ runtimeDependencies.push("NumberArrayFilter");
783
+ }
784
+ } else if (field.type === "BigInt" && !typeOverwrite && !schemaAnnotation) {
785
+ fieldType = "BigIntArrayFilter";
786
+ if (!runtimeDependencies.includes("BigIntArrayFilter")) {
787
+ runtimeDependencies.push("BigIntArrayFilter");
788
+ }
789
+ } else if (isExternalSchema || isBytesField) {
734
790
  fieldType = `${fieldType}.array()`;
735
791
  } else {
736
792
  const inner = fieldType.slice(1, -1);
737
793
  fieldType = `"${wrapPrimitiveWithArray(inner)}"`;
738
794
  }
739
795
  }
796
+ if (isDateTimeField && !field.isList) {
797
+ fieldType = `type("Date").or(DateTimeFilter)`;
798
+ if (!runtimeDependencies.includes("DateTimeFilter")) {
799
+ runtimeDependencies.push("DateTimeFilter");
800
+ }
801
+ }
802
+ if (isStringField && !field.isList) {
803
+ fieldType = `type("string").or(StringFilter)`;
804
+ if (!runtimeDependencies.includes("StringFilter")) {
805
+ runtimeDependencies.push("StringFilter");
806
+ }
807
+ }
808
+ if (isIntField && !field.isList) {
809
+ fieldType = `type("number.integer").or(IntFilter)`;
810
+ if (!runtimeDependencies.includes("IntFilter")) {
811
+ runtimeDependencies.push("IntFilter");
812
+ }
813
+ }
814
+ if (isFloatField && !field.isList) {
815
+ fieldType = `type("number").or(NumberFilter)`;
816
+ if (!runtimeDependencies.includes("NumberFilter")) {
817
+ runtimeDependencies.push("NumberFilter");
818
+ }
819
+ }
820
+ if (isEnumType && !field.isList) {
821
+ fieldType = `type(${fieldType}).or(enumFilter(${fieldType}))`;
822
+ if (!runtimeDependencies.includes("enumFilter")) {
823
+ runtimeDependencies.push("enumFilter");
824
+ }
825
+ }
826
+ if (isBooleanField && !field.isList) {
827
+ fieldType = `type("boolean").or(BooleanFilter)`;
828
+ if (!runtimeDependencies.includes("BooleanFilter")) {
829
+ runtimeDependencies.push("BooleanFilter");
830
+ }
831
+ }
740
832
  fields.push(`"${field.name}?": ${fieldType}`);
741
833
  }
742
834
  return {
@@ -744,7 +836,8 @@ function stringifyWhere(model) {
744
836
  ${fields.join(",\n ")}
745
837
  }`,
746
838
  enumDependencies,
747
- externalSchemaDependencies
839
+ externalSchemaDependencies,
840
+ runtimeDependencies
748
841
  };
749
842
  }
750
843
  function stringifyWhereUnique(model) {
@@ -755,6 +848,7 @@ function stringifyWhereUnique(model) {
755
848
  const fields = [];
756
849
  const enumDependencies = [];
757
850
  const externalSchemaDependencies = [];
851
+ const runtimeDependencies = [];
758
852
  function generateUniqueAlias(path, exportName, fieldName) {
759
853
  const baseName = exportName || path.split("/").pop()?.replace(extRegex, "") || "Schema";
760
854
  const suffix = fieldName ? `_${fieldName}` : "";
@@ -807,6 +901,20 @@ function stringifyWhereUnique(model) {
807
901
  } else {
808
902
  continue;
809
903
  }
904
+ const isDateTimeField = field.type === "DateTime" && !typeOverwrite && !schemaAnnotation;
905
+ const isBytesField = field.type === "Bytes" && !typeOverwrite && !schemaAnnotation;
906
+ if (isBytesField) {
907
+ const runtimeDep = fieldType;
908
+ if (!runtimeDependencies.includes(runtimeDep)) {
909
+ runtimeDependencies.push(runtimeDep);
910
+ }
911
+ }
912
+ if (isDateTimeField) {
913
+ fieldType = `type("Date").or(DateTimeFilter)`;
914
+ if (!runtimeDependencies.includes("DateTimeFilter")) {
915
+ runtimeDependencies.push("DateTimeFilter");
916
+ }
917
+ }
810
918
  fields.push(`"${field.name}?": ${fieldType}`);
811
919
  }
812
920
  if (fields.length === 0) {
@@ -817,7 +925,8 @@ function stringifyWhereUnique(model) {
817
925
  ${fields.join(",\n ")}
818
926
  }`,
819
927
  enumDependencies,
820
- externalSchemaDependencies
928
+ externalSchemaDependencies,
929
+ runtimeDependencies
821
930
  };
822
931
  }
823
932
 
@@ -852,6 +961,38 @@ function generateExternalSchemaImports(externalSchemaDependencies) {
852
961
  }).join("\n")}
853
962
  `;
854
963
  }
964
+ const RUNTIME_DEPENDENCY_IMPORTS = {
965
+ DateTimeFilter: `import { DateTimeFilter } from "prisma-arktype/runtime/filters";
966
+ `,
967
+ StringFilter: `import { StringFilter } from "prisma-arktype/runtime/stringFilter";
968
+ `,
969
+ NumberFilter: `import { NumberFilter } from "prisma-arktype/runtime/numberFilter";
970
+ `,
971
+ IntFilter: `import { IntFilter } from "prisma-arktype/runtime/numberFilter";
972
+ `,
973
+ BooleanFilter: `import { BooleanFilter } from "prisma-arktype/runtime/booleanFilter";
974
+ `,
975
+ enumFilter: `import { enumFilter } from "prisma-arktype/runtime/enumFilter";
976
+ `,
977
+ BufferInstance: `import { BufferInstance } from "prisma-arktype/runtime/buffer";
978
+ `,
979
+ Uint8ArrayInstance: `import { Uint8ArrayInstance } from "prisma-arktype/runtime/uint8array";
980
+ `,
981
+ arrayFilter: `import { arrayFilter } from "prisma-arktype/runtime/arrayFilters";
982
+ `,
983
+ StringArrayFilter: `import { StringArrayFilter } from "prisma-arktype/runtime/arrayFilters";
984
+ `,
985
+ NumberArrayFilter: `import { NumberArrayFilter } from "prisma-arktype/runtime/arrayFilters";
986
+ `,
987
+ BigIntArrayFilter: `import { BigIntArrayFilter } from "prisma-arktype/runtime/arrayFilters";
988
+ `
989
+ };
990
+ function generateRuntimeDependencyImports(runtimeDependencies) {
991
+ if (!runtimeDependencies || runtimeDependencies.length === 0) {
992
+ return "";
993
+ }
994
+ return runtimeDependencies.map((dep) => RUNTIME_DEPENDENCY_IMPORTS[dep]).join("");
995
+ }
855
996
  function mapAllModelsForWrite(processedEnums, processedPlain, processedRelations, processedWhere, processedWhereUnique, processedCreate, processedUpdate, processedRelationsCreate, processedRelationsUpdate, processedSelect, processedInclude, processedOrderBy) {
856
997
  const config = getConfig();
857
998
  const modelMap = /* @__PURE__ */ new Map();
@@ -868,7 +1009,10 @@ function mapAllModelsForWrite(processedEnums, processedPlain, processedRelations
868
1009
  const externalSchemaImports = generateExternalSchemaImports(
869
1010
  model.externalSchemaDependencies
870
1011
  );
871
- const content = `${arktypeImport}${enumImports}${externalSchemaImports}export const ${model.name}Plain = type(${model.stringified});
1012
+ const runtimeImports = generateRuntimeDependencyImports(
1013
+ model.runtimeDependencies
1014
+ );
1015
+ const content = `${arktypeImport}${enumImports}${externalSchemaImports}${runtimeImports}export const ${model.name}Plain = type(${model.stringified});
872
1016
  `;
873
1017
  modelMap.set(`${model.name}Plain`, content);
874
1018
  }
@@ -900,7 +1044,10 @@ export const ${plain.name} = ${plain.name}Plain;
900
1044
  const externalSchemaImports = generateExternalSchemaImports(
901
1045
  model.externalSchemaDependencies
902
1046
  );
903
- const content = `${arktypeImport}${enumImports}${externalSchemaImports}export const ${model.name}Where = type(${model.stringified});
1047
+ const runtimeImports = generateRuntimeDependencyImports(
1048
+ model.runtimeDependencies
1049
+ );
1050
+ const content = `${arktypeImport}${enumImports}${externalSchemaImports}${runtimeImports}export const ${model.name}Where = type(${model.stringified});
904
1051
  `;
905
1052
  modelMap.set(`${model.name}Where`, content);
906
1053
  }
@@ -909,7 +1056,10 @@ export const ${plain.name} = ${plain.name}Plain;
909
1056
  const externalSchemaImports = generateExternalSchemaImports(
910
1057
  model.externalSchemaDependencies
911
1058
  );
912
- const content = `${arktypeImport}${enumImports}${externalSchemaImports}export const ${model.name}WhereUnique = type(${model.stringified});
1059
+ const runtimeImports = generateRuntimeDependencyImports(
1060
+ model.runtimeDependencies
1061
+ );
1062
+ const content = `${arktypeImport}${enumImports}${externalSchemaImports}${runtimeImports}export const ${model.name}WhereUnique = type(${model.stringified});
913
1063
  `;
914
1064
  modelMap.set(`${model.name}WhereUnique`, content);
915
1065
  }
@@ -918,7 +1068,10 @@ export const ${plain.name} = ${plain.name}Plain;
918
1068
  const externalSchemaImports = generateExternalSchemaImports(
919
1069
  model.externalSchemaDependencies
920
1070
  );
921
- const content = `${arktypeImport}${enumImports}${externalSchemaImports}export const ${model.name}Create = type(${model.stringified});
1071
+ const runtimeImports = generateRuntimeDependencyImports(
1072
+ model.runtimeDependencies
1073
+ );
1074
+ const content = `${arktypeImport}${enumImports}${externalSchemaImports}${runtimeImports}export const ${model.name}Create = type(${model.stringified});
922
1075
  `;
923
1076
  modelMap.set(`${model.name}Create`, content);
924
1077
  }
@@ -927,7 +1080,10 @@ export const ${plain.name} = ${plain.name}Plain;
927
1080
  const externalSchemaImports = generateExternalSchemaImports(
928
1081
  model.externalSchemaDependencies
929
1082
  );
930
- const content = `${arktypeImport}${enumImports}${externalSchemaImports}export const ${model.name}Update = type(${model.stringified});
1083
+ const runtimeImports = generateRuntimeDependencyImports(
1084
+ model.runtimeDependencies
1085
+ );
1086
+ const content = `${arktypeImport}${enumImports}${externalSchemaImports}${runtimeImports}export const ${model.name}Update = type(${model.stringified});
931
1087
  `;
932
1088
  modelMap.set(`${model.name}Update`, content);
933
1089
  }
@@ -0,0 +1,46 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+ import * as arktype from 'arktype';
3
+
4
+ /**
5
+ * @description Generic array filter for Prisma where clauses
6
+ * Supports: isEmpty, has, hasEvery, hasSome, equals
7
+ */
8
+ declare const arrayFilter: arktype.Generic<[["t", unknown]], {
9
+ readonly "isEmpty?": "boolean";
10
+ readonly "has?": "t";
11
+ readonly "hasEvery?": "t[]";
12
+ readonly "hasSome?": "t[]";
13
+ readonly "equals?": "t[]";
14
+ }, {}, {}>;
15
+ /**
16
+ * @description String array filter for Prisma where clauses
17
+ */
18
+ declare const StringArrayFilter: arktype_internal_variants_object_ts.ObjectType<{
19
+ isEmpty?: boolean;
20
+ has?: string;
21
+ hasEvery?: string[];
22
+ hasSome?: string[];
23
+ equals?: string[];
24
+ }, {}>;
25
+ /**
26
+ * @description Number array filter for Prisma where clauses
27
+ */
28
+ declare const NumberArrayFilter: arktype_internal_variants_object_ts.ObjectType<{
29
+ isEmpty?: boolean;
30
+ has?: number;
31
+ hasEvery?: number[];
32
+ hasSome?: number[];
33
+ equals?: number[];
34
+ }, {}>;
35
+ /**
36
+ * @description BigInt array filter for Prisma where clauses
37
+ */
38
+ declare const BigIntArrayFilter: arktype_internal_variants_object_ts.ObjectType<{
39
+ isEmpty?: boolean;
40
+ has?: number;
41
+ hasEvery?: number[];
42
+ hasSome?: number[];
43
+ equals?: number[];
44
+ }, {}>;
45
+
46
+ export { BigIntArrayFilter, NumberArrayFilter, StringArrayFilter, arrayFilter };
@@ -0,0 +1,14 @@
1
+ import { type } from 'arktype';
2
+
3
+ const arrayFilter = type("<t>", {
4
+ "isEmpty?": "boolean",
5
+ "has?": "t",
6
+ "hasEvery?": "t[]",
7
+ "hasSome?": "t[]",
8
+ "equals?": "t[]"
9
+ });
10
+ const StringArrayFilter = arrayFilter("string");
11
+ const NumberArrayFilter = arrayFilter("number");
12
+ const BigIntArrayFilter = arrayFilter("number.integer");
13
+
14
+ export { BigIntArrayFilter, NumberArrayFilter, StringArrayFilter, arrayFilter };
@@ -0,0 +1,12 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+
3
+ /**
4
+ * @description Boolean filter for Prisma where clauses
5
+ * Supports: equals, not
6
+ */
7
+ declare const BooleanFilter: arktype_internal_variants_object_ts.ObjectType<{
8
+ equals?: boolean;
9
+ not?: boolean;
10
+ }, {}>;
11
+
12
+ export { BooleanFilter };
@@ -0,0 +1,8 @@
1
+ import { type } from 'arktype';
2
+
3
+ const BooleanFilter = type({
4
+ "equals?": "boolean",
5
+ "not?": "boolean"
6
+ });
7
+
8
+ export { BooleanFilter };
@@ -0,0 +1,8 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+
3
+ /**
4
+ * @description Buffer instance type
5
+ */
6
+ declare const BufferInstance: arktype_internal_variants_object_ts.ObjectType<Buffer<ArrayBufferLike>, {}>;
7
+
8
+ export { BufferInstance };
@@ -0,0 +1,14 @@
1
+ import { type } from 'arktype';
2
+
3
+ const BufferInstance = type("unknown").narrow(
4
+ (value, ctx) => {
5
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) {
6
+ return true;
7
+ } else if (typeof Buffer === "undefined") {
8
+ ctx.errors.add(ctx.error("Buffer is not defined in this environment"));
9
+ }
10
+ return ctx.mustBe("an instance of Buffer");
11
+ }
12
+ );
13
+
14
+ export { BufferInstance };
@@ -0,0 +1,14 @@
1
+ import * as arktype from 'arktype';
2
+
3
+ /**
4
+ * @description Generic enum filter for Prisma where clauses
5
+ * Supports: equals, in, not, notIn
6
+ */
7
+ declare const enumFilter: arktype.Generic<[["t", unknown]], {
8
+ readonly "equals?": "t";
9
+ readonly "in?": "t[]";
10
+ readonly "not?": "t";
11
+ readonly "notIn?": "t[]";
12
+ }, {}, {}>;
13
+
14
+ export { enumFilter };
@@ -0,0 +1,10 @@
1
+ import { type } from 'arktype';
2
+
3
+ const enumFilter = type("<t>", {
4
+ "equals?": "t",
5
+ "in?": "t[]",
6
+ "not?": "t",
7
+ "notIn?": "t[]"
8
+ });
9
+
10
+ export { enumFilter };
@@ -0,0 +1,19 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+
3
+ /**
4
+ * DateTimeFilter allows querying DateTime fields with comparison operators.
5
+ * Can be used instead of a direct Date value in where clauses.
6
+ */
7
+ declare const DateTimeFilter: arktype_internal_variants_object_ts.ObjectType<{
8
+ equals?: Date;
9
+ in?: Date[];
10
+ notIn?: Date[];
11
+ lt?: Date;
12
+ lte?: Date;
13
+ gt?: Date;
14
+ gte?: Date;
15
+ not?: Date;
16
+ }, {}>;
17
+ type DateTimeFilter = typeof DateTimeFilter.infer;
18
+
19
+ export { DateTimeFilter };
@@ -0,0 +1,14 @@
1
+ import { type } from 'arktype';
2
+
3
+ const DateTimeFilter = type({
4
+ "equals?": "Date",
5
+ "in?": "Date[]",
6
+ "notIn?": "Date[]",
7
+ "lt?": "Date",
8
+ "lte?": "Date",
9
+ "gt?": "Date",
10
+ "gte?": "Date",
11
+ "not?": "Date"
12
+ });
13
+
14
+ export { DateTimeFilter };
@@ -0,0 +1,32 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+
3
+ /**
4
+ * @description Number filter for Prisma where clauses
5
+ * Supports: equals, gt, gte, in, lt, lte, not, notIn
6
+ */
7
+ declare const NumberFilter: arktype_internal_variants_object_ts.ObjectType<{
8
+ equals?: number;
9
+ gt?: number;
10
+ gte?: number;
11
+ in?: number[];
12
+ lt?: number;
13
+ lte?: number;
14
+ not?: number;
15
+ notIn?: number[];
16
+ }, {}>;
17
+ /**
18
+ * @description Integer filter for Prisma where clauses (Int, BigInt)
19
+ * Supports: equals, gt, gte, in, lt, lte, not, notIn
20
+ */
21
+ declare const IntFilter: arktype_internal_variants_object_ts.ObjectType<{
22
+ equals?: number;
23
+ gt?: number;
24
+ gte?: number;
25
+ in?: number[];
26
+ lt?: number;
27
+ lte?: number;
28
+ not?: number;
29
+ notIn?: number[];
30
+ }, {}>;
31
+
32
+ export { IntFilter, NumberFilter };
@@ -0,0 +1,24 @@
1
+ import { type } from 'arktype';
2
+
3
+ const NumberFilter = type({
4
+ "equals?": "number",
5
+ "gt?": "number",
6
+ "gte?": "number",
7
+ "in?": "number[]",
8
+ "lt?": "number",
9
+ "lte?": "number",
10
+ "not?": "number",
11
+ "notIn?": "number[]"
12
+ });
13
+ const IntFilter = type({
14
+ "equals?": "number.integer",
15
+ "gt?": "number.integer",
16
+ "gte?": "number.integer",
17
+ "in?": "number.integer[]",
18
+ "lt?": "number.integer",
19
+ "lte?": "number.integer",
20
+ "not?": "number.integer",
21
+ "notIn?": "number.integer[]"
22
+ });
23
+
24
+ export { IntFilter, NumberFilter };
@@ -0,0 +1,21 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+
3
+ /**
4
+ * @description String filter for Prisma where clauses
5
+ * Supports: contains, endsWith, equals, gt, gte, in, lt, lte, not, notIn, startsWith
6
+ */
7
+ declare const StringFilter: arktype_internal_variants_object_ts.ObjectType<{
8
+ contains?: string;
9
+ endsWith?: string;
10
+ equals?: string;
11
+ gt?: string;
12
+ gte?: string;
13
+ in?: string[];
14
+ lt?: string;
15
+ lte?: string;
16
+ not?: string;
17
+ notIn?: string[];
18
+ startsWith?: string;
19
+ }, {}>;
20
+
21
+ export { StringFilter };
@@ -0,0 +1,17 @@
1
+ import { type } from 'arktype';
2
+
3
+ const StringFilter = type({
4
+ "contains?": "string",
5
+ "endsWith?": "string",
6
+ "equals?": "string",
7
+ "gt?": "string",
8
+ "gte?": "string",
9
+ "in?": "string[]",
10
+ "lt?": "string",
11
+ "lte?": "string",
12
+ "not?": "string",
13
+ "notIn?": "string[]",
14
+ "startsWith?": "string"
15
+ });
16
+
17
+ export { StringFilter };
@@ -0,0 +1,9 @@
1
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
2
+
3
+ /**
4
+ * @description Uint8Array instance type for Prisma v7+
5
+ * In Prisma v7+, Bytes fields return as Uint8Array instead of Buffer
6
+ */
7
+ declare const Uint8ArrayInstance: arktype_internal_variants_object_ts.ObjectType<Uint8Array<ArrayBufferLike>, {}>;
8
+
9
+ export { Uint8ArrayInstance };
@@ -0,0 +1,12 @@
1
+ import { type } from 'arktype';
2
+
3
+ const Uint8ArrayInstance = type("unknown").narrow(
4
+ (value, ctx) => {
5
+ if (value instanceof Uint8Array) {
6
+ return true;
7
+ }
8
+ return ctx.mustBe("an instance of Uint8Array");
9
+ }
10
+ );
11
+
12
+ export { Uint8ArrayInstance };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-arktype",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "Generate ArkType schemas from your Prisma schema",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -8,7 +8,48 @@
8
8
  "exports": {
9
9
  ".": {
10
10
  "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./runtime/filters": {
15
+ "import": "./dist/runtime/filters.js",
16
+ "types": "./dist/runtime/filters.d.ts",
17
+ "default": "./dist/runtime/filters.js"
18
+ },
19
+ "./runtime/buffer": {
20
+ "import": "./dist/runtime/buffer.js",
21
+ "types": "./dist/runtime/buffer.d.ts",
22
+ "default": "./dist/runtime/buffer.js"
23
+ },
24
+ "./runtime/uint8array": {
25
+ "import": "./dist/runtime/uint8array.js",
26
+ "types": "./dist/runtime/uint8array.d.ts",
27
+ "default": "./dist/runtime/uint8array.js"
28
+ },
29
+ "./runtime/arrayFilters": {
30
+ "import": "./dist/runtime/arrayFilters.js",
31
+ "types": "./dist/runtime/arrayFilters.d.ts",
32
+ "default": "./dist/runtime/arrayFilters.js"
33
+ },
34
+ "./runtime/stringFilter": {
35
+ "import": "./dist/runtime/stringFilter.js",
36
+ "types": "./dist/runtime/stringFilter.d.ts",
37
+ "default": "./dist/runtime/stringFilter.js"
38
+ },
39
+ "./runtime/numberFilter": {
40
+ "import": "./dist/runtime/numberFilter.js",
41
+ "types": "./dist/runtime/numberFilter.d.ts",
42
+ "default": "./dist/runtime/numberFilter.js"
43
+ },
44
+ "./runtime/enumFilter": {
45
+ "import": "./dist/runtime/enumFilter.js",
46
+ "types": "./dist/runtime/enumFilter.d.ts",
47
+ "default": "./dist/runtime/enumFilter.js"
48
+ },
49
+ "./runtime/booleanFilter": {
50
+ "import": "./dist/runtime/booleanFilter.js",
51
+ "types": "./dist/runtime/booleanFilter.d.ts",
52
+ "default": "./dist/runtime/booleanFilter.js"
12
53
  }
13
54
  },
14
55
  "bin": {
@@ -39,12 +80,16 @@
39
80
  "@prisma/generator-helper": "^6.18.0",
40
81
  "arktype": "^2.1.25"
41
82
  },
83
+ "peerDependencies": {
84
+ "@prisma/client": ">=6"
85
+ },
42
86
  "devDependencies": {
43
87
  "@biomejs/biome": "2.3.11",
44
88
  "@changesets/cli": "2.29.8",
45
89
  "@commitlint/cli": "^20.1.0",
46
90
  "@commitlint/config-conventional": "^20.0.0",
47
- "@prisma/client": "^6.18.0",
91
+ "@prisma/client": "7.2.0",
92
+ "@prisma/internals": "7.2.0",
48
93
  "@tilli-pro/biome": "0.9.0",
49
94
  "@types/node": "^24.10.0",
50
95
  "lefthook": "^2.0.2",
@@ -66,6 +111,16 @@
66
111
  "lint:fix": "biome check --write",
67
112
  "changeset": "changeset",
68
113
  "version": "changeset version",
69
- "release": "pnpm build && changeset publish"
114
+ "release": "pnpm build && changeset publish",
115
+ "bench": "vitest bench --config vitest.bench.config.ts",
116
+ "bench:ui": "vitest bench --ui --config vitest.bench.config.ts",
117
+ "bench:generation": "vitest bench __benchmarks__/suites/generation.bench.ts --config vitest.bench.config.ts",
118
+ "bench:processors": "vitest bench __benchmarks__/suites/processors.bench.ts --config vitest.bench.config.ts",
119
+ "bench:annotations": "vitest bench __benchmarks__/suites/annotations.bench.ts --config vitest.bench.config.ts",
120
+ "bench:memory": "node --expose-gc node_modules/.bin/vitest bench __benchmarks__/suites/memory.bench.ts --config vitest.bench.config.ts",
121
+ "bench:compare": "tsx __benchmarks__/scripts/compare.ts",
122
+ "bench:update-baseline": "tsx __benchmarks__/scripts/update-baseline.ts",
123
+ "bench:profile": "node --cpu-prof --expose-gc node_modules/.bin/vitest bench --config vitest.bench.config.ts",
124
+ "bench:ci": "tsx __benchmarks__/scripts/run-and-save.ts"
70
125
  }
71
126
  }