cogsbox-shape 0.5.62 → 0.5.63
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.js +57 -75
- package/package.json +1 -1
package/dist/schema.js
CHANGED
|
@@ -422,68 +422,35 @@ function isRelation(value) {
|
|
|
422
422
|
"toKey" in value &&
|
|
423
423
|
"schema" in value);
|
|
424
424
|
}
|
|
425
|
-
// In your cogsbox-shape file...
|
|
426
|
-
// Replace the entire existing createSchema function with this SINGLE, CORRECT version.
|
|
427
|
-
// In your cogsbox-shape file...
|
|
428
|
-
// Replace the entire existing createSchema function with this SINGLE, CORRECT version.
|
|
429
425
|
export function createSchema(schema) {
|
|
430
426
|
const sqlFields = {};
|
|
431
427
|
const clientFields = {};
|
|
432
428
|
const validationFields = {};
|
|
433
429
|
const defaultValues = {};
|
|
434
|
-
// Store the functions to be executed in a second pass
|
|
435
430
|
const deferredFields = [];
|
|
436
|
-
// --- PASS 1:
|
|
431
|
+
// --- PASS 1: Separate immediate fields from deferred relations/references ---
|
|
437
432
|
for (const key in schema) {
|
|
438
433
|
if (key === "_tableName" || key.startsWith("__"))
|
|
439
434
|
continue;
|
|
440
435
|
const definition = schema[key];
|
|
441
|
-
if (typeof definition === "
|
|
442
|
-
// It's a
|
|
436
|
+
if ((definition && typeof definition.config === "object") || // It's a builder
|
|
437
|
+
typeof definition === "function" || // It's a legacy relation
|
|
438
|
+
(definition && definition.type === "reference") // It's a reference
|
|
439
|
+
) {
|
|
440
|
+
// Defer all builders, functions, and references to Pass 2
|
|
443
441
|
deferredFields.push({ key, definition });
|
|
444
442
|
}
|
|
445
|
-
else
|
|
446
|
-
//
|
|
447
|
-
|
|
448
|
-
}
|
|
449
|
-
else if (definition && typeof definition.config === "object") {
|
|
450
|
-
// Check if it's a relation builder
|
|
451
|
-
const sqlConfig = definition.config.sql;
|
|
452
|
-
if (sqlConfig &&
|
|
453
|
-
typeof sqlConfig === "object" &&
|
|
454
|
-
["hasMany", "manyToMany", "hasOne", "belongsTo"].includes(sqlConfig.type)) {
|
|
455
|
-
// It's a relation builder - defer it
|
|
456
|
-
deferredFields.push({ key, definition: sqlConfig });
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
// It's a standard field builder. Process it now.
|
|
460
|
-
sqlFields[key] = definition.config.zodSqlSchema;
|
|
461
|
-
clientFields[key] = definition.config.zodClientSchema;
|
|
462
|
-
validationFields[key] = definition.config.zodValidationSchema;
|
|
463
|
-
defaultValues[key] = definition.config.initialValue;
|
|
464
|
-
}
|
|
443
|
+
else {
|
|
444
|
+
// This case should ideally not be hit with the builder pattern, but is safe to have.
|
|
445
|
+
// Process any non-builder, non-deferred fields if they exist.
|
|
465
446
|
}
|
|
466
447
|
}
|
|
467
|
-
//
|
|
448
|
+
// --- PASS 2: Process all deferred references and relations ---
|
|
468
449
|
for (const { key, definition } of deferredFields) {
|
|
469
450
|
let resolvedDefinition = definition;
|
|
470
|
-
// If it's a relation like hasMany, call the outer function to get the config object
|
|
471
451
|
if (typeof resolvedDefinition === "function") {
|
|
452
|
+
// Handle legacy function style: hasMany(...)
|
|
472
453
|
resolvedDefinition = resolvedDefinition();
|
|
473
|
-
}
|
|
474
|
-
if (resolvedDefinition && resolvedDefinition.type === "reference") {
|
|
475
|
-
const referencedField = resolvedDefinition.to(); // This is now safe to call
|
|
476
|
-
if (!referencedField || !referencedField.config) {
|
|
477
|
-
throw new Error(`Could not resolve reference for key "${key}"`);
|
|
478
|
-
}
|
|
479
|
-
sqlFields[key] = referencedField.config.zodSqlSchema;
|
|
480
|
-
clientFields[key] = referencedField.config.zodClientSchema;
|
|
481
|
-
validationFields[key] = referencedField.config.zodValidationSchema;
|
|
482
|
-
defaultValues[key] = referencedField.config.initialValue;
|
|
483
|
-
}
|
|
484
|
-
else if (resolvedDefinition &&
|
|
485
|
-
["hasMany", "manyToMany", "hasOne", "belongsTo"].includes(resolvedDefinition.type)) {
|
|
486
|
-
// Handle legacy function-style relations
|
|
487
454
|
const relation = resolvedDefinition;
|
|
488
455
|
const childSchemaResult = createSchema(relation.schema);
|
|
489
456
|
if (relation.type === "hasMany" || relation.type === "manyToMany") {
|
|
@@ -495,46 +462,61 @@ export function createSchema(schema) {
|
|
|
495
462
|
defaultValues[key] = Array.from({ length: relation.defaultCount || 0 }, () => childSchemaResult.defaultValues);
|
|
496
463
|
}
|
|
497
464
|
else {
|
|
498
|
-
// hasOne or belongsTo
|
|
499
465
|
sqlFields[key] = childSchemaResult.sqlSchema.optional();
|
|
500
466
|
clientFields[key] = childSchemaResult.clientSchema.optional();
|
|
501
467
|
validationFields[key] = childSchemaResult.validationSchema.optional();
|
|
502
468
|
defaultValues[key] = childSchemaResult.defaultValues;
|
|
503
469
|
}
|
|
504
470
|
}
|
|
505
|
-
else if (
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
[
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
//
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
if (
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
471
|
+
else if (resolvedDefinition && resolvedDefinition.type === "reference") {
|
|
472
|
+
// Handle reference fields
|
|
473
|
+
const referencedField = resolvedDefinition.to();
|
|
474
|
+
sqlFields[key] = referencedField.config.zodSqlSchema;
|
|
475
|
+
clientFields[key] = referencedField.config.zodClientSchema;
|
|
476
|
+
validationFields[key] = referencedField.config.zodValidationSchema;
|
|
477
|
+
defaultValues[key] = referencedField.config.initialValue;
|
|
478
|
+
}
|
|
479
|
+
else if (resolvedDefinition && resolvedDefinition.config) {
|
|
480
|
+
// It's a builder object (`shape.sql(...)` or `shape.hasMany(...)`)
|
|
481
|
+
const config = resolvedDefinition.config;
|
|
482
|
+
const sqlConfig = config.sql;
|
|
483
|
+
if (sqlConfig &&
|
|
484
|
+
typeof sqlConfig === "object" &&
|
|
485
|
+
["hasMany", "hasOne", "belongsTo", "manyToMany"].includes(sqlConfig.type)) {
|
|
486
|
+
// --- THIS IS THE KEY PART FOR RELATION BUILDERS ---
|
|
487
|
+
const relationConfig = sqlConfig;
|
|
488
|
+
const childSchemaResult = createSchema(relationConfig.schema);
|
|
489
|
+
let baseClientSchema;
|
|
490
|
+
let baseValidationSchema;
|
|
491
|
+
if (relationConfig.type === "hasMany" ||
|
|
492
|
+
relationConfig.type === "manyToMany") {
|
|
493
|
+
baseClientSchema = z.array(childSchemaResult.clientSchema).optional();
|
|
494
|
+
baseValidationSchema = z
|
|
495
|
+
.array(childSchemaResult.validationSchema)
|
|
496
|
+
.optional();
|
|
497
|
+
defaultValues[key] = Array.from({ length: relationConfig.defaultCount || 0 }, () => childSchemaResult.defaultValues);
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
baseClientSchema = childSchemaResult.clientSchema.optional();
|
|
501
|
+
baseValidationSchema = childSchemaResult.validationSchema.optional();
|
|
502
|
+
defaultValues[key] = childSchemaResult.defaultValues;
|
|
503
|
+
}
|
|
504
|
+
// Apply the stored transform from the builder if it exists.
|
|
505
|
+
sqlFields[key] = z.array(childSchemaResult.sqlSchema).optional();
|
|
506
|
+
clientFields[key] = config.clientTransform
|
|
507
|
+
? config.clientTransform(baseClientSchema) // APPLY THE TRANSFORM
|
|
508
|
+
: baseClientSchema;
|
|
509
|
+
validationFields[key] = config.validationTransform
|
|
510
|
+
? config.validationTransform(baseValidationSchema) // APPLY VALIDATION TRANSFORM
|
|
511
|
+
: clientFields[key]; // Fallback to the (potentially transformed) client schema
|
|
524
512
|
}
|
|
525
513
|
else {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
514
|
+
// It's a standard field builder (`shape.sql(...)`)
|
|
515
|
+
sqlFields[key] = config.zodSqlSchema;
|
|
516
|
+
clientFields[key] = config.zodClientSchema;
|
|
517
|
+
validationFields[key] = config.zodValidationSchema;
|
|
518
|
+
defaultValues[key] = config.initialValue;
|
|
529
519
|
}
|
|
530
|
-
sqlFields[key] = z.array(childSchemaResult.sqlSchema).optional(); // SQL schema is never transformed by client
|
|
531
|
-
clientFields[key] = config.clientTransform
|
|
532
|
-
? config.clientTransform(baseClientSchema) // Apply the stored function
|
|
533
|
-
: baseClientSchema; // Or use the default if no transform exists
|
|
534
|
-
// Validation falls back to the client schema (which may have been transformed)
|
|
535
|
-
validationFields[key] = config.validationTransform
|
|
536
|
-
? config.validationTransform(baseValidationSchema)
|
|
537
|
-
: clientFields[key];
|
|
538
520
|
}
|
|
539
521
|
}
|
|
540
522
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cogsbox-shape",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.63",
|
|
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",
|