prisma-arktype 2.2.0 → 2.3.0

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.
Files changed (3) hide show
  1. package/README.md +112 -14
  2. package/dist/index.js +28 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -86,16 +86,18 @@ generator prisma-arktype {
86
86
 
87
87
  For each model, the generator creates multiple schema types:
88
88
 
89
- - **`ModelPlain`** - Fields without relationships
90
- - **`ModelRelations`** - Relationship definitions only
91
- - **`Model`** - Complete composite schema (Plain & Relations)
92
- - **`ModelWhere`** - Where clause schema
93
- - **`ModelWhereUnique`** - Unique where clause schema
94
- - **`ModelCreate`** - Create input schema
95
- - **`ModelUpdate`** - Update input schema
96
- - **`ModelSelect`** - Select schema
97
- - **`ModelInclude`** - Include schema
98
- - **`ModelOrderBy`** - OrderBy schema
89
+ - **`ModelPlain`** - Scalar fields only (strings, numbers, dates, enums) - no relations
90
+ - **`ModelRelations`** - Relationship fields only, referencing related model Plain types
91
+ - **`Model`** - Complete composite schema combining Plain & Relations
92
+ - **`ModelWhere`** - Where clause schema for filtering
93
+ - **`ModelWhereUnique`** - Unique where clause schema for finding specific records
94
+ - **`ModelCreate`** - Input schema for creating records
95
+ - **`ModelUpdate`** - Input schema for updating records
96
+ - **`ModelSelect`** - Schema for selecting specific fields
97
+ - **`ModelInclude`** - Schema for including relations
98
+ - **`ModelOrderBy`** - Schema for ordering results
99
+
100
+ **Enums** are generated as separate reusable types that are imported and referenced by models that use them.
99
101
 
100
102
  ### Using Generated Schemas
101
103
 
@@ -130,6 +132,101 @@ const whereResult = UserWhere(whereClause);
130
132
  // ...
131
133
  ```
132
134
 
135
+ ### Generated Code Examples
136
+
137
+ #### Enum Generation
138
+
139
+ For a Prisma enum like:
140
+ ```prisma
141
+ enum Currency {
142
+ USD
143
+ EUR
144
+ GBP
145
+ }
146
+ ```
147
+
148
+ The generator creates a separate reusable type:
149
+ ```typescript
150
+ // Currency.ts
151
+ import { type } from "arktype";
152
+
153
+ export const Currency = type("'USD' | 'EUR' | 'GBP'");
154
+ ```
155
+
156
+ Which is then imported and used in models:
157
+ ```typescript
158
+ // PaymentPlain.ts
159
+ import { type } from "arktype";
160
+ import { Currency } from "./Currency";
161
+
162
+ export const PaymentPlain = type({
163
+ "id": "string",
164
+ "amount": "number",
165
+ "currency": Currency, // Required enum
166
+ "status?": Currency.or("null") // Optional enum
167
+ });
168
+ ```
169
+
170
+ #### Relation Generation
171
+
172
+ For Prisma models with relations like:
173
+ ```prisma
174
+ model User {
175
+ id String @id
176
+ email String
177
+ posts Post[]
178
+ }
179
+
180
+ model Post {
181
+ id String @id
182
+ title String
183
+ author User @relation(fields: [authorId], references: [id])
184
+ authorId String
185
+ }
186
+ ```
187
+
188
+ The generator creates Plain types (without relations):
189
+ ```typescript
190
+ // UserPlain.ts
191
+ export const UserPlain = type({
192
+ "id": "string",
193
+ "email": "string"
194
+ });
195
+
196
+ // PostPlain.ts
197
+ export const PostPlain = type({
198
+ "id": "string",
199
+ "title": "string",
200
+ "authorId": "string"
201
+ });
202
+ ```
203
+
204
+ And Relations types that reference the Plain types:
205
+ ```typescript
206
+ // UserRelations.ts
207
+ import { PostPlain } from "./PostPlain";
208
+
209
+ export const UserRelations = type({
210
+ "posts": PostPlain.array() // Array of Post objects
211
+ });
212
+
213
+ // PostRelations.ts
214
+ import { UserPlain } from "./UserPlain";
215
+
216
+ export const PostRelations = type({
217
+ "author": UserPlain // Single User object
218
+ });
219
+ ```
220
+
221
+ The combined model merges both:
222
+ ```typescript
223
+ // User.ts
224
+ import { UserPlain } from "./UserPlain";
225
+ import { UserRelations } from "./UserRelations";
226
+
227
+ export const User = type(() => UserPlain.and(UserRelations));
228
+ ```
229
+
133
230
  ## Annotations
134
231
 
135
232
  Control schema generation using annotations in your Prisma schema. All annotations are added as documentation comments (`///`).
@@ -219,15 +316,16 @@ Prisma types are mapped to ArkType as follows:
219
316
  | `DateTime` | `"Date"` | `"Date"` |
220
317
  | `Json` | `"unknown"` | `"unknown"` |
221
318
  | `Bytes` | `"instanceof Buffer"` | `"instanceof Buffer"` |
222
- | Enums | Union of literal values | `type("'USD' \| 'EUR' \| 'GBP'")` |
223
- | Relations | `"unknown"` | `type("unknown").array()` for lists |
319
+ | Enums | Reference to enum type | `Currency` (imported from `./Currency`) |
320
+ | Relations | Reference to related Plain type | `PostPlain` or `PostPlain.array()` |
224
321
 
225
322
  ### Special Handling
226
323
 
227
324
  - **Optional fields**: Use `?` on the key name (`"name?": "string"`)
228
325
  - **Nullable fields**: Add `| null` to the type (`"string | null"`)
229
- - **Arrays**: Use `.array()` syntax for lists (`type("string").array()`)
230
- - **Enums**: Generated as string literal unions wrapped in `type()`
326
+ - **Arrays**: Use `.array()` syntax for lists (`type("string").array()` or `Currency.array()`)
327
+ - **Enums**: Generated as separate reusable type definitions and imported where used
328
+ - **Relations**: Reference the Plain type of the related model, imported automatically
231
329
 
232
330
  ## Differences from prismabox
233
331
 
package/dist/index.js CHANGED
@@ -364,11 +364,12 @@ const processedRelationsCreate = [];
364
364
  const processedRelationsUpdate = [];
365
365
  function processRelations(models) {
366
366
  for (const model of models) {
367
- const stringified = stringifyRelations(model);
368
- if (stringified) {
367
+ const result = stringifyRelations(model);
368
+ if (result) {
369
369
  processedRelations.push({
370
370
  name: model.name,
371
- stringified
371
+ stringified: result.stringified,
372
+ modelDependencies: result.modelDependencies
372
373
  });
373
374
  }
374
375
  }
@@ -382,26 +383,34 @@ function stringifyRelations(model) {
382
383
  return;
383
384
  }
384
385
  const fields = [];
386
+ const modelDependencies = [];
385
387
  for (const field of model.fields) {
386
388
  const { hidden: fieldHidden } = extractAnnotations(field.documentation);
387
389
  if (fieldHidden) continue;
388
390
  if (field.kind !== "object") continue;
391
+ const relatedModelPlain = `${field.type}Plain`;
392
+ if (!modelDependencies.includes(field.type)) {
393
+ modelDependencies.push(field.type);
394
+ }
389
395
  let fieldType;
390
396
  if (field.isList) {
391
- fieldType = `type("unknown").array()`;
397
+ fieldType = `${relatedModelPlain}.array()`;
392
398
  } else if (!field.isRequired) {
393
- fieldType = `"unknown | null"`;
399
+ fieldType = `${relatedModelPlain}.or("null")`;
394
400
  } else {
395
- fieldType = `"unknown"`;
401
+ fieldType = relatedModelPlain;
396
402
  }
397
403
  fields.push(`"${field.name}": ${fieldType}`);
398
404
  }
399
405
  if (fields.length === 0) {
400
406
  return;
401
407
  }
402
- return `{
408
+ return {
409
+ stringified: `{
403
410
  ${fields.join(",\n ")}
404
- }`;
411
+ }`,
412
+ modelDependencies
413
+ };
405
414
  }
406
415
  function processRelationsCreate(models) {
407
416
  for (const model of models) {
@@ -682,6 +691,15 @@ function generateEnumImports(enumDependencies) {
682
691
  return `${enumDependencies.map((enumName) => `import { ${enumName} } from "./${enumName}";`).join("\n")}
683
692
  `;
684
693
  }
694
+ function generateModelImports(modelDependencies) {
695
+ if (!modelDependencies || modelDependencies.length === 0) {
696
+ return "";
697
+ }
698
+ return `${modelDependencies.map(
699
+ (modelName) => `import { ${modelName}Plain } from "./${modelName}Plain";`
700
+ ).join("\n")}
701
+ `;
702
+ }
685
703
  function mapAllModelsForWrite(processedEnums, processedPlain, processedRelations, processedWhere, processedWhereUnique, processedCreate, processedUpdate, processedRelationsCreate, processedRelationsUpdate, processedSelect, processedInclude, processedOrderBy) {
686
704
  const config = getConfig();
687
705
  const modelMap = /* @__PURE__ */ new Map();
@@ -700,7 +718,8 @@ function mapAllModelsForWrite(processedEnums, processedPlain, processedRelations
700
718
  modelMap.set(`${model.name}Plain`, content);
701
719
  }
702
720
  for (const model of processedRelations) {
703
- const content = `${arktypeImport}export const ${model.name}Relations = type(${model.stringified});
721
+ const modelImports = generateModelImports(model.modelDependencies);
722
+ const content = `${arktypeImport}${modelImports}export const ${model.name}Relations = type(${model.stringified});
704
723
  `;
705
724
  modelMap.set(`${model.name}Relations`, content);
706
725
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-arktype",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Generate ArkType schemas from your Prisma schema",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",