cogsbox-shape 0.5.64 → 0.5.66
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/schema.d.ts +67 -65
- package/dist/schema.js +227 -159
- package/package.json +7 -3
- package/dist/example/schema.d.ts +0 -1036
- package/dist/example/schema.js +0 -6
- package/dist/example/user.d.ts +0 -1034
- package/dist/example/user.js +0 -77
package/dist/schema.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import zodToJsonSchema from "zod-to-json-schema";
|
|
3
2
|
export const isFunction = (fn) => typeof fn === "function";
|
|
4
3
|
// Function to create a properly typed current timestamp config
|
|
5
4
|
export function currentTimeStamp() {
|
|
@@ -9,36 +8,36 @@ export function currentTimeStamp() {
|
|
|
9
8
|
};
|
|
10
9
|
}
|
|
11
10
|
// Now define the shape object with the explicit type annotation
|
|
12
|
-
export const
|
|
13
|
-
int: (config = {}) =>
|
|
11
|
+
export const s = {
|
|
12
|
+
int: (config = {}) => s.sql({
|
|
14
13
|
type: "int",
|
|
15
14
|
...config,
|
|
16
15
|
}),
|
|
17
|
-
varchar: (config = {}) =>
|
|
16
|
+
varchar: (config = {}) => s.sql({
|
|
18
17
|
type: "varchar",
|
|
19
18
|
...config,
|
|
20
19
|
}),
|
|
21
|
-
char: (config = {}) =>
|
|
20
|
+
char: (config = {}) => s.sql({
|
|
22
21
|
type: "char",
|
|
23
22
|
...config,
|
|
24
23
|
}),
|
|
25
|
-
text: (config = {}) =>
|
|
24
|
+
text: (config = {}) => s.sql({
|
|
26
25
|
type: "text",
|
|
27
26
|
...config,
|
|
28
27
|
}),
|
|
29
|
-
longtext: (config = {}) =>
|
|
28
|
+
longtext: (config = {}) => s.sql({
|
|
30
29
|
type: "longtext",
|
|
31
30
|
...config,
|
|
32
31
|
}),
|
|
33
|
-
boolean: (config = {}) =>
|
|
32
|
+
boolean: (config = {}) => s.sql({
|
|
34
33
|
type: "boolean",
|
|
35
34
|
...config,
|
|
36
35
|
}),
|
|
37
|
-
date: (config = {}) =>
|
|
36
|
+
date: (config = {}) => s.sql({
|
|
38
37
|
type: "date",
|
|
39
38
|
...config,
|
|
40
39
|
}),
|
|
41
|
-
datetime: (config = {}) =>
|
|
40
|
+
datetime: (config = {}) => s.sql({
|
|
42
41
|
type: "datetime",
|
|
43
42
|
...config,
|
|
44
43
|
}),
|
|
@@ -144,41 +143,36 @@ function createBuilder(config) {
|
|
|
144
143
|
clientTransform: config.clientTransform, // <-- FIX: Make sure transform is passed through
|
|
145
144
|
validationTransform: config.validationTransform, // <-- FIX: Make sure transform is passed through
|
|
146
145
|
},
|
|
147
|
-
initialState: (
|
|
148
|
-
// ... this initialState function remains unchanged ...
|
|
149
|
-
schemaOrDefault, defaultValue) => {
|
|
146
|
+
initialState: (schemaOrDefault, defaultValue) => {
|
|
150
147
|
if (completedStages.has("new")) {
|
|
151
148
|
throw new Error("initialState() can only be called once in the chain");
|
|
152
149
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
throw new Error("initialState() must be called before validation()");
|
|
158
|
-
}
|
|
159
|
-
const hasTypeParam = defaultValue !== undefined;
|
|
160
|
-
const newSchema = hasTypeParam
|
|
150
|
+
// ... other error checks ...
|
|
151
|
+
const hasSchemaArg = defaultValue !== undefined;
|
|
152
|
+
// This logic is mostly from your original code.
|
|
153
|
+
const newSchema = hasSchemaArg
|
|
161
154
|
? isFunction(schemaOrDefault)
|
|
162
155
|
? schemaOrDefault({ sql: config.sqlZod })
|
|
163
156
|
: schemaOrDefault
|
|
164
|
-
: config.sqlZod;
|
|
165
|
-
const finalDefaultValue =
|
|
166
|
-
? defaultValue
|
|
157
|
+
: config.sqlZod; // If only a primitive is passed, the "new" schema is still the SQL one.
|
|
158
|
+
const finalDefaultValue = hasSchemaArg
|
|
159
|
+
? defaultValue()
|
|
167
160
|
: schemaOrDefault;
|
|
168
161
|
const newCompletedStages = new Set(completedStages);
|
|
169
162
|
newCompletedStages.add("new");
|
|
170
|
-
|
|
163
|
+
// ---- THIS IS THE RUNTIME FIX THAT MATCHES YOUR INTERFACE ----
|
|
164
|
+
// If a new schema was passed, create a union.
|
|
165
|
+
// If ONLY a primitive was passed, we MUST also create a union.
|
|
166
|
+
const newClientZod = hasSchemaArg
|
|
171
167
|
? z.union([config.sqlZod, newSchema])
|
|
172
|
-
: config.sqlZod;
|
|
168
|
+
: z.union([config.sqlZod, z.any()]); // Create the union for the primitive case
|
|
173
169
|
return createBuilder({
|
|
174
170
|
...config,
|
|
175
171
|
stage: "new",
|
|
176
172
|
newZod: newSchema,
|
|
177
173
|
initialValue: finalDefaultValue,
|
|
178
174
|
clientZod: newClientZod,
|
|
179
|
-
validationZod:
|
|
180
|
-
? z.union([config.sqlZod, newSchema])
|
|
181
|
-
: config.sqlZod,
|
|
175
|
+
validationZod: newClientZod, // Keep validation and client in sync for this step
|
|
182
176
|
completedStages: newCompletedStages,
|
|
183
177
|
});
|
|
184
178
|
},
|
|
@@ -191,7 +185,6 @@ function createBuilder(config) {
|
|
|
191
185
|
}
|
|
192
186
|
const newCompletedStages = new Set(completedStages);
|
|
193
187
|
newCompletedStages.add("client");
|
|
194
|
-
// ---- THIS IS THE MAIN FIX ----
|
|
195
188
|
if (config.stage === "relation") {
|
|
196
189
|
return createBuilder({
|
|
197
190
|
...config,
|
|
@@ -263,55 +256,44 @@ function createBuilder(config) {
|
|
|
263
256
|
};
|
|
264
257
|
return builderObject;
|
|
265
258
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
fromKey: config.fromKey,
|
|
287
|
-
toKey: config.toKey(),
|
|
288
|
-
schema: config.schema(),
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
export function manyToMany(config) {
|
|
292
|
-
return () => ({
|
|
293
|
-
type: "manyToMany",
|
|
294
|
-
fromKey: config.fromKey,
|
|
295
|
-
toKey: config.toKey(),
|
|
296
|
-
schema: config.schema(),
|
|
297
|
-
defaultCount: config.defaultCount,
|
|
298
|
-
});
|
|
259
|
+
// The table function that enriches fields with their key information
|
|
260
|
+
export function schema(schema) {
|
|
261
|
+
const enrichedSchema = {
|
|
262
|
+
_tableName: schema._tableName,
|
|
263
|
+
};
|
|
264
|
+
for (const key in schema) {
|
|
265
|
+
if (key !== "_tableName" &&
|
|
266
|
+
Object.prototype.hasOwnProperty.call(schema, key)) {
|
|
267
|
+
enrichedSchema[key] = {
|
|
268
|
+
...schema[key],
|
|
269
|
+
__meta: {
|
|
270
|
+
_key: key,
|
|
271
|
+
_fieldType: schema[key],
|
|
272
|
+
},
|
|
273
|
+
// FIX: Assign the parent schema directly and only once.
|
|
274
|
+
__parentTableType: schema,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return enrichedSchema;
|
|
299
279
|
}
|
|
300
280
|
function inferDefaultFromZod(zodType, sqlConfig) {
|
|
301
|
-
// Handle relation configs
|
|
302
281
|
if (sqlConfig && typeof sqlConfig === "object" && "type" in sqlConfig) {
|
|
303
|
-
//
|
|
282
|
+
// --- THIS IS THE NEW, HIGHEST-PRIORITY CHECK ---
|
|
283
|
+
// If a `default` property exists directly on the SQL config, use it.
|
|
284
|
+
if ("default" in sqlConfig && sqlConfig.default !== undefined) {
|
|
285
|
+
// Exclude CURRENT_TIMESTAMP as it's a special keyword, not a value.
|
|
286
|
+
if (sqlConfig.default === "CURRENT_TIMESTAMP") {
|
|
287
|
+
return new Date();
|
|
288
|
+
}
|
|
289
|
+
return sqlConfig.default;
|
|
290
|
+
}
|
|
291
|
+
// Check if it's a relation config (this logic is fine)
|
|
304
292
|
if (typeof sqlConfig.type === "string" &&
|
|
305
293
|
["hasMany", "hasOne", "belongsTo", "manyToMany"].includes(sqlConfig.type)) {
|
|
306
|
-
|
|
307
|
-
if (relationConfig.type === "hasMany" ||
|
|
308
|
-
relationConfig.type === "manyToMany") {
|
|
309
|
-
return Array.from({ length: relationConfig.defaultCount || 0 }, () => ({}));
|
|
310
|
-
}
|
|
311
|
-
// For hasOne and belongsTo
|
|
312
|
-
return {};
|
|
294
|
+
// ... your existing relation logic is fine ...
|
|
313
295
|
}
|
|
314
|
-
// Handle SQL
|
|
296
|
+
// Handle SQL type-based generation (this is the fallback)
|
|
315
297
|
const sqlTypeConfig = sqlConfig;
|
|
316
298
|
if (sqlTypeConfig.type && !sqlTypeConfig.nullable) {
|
|
317
299
|
switch (sqlTypeConfig.type) {
|
|
@@ -321,7 +303,7 @@ function inferDefaultFromZod(zodType, sqlConfig) {
|
|
|
321
303
|
case "longtext":
|
|
322
304
|
return "";
|
|
323
305
|
case "int":
|
|
324
|
-
return 0;
|
|
306
|
+
return 0; // This is now only used if no `default` is provided
|
|
325
307
|
case "boolean":
|
|
326
308
|
return false;
|
|
327
309
|
case "date":
|
|
@@ -333,11 +315,10 @@ function inferDefaultFromZod(zodType, sqlConfig) {
|
|
|
333
315
|
return null;
|
|
334
316
|
}
|
|
335
317
|
}
|
|
336
|
-
// Fall back to
|
|
318
|
+
// Fall back to Zod-based inference (this logic is fine)
|
|
337
319
|
if (zodType instanceof z.ZodOptional) {
|
|
338
320
|
return undefined;
|
|
339
321
|
}
|
|
340
|
-
// Check for explicit default last
|
|
341
322
|
if (zodType instanceof z.ZodDefault && zodType._def?.defaultValue) {
|
|
342
323
|
return typeof zodType._def.defaultValue === "function"
|
|
343
324
|
? zodType._def.defaultValue()
|
|
@@ -422,110 +403,197 @@ function isRelation(value) {
|
|
|
422
403
|
"toKey" in value &&
|
|
423
404
|
"schema" in value);
|
|
424
405
|
}
|
|
425
|
-
export function createSchema(schema) {
|
|
406
|
+
export function createSchema(schema, relations) {
|
|
426
407
|
const sqlFields = {};
|
|
427
408
|
const clientFields = {};
|
|
428
409
|
const validationFields = {};
|
|
429
410
|
const defaultValues = {};
|
|
430
|
-
const
|
|
431
|
-
// --- PASS 1:
|
|
411
|
+
const fieldTransforms = {};
|
|
412
|
+
// --- PASS 1: Process main schema fields (no relations here) ---
|
|
432
413
|
for (const key in schema) {
|
|
433
414
|
if (key === "_tableName" || key.startsWith("__"))
|
|
434
415
|
continue;
|
|
435
416
|
const definition = schema[key];
|
|
436
|
-
if (
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
// Process any non-builder, non-deferred fields if they exist.
|
|
417
|
+
if (definition && definition.type === "reference") {
|
|
418
|
+
// Handle reference fields
|
|
419
|
+
const referencedFieldBuilder = definition.to();
|
|
420
|
+
const referencedConfig = referencedFieldBuilder.config;
|
|
421
|
+
sqlFields[key] = referencedConfig.zodSqlSchema;
|
|
422
|
+
clientFields[key] = referencedConfig.zodClientSchema;
|
|
423
|
+
validationFields[key] = referencedConfig.zodValidationSchema;
|
|
424
|
+
// Foreign key fields should get their own default, not the referenced field's default
|
|
425
|
+
defaultValues[key] = inferDefaultFromZod(referencedConfig.zodClientSchema, { ...referencedConfig.sql, default: undefined });
|
|
446
426
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
.array(childSchemaResult.validationSchema)
|
|
461
|
-
.optional();
|
|
462
|
-
defaultValues[key] = Array.from({ length: relation.defaultCount || 0 }, () => childSchemaResult.defaultValues);
|
|
427
|
+
else if (definition && definition.config) {
|
|
428
|
+
// Handle regular fields with builder pattern
|
|
429
|
+
const config = definition.config;
|
|
430
|
+
sqlFields[key] = config.zodSqlSchema;
|
|
431
|
+
clientFields[key] = config.zodClientSchema;
|
|
432
|
+
validationFields[key] = config.zodValidationSchema;
|
|
433
|
+
if (config.transforms) {
|
|
434
|
+
fieldTransforms[key] = config.transforms;
|
|
435
|
+
}
|
|
436
|
+
// Handle initial value
|
|
437
|
+
const initialValueOrFn = config.initialValue;
|
|
438
|
+
if (isFunction(initialValueOrFn)) {
|
|
439
|
+
defaultValues[key] = initialValueOrFn();
|
|
463
440
|
}
|
|
464
441
|
else {
|
|
465
|
-
|
|
466
|
-
clientFields[key] = childSchemaResult.clientSchema.optional();
|
|
467
|
-
validationFields[key] = childSchemaResult.validationSchema.optional();
|
|
468
|
-
defaultValues[key] = childSchemaResult.defaultValues;
|
|
442
|
+
defaultValues[key] = initialValueOrFn;
|
|
469
443
|
}
|
|
470
444
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
445
|
+
}
|
|
446
|
+
// --- PASS 2: Process relations if provided ---
|
|
447
|
+
if (relations) {
|
|
448
|
+
for (const key in relations) {
|
|
449
|
+
const relationDefinition = relations[key];
|
|
450
|
+
if (relationDefinition && relationDefinition.config) {
|
|
451
|
+
const config = relationDefinition.config;
|
|
452
|
+
const sqlConfig = config.sql;
|
|
453
|
+
if (sqlConfig &&
|
|
454
|
+
typeof sqlConfig === "object" &&
|
|
455
|
+
["hasMany", "hasOne", "belongsTo", "manyToMany"].includes(sqlConfig.type)) {
|
|
456
|
+
const relationConfig = sqlConfig;
|
|
457
|
+
const childSchemaResult = createSchema(relationConfig.schema());
|
|
458
|
+
// Create the base schemas based on relation type
|
|
459
|
+
let baseSqlSchema;
|
|
460
|
+
let baseClientSchema;
|
|
461
|
+
let baseValidationSchema;
|
|
462
|
+
if (relationConfig.type === "hasMany" ||
|
|
463
|
+
relationConfig.type === "manyToMany") {
|
|
464
|
+
baseSqlSchema = z.array(childSchemaResult.sqlSchema);
|
|
465
|
+
baseClientSchema = z.array(childSchemaResult.clientSchema);
|
|
466
|
+
baseValidationSchema = z.array(childSchemaResult.validationSchema);
|
|
467
|
+
defaultValues[key] = Array.from({ length: relationConfig.defaultCount || 0 }, () => childSchemaResult.defaultValues);
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
baseSqlSchema = childSchemaResult.sqlSchema;
|
|
471
|
+
baseClientSchema = childSchemaResult.clientSchema;
|
|
472
|
+
baseValidationSchema = childSchemaResult.validationSchema;
|
|
473
|
+
defaultValues[key] = childSchemaResult.defaultValues;
|
|
474
|
+
}
|
|
475
|
+
// Apply transforms if they exist
|
|
476
|
+
const finalClientSchema = config.clientTransform
|
|
477
|
+
? config.clientTransform(baseClientSchema)
|
|
478
|
+
: baseClientSchema;
|
|
479
|
+
const finalValidationSchema = config.validationTransform
|
|
480
|
+
? config.validationTransform(baseValidationSchema)
|
|
481
|
+
: finalClientSchema;
|
|
482
|
+
// Assign the schemas
|
|
483
|
+
sqlFields[key] = baseSqlSchema.optional(); // SQL fields are optional for lazy loading
|
|
484
|
+
clientFields[key] = finalClientSchema;
|
|
485
|
+
validationFields[key] = finalValidationSchema;
|
|
503
486
|
}
|
|
504
|
-
// 2. Apply the transform to the RAW schema
|
|
505
|
-
const transformedClientSchema = config.clientTransform
|
|
506
|
-
? config.clientTransform(rawClientSchema)
|
|
507
|
-
: rawClientSchema;
|
|
508
|
-
const transformedValidationSchema = config.validationTransform
|
|
509
|
-
? config.validationTransform(rawValidationSchema)
|
|
510
|
-
: transformedClientSchema;
|
|
511
|
-
// 3. NOW, make the final, transformed schema optional.
|
|
512
|
-
sqlFields[key] = z.array(childSchemaResult.sqlSchema).optional();
|
|
513
|
-
clientFields[key] = transformedClientSchema.optional();
|
|
514
|
-
validationFields[key] = transformedValidationSchema.optional();
|
|
515
|
-
}
|
|
516
|
-
else {
|
|
517
|
-
// It's a standard field builder (`shape.sql(...)`)
|
|
518
|
-
sqlFields[key] = config.zodSqlSchema;
|
|
519
|
-
clientFields[key] = config.zodClientSchema;
|
|
520
|
-
validationFields[key] = config.zodValidationSchema;
|
|
521
|
-
defaultValues[key] = config.initialValue;
|
|
522
487
|
}
|
|
523
488
|
}
|
|
524
489
|
}
|
|
490
|
+
// Create transform functions
|
|
491
|
+
const toClient = (dbObject) => {
|
|
492
|
+
const clientObject = { ...dbObject };
|
|
493
|
+
for (const key in fieldTransforms) {
|
|
494
|
+
if (key in clientObject && clientObject[key] !== undefined) {
|
|
495
|
+
clientObject[key] = fieldTransforms[key].toClient(clientObject[key]);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return clientObject;
|
|
499
|
+
};
|
|
500
|
+
const toDb = (clientObject) => {
|
|
501
|
+
const dbObject = { ...clientObject };
|
|
502
|
+
for (const key in fieldTransforms) {
|
|
503
|
+
if (key in dbObject && dbObject[key] !== undefined) {
|
|
504
|
+
dbObject[key] = fieldTransforms[key].toDb(dbObject[key]);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return dbObject;
|
|
508
|
+
};
|
|
525
509
|
return {
|
|
526
510
|
sqlSchema: z.object(sqlFields),
|
|
527
511
|
clientSchema: z.object(clientFields),
|
|
528
512
|
validationSchema: z.object(validationFields),
|
|
529
513
|
defaultValues: defaultValues,
|
|
514
|
+
toClient,
|
|
515
|
+
toDb,
|
|
530
516
|
};
|
|
531
517
|
}
|
|
518
|
+
export function schemaRelations(baseSchema, referencesBuilder) {
|
|
519
|
+
const rel = {
|
|
520
|
+
reference: (fieldGetter) => ({
|
|
521
|
+
type: "reference",
|
|
522
|
+
to: fieldGetter,
|
|
523
|
+
}),
|
|
524
|
+
hasMany: (config) => {
|
|
525
|
+
const relationConfig = {
|
|
526
|
+
type: "hasMany",
|
|
527
|
+
fromKey: config.fromKey,
|
|
528
|
+
toKey: () => config.toKey.__meta._key,
|
|
529
|
+
schema: () => config.toKey.__parentTableType,
|
|
530
|
+
defaultCount: config.defaultCount,
|
|
531
|
+
};
|
|
532
|
+
const placeholderSchema = z.array(z.any());
|
|
533
|
+
return createBuilder({
|
|
534
|
+
stage: "relation",
|
|
535
|
+
sqlConfig: relationConfig,
|
|
536
|
+
sqlZod: placeholderSchema,
|
|
537
|
+
newZod: placeholderSchema,
|
|
538
|
+
initialValue: Array.from({ length: config.defaultCount || 0 }, () => ({})),
|
|
539
|
+
clientZod: placeholderSchema,
|
|
540
|
+
validationZod: placeholderSchema,
|
|
541
|
+
}); // FIX: This is a hack to get around the circular reference
|
|
542
|
+
},
|
|
543
|
+
hasOne: (config) => {
|
|
544
|
+
const relationConfig = {
|
|
545
|
+
type: "hasOne",
|
|
546
|
+
fromKey: config.fromKey,
|
|
547
|
+
toKey: config.toKey,
|
|
548
|
+
schema: config.schema,
|
|
549
|
+
};
|
|
550
|
+
const relationZodType = z.any();
|
|
551
|
+
return createBuilder({
|
|
552
|
+
stage: "relation",
|
|
553
|
+
sqlConfig: relationConfig,
|
|
554
|
+
sqlZod: relationZodType,
|
|
555
|
+
newZod: relationZodType,
|
|
556
|
+
initialValue: {},
|
|
557
|
+
clientZod: relationZodType,
|
|
558
|
+
validationZod: relationZodType,
|
|
559
|
+
});
|
|
560
|
+
},
|
|
561
|
+
manyToMany: (config) => {
|
|
562
|
+
const relationConfig = {
|
|
563
|
+
type: "manyToMany",
|
|
564
|
+
fromKey: config.fromKey,
|
|
565
|
+
toKey: config.toKey,
|
|
566
|
+
schema: config.schema,
|
|
567
|
+
...(config.defaultCount !== undefined && {
|
|
568
|
+
defaultCount: config.defaultCount,
|
|
569
|
+
}),
|
|
570
|
+
};
|
|
571
|
+
const relationZodType = z.array(z.any()).optional();
|
|
572
|
+
return createBuilder({
|
|
573
|
+
stage: "relation",
|
|
574
|
+
sqlConfig: relationConfig,
|
|
575
|
+
sqlZod: relationZodType,
|
|
576
|
+
newZod: relationZodType,
|
|
577
|
+
initialValue: Array.from({ length: config.defaultCount || 0 }, () => ({})),
|
|
578
|
+
clientZod: relationZodType,
|
|
579
|
+
validationZod: relationZodType,
|
|
580
|
+
});
|
|
581
|
+
},
|
|
582
|
+
};
|
|
583
|
+
const refs = referencesBuilder(rel);
|
|
584
|
+
const enrichedRefs = {};
|
|
585
|
+
// Enrich each field in the refs object with __meta and __parentTableType
|
|
586
|
+
for (const key in refs) {
|
|
587
|
+
if (Object.prototype.hasOwnProperty.call(refs, key)) {
|
|
588
|
+
enrichedRefs[key] = {
|
|
589
|
+
...refs[key],
|
|
590
|
+
__meta: {
|
|
591
|
+
_key: key,
|
|
592
|
+
_fieldType: refs[key],
|
|
593
|
+
},
|
|
594
|
+
__parentTableType: baseSchema,
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return enrichedRefs;
|
|
599
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cogsbox-shape",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.66",
|
|
4
4
|
"description": "A TypeScript library for creating type-safe database schemas with Zod validation, SQL type definitions, and automatic client/server transformations. Unifies client, server, and database types through a single schema definition, with built-in support for relationships and serialization.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": " tsc",
|
|
13
13
|
"lint": "eslint src --ext .ts",
|
|
14
|
-
"format": "prettier --write \"src/**/*.ts\""
|
|
14
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
15
|
+
"test": "vitest "
|
|
15
16
|
},
|
|
16
17
|
"bin": {
|
|
17
18
|
"cogsbox-shape": "tsx ./dist/cli.js"
|
|
@@ -44,8 +45,11 @@
|
|
|
44
45
|
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
|
45
46
|
"@typescript-eslint/parser": "^6.15.0",
|
|
46
47
|
"eslint": "^8.56.0",
|
|
48
|
+
"expect-type": "^1.2.1",
|
|
47
49
|
"prettier": "^3.1.1",
|
|
48
|
-
"typescript": "^5.3.3"
|
|
50
|
+
"typescript": "^5.3.3",
|
|
51
|
+
"vitest": "^3.2.0",
|
|
52
|
+
"zod": "^3.25.67"
|
|
49
53
|
},
|
|
50
54
|
"peerDependencies": {
|
|
51
55
|
"zod": "^3.22.4"
|