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.
- package/README.md +112 -14
- package/dist/index.js +28 -9
- 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`** -
|
|
90
|
-
- **`ModelRelations`** - Relationship
|
|
91
|
-
- **`Model`** - Complete composite schema
|
|
92
|
-
- **`ModelWhere`** - Where clause schema
|
|
93
|
-
- **`ModelWhereUnique`** - Unique where clause schema
|
|
94
|
-
- **`ModelCreate`** -
|
|
95
|
-
- **`ModelUpdate`** -
|
|
96
|
-
- **`ModelSelect`** -
|
|
97
|
-
- **`ModelInclude`** -
|
|
98
|
-
- **`ModelOrderBy`** -
|
|
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 |
|
|
223
|
-
| Relations | `
|
|
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
|
|
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
|
|
368
|
-
if (
|
|
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 =
|
|
397
|
+
fieldType = `${relatedModelPlain}.array()`;
|
|
392
398
|
} else if (!field.isRequired) {
|
|
393
|
-
fieldType =
|
|
399
|
+
fieldType = `${relatedModelPlain}.or("null")`;
|
|
394
400
|
} else {
|
|
395
|
-
fieldType =
|
|
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
|
|
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
|
}
|