cogsbox-shape 0.5.148 → 0.5.149

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.
Files changed (2) hide show
  1. package/dist/schema.js +19 -36
  2. package/package.json +1 -1
package/dist/schema.js CHANGED
@@ -559,54 +559,43 @@ export function createSchema(schema, relations) {
559
559
  toDb,
560
560
  };
561
561
  }
562
- function createViewObject(initialRegistryKey, // The key for the starting schema, e.g., "users"
563
- selection, registry, tableNameToRegistryKeyMap // The lookup map
564
- ) {
565
- /**
566
- * A recursive helper function that builds a Zod schema for a given schema and its selected relations.
567
- * It is defined inside createViewObject to have access to the `registry` and `tableNameToRegistryKeyMap` via a closure.
568
- *
569
- * @param currentRegistryKey - The user-defined key for the current schema being processed (e.g., "users", then "posts").
570
- * @param subSelection - The part of the selection object for the current schema (e.g., { comments: true } or just `true`).
571
- * @param schemaType - Whether to build the 'client' or 'validation' schema.
572
- * @returns A ZodObject representing the composed schema.
573
- */
562
+ function createViewObject(initialRegistryKey, selection, registry, tableNameToRegistryKeyMap) {
563
+ // Add a flag to track if all tables support reconciliation
564
+ let allTablesSupportsReconciliation = true;
574
565
  function buildView(currentRegistryKey, subSelection, schemaType) {
575
- // 1. Find the current schema's definition in the registry using its KEY.
576
566
  const registryEntry = registry[currentRegistryKey];
577
567
  if (!registryEntry) {
578
568
  throw new Error(`Schema with key "${currentRegistryKey}" not found in the registry.`);
579
569
  }
580
- // 2. Get the base Zod schema (primitives and references only) for the current level.
570
+ // Check if this table has pk and clientPk
571
+ const hasPks = !!(registryEntry.pk &&
572
+ registryEntry.pk.length > 0 &&
573
+ registryEntry.clientPk &&
574
+ registryEntry.clientPk.length > 0);
575
+ if (!hasPks) {
576
+ allTablesSupportsReconciliation = false;
577
+ }
581
578
  const baseSchema = schemaType === "server"
582
579
  ? registryEntry.zodSchemas.validationSchema
583
580
  : registryEntry.zodSchemas.clientSchema;
584
581
  const primitiveShape = baseSchema.shape;
585
- // 3. If the selection is just `true`, we are done at this level. Return the base primitive schema.
586
582
  if (subSelection === true) {
587
583
  return z.object(primitiveShape);
588
584
  }
589
- // 4. If the selection is an object, we need to process its relations.
590
585
  const selectedRelationShapes = {};
591
586
  if (typeof subSelection === "object") {
592
- // Iterate over the keys in the selection object (e.g., "posts", "profile").
593
587
  for (const relationKey in subSelection) {
594
- // Check if this key corresponds to a valid relation in the raw schema definition.
595
588
  const relationBuilder = registryEntry.rawSchema[relationKey];
596
589
  const isRelation = relationBuilder?.config?.sql?.schema;
597
590
  if (subSelection[relationKey] && isRelation) {
598
591
  const relationConfig = relationBuilder.config.sql;
599
- // 5. KEY STEP: Get the internal `_tableName` of the TARGET schema (e.g., "post_table").
600
592
  const targetTableName = relationConfig.schema()._tableName;
601
- // 6. KEY STEP: Use the map to find the REGISTRY KEY for that target schema (e.g., "posts").
602
593
  const nextRegistryKey = tableNameToRegistryKeyMap[targetTableName];
603
594
  if (!nextRegistryKey) {
604
595
  throw new Error(`Could not resolve registry key for table "${targetTableName}"`);
605
596
  }
606
- // 7. RECURSIVE CALL: Call `buildView` for the related schema, passing the
607
- // CORRECT registry key and the sub-selection for that relation.
597
+ // Recursive call will also check that table's pk/clientPk
608
598
  const relationSchema = buildView(nextRegistryKey, subSelection[relationKey], schemaType);
609
- // 8. Wrap the resulting schema in an array or optional based on the relation type.
610
599
  if (["hasMany", "manyToMany"].includes(relationConfig.type)) {
611
600
  selectedRelationShapes[relationKey] = z.array(relationSchema);
612
601
  }
@@ -616,15 +605,14 @@ selection, registry, tableNameToRegistryKeyMap // The lookup map
616
605
  }
617
606
  }
618
607
  }
619
- // 9. Combine the base primitive fields with the newly built relational schemas.
620
608
  const finalShape = { ...primitiveShape, ...selectedRelationShapes };
621
609
  return z.object(finalShape);
622
610
  }
623
- // The main function's return value. It kicks off the recursive process for both client and validation schemas.
624
611
  return {
625
612
  sql: registry[initialRegistryKey].zodSchemas.sqlSchema,
626
613
  client: buildView(initialRegistryKey, selection, "client"),
627
614
  server: buildView(initialRegistryKey, selection, "server"),
615
+ supportsReconciliation: allTablesSupportsReconciliation, // Add this flag
628
616
  };
629
617
  }
630
618
  export function createSchemaBox(schemas, resolver) {
@@ -771,9 +759,8 @@ export function createSchemaBox(schemas, resolver) {
771
759
  createView: (selection) => {
772
760
  const view = createViewObject(tableName, selection, finalRegistry, tableNameToRegistryKeyMap);
773
761
  const defaults = computeViewDefaults(tableName, selection, finalRegistry, tableNameToRegistryKeyMap);
774
- // Return the same shape as regular entries, but with isView marker
775
762
  return {
776
- definition: entry.rawSchema, // Could be enhanced with selection info
763
+ definition: entry.rawSchema,
777
764
  schemaKey: tableName,
778
765
  schemas: {
779
766
  sql: view.sql,
@@ -781,19 +768,15 @@ export function createSchemaBox(schemas, resolver) {
781
768
  server: view.server,
782
769
  },
783
770
  transforms: {
784
- toClient: entry.zodSchemas.toClient, // May need composition for nested
771
+ toClient: entry.zodSchemas.toClient,
785
772
  toDb: entry.zodSchemas.toDb,
786
773
  },
787
- pk: entry.zodSchemas.pk,
788
- clientPk: entry.zodSchemas.clientPk,
789
774
  defaults: defaults,
790
- isView: true, // Discriminator
791
- viewSelection: selection, // Store what was selected
775
+ // Use the flag from createViewObject
776
+ supportsReconciliation: view.supportsReconciliation,
777
+ isView: true,
778
+ viewSelection: selection,
792
779
  baseTable: tableName,
793
- // Optionally exclude these for views:
794
- // nav: undefined,
795
- // createView: undefined,
796
- // RelationSelection: undefined,
797
780
  __registry: finalRegistry,
798
781
  };
799
782
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-shape",
3
- "version": "0.5.148",
3
+ "version": "0.5.149",
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",