cogsbox-shape 0.5.40 → 0.5.42

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 CHANGED
@@ -4784,56 +4784,15 @@ export declare function reference<TField extends object>(config: TField): {
4784
4784
  to: TField;
4785
4785
  };
4786
4786
  export declare function createMixedValidationSchema<T extends Schema<any>>(schema: T, clientSchema?: z.ZodObject<any>, dbSchema?: z.ZodObject<any>): z.ZodObject<any>;
4787
- type SchemaDefinition = {
4788
- _tableName: string;
4789
- [key: string]: any;
4790
- };
4791
- type InferSchemaByKey<T, Key extends "zodSqlSchema" | "zodClientSchema" | "zodValidationSchema"> = {
4792
- [K in keyof T as K extends "_tableName" ? never : K]: T[K] extends {
4793
- config: {
4794
- [P in Key]: infer S extends z.ZodTypeAny;
4795
- };
4796
- } ? S : T[K] extends {
4797
- type: "reference";
4798
- to: () => {
4799
- config: {
4800
- [P in Key]: infer S extends z.ZodTypeAny;
4801
- };
4802
- };
4803
- } ? S : T[K] extends () => {
4804
- type: "hasMany" | "manyToMany";
4805
- schema: infer S extends SchemaDefinition;
4806
- } ? z.ZodArray<z.ZodObject<Prettify<InferSchemaByKey<S, Key>>>> : T[K] extends () => {
4807
- type: "hasOne" | "belongsTo";
4808
- schema: infer S extends SchemaDefinition;
4809
- } ? z.ZodObject<Prettify<InferSchemaByKey<S, Key>>> : never;
4810
- };
4811
- type InferSqlSchema<T> = InferSchemaByKey<T, "zodSqlSchema">;
4812
- type InferClientSchema<T> = InferSchemaByKey<T, "zodClientSchema">;
4813
- type InferValidationSchema<T> = InferSchemaByKey<T, "zodValidationSchema">;
4814
- type InferDefaultValues2<T> = {
4815
- [K in keyof T as K extends "_tableName" ? never : K]: T[K] extends {
4816
- config: {
4817
- initialValue: infer D;
4818
- };
4819
- } ? D : T[K] extends () => {
4820
- type: "hasMany" | "manyToMany";
4821
- schema: infer S extends SchemaDefinition;
4822
- defaultCount?: number;
4823
- } ? Array<Prettify<InferDefaultValues2<S>>> : T[K] extends () => {
4824
- type: "hasOne" | "belongsTo";
4825
- schema: infer S extends SchemaDefinition;
4826
- } ? Prettify<InferDefaultValues2<S>> : never;
4827
- };
4828
4787
  export declare function createSchema<T extends {
4829
4788
  _tableName: string;
4830
4789
  }>(schema: T extends {
4831
4790
  _tableName: string;
4832
4791
  } ? T : never): {
4833
- sqlSchema: z.ZodObject<Prettify<InferSqlSchema<T>>>;
4834
- clientSchema: z.ZodObject<Prettify<InferClientSchema<T>>>;
4835
- validationSchema: z.ZodObject<Prettify<InferValidationSchema<T>>>;
4836
- defaultValues: Prettify<InferDefaultValues2<T>>;
4792
+ sqlSchema: any;
4793
+ clientSchema: any;
4794
+ validationSchema: any;
4795
+ defaultValues: any;
4837
4796
  };
4838
4797
  export type InferSchemaTypes<T extends {
4839
4798
  _tableName: string;
package/dist/schema.js CHANGED
@@ -340,7 +340,7 @@ function isRelation(value) {
340
340
  typeof value === "object" &&
341
341
  "type" in value &&
342
342
  "fromKey" in value &&
343
- "toKey" in value &&
343
+ typeof value.toKey === "function" && // More specific check
344
344
  "schema" in value);
345
345
  }
346
346
  export function createSchema(schema) {
@@ -349,11 +349,11 @@ export function createSchema(schema) {
349
349
  const validationFields = {};
350
350
  const defaultValues = {};
351
351
  for (const key in schema) {
352
- if (key === "_tableName")
352
+ if (key === "_tableName" || key.startsWith("__"))
353
353
  continue;
354
354
  const field = schema[key];
355
355
  // Case 1: Handle relation functions (hasMany, hasOne, etc.)
356
- if (typeof field === "function") {
356
+ if (isFunction(field)) {
357
357
  const relation = field();
358
358
  if (!isRelation(relation)) {
359
359
  continue;
@@ -362,34 +362,36 @@ export function createSchema(schema) {
362
362
  const childSchemaResult = createSchema(relation.schema);
363
363
  // For to-many relations, wrap schemas in z.array()
364
364
  if (relation.type === "hasMany" || relation.type === "manyToMany") {
365
- sqlFields[key] = z.array(childSchemaResult.sqlSchema);
366
- clientFields[key] = z.array(childSchemaResult.clientSchema);
367
- validationFields[key] = z.array(childSchemaResult.validationSchema);
368
- // Create an array of default values for the relation
365
+ const arraySchema = z.array(childSchemaResult.validationSchema);
366
+ // Relations are often not present on creation, so they should be optional.
367
+ validationFields[key] = arraySchema.optional();
368
+ clientFields[key] = z.array(childSchemaResult.clientSchema).optional();
369
+ sqlFields[key] = z.array(childSchemaResult.sqlSchema).optional();
369
370
  const count = relation.defaultCount || 0;
370
371
  defaultValues[key] = Array.from({ length: count }, () => childSchemaResult.defaultValues);
371
372
  }
372
373
  else {
373
- // For to-one relations, use schemas directly
374
- sqlFields[key] = childSchemaResult.sqlSchema;
375
- clientFields[key] = childSchemaResult.clientSchema;
376
- validationFields[key] = childSchemaResult.validationSchema;
374
+ // hasOne or belongsTo
375
+ // Relations are often not present on creation, so they should be optional.
376
+ validationFields[key] = childSchemaResult.validationSchema.optional();
377
+ clientFields[key] = childSchemaResult.clientSchema.optional();
378
+ sqlFields[key] = childSchemaResult.sqlSchema.optional();
377
379
  defaultValues[key] = childSchemaResult.defaultValues;
378
380
  }
379
381
  }
380
- else if (field &&
381
- typeof field === "object" &&
382
- field.type === "reference") {
382
+ // Case 2: Handle reference() objects
383
+ else if (field && field.type === "reference") {
383
384
  const referencedField = field.to();
384
- sqlFields[key] = referencedField.config.zodSqlSchema;
385
- clientFields[key] = referencedField.config.zodClientSchema;
386
385
  validationFields[key] = referencedField.config.zodValidationSchema;
386
+ clientFields[key] = referencedField.config.zodClientSchema;
387
+ sqlFields[key] = referencedField.config.zodSqlSchema;
387
388
  defaultValues[key] = referencedField.config.initialValue;
388
389
  }
390
+ // Case 3: Handle standard shape.sql() fields
389
391
  else if (field && typeof field === "object" && "config" in field) {
390
- sqlFields[key] = field.config.zodSqlSchema;
391
- clientFields[key] = field.config.zodClientSchema;
392
392
  validationFields[key] = field.config.zodValidationSchema;
393
+ clientFields[key] = field.config.zodClientSchema;
394
+ sqlFields[key] = field.config.zodSqlSchema;
393
395
  defaultValues[key] = field.config.initialValue;
394
396
  }
395
397
  }
@@ -404,6 +406,7 @@ export function createSchema(schema) {
404
406
  /**
405
407
  * (This is the smart function from the last answer that resolves `toKey` functions)
406
408
  */
409
+ // In your cogsbox-shape file, replace the entire `serializeSchemaMetadata` function.
407
410
  function serializeSchemaMetadata(schema) {
408
411
  const fields = {};
409
412
  const relations = {};
@@ -418,9 +421,13 @@ function serializeSchemaMetadata(schema) {
418
421
  continue;
419
422
  let toKeyName = null;
420
423
  try {
421
- const targetFieldBuilder = relation.toKey();
424
+ let targetFieldDefinition = relation.toKey();
425
+ if (targetFieldDefinition &&
426
+ targetFieldDefinition.type === "reference") {
427
+ targetFieldDefinition = targetFieldDefinition.to();
428
+ }
422
429
  for (const targetKey in relation.schema) {
423
- if (relation.schema[targetKey] === targetFieldBuilder) {
430
+ if (relation.schema[targetKey] === targetFieldDefinition) {
424
431
  toKeyName = targetKey;
425
432
  break;
426
433
  }
@@ -432,6 +439,7 @@ function serializeSchemaMetadata(schema) {
432
439
  console.error(`[cogsbox-shape] Error resolving 'toKey' for relation '${key}' in schema '${schema._tableName}'.`);
433
440
  throw e;
434
441
  }
442
+ // This is the critical part: ADD the processed relation to the relations object.
435
443
  relations[key] = {
436
444
  type: "relation",
437
445
  relationType: relation.type,
@@ -444,10 +452,23 @@ function serializeSchemaMetadata(schema) {
444
452
  fields[key] = { type: "field", sql: definition.config.sql };
445
453
  if (definition.config.sql.pk === true) {
446
454
  if (primaryKey)
447
- console.warn(`[cogsbox-shape] Multiple primary keys in schema '${schema._tableName}'. Using last one found: '${key}'.`);
455
+ console.warn(`[cogsbox-shape] Multiple primary keys found. Using last one: '${key}'.`);
448
456
  primaryKey = key;
449
457
  }
450
458
  }
459
+ else if (definition && definition.type === "reference") {
460
+ const targetFieldBuilder = definition.to();
461
+ if (targetFieldBuilder &&
462
+ targetFieldBuilder.config &&
463
+ targetFieldBuilder.config.sql) {
464
+ fields[key] = { type: "field", sql: targetFieldBuilder.config.sql };
465
+ if (targetFieldBuilder.config.sql.pk) {
466
+ if (primaryKey)
467
+ console.warn(`[cogsbox-shape] Multiple primary keys found. Using last one: '${key}'.`);
468
+ primaryKey = key;
469
+ }
470
+ }
471
+ }
451
472
  }
452
473
  return { _tableName: schema._tableName, primaryKey, fields, relations };
453
474
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-shape",
3
- "version": "0.5.40",
3
+ "version": "0.5.42",
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",