cogsbox-shape 0.5.2

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/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # Unified Schema
2
+
3
+ > ⚠️ **Warning**: This package is currently a work in progress and not ready for production use. The API is unstable and subject to breaking changes. Please do not use in production environments.
4
+
5
+ ---
6
+
7
+ 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.
8
+
9
+ ## Features
10
+
11
+ - Single source of truth for database, server, and client types
12
+ - Type-safe schema definitions with TypeScript
13
+ - Built-in Zod validation
14
+ - Automatic type transformations between client and database
15
+ - SQL migrations codegen from schemas
16
+ - Relationship handling (hasMany, hasOne, belongsTo)
17
+ - Schema serialization
18
+ - Default value generation
19
+ - CLI tool for SQL generation
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install cogsbox-shape
25
+ ```
26
+
27
+ ## Basic Usage
28
+
29
+ ```typescript
30
+ import { shape, hasMany, createSchema } from "cogsbox-shape";
31
+
32
+ // Define your schemas with type safety
33
+ const userSchema = {
34
+ _tableName: "users",
35
+ id: shape.sql({ type: "int", pk: true }),
36
+ firstname: shape
37
+ .sql({ type: "varchar", length: 255 })
38
+ .db(({ zod }) => zod.min(1)),
39
+ surname: shape
40
+ .sql({ type: "varchar", length: 255 })
41
+ .db(({ zod }) => zod.min(1)),
42
+ email: shape
43
+ .sql({ type: "varchar", length: 255 })
44
+ .db(({ zod }) => zod.email()),
45
+ pets: hasMany({
46
+ fromKey: "id",
47
+ toKey: () => petSchema.userId,
48
+ schema: () => petSchema,
49
+ defaultCount: 1,
50
+ }),
51
+ };
52
+
53
+ // Create your schema and get typed utilities
54
+ const { dbSchema, clientSchema, initialValues, serialized } =
55
+ createSchema(userSchema);
56
+ ```
57
+
58
+ ## Schema Export and SQL Generation
59
+
60
+ ### Exporting Schemas
61
+
62
+ You can export your schemas for use with the CLI tool:
63
+
64
+ ```typescript
65
+ // schemas.ts
66
+ import { petSchema, userSchema } from "./schemas";
67
+
68
+ const schemas = {
69
+ user: userSchema,
70
+ pet: petSchema,
71
+ };
72
+
73
+ export { schemas };
74
+ ```
75
+
76
+ ### Using the CLI
77
+
78
+ The package includes a CLI tool for generating SQL from your schemas. After installation, you can use it with:
79
+
80
+ ```bash
81
+ npx cogsbox-shape generate-sql <file>
82
+ ```
83
+
84
+ The CLI supports both TypeScript and JavaScript files:
85
+
86
+ ```bash
87
+ # For TypeScript files
88
+ npx cogsbox-shape generate-sql schemas.ts
89
+
90
+ # For JavaScript files
91
+ npx cogsbox-shape generate-sql schemas.js
92
+ ```
93
+
94
+ This will generate a SQL file (`cogsbox-shape-sql.sql`) containing the table definitions for all your schemas.
95
+
96
+ ## Advanced Features
97
+
98
+ ### Type Transformations
99
+
100
+ Transform data between client and database representations:
101
+
102
+ ```typescript
103
+ const petSchema = {
104
+ _tableName: "pets",
105
+ fluffynessScale: shape
106
+ .sql({ type: "text" })
107
+ .client(({ zod }) => z.array(z.enum(["bald", "fuzzy", "fluffy", "poof"])))
108
+ .transform({
109
+ toClient: (value) => value.split(",").filter(Boolean),
110
+ toDb: (value) => value.join(","),
111
+ }),
112
+ favourite: shape
113
+ .sql({ type: "int" })
114
+ .client(({ zod }) => z.boolean())
115
+ .transform({
116
+ toClient: (dbValue) => dbValue === 1,
117
+ toDb: (clientValue) => (clientValue ? 1 : 0),
118
+ }),
119
+ };
120
+ ```
121
+
122
+ ### Relationships
123
+
124
+ Define relationships between schemas:
125
+
126
+ ```typescript
127
+ const userSchema = {
128
+ // ... other fields
129
+ pets: hasMany({
130
+ fromKey: "id",
131
+ toKey: () => petSchema.userId,
132
+ schema: () => petSchema,
133
+ defaultCount: 1,
134
+ }),
135
+ };
136
+ ```
137
+
138
+ Supported relationships:
139
+
140
+ - `hasMany`
141
+ - `hasOne`
142
+ - `belongsTo`
143
+ - `manyToMany`
144
+
145
+ ### SQL Types
146
+
147
+ Built-in SQL type definitions:
148
+
149
+ ```typescript
150
+ shape.int({ nullable: true });
151
+ shape.varchar({ length: 255 });
152
+ shape.boolean();
153
+ shape.date();
154
+ shape.datetime();
155
+ shape.text();
156
+ shape.longtext();
157
+ ```
158
+
159
+ ### Validation
160
+
161
+ Add Zod validation to your schemas:
162
+
163
+ ```typescript
164
+ const schema = {
165
+ email: shape
166
+ .sql({ type: "varchar", length: 255 })
167
+ .db(({ zod }) => zod.email()),
168
+ age: shape.sql({ type: "int" }).db(({ zod }) => zod.min(0).max(120)),
169
+ };
170
+ ```
171
+
172
+ ## Type Safety
173
+
174
+ The library provides full type inference:
175
+
176
+ ```typescript
177
+ const { dbSchema, clientSchema, initialValues } = createSchema(userSchema);
178
+
179
+ // These are fully typed:
180
+ type DBUser = z.infer<typeof dbSchema>;
181
+ type ClientUser = z.infer<typeof clientSchema>;
182
+ const defaults: typeof initialValues = {
183
+ // TypeScript will ensure this matches your schema
184
+ };
185
+ ```
186
+
187
+ ## License
188
+
189
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { pathToFileURL } from "url";
4
+ import path from "path";
5
+ import { generateSQL } from "./generateSQL.js";
6
+ import { unlink, writeFile } from "fs/promises";
7
+ import { spawnSync } from "child_process";
8
+ const program = new Command();
9
+ program.command("generate-sql <file>").action(async (file) => {
10
+ try {
11
+ const fullPath = path.resolve(process.cwd(), file);
12
+ if (file.endsWith(".ts")) {
13
+ // Create a virtual module that imports and outputs the schema
14
+ const virtualModule = `
15
+ import { schemas } from '${pathToFileURL(fullPath).href}';
16
+ console.log(JSON.stringify(schemas));
17
+ `;
18
+ // Write this to a temporary file
19
+ const tmpFile = path.join(path.dirname(fullPath), ".tmp-schema-loader.ts");
20
+ await writeFile(tmpFile, virtualModule, "utf8");
21
+ const result = spawnSync("npx", ["tsx", tmpFile], {
22
+ encoding: "utf8",
23
+ stdio: ["inherit", "pipe", "pipe"],
24
+ });
25
+ // Clean up temp file
26
+ await unlink(tmpFile).catch(() => { });
27
+ if (result.error) {
28
+ throw result.error;
29
+ }
30
+ if (result.stderr) {
31
+ console.error("stderr:", result.stderr);
32
+ }
33
+ const schema = JSON.parse(result.stdout);
34
+ await generateSQL(schema);
35
+ }
36
+ else {
37
+ const schema = await import(pathToFileURL(fullPath).href);
38
+ await generateSQL(schema.schemas);
39
+ }
40
+ console.log("Generated SQL successfully");
41
+ }
42
+ catch (error) {
43
+ console.error("Error:", error);
44
+ process.exit(1);
45
+ }
46
+ });
47
+ program.parse();