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