cogsbox-shape 0.5.148 → 0.5.150
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 +35 -37
- package/package.json +1 -1
package/dist/schema.js
CHANGED
|
@@ -559,54 +559,52 @@ export function createSchema(schema, relations) {
|
|
|
559
559
|
toDb,
|
|
560
560
|
};
|
|
561
561
|
}
|
|
562
|
-
function createViewObject(initialRegistryKey,
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
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;
|
|
565
|
+
// Debug: track which tables are checked
|
|
566
|
+
const checkedTables = {};
|
|
574
567
|
function buildView(currentRegistryKey, subSelection, schemaType) {
|
|
575
|
-
// 1. Find the current schema's definition in the registry using its KEY.
|
|
576
568
|
const registryEntry = registry[currentRegistryKey];
|
|
577
569
|
if (!registryEntry) {
|
|
578
570
|
throw new Error(`Schema with key "${currentRegistryKey}" not found in the registry.`);
|
|
579
571
|
}
|
|
580
|
-
//
|
|
572
|
+
// Check if this table has pk and clientPk (only check once per table)
|
|
573
|
+
if (!(currentRegistryKey in checkedTables)) {
|
|
574
|
+
const hasPks = !!(registryEntry.pk &&
|
|
575
|
+
registryEntry.pk.length > 0 &&
|
|
576
|
+
registryEntry.clientPk &&
|
|
577
|
+
registryEntry.clientPk.length > 0);
|
|
578
|
+
checkedTables[currentRegistryKey] = hasPks;
|
|
579
|
+
if (!hasPks) {
|
|
580
|
+
console.log(`Table ${currentRegistryKey} missing pk/clientPk:`, {
|
|
581
|
+
pk: registryEntry.pk,
|
|
582
|
+
clientPk: registryEntry.clientPk,
|
|
583
|
+
});
|
|
584
|
+
allTablesSupportsReconciliation = false;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
581
587
|
const baseSchema = schemaType === "server"
|
|
582
588
|
? registryEntry.zodSchemas.validationSchema
|
|
583
589
|
: registryEntry.zodSchemas.clientSchema;
|
|
584
590
|
const primitiveShape = baseSchema.shape;
|
|
585
|
-
// 3. If the selection is just `true`, we are done at this level. Return the base primitive schema.
|
|
586
591
|
if (subSelection === true) {
|
|
587
592
|
return z.object(primitiveShape);
|
|
588
593
|
}
|
|
589
|
-
// 4. If the selection is an object, we need to process its relations.
|
|
590
594
|
const selectedRelationShapes = {};
|
|
591
595
|
if (typeof subSelection === "object") {
|
|
592
|
-
// Iterate over the keys in the selection object (e.g., "posts", "profile").
|
|
593
596
|
for (const relationKey in subSelection) {
|
|
594
|
-
// Check if this key corresponds to a valid relation in the raw schema definition.
|
|
595
597
|
const relationBuilder = registryEntry.rawSchema[relationKey];
|
|
596
598
|
const isRelation = relationBuilder?.config?.sql?.schema;
|
|
597
599
|
if (subSelection[relationKey] && isRelation) {
|
|
598
600
|
const relationConfig = relationBuilder.config.sql;
|
|
599
|
-
// 5. KEY STEP: Get the internal `_tableName` of the TARGET schema (e.g., "post_table").
|
|
600
601
|
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
602
|
const nextRegistryKey = tableNameToRegistryKeyMap[targetTableName];
|
|
603
603
|
if (!nextRegistryKey) {
|
|
604
604
|
throw new Error(`Could not resolve registry key for table "${targetTableName}"`);
|
|
605
605
|
}
|
|
606
|
-
//
|
|
607
|
-
// CORRECT registry key and the sub-selection for that relation.
|
|
606
|
+
// Recursive call will also check that table's pk/clientPk
|
|
608
607
|
const relationSchema = buildView(nextRegistryKey, subSelection[relationKey], schemaType);
|
|
609
|
-
// 8. Wrap the resulting schema in an array or optional based on the relation type.
|
|
610
608
|
if (["hasMany", "manyToMany"].includes(relationConfig.type)) {
|
|
611
609
|
selectedRelationShapes[relationKey] = z.array(relationSchema);
|
|
612
610
|
}
|
|
@@ -616,15 +614,19 @@ selection, registry, tableNameToRegistryKeyMap // The lookup map
|
|
|
616
614
|
}
|
|
617
615
|
}
|
|
618
616
|
}
|
|
619
|
-
// 9. Combine the base primitive fields with the newly built relational schemas.
|
|
620
617
|
const finalShape = { ...primitiveShape, ...selectedRelationShapes };
|
|
621
618
|
return z.object(finalShape);
|
|
622
619
|
}
|
|
623
|
-
//
|
|
620
|
+
// For array schemas, handle the initial registry key check
|
|
621
|
+
const isArray = Array.isArray(selection);
|
|
622
|
+
const actualSelection = isArray ? true : selection;
|
|
624
623
|
return {
|
|
625
624
|
sql: registry[initialRegistryKey].zodSchemas.sqlSchema,
|
|
626
|
-
client: buildView(initialRegistryKey,
|
|
627
|
-
server: buildView(initialRegistryKey,
|
|
625
|
+
client: buildView(initialRegistryKey, actualSelection, "client"),
|
|
626
|
+
server: buildView(initialRegistryKey, actualSelection, "server"),
|
|
627
|
+
supportsReconciliation: allTablesSupportsReconciliation,
|
|
628
|
+
// Debug info
|
|
629
|
+
checkedTables,
|
|
628
630
|
};
|
|
629
631
|
}
|
|
630
632
|
export function createSchemaBox(schemas, resolver) {
|
|
@@ -771,9 +773,8 @@ export function createSchemaBox(schemas, resolver) {
|
|
|
771
773
|
createView: (selection) => {
|
|
772
774
|
const view = createViewObject(tableName, selection, finalRegistry, tableNameToRegistryKeyMap);
|
|
773
775
|
const defaults = computeViewDefaults(tableName, selection, finalRegistry, tableNameToRegistryKeyMap);
|
|
774
|
-
// Return the same shape as regular entries, but with isView marker
|
|
775
776
|
return {
|
|
776
|
-
definition: entry.rawSchema,
|
|
777
|
+
definition: entry.rawSchema,
|
|
777
778
|
schemaKey: tableName,
|
|
778
779
|
schemas: {
|
|
779
780
|
sql: view.sql,
|
|
@@ -781,19 +782,16 @@ export function createSchemaBox(schemas, resolver) {
|
|
|
781
782
|
server: view.server,
|
|
782
783
|
},
|
|
783
784
|
transforms: {
|
|
784
|
-
toClient: entry.zodSchemas.toClient,
|
|
785
|
+
toClient: entry.zodSchemas.toClient,
|
|
785
786
|
toDb: entry.zodSchemas.toDb,
|
|
786
787
|
},
|
|
788
|
+
defaults: defaults,
|
|
789
|
+
// ADD THESE BACK - views need the pk/clientPk arrays from base table
|
|
787
790
|
pk: entry.zodSchemas.pk,
|
|
788
791
|
clientPk: entry.zodSchemas.clientPk,
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
viewSelection: selection, // Store what was selected
|
|
792
|
+
isView: true,
|
|
793
|
+
viewSelection: selection,
|
|
792
794
|
baseTable: tableName,
|
|
793
|
-
// Optionally exclude these for views:
|
|
794
|
-
// nav: undefined,
|
|
795
|
-
// createView: undefined,
|
|
796
|
-
// RelationSelection: undefined,
|
|
797
795
|
__registry: finalRegistry,
|
|
798
796
|
};
|
|
799
797
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cogsbox-shape",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.150",
|
|
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",
|