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.
- package/dist/example/schema.d.ts +434 -3047
- package/dist/example/user.d.ts +489 -3102
- package/dist/example/user.js +5 -4
- package/dist/schema.d.ts +14 -57
- package/dist/schema.js +7 -150
- package/package.json +1 -1
package/dist/example/user.js
CHANGED
|
@@ -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:
|
|
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> =
|
|
116
|
-
config:
|
|
117
|
-
|
|
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.
|
|
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.
|
|
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" | "
|
|
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
|
-
|
|
88
|
+
// Just pass the config object like reference does
|
|
89
89
|
return createBuilder({
|
|
90
90
|
stage: "relation",
|
|
91
|
-
sqlConfig: relationConfig,
|
|
92
|
-
sqlZod:
|
|
93
|
-
newZod:
|
|
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:
|
|
96
|
-
validationZod:
|
|
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()
|
|
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.
|
|
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",
|