cogsbox-shape 0.5.158 → 0.5.160

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
@@ -40,7 +40,9 @@ type ZodTypeFromPrimitive<T> = T extends string ? z.ZodString : T extends number
40
40
  type CollapsedUnion<A extends z.ZodTypeAny, B extends z.ZodTypeAny> = A extends B ? (B extends A ? A : z.ZodUnion<[A, B]>) : z.ZodUnion<[A, B]>;
41
41
  export interface IBuilderMethods<T extends DbConfig, TSql extends z.ZodTypeAny, TNew extends z.ZodTypeAny, TInitialValue, TClient extends z.ZodTypeAny, TValidation extends z.ZodTypeAny> {
42
42
  initialState<const TValue>(options: {
43
- value: TValue | (() => TValue);
43
+ value: TValue | ((tools: {
44
+ uuid: () => string;
45
+ }) => TValue);
44
46
  schema?: never;
45
47
  clientPk?: boolean;
46
48
  }): Prettify<Builder<"new", T, TSql, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, TValue extends () => infer R ? R : TValue, CollapsedUnion<TSql, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>, CollapsedUnion<TSql, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>>>;
@@ -50,7 +52,9 @@ export interface IBuilderMethods<T extends DbConfig, TSql extends z.ZodTypeAny,
50
52
  clientPk?: boolean;
51
53
  }): Prettify<Builder<"new", T, TSql, TSchema, z.infer<TSchema>, CollapsedUnion<TSql, TSchema>, CollapsedUnion<TSql, TSchema>>>;
52
54
  initialState<const TValue, const TSchema extends z.ZodTypeAny>(options: {
53
- value: TValue | (() => TValue);
55
+ value: TValue | ((tools: {
56
+ uuid: () => string;
57
+ }) => TValue);
54
58
  schema: TSchema | ((base: ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>) => TSchema);
55
59
  clientPk?: boolean;
56
60
  }): Prettify<Builder<"new", T, TSql, TSchema, z.infer<TSchema>, // <-- THIS IS THE FIX: Use schema's type, not literal value
@@ -131,7 +135,9 @@ export type Reference<TGetter extends () => any> = {
131
135
  getter: TGetter;
132
136
  };
133
137
  interface ShapeAPI {
134
- initialState: <const TValue>(value: TValue | (() => TValue)) => Builder<"new", null, z.ZodUndefined, // No SQL schema
138
+ initialState: <const TValue>(value: TValue | ((tools: {
139
+ uuid: () => string;
140
+ }) => TValue)) => Builder<"new", null, z.ZodUndefined, // No SQL schema
135
141
  ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, TValue extends () => infer R ? R : TValue, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>;
136
142
  sql: <T extends SQLType>(sqlConfig: T) => Builder<"sql", T, SQLToZodType<T, false>, SQLToZodType<T, false>, z.infer<SQLToZodType<T, false>>, SQLToZodType<T, false>, SQLToZodType<T, false>>;
137
143
  reference: <TGetter extends () => any>(getter: TGetter) => Reference<TGetter>;
@@ -207,6 +213,7 @@ export declare function createSchema<T extends {
207
213
  }, R extends Record<string, any> = {}, TActualSchema extends Omit<T & R, typeof SchemaWrapperBrand> = Omit<T & R, typeof SchemaWrapperBrand>>(schema: T, relations?: R): {
208
214
  pk: string[] | null;
209
215
  clientPk: string[] | null;
216
+ isClientRecord: ((record: any) => boolean) | undefined;
210
217
  sqlSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>;
211
218
  clientSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodClientSchema">>>;
212
219
  validationSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodValidationSchema">>>;
@@ -454,13 +461,11 @@ type DeriveDefaults<T, Depth extends any[] = []> = Prettify<Depth["length"] exte
454
461
  };
455
462
  } ? D extends () => infer R ? R : D : never : T[K] extends {
456
463
  config: {
457
- transforms: any;
464
+ zodNewSchema: infer TNew;
465
+ zodSqlSchema: infer TSql;
458
466
  zodClientSchema: infer TClient extends z.ZodTypeAny;
459
- };
460
- } ? z.infer<TClient> : T[K] extends {
461
- config: {
462
467
  initialValue: infer D;
463
468
  };
464
- } ? D extends () => infer R ? R : D : never;
469
+ } ? TNew extends TSql ? z.infer<TClient> : D extends () => infer R ? R : D : never;
465
470
  }>;
466
471
  export {};
package/dist/schema.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { v4 as uuid } from "uuid";
2
3
  export const isFunction = (fn) => typeof fn === "function";
3
4
  // Function to create a properly typed current timestamp config
4
5
  export function currentTimeStamp() {
@@ -9,7 +10,7 @@ export function currentTimeStamp() {
9
10
  }
10
11
  export const s = {
11
12
  initialState: (value) => {
12
- const actualValue = isFunction(value) ? value() : value;
13
+ const actualValue = isFunction(value) ? value({ uuid }) : value;
13
14
  // Infer the Zod type from the primitive value
14
15
  let inferredZodType;
15
16
  if (typeof actualValue === "string") {
@@ -129,7 +130,7 @@ function createBuilder(config) {
129
130
  let finalSchema;
130
131
  // 1. Determine the actual value
131
132
  if (value !== undefined) {
132
- actualValue = isFunction(value) ? value() : value;
133
+ actualValue = isFunction(value) ? value({ uuid }) : value;
133
134
  }
134
135
  else if (schemaOrModifier &&
135
136
  typeof schemaOrModifier === "object" &&
@@ -459,6 +460,7 @@ export function createSchema(schema, relations) {
459
460
  const fullSchema = { ...schema, ...(relations || {}) };
460
461
  let pkKeys = [];
461
462
  let clientPkKeys = [];
463
+ // FIRST PASS: Collect all fields and PKs
462
464
  for (const key in fullSchema) {
463
465
  const value = fullSchema[key];
464
466
  if (key === "_tableName" ||
@@ -469,7 +471,6 @@ export function createSchema(schema, relations) {
469
471
  typeof value === "function")
470
472
  continue;
471
473
  const definition = fullSchema[key];
472
- // Handle new-style references
473
474
  if (isReference(definition)) {
474
475
  const targetField = definition.getter();
475
476
  if (targetField && targetField.config) {
@@ -487,27 +488,18 @@ export function createSchema(schema, relations) {
487
488
  fieldTransforms[key] = config.transforms;
488
489
  }
489
490
  }
490
- continue; // Skip the rest of the logic for references
491
+ continue;
491
492
  }
492
- // THEN, handle all other fields that have a config (builders, relations, etc.)
493
493
  if (definition && definition.config) {
494
494
  const config = definition.config;
495
- if (config.sql?.pk && !config.sql?.isForeignKey) {
496
- pkKeys.push(key);
497
- }
498
- if (config.sql?.isClientPk) {
499
- clientPkKeys.push(key);
500
- }
501
- // The rest of the logic for builders
495
+ // ... pk collection logic ...
502
496
  const sqlConfig = config.sql;
503
497
  if (sqlConfig &&
504
498
  typeof sqlConfig === "object" &&
505
499
  ["hasMany", "hasOne", "belongsTo", "manyToMany"].includes(sqlConfig.type)) {
506
- // This is for relations, which also aren't PKs, so we just continue.
507
500
  continue;
508
501
  }
509
502
  else {
510
- // This is for regular s.sql() fields
511
503
  sqlFields[key] = config.zodSqlSchema;
512
504
  clientFields[key] = config.zodClientSchema;
513
505
  serverFields[key] = config.zodValidationSchema;
@@ -516,28 +508,55 @@ export function createSchema(schema, relations) {
516
508
  }
517
509
  const initialValueOrFn = config.initialValue;
518
510
  defaultGenerators[key] = initialValueOrFn;
519
- defaultValues[key] = isFunction(initialValueOrFn)
511
+ // Get the raw default value
512
+ let rawDefault = isFunction(initialValueOrFn)
520
513
  ? initialValueOrFn()
521
514
  : initialValueOrFn;
515
+ // Apply toClient transform if it exists
516
+ if (config.transforms?.toClient && rawDefault !== undefined) {
517
+ defaultValues[key] = config.transforms.toClient(rawDefault);
518
+ }
519
+ else {
520
+ defaultValues[key] = rawDefault;
521
+ }
522
+ }
523
+ }
524
+ }
525
+ // AFTER THE LOOP: Build isClientRecord checker
526
+ let isClientRecord;
527
+ const explicitChecker = fullSchema.__isClientChecker;
528
+ if (explicitChecker) {
529
+ isClientRecord = explicitChecker;
530
+ }
531
+ else if (clientPkKeys.length > 0) {
532
+ const autoChecks = [];
533
+ for (const key of clientPkKeys) {
534
+ const field = fullSchema[key];
535
+ const sqlType = field?.config?.sql?.type;
536
+ const initialValue = field?.config?.initialValue;
537
+ const dbIsNumeric = sqlType === "int";
538
+ const clientIsString = typeof initialValue === "string";
539
+ if (dbIsNumeric && clientIsString) {
540
+ autoChecks.push({ key, check: (val) => typeof val === "string" });
522
541
  }
523
542
  }
524
- } // Apply transforms to default values so they match client schema
525
- for (const key in fieldTransforms) {
526
- if (key in defaultValues && defaultValues[key] !== undefined) {
527
- defaultValues[key] = fieldTransforms[key].toClient(defaultValues[key]);
543
+ if (autoChecks.length > 0) {
544
+ isClientRecord = (record) => autoChecks.some(({ key, check }) => check(record[key]));
528
545
  }
529
546
  }
530
547
  const generateDefaults = () => {
531
548
  const freshDefaults = {};
532
549
  for (const key in defaultGenerators) {
533
550
  const generatorOrValue = defaultGenerators[key];
534
- freshDefaults[key] = isFunction(generatorOrValue)
535
- ? generatorOrValue() // Call the function to get a fresh value
536
- : generatorOrValue; // Use the static value
537
- }
538
- for (const key in fieldTransforms) {
539
- if (key in freshDefaults && freshDefaults[key] !== undefined) {
540
- freshDefaults[key] = fieldTransforms[key].toClient(freshDefaults[key]);
551
+ let rawValue = isFunction(generatorOrValue)
552
+ ? generatorOrValue()
553
+ : generatorOrValue;
554
+ // Apply toClient transform if it exists
555
+ if (fieldTransforms[key]?.toClient && rawValue !== undefined) {
556
+ freshDefaults[key] = fieldTransforms[key].toClient(rawValue);
557
+ }
558
+ else {
559
+ freshDefaults[key] = rawValue;
541
560
  }
542
561
  }
543
562
  return freshDefaults;
@@ -561,8 +580,9 @@ export function createSchema(schema, relations) {
561
580
  return dbObject;
562
581
  };
563
582
  return {
564
- pk: pkKeys?.length ? pkKeys : null,
565
- clientPk: clientPkKeys ? clientPkKeys : null,
583
+ pk: pkKeys.length ? pkKeys : null,
584
+ clientPk: clientPkKeys.length ? clientPkKeys : null,
585
+ isClientRecord, // NOW IT'S IN SCOPE
566
586
  sqlSchema: z.object(sqlFields),
567
587
  clientSchema: z.object(clientFields),
568
588
  validationSchema: z.object(serverFields),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-shape",
3
- "version": "0.5.158",
3
+ "version": "0.5.160",
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",