cogsbox-shape 0.5.57 → 0.5.59

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.
@@ -28,9 +28,8 @@ export const petSchema = {
28
28
  toDb: (clientValue) => (clientValue ? 1 : 0),
29
29
  }),
30
30
  };
31
- // export const { dbSchema, clientSchema, initialValues, serialized } =
32
- // createSchema(userSchema);
33
31
  export const userSchema = {
32
+ //The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.
34
33
  _tableName: "users",
35
34
  id: shape.sql({ type: "int", pk: true }),
36
35
  firstname: shape
@@ -43,12 +42,14 @@ export const userSchema = {
43
42
  email: shape
44
43
  .sql({ type: "varchar", length: 255 })
45
44
  .validation(({ sql }) => sql.email()),
46
- pets: hasMany({
45
+ pets: shape
46
+ .hasMany({
47
47
  fromKey: "id",
48
48
  toKey: () => petSchema.userId,
49
49
  schema: () => petSchema,
50
50
  defaultCount: 1,
51
- }),
51
+ })
52
+ .validation(({ sql }) => sql),
52
53
  };
53
54
  const testPets = {
54
55
  _tableName: "users",
package/dist/schema.d.ts CHANGED
@@ -5,7 +5,7 @@ type CurrentTimestampConfig = {
5
5
  };
6
6
  export declare const isFunction: (fn: unknown) => fn is Function;
7
7
  export declare function currentTimeStamp(): CurrentTimestampConfig;
8
- type SQLType = ({
8
+ export type SQLType = ({
9
9
  type: "int";
10
10
  nullable?: boolean;
11
11
  default?: number;
@@ -112,9 +112,16 @@ type BuilderConfig<T extends SQLType | RelationConfig<any>, TSql extends z.ZodTy
112
112
  zodClientSchema: TClient;
113
113
  zodValidationSchema: TValidation;
114
114
  };
115
- export type Builder<TStage extends Stage, T extends SQLType | RelationConfig<any>, TSql extends z.ZodTypeAny, TNew extends z.ZodTypeAny, TInitialValue, TClient extends z.ZodTypeAny, TValidation extends z.ZodTypeAny> = Prettify<{
116
- config: Prettify<BuilderConfig<T, TSql, TNew, TInitialValue, TClient, TValidation>>;
117
- } & Pick<IBuilderMethods<T, TSql, TNew, TInitialValue, TClient, TValidation>, StageMethods[TStage]>>;
115
+ export type Builder<TStage extends Stage, T extends SQLType | RelationConfig<any>, TSql extends z.ZodTypeAny, TNew extends z.ZodTypeAny, TInitialValue, TClient extends z.ZodTypeAny, TValidation extends z.ZodTypeAny> = {
116
+ config: {
117
+ sql: T;
118
+ zodSqlSchema: TSql;
119
+ zodNewSchema: TNew;
120
+ initialValue: TInitialValue;
121
+ zodClientSchema: TClient;
122
+ zodValidationSchema: TValidation;
123
+ };
124
+ } & Pick<IBuilderMethods<T, TSql, TNew, TInitialValue, TClient, TValidation>, StageMethods[TStage]>;
118
125
  interface ShapeAPI {
119
126
  int: (config?: IntConfig) => ReturnType<typeof createBuilder>;
120
127
  varchar: (config?: Omit<StringConfig, "type">) => ReturnType<typeof createBuilder>;
@@ -130,17 +137,12 @@ interface ShapeAPI {
130
137
  toKey: () => any;
131
138
  schema: () => T;
132
139
  defaultCount?: number;
133
- }) => Builder<"relation", RelationConfig<T>, z.ZodOptional<z.ZodArray<z.ZodAny>>, z.ZodOptional<z.ZodArray<z.ZodAny>>, any[], z.ZodOptional<z.ZodArray<z.ZodAny>>, z.ZodOptional<z.ZodArray<z.ZodAny>>>;
140
+ }) => Builder<"relation", RelationConfig<T>, z.ZodArray<z.ZodAny>, z.ZodArray<z.ZodAny>, any[], z.ZodArray<z.ZodAny>, z.ZodArray<z.ZodAny>>;
134
141
  hasOne: <T extends Schema<any>>(config: {
135
142
  fromKey: string;
136
143
  toKey: () => any;
137
144
  schema: () => T;
138
- }) => Builder<"relation", RelationConfig<T>, z.ZodOptional<z.ZodAny>, z.ZodOptional<z.ZodAny>, any, z.ZodOptional<z.ZodAny>, z.ZodOptional<z.ZodAny>>;
139
- belongsTo: <T extends Schema<any>>(config: {
140
- fromKey: string;
141
- toKey: () => any;
142
- schema: () => T;
143
- }) => Builder<"relation", RelationConfig<T>, z.ZodOptional<z.ZodAny>, z.ZodOptional<z.ZodAny>, any, z.ZodOptional<z.ZodAny>, z.ZodOptional<z.ZodAny>>;
145
+ }) => Builder<"relation", RelationConfig<T>, z.ZodAny, z.ZodAny, any, z.ZodAny, z.ZodAny>;
144
146
  manyToMany: <T extends Schema<any>>(config: {
145
147
  fromKey: string;
146
148
  toKey: () => any;
@@ -203,7 +205,7 @@ export declare function manyToMany<T extends Schema<any>>(config: {
203
205
  schema: T;
204
206
  defaultCount: number | undefined;
205
207
  };
206
- type RelationType = "hasMany" | "belongsTo" | "hasOne" | "manyToMany";
208
+ export type RelationType = "hasMany" | "hasOne" | "manyToMany";
207
209
  type BaseSchemaField<T extends SQLType = SQLType> = {
208
210
  type: "field";
209
211
  sql: T;
@@ -329,49 +331,4 @@ export type InferSchemaTypes<T extends {
329
331
  /** The TypeScript type for the default values object. */
330
332
  defaults: ReturnType<typeof createSchema<T>>["defaultValues"];
331
333
  }>;
332
- type SerializableFieldMetadata = {
333
- type: "field";
334
- sql: SQLType;
335
- };
336
- type SerializableRelationMetadata = {
337
- type: "relation";
338
- relationType: RelationType;
339
- fromKey: string;
340
- toKey: string;
341
- schema: SerializableSchemaMetadata;
342
- };
343
- type SerializableSchemaMetadata = {
344
- _tableName: string;
345
- primaryKey: string | null;
346
- fields: Record<string, SerializableFieldMetadata>;
347
- relations: Record<string, SerializableRelationMetadata>;
348
- };
349
- export type ProcessedSyncSchemaEntry<T extends {
350
- _tableName: string;
351
- }> = {
352
- rawSchema: T;
353
- schemas: ReturnType<typeof createSchema<T>>;
354
- validate: (data: unknown) => z.SafeParseReturnType<any, any>;
355
- validateClient: (data: unknown) => z.SafeParseReturnType<any, any>;
356
- serializable: {
357
- key: string;
358
- validationJsonSchema: object;
359
- clientJsonSchema: object;
360
- metadata: SerializableSchemaMetadata;
361
- };
362
- };
363
- export type ProcessedSyncSchemaMap<T extends Record<string, {
364
- _tableName: string;
365
- }>> = {
366
- [K in keyof T]: ProcessedSyncSchemaEntry<T[K]>;
367
- };
368
- export declare function createSyncSchema<T extends Record<string, {
369
- _tableName: string;
370
- }>>(config: {
371
- [K in keyof T]: {
372
- schema: T[K];
373
- validation?: (schema: ReturnType<typeof createSchema<T[K]>>["validationSchema"]) => z.ZodSchema;
374
- client?: (schema: ReturnType<typeof createSchema<T[K]>>["clientSchema"]) => z.ZodSchema;
375
- };
376
- }): ProcessedSyncSchemaMap<T>;
377
334
  export {};
package/dist/schema.js CHANGED
@@ -85,15 +85,15 @@ export const shape = {
85
85
  type: "hasMany",
86
86
  ...config,
87
87
  };
88
- const relationZodType = z.array(z.any()).optional();
88
+ // Just pass the config object like reference does
89
89
  return createBuilder({
90
90
  stage: "relation",
91
- sqlConfig: relationConfig,
92
- sqlZod: relationZodType,
93
- newZod: relationZodType,
91
+ sqlConfig: relationConfig, // Pass the whole config object
92
+ sqlZod: z.array(z.any()), // Remove .optional()
93
+ newZod: z.array(z.any()),
94
94
  initialValue: Array.from({ length: config.defaultCount || 0 }, () => ({})),
95
- clientZod: relationZodType,
96
- validationZod: relationZodType,
95
+ clientZod: z.array(z.any()),
96
+ validationZod: z.array(z.any()),
97
97
  });
98
98
  },
99
99
  hasOne: (config) => {
@@ -101,23 +101,7 @@ export const shape = {
101
101
  type: "hasOne",
102
102
  ...config,
103
103
  };
104
- const relationZodType = z.any().optional();
105
- return createBuilder({
106
- stage: "relation",
107
- sqlConfig: relationConfig,
108
- sqlZod: relationZodType,
109
- newZod: relationZodType,
110
- initialValue: {},
111
- clientZod: relationZodType,
112
- validationZod: relationZodType,
113
- });
114
- },
115
- belongsTo: (config) => {
116
- const relationConfig = {
117
- type: "belongsTo",
118
- ...config,
119
- };
120
- const relationZodType = z.any().optional();
104
+ const relationZodType = z.any();
121
105
  return createBuilder({
122
106
  stage: "relation",
123
107
  sqlConfig: relationConfig,
@@ -489,130 +473,3 @@ export function createSchema(schema) {
489
473
  defaultValues: defaultValues,
490
474
  };
491
475
  }
492
- // --- 2. The Smart Introspection Logic (Also good, keep it) ---
493
- /**
494
- * (This is the smart function from the last answer that resolves `toKey` functions)
495
- */
496
- // In your cogsbox-shape file, replace the entire `serializeSchemaMetadata` function.
497
- function serializeSchemaMetadata(schema) {
498
- const fields = {};
499
- const relations = {};
500
- let primaryKey = null;
501
- for (const key in schema) {
502
- if (key === "_tableName" || key.startsWith("__"))
503
- continue;
504
- const definition = schema[key];
505
- // Case 1: Is it a relation object? Check the `type` property.
506
- if (definition &&
507
- (definition.type === "hasMany" ||
508
- definition.type === "hasOne" ||
509
- definition.type === "belongsTo" ||
510
- definition.type === "manyToMany")) {
511
- const relation = definition;
512
- let toKeyName = null;
513
- try {
514
- let targetFieldDefinition = relation.toKey;
515
- if (targetFieldDefinition &&
516
- targetFieldDefinition.type === "reference") {
517
- targetFieldDefinition = targetFieldDefinition.to;
518
- }
519
- const targetSchemaObject = relation.schema;
520
- for (const targetKey in targetSchemaObject) {
521
- if (targetSchemaObject[targetKey] === targetFieldDefinition) {
522
- toKeyName = targetKey;
523
- break;
524
- }
525
- }
526
- if (!toKeyName)
527
- throw new Error(`Could not find field name for relation target.`);
528
- relations[key] = {
529
- type: "relation",
530
- relationType: relation.type,
531
- fromKey: relation.fromKey,
532
- toKey: toKeyName,
533
- schema: serializeSchemaMetadata(targetSchemaObject),
534
- };
535
- }
536
- catch (e) {
537
- console.error(`[cogsbox-shape] Error resolving 'toKey' for relation '${key}' in schema '${schema._tableName}'.`);
538
- throw e;
539
- }
540
- // This is the critical part: ADD the processed relation to the relations object.
541
- relations[key] = {
542
- type: "relation",
543
- relationType: relation.type,
544
- fromKey: relation.fromKey,
545
- toKey: toKeyName,
546
- schema: serializeSchemaMetadata(relation.schema),
547
- };
548
- }
549
- else if (definition && definition.config && definition.config.sql) {
550
- fields[key] = { type: "field", sql: definition.config.sql };
551
- if (definition.config.sql.pk === true) {
552
- if (primaryKey)
553
- console.warn(`[cogsbox-shape] Multiple primary keys found. Using last one: '${key}'.`);
554
- primaryKey = key;
555
- }
556
- }
557
- else if (definition && definition.type === "reference") {
558
- const targetFieldBuilder = definition.to();
559
- if (targetFieldBuilder &&
560
- targetFieldBuilder.config &&
561
- targetFieldBuilder.config.sql) {
562
- fields[key] = { type: "field", sql: targetFieldBuilder.config.sql };
563
- if (targetFieldBuilder.config.sql.pk) {
564
- if (primaryKey)
565
- console.warn(`[cogsbox-shape] Multiple primary keys found. Using last one: '${key}'.`);
566
- primaryKey = key;
567
- }
568
- }
569
- }
570
- }
571
- return { _tableName: schema._tableName, primaryKey, fields, relations };
572
- }
573
- // --- 4. The Final, Corrected `createSyncSchema` Function ---
574
- export function createSyncSchema(config) {
575
- const processedOutput = {};
576
- for (const key in config) {
577
- const entry = config[key];
578
- // Part 1: Generate Zod Schemas and Live Validators (same as before)
579
- const { sqlSchema, clientSchema, validationSchema, defaultValues } = createSchema(entry.schema);
580
- const finalValidationSchema = entry.validation
581
- ? entry.validation(validationSchema)
582
- : validationSchema;
583
- const finalClientSchema = entry.client
584
- ? entry.client(clientSchema)
585
- : clientSchema;
586
- // Part 2: Generate the Serializable Payload (NEW, integrated logic)
587
- const validationJsonSchema = zodToJsonSchema(finalValidationSchema, {
588
- target: "jsonSchema7",
589
- $refStrategy: "none",
590
- });
591
- const clientJsonSchema = zodToJsonSchema(finalClientSchema, {
592
- target: "jsonSchema7",
593
- $refStrategy: "none",
594
- });
595
- const metadata = serializeSchemaMetadata(entry.schema);
596
- // Part 3: Combine EVERYTHING into the final output object for this key
597
- processedOutput[key] = {
598
- // For runtime server use
599
- rawSchema: entry.schema,
600
- schemas: {
601
- sql: sqlSchema,
602
- client: clientSchema,
603
- validation: validationSchema,
604
- defaults: defaultValues,
605
- },
606
- validate: (data) => finalValidationSchema.safeParse(data),
607
- validateClient: (data) => finalClientSchema.safeParse(data),
608
- // For deployment to DO
609
- serializable: {
610
- key,
611
- validationJsonSchema,
612
- clientJsonSchema,
613
- metadata,
614
- },
615
- };
616
- }
617
- return processedOutput;
618
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-shape",
3
- "version": "0.5.57",
3
+ "version": "0.5.59",
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",