cogsbox-shape 0.5.190 → 0.5.191

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
@@ -194,11 +194,38 @@ type PickPrimaryKeys<T extends ShapeSchema> = {
194
194
  };
195
195
  } ? K : never]: T[K];
196
196
  };
197
+ type PickClientOnlyKeys<T extends ShapeSchema> = {
198
+ [K in keyof T]: T[K] extends {
199
+ config: {
200
+ sql: null;
201
+ };
202
+ } ? K : never;
203
+ }[keyof T];
204
+ type PickSqlOnlyKeys<T extends ShapeSchema> = {
205
+ [K in keyof T]: T[K] extends {
206
+ config: {
207
+ sql: {
208
+ sqlOnly: true;
209
+ };
210
+ };
211
+ } ? K : never;
212
+ }[keyof T];
213
+ type InferClientRow<T extends ShapeSchema> = Prettify<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<T, "zodClientSchema">>>>>;
197
214
  type SchemaBuilder<T extends ShapeSchema> = Prettify<EnrichFields<T>> & {
198
215
  __primaryKeySQL?: string;
199
- __derives?: Record<string, (row: any) => any>;
216
+ __derives?: {
217
+ forClient?: Record<string, (row: any) => any>;
218
+ forDb?: Record<string, (row: any) => any>;
219
+ };
200
220
  primaryKeySQL: (definer: (pkFields: PickPrimaryKeys<T>) => string) => SchemaBuilder<T>;
201
- derive: <D extends Partial<Record<keyof T, (row: Prettify<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<T, "zodClientSchema">>>>>) => any>>>(derivers: D) => SchemaBuilder<T>;
221
+ derive: (derivers: {
222
+ forClient?: {
223
+ [K in PickClientOnlyKeys<T>]?: (row: InferClientRow<T>) => any;
224
+ };
225
+ forDb?: {
226
+ [K in PickSqlOnlyKeys<T>]?: (row: InferClientRow<T>) => any;
227
+ };
228
+ }) => SchemaBuilder<T>;
202
229
  };
203
230
  export declare function schema<T extends string, U extends ShapeSchema<T>>(schema: U): SchemaBuilder<U>;
204
231
  export type RelationType = "hasMany" | "hasOne" | "manyToMany";
package/dist/schema.js CHANGED
@@ -578,6 +578,7 @@ export function createSchema(schema, relations) {
578
578
  const generateDefaults = () => {
579
579
  const freshDefaults = {};
580
580
  for (const key in defaultGenerators) {
581
+ // ... same logic for mapping standard defaults ...
581
582
  const generatorOrValue = defaultGenerators[key];
582
583
  let rawValue = isFunction(generatorOrValue)
583
584
  ? generatorOrValue({ uuid })
@@ -586,9 +587,10 @@ export function createSchema(schema, relations) {
586
587
  ? fieldTransforms[key].toClient(rawValue)
587
588
  : rawValue;
588
589
  }
589
- if (derives) {
590
- for (const key in derives) {
591
- freshDefaults[key] = derives[key](freshDefaults);
590
+ // Only apply client derivations
591
+ if (derives?.forClient) {
592
+ for (const key in derives.forClient) {
593
+ freshDefaults[key] = derives.forClient[key]?.(freshDefaults);
592
594
  }
593
595
  }
594
596
  return freshDefaults;
@@ -606,31 +608,34 @@ export function createSchema(schema, relations) {
606
608
  ? transform(dbObject[dbKey])
607
609
  : dbObject[dbKey];
608
610
  }
609
- if (derives) {
610
- for (const key in derives) {
611
- clientObject[key] = derives[key](clientObject);
611
+ // Only apply Client derives AFTER mapping standard fields
612
+ if (derives?.forClient) {
613
+ for (const key in derives.forClient) {
614
+ clientObject[key] = derives.forClient[key]?.(clientObject);
612
615
  }
613
616
  }
614
617
  return clientObject;
615
618
  };
616
619
  const toDb = (clientObject) => {
617
- // 1. Calculate derives FIRST based on the client data
618
- const clientWithDerives = { ...clientObject };
619
- if (derives) {
620
- for (const key in derives) {
621
- clientWithDerives[key] = derives[key](clientWithDerives);
622
- }
623
- }
624
- // 2. Map the data (including the newly derived fields) to the DB object
625
620
  const dbObject = {};
626
- for (const clientKey in clientWithDerives) {
627
- if (clientWithDerives[clientKey] === undefined)
621
+ // 1. Map standard client fields to DB fields
622
+ for (const clientKey in clientObject) {
623
+ if (clientObject[clientKey] === undefined)
628
624
  continue;
629
625
  const dbKey = clientToDbKeys[clientKey] || clientKey;
630
626
  const transform = fieldTransforms[clientKey]?.toDb;
631
627
  dbObject[dbKey] = transform
632
- ? transform(clientWithDerives[clientKey])
633
- : clientWithDerives[clientKey];
628
+ ? transform(clientObject[clientKey])
629
+ : clientObject[clientKey];
630
+ }
631
+ // 2. Map Database ONLY derives directly to the dbObject
632
+ if (derives?.forDb) {
633
+ for (const schemaKey in derives.forDb) {
634
+ // Resolve custom DB column name if they used s.sql({ field: "custom_name" })
635
+ const sqlConfig = fullSchema[schemaKey]?.config?.sql;
636
+ const dbKey = sqlConfig?.field || schemaKey;
637
+ dbObject[dbKey] = derives.forDb[schemaKey]?.(clientObject);
638
+ }
634
639
  }
635
640
  return dbObject;
636
641
  };
@@ -639,9 +644,9 @@ export function createSchema(schema, relations) {
639
644
  const finalClientSchema = z.object(clientFields);
640
645
  const finalValidationSchema = z.object(serverFields);
641
646
  const deriveDependencies = {};
642
- if (derives) {
647
+ if (derives?.forClient) {
643
648
  const trackingSeed = { ...defaultValues };
644
- for (const key in derives) {
649
+ for (const key in derives.forClient) {
645
650
  const accessed = new Set();
646
651
  const trackingRow = new Proxy(trackingSeed, {
647
652
  get(target, prop, receiver) {
@@ -652,7 +657,7 @@ export function createSchema(schema, relations) {
652
657
  },
653
658
  });
654
659
  try {
655
- derives[key](trackingRow);
660
+ derives.forClient[key]?.(trackingRow);
656
661
  }
657
662
  catch (e) { }
658
663
  deriveDependencies[key] = Array.from(accessed);
@@ -945,9 +950,10 @@ export function createSchemaBox(schemas, resolutions) {
945
950
  }
946
951
  }
947
952
  }
948
- if (regEntry.rawSchema.__derives) {
949
- for (const key in regEntry.rawSchema.__derives) {
950
- baseMapped[key] = regEntry.rawSchema.__derives[key](baseMapped);
953
+ if (regEntry.rawSchema.__derives?.forClient) {
954
+ for (const key in regEntry.rawSchema.__derives.forClient) {
955
+ baseMapped[key] =
956
+ regEntry.rawSchema.__derives.forClient[key](baseMapped);
951
957
  }
952
958
  }
953
959
  return baseMapped;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-shape",
3
- "version": "0.5.190",
3
+ "version": "0.5.191",
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",