@vibeorm/generator 1.0.2 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeorm/generator",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "description": "TypeScript client generator for VibeORM — produces typed delegates, inputs, and Zod schemas from a Prisma schema",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -37,6 +37,6 @@
37
37
  "bun": ">=1.1.0"
38
38
  },
39
39
  "dependencies": {
40
- "@vibeorm/parser": "1.0.2"
40
+ "@vibeorm/parser": "1.1.1"
41
41
  }
42
42
  }
@@ -28,7 +28,7 @@ export function generateClient(params: { schema: Schema }): string {
28
28
 
29
29
  // Import runtime
30
30
  parts.push(`import { createClient } from "@vibeorm/runtime";`);
31
- parts.push(`import type { VibeClientOptions } from "@vibeorm/runtime";`);
31
+ parts.push(`import type { VibeClientOptions, TransactionOptions } from "@vibeorm/runtime";`);
32
32
  parts.push(``);
33
33
 
34
34
  // Import schemas for validation wiring
@@ -54,8 +54,8 @@ export function generateClient(params: { schema: Schema }): string {
54
54
 
55
55
  parts.push(`export type VibeClientInstance = {
56
56
  ${clientProperties}
57
- $transaction<T>(fn: (tx: VibeClientInstance) => Promise<T>): Promise<T>;
58
- $transaction(promises: Promise<unknown>[]): Promise<unknown[]>;
57
+ $transaction<T>(fn: (tx: VibeClientInstance) => Promise<T>, options?: TransactionOptions): Promise<T>;
58
+ $transaction(promises: Promise<unknown>[], options?: TransactionOptions): Promise<unknown[]>;
59
59
  $queryRaw<T = unknown>(strings: TemplateStringsArray, ...values: unknown[]): Promise<T[]>;
60
60
  $executeRaw(strings: TemplateStringsArray, ...values: unknown[]): Promise<number>;
61
61
  $queryRawUnsafe<T = unknown>(query: string, ...values: unknown[]): Promise<T[]>;
@@ -39,7 +39,13 @@ export function generateDelegates(params: { schema: Schema }): string {
39
39
  const payloadImports = schema.models
40
40
  .map((m) => `$${m.name}Payload`)
41
41
  .join(", ");
42
- parts.push(`import type { ${payloadImports} } from "./models.ts";`);
42
+
43
+ // Include JsonValue if any model has Json scalar fields (used in aggregate/groupBy types)
44
+ const hasJsonField = schema.models.some((m) =>
45
+ m.fields.some((f) => f.kind === "scalar" && f.prismaType === "Json")
46
+ );
47
+ const extraImports = hasJsonField ? ", JsonValue" : "";
48
+ parts.push(`import type { ${payloadImports}${extraImports} } from "./models.ts";`);
43
49
 
44
50
  parts.push(`import type { GetResult } from "./result.ts";`);
45
51
 
@@ -64,7 +64,7 @@ function generateWhereInput(params: { model: Model; schema: Schema }): string {
64
64
  const listFilterType = scalarListFilterType({ field });
65
65
  entries.push(` ${field.name}?: ${listFilterType};`);
66
66
  } else {
67
- entries.push(` ${field.name}?: ${scalarFilterType({ field })} | ${scalarTsType({ field })};`);
67
+ entries.push(` ${field.name}?: ${scalarFilterType({ field })} | ${scalarTsType({ field, context: "input" })};`);
68
68
  }
69
69
  } else if (field.kind === "enum") {
70
70
  entries.push(` ${field.name}?: EnumFilter<${field.enumName}> | ${field.enumName};`);
@@ -124,6 +124,21 @@ function generateWhereUniqueInput(params: { model: Model }): string {
124
124
  entries.push(` ${model.primaryKey.fields.join("_")}?: { ${compositeType} };`);
125
125
  }
126
126
 
127
+ // Also support compound @@unique constraints
128
+ for (const uc of model.uniqueConstraints) {
129
+ if (uc.fields.length > 1) {
130
+ const compositeType = uc.fields
131
+ .map((fn) => {
132
+ const field = model.fields.find((f) => f.name === fn);
133
+ if (!field || field.kind === "relation") return `${fn}: unknown`;
134
+ const tsType = field.kind === "scalar" ? field.tsType : field.enumName;
135
+ return `${fn}: ${tsType}`;
136
+ })
137
+ .join("; ");
138
+ entries.push(` ${uc.fields.join("_")}?: { ${compositeType} };`);
139
+ }
140
+ }
141
+
127
142
  return `export type ${model.name}WhereUniqueInput = {
128
143
  ${entries.join("\n")}
129
144
  };
@@ -178,7 +193,7 @@ function generateCreateInput(params: {
178
193
  field.default.kind === "nanoid" ||
179
194
  field.default.kind === "ulid");
180
195
  const isOptional = !field.isRequired || field.default !== undefined || isAutoGenerated || field.isUpdatedAt;
181
- const tsType = scalarTsType({ field });
196
+ const tsType = scalarTsType({ field, context: "input" });
182
197
  entries.push(` ${field.name}${isOptional ? "?" : ""}: ${tsType};`);
183
198
  } else if (field.kind === "enum") {
184
199
  const isOptional = !field.isRequired || field.default !== undefined;
@@ -224,7 +239,7 @@ function generateUpdateInput(params: {
224
239
  const listUpdateType = scalarListUpdateType({ field });
225
240
  entries.push(` ${field.name}?: ${listUpdateType};`);
226
241
  } else {
227
- const tsType = scalarTsType({ field });
242
+ const tsType = scalarTsType({ field, context: "input" });
228
243
  const atomicType = numericFieldUpdateType({ field });
229
244
  if (atomicType) {
230
245
  entries.push(` ${field.name}?: ${tsType} | ${atomicType};`);
@@ -270,9 +285,10 @@ ${entries.join("\n")}
270
285
 
271
286
  // ─── Scalar Filter Types ──────────────────────────────────────────
272
287
 
273
- function scalarTsType(params: { field: ScalarField }): string {
274
- const { field } = params;
275
- const base = field.tsType;
288
+ function scalarTsType(params: { field: ScalarField; context?: "input" | "output" }): string {
289
+ const { field, context } = params;
290
+ // For Decimal input types, accept both number and string for better DX
291
+ const base = context === "input" && field.prismaType === "Decimal" ? "number | string" : field.tsType;
276
292
  if (field.isList) return `${base}[]`;
277
293
  if (!field.isRequired) return `${base} | null`;
278
294
  return base;
@@ -74,16 +74,16 @@ export type GetFindResult<P extends OperationPayload, A> =
74
74
  S[K] extends Record<string, unknown>
75
75
  ? GetFindResult<P["objects"][K][number], S[K]>[]
76
76
  : DefaultSelection<P["objects"][K][number]>[]
77
- : P["objects"][K] extends OperationPayload | null
78
- ? // Nullable single relation
77
+ : P["objects"][K] extends OperationPayload
78
+ ? // Required single relation (checked before nullable to avoid false match)
79
79
  S[K] extends Record<string, unknown>
80
- ? GetFindResult<NonNullable<P["objects"][K]> & OperationPayload, S[K]> | null
81
- : DefaultSelection<NonNullable<P["objects"][K]> & OperationPayload> | null
82
- : P["objects"][K] extends OperationPayload
83
- ? // Required single relation
80
+ ? GetFindResult<P["objects"][K], S[K]>
81
+ : DefaultSelection<P["objects"][K]>
82
+ : P["objects"][K] extends OperationPayload | null
83
+ ? // Nullable single relation
84
84
  S[K] extends Record<string, unknown>
85
- ? GetFindResult<P["objects"][K], S[K]>
86
- : DefaultSelection<P["objects"][K]>
85
+ ? GetFindResult<NonNullable<P["objects"][K]> & OperationPayload, S[K]> | null
86
+ : DefaultSelection<NonNullable<P["objects"][K]> & OperationPayload> | null
87
87
  : never
88
88
  : never;
89
89
  }>
@@ -100,16 +100,16 @@ export type GetFindResult<P extends OperationPayload, A> =
100
100
  I[K] extends Record<string, unknown>
101
101
  ? GetFindResult<P["objects"][K][number], I[K]>[]
102
102
  : DefaultSelection<P["objects"][K][number]>[]
103
- : P["objects"][K] extends OperationPayload | null
104
- ? // Nullable single relation
103
+ : P["objects"][K] extends OperationPayload
104
+ ? // Required single relation (checked before nullable to avoid false match)
105
105
  I[K] extends Record<string, unknown>
106
- ? GetFindResult<NonNullable<P["objects"][K]> & OperationPayload, I[K]> | null
107
- : DefaultSelection<NonNullable<P["objects"][K]> & OperationPayload> | null
108
- : P["objects"][K] extends OperationPayload
109
- ? // Required single relation
106
+ ? GetFindResult<P["objects"][K], I[K]>
107
+ : DefaultSelection<P["objects"][K]>
108
+ : P["objects"][K] extends OperationPayload | null
109
+ ? // Nullable single relation
110
110
  I[K] extends Record<string, unknown>
111
- ? GetFindResult<P["objects"][K], I[K]>
112
- : DefaultSelection<P["objects"][K]>
111
+ ? GetFindResult<NonNullable<P["objects"][K]> & OperationPayload, I[K]> | null
112
+ : DefaultSelection<NonNullable<P["objects"][K]> & OperationPayload> | null
113
113
  : never
114
114
  : never;
115
115
  }
@@ -265,7 +265,7 @@ function generateWhereFilterSchemas(): string {
265
265
  return `
266
266
  // ─── Where Filter Schemas ───────────────────────────────────────
267
267
 
268
- export const StringFilterSchema = z.object({
268
+ export const StringFilterSchema: z.ZodTypeAny = z.object({
269
269
  equals: z.string().optional(),
270
270
  not: z.union([z.string(), z.lazy(() => StringFilterSchema)]).optional(),
271
271
  in: z.array(z.string()).optional(),
@@ -280,7 +280,7 @@ export const StringFilterSchema = z.object({
280
280
  mode: z.enum(["default", "insensitive"]).optional(),
281
281
  });
282
282
 
283
- export const NullableStringFilterSchema = z.object({
283
+ export const NullableStringFilterSchema: z.ZodTypeAny = z.object({
284
284
  equals: z.string().nullable().optional(),
285
285
  not: z.union([z.string().nullable(), z.lazy(() => NullableStringFilterSchema)]).optional(),
286
286
  in: z.array(z.string().nullable()).optional(),
@@ -295,7 +295,7 @@ export const NullableStringFilterSchema = z.object({
295
295
  mode: z.enum(["default", "insensitive"]).optional(),
296
296
  });
297
297
 
298
- export const NumberFilterSchema = z.object({
298
+ export const NumberFilterSchema: z.ZodTypeAny = z.object({
299
299
  equals: z.number().optional(),
300
300
  not: z.union([z.number(), z.lazy(() => NumberFilterSchema)]).optional(),
301
301
  in: z.array(z.number()).optional(),
@@ -306,7 +306,7 @@ export const NumberFilterSchema = z.object({
306
306
  gte: z.number().optional(),
307
307
  });
308
308
 
309
- export const NullableNumberFilterSchema = z.object({
309
+ export const NullableNumberFilterSchema: z.ZodTypeAny = z.object({
310
310
  equals: z.number().nullable().optional(),
311
311
  not: z.union([z.number().nullable(), z.lazy(() => NullableNumberFilterSchema)]).optional(),
312
312
  in: z.array(z.number().nullable()).optional(),
@@ -317,7 +317,7 @@ export const NullableNumberFilterSchema = z.object({
317
317
  gte: z.number().optional(),
318
318
  });
319
319
 
320
- export const BigIntFilterSchema = z.object({
320
+ export const BigIntFilterSchema: z.ZodTypeAny = z.object({
321
321
  equals: z.bigint().optional(),
322
322
  not: z.union([z.bigint(), z.lazy(() => BigIntFilterSchema)]).optional(),
323
323
  in: z.array(z.bigint()).optional(),
@@ -328,7 +328,7 @@ export const BigIntFilterSchema = z.object({
328
328
  gte: z.bigint().optional(),
329
329
  });
330
330
 
331
- export const NullableBigIntFilterSchema = z.object({
331
+ export const NullableBigIntFilterSchema: z.ZodTypeAny = z.object({
332
332
  equals: z.bigint().nullable().optional(),
333
333
  not: z.union([z.bigint().nullable(), z.lazy(() => NullableBigIntFilterSchema)]).optional(),
334
334
  in: z.array(z.bigint().nullable()).optional(),
@@ -339,17 +339,17 @@ export const NullableBigIntFilterSchema = z.object({
339
339
  gte: z.bigint().optional(),
340
340
  });
341
341
 
342
- export const BooleanFilterSchema = z.object({
342
+ export const BooleanFilterSchema: z.ZodTypeAny = z.object({
343
343
  equals: z.boolean().optional(),
344
344
  not: z.union([z.boolean(), z.lazy(() => BooleanFilterSchema)]).optional(),
345
345
  });
346
346
 
347
- export const NullableBooleanFilterSchema = z.object({
347
+ export const NullableBooleanFilterSchema: z.ZodTypeAny = z.object({
348
348
  equals: z.boolean().nullable().optional(),
349
349
  not: z.union([z.boolean().nullable(), z.lazy(() => NullableBooleanFilterSchema)]).optional(),
350
350
  });
351
351
 
352
- export const DateTimeFilterSchema = z.object({
352
+ export const DateTimeFilterSchema: z.ZodTypeAny = z.object({
353
353
  equals: z.union([z.date(), z.string()]).optional(),
354
354
  not: z.union([z.date(), z.string(), z.lazy(() => DateTimeFilterSchema)]).optional(),
355
355
  in: z.array(z.union([z.date(), z.string()])).optional(),
@@ -360,7 +360,7 @@ export const DateTimeFilterSchema = z.object({
360
360
  gte: z.union([z.date(), z.string()]).optional(),
361
361
  });
362
362
 
363
- export const NullableDateTimeFilterSchema = z.object({
363
+ export const NullableDateTimeFilterSchema: z.ZodTypeAny = z.object({
364
364
  equals: z.union([z.date(), z.string()]).nullable().optional(),
365
365
  not: z.union([z.date(), z.string(), z.lazy(() => NullableDateTimeFilterSchema)]).nullable().optional(),
366
366
  in: z.array(z.union([z.date(), z.string()]).nullable()).optional(),
@@ -371,14 +371,14 @@ export const NullableDateTimeFilterSchema = z.object({
371
371
  gte: z.union([z.date(), z.string()]).optional(),
372
372
  });
373
373
 
374
- export const EnumFilterSchema = z.object({
374
+ export const EnumFilterSchema: z.ZodTypeAny = z.object({
375
375
  equals: z.string().optional(),
376
376
  not: z.union([z.string(), z.lazy(() => EnumFilterSchema)]).optional(),
377
377
  in: z.array(z.string()).optional(),
378
378
  notIn: z.array(z.string()).optional(),
379
379
  });
380
380
 
381
- export const NullableEnumFilterSchema = z.object({
381
+ export const NullableEnumFilterSchema: z.ZodTypeAny = z.object({
382
382
  equals: z.string().nullable().optional(),
383
383
  not: z.union([z.string().nullable(), z.lazy(() => NullableEnumFilterSchema)]).optional(),
384
384
  in: z.array(z.string().nullable()).optional(),