cogsbox-shape 0.5.23 → 0.5.26
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 +86 -89
- package/dist/example/schema.d.ts +1419 -633
- package/dist/example/user.d.ts +1409 -905
- package/dist/example/user.js +41 -8
- package/dist/schema copy.d.ts +1568 -0
- package/dist/schema copy.js +680 -0
- package/dist/schema.d.ts +1715 -870
- package/dist/schema.js +157 -189
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -12,11 +12,9 @@ A TypeScript library for creating type-safe database schemas with Zod validation
|
|
|
12
12
|
- Type-safe schema definitions with TypeScript
|
|
13
13
|
- Built-in Zod validation
|
|
14
14
|
- Automatic type transformations between client and database
|
|
15
|
-
- SQL migrations codegen from schemas
|
|
16
15
|
- Relationship handling (hasMany, hasOne, belongsTo)
|
|
17
16
|
- Schema serialization
|
|
18
17
|
- Default value generation
|
|
19
|
-
- CLI tool for SQL generation
|
|
20
18
|
|
|
21
19
|
## Installation
|
|
22
20
|
|
|
@@ -29,70 +27,38 @@ npm install cogsbox-shape
|
|
|
29
27
|
```typescript
|
|
30
28
|
import { shape, hasMany, createSchema } from "cogsbox-shape";
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
_tableName: "users",
|
|
30
|
+
const productSchema = {
|
|
31
|
+
_tableName: "products",
|
|
35
32
|
id: shape.sql({ type: "int", pk: true }),
|
|
36
|
-
|
|
37
|
-
.sql({ type: "varchar", length:
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.
|
|
45
|
-
|
|
33
|
+
sku: shape
|
|
34
|
+
.sql({ type: "varchar", length: 50 })
|
|
35
|
+
.initialState(
|
|
36
|
+
z.string(),
|
|
37
|
+
() => "PRD-" + Math.random().toString(36).slice(2)
|
|
38
|
+
)
|
|
39
|
+
.validation(({ sql }) => sql.min(5).max(50)),
|
|
40
|
+
price: shape
|
|
41
|
+
.sql({ type: "int" })
|
|
42
|
+
.client(({ sql }) => z.number().multipleOf(0.01))
|
|
43
|
+
.transform({
|
|
44
|
+
toClient: (dbValue) => dbValue / 100,
|
|
45
|
+
toDb: (clientValue) => Math.round(clientValue * 100),
|
|
46
|
+
}),
|
|
47
|
+
inStock: shape
|
|
48
|
+
.sql({ type: "boolean" })
|
|
49
|
+
.client(({ sql }) => z.boolean())
|
|
50
|
+
.initialState(z.boolean(), () => true),
|
|
51
|
+
categories: hasMany({
|
|
46
52
|
fromKey: "id",
|
|
47
|
-
toKey: () =>
|
|
48
|
-
schema: () =>
|
|
49
|
-
defaultCount: 1,
|
|
53
|
+
toKey: () => categorySchema.productId,
|
|
54
|
+
schema: () => categorySchema,
|
|
50
55
|
}),
|
|
51
56
|
};
|
|
52
57
|
|
|
53
|
-
|
|
54
|
-
|
|
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>
|
|
58
|
+
const { sqlSchema, clientSchema, validationSchema, defaultValues } =
|
|
59
|
+
createSchema(productSchema);
|
|
82
60
|
```
|
|
83
61
|
|
|
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
62
|
## Advanced Features
|
|
97
63
|
|
|
98
64
|
### Type Transformations
|
|
@@ -100,21 +66,35 @@ This will generate a SQL file (`cogsbox-shape-sql.sql`) containing the table def
|
|
|
100
66
|
Transform data between client and database representations:
|
|
101
67
|
|
|
102
68
|
```typescript
|
|
103
|
-
const
|
|
104
|
-
_tableName: "
|
|
105
|
-
|
|
69
|
+
const orderSchema = {
|
|
70
|
+
_tableName: "orders",
|
|
71
|
+
id: shape
|
|
72
|
+
.sql({ type: "int", pk: true })
|
|
73
|
+
.initialState(z.string().uuid(), () => crypto.randomUUID())
|
|
74
|
+
.client(({ sql, initialState }) => z.union([sql, initialState])),
|
|
75
|
+
status: shape
|
|
76
|
+
.sql({ type: "varchar", length: 20 })
|
|
77
|
+
.client(({ sql }) =>
|
|
78
|
+
z.enum(["pending", "processing", "shipped", "delivered"])
|
|
79
|
+
)
|
|
80
|
+
.validation(({ sql }) =>
|
|
81
|
+
sql.refine((val) =>
|
|
82
|
+
["pending", "processing", "shipped", "delivered"].includes(val)
|
|
83
|
+
)
|
|
84
|
+
),
|
|
85
|
+
metadata: shape
|
|
106
86
|
.sql({ type: "text" })
|
|
107
|
-
.client(({
|
|
87
|
+
.client(({ sql }) => z.record(z.unknown()))
|
|
108
88
|
.transform({
|
|
109
|
-
toClient: (value) =>
|
|
110
|
-
toDb: (value) =>
|
|
89
|
+
toClient: (value) => JSON.parse(value),
|
|
90
|
+
toDb: (value) => JSON.stringify(value),
|
|
111
91
|
}),
|
|
112
|
-
|
|
113
|
-
.sql({ type: "
|
|
114
|
-
.client(({
|
|
92
|
+
createdAt: shape
|
|
93
|
+
.sql({ type: "datetime" })
|
|
94
|
+
.client(({ sql }) => z.string().datetime())
|
|
115
95
|
.transform({
|
|
116
|
-
toClient: (
|
|
117
|
-
toDb: (
|
|
96
|
+
toClient: (date) => date.toISOString(),
|
|
97
|
+
toDb: (isoString) => new Date(isoString),
|
|
118
98
|
}),
|
|
119
99
|
};
|
|
120
100
|
```
|
|
@@ -124,24 +104,28 @@ const petSchema = {
|
|
|
124
104
|
Define relationships between schemas:
|
|
125
105
|
|
|
126
106
|
```typescript
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
107
|
+
const customerSchema = {
|
|
108
|
+
_tableName: "customers",
|
|
109
|
+
id: shape.sql({ type: "int", pk: true }),
|
|
110
|
+
name: shape.sql({ type: "varchar", length: 100 }),
|
|
111
|
+
orders: hasMany({
|
|
112
|
+
fromKey: "id",
|
|
113
|
+
toKey: () => orderSchema.customerId,
|
|
114
|
+
schema: () => orderSchema,
|
|
115
|
+
}),
|
|
116
|
+
primaryAddress: hasOne({
|
|
130
117
|
fromKey: "id",
|
|
131
|
-
toKey: () =>
|
|
132
|
-
schema: () =>
|
|
133
|
-
|
|
118
|
+
toKey: () => addressSchema.customerId,
|
|
119
|
+
schema: () => addressSchema,
|
|
120
|
+
}),
|
|
121
|
+
company: belongsTo({
|
|
122
|
+
fromKey: "companyId",
|
|
123
|
+
toKey: () => companySchema.id,
|
|
124
|
+
schema: () => companySchema,
|
|
134
125
|
}),
|
|
135
126
|
};
|
|
136
127
|
```
|
|
137
128
|
|
|
138
|
-
Supported relationships:
|
|
139
|
-
|
|
140
|
-
- `hasMany`
|
|
141
|
-
- `hasOne`
|
|
142
|
-
- `belongsTo`
|
|
143
|
-
- `manyToMany`
|
|
144
|
-
|
|
145
129
|
### SQL Types
|
|
146
130
|
|
|
147
131
|
Built-in SQL type definitions:
|
|
@@ -161,11 +145,22 @@ shape.longtext();
|
|
|
161
145
|
Add Zod validation to your schemas:
|
|
162
146
|
|
|
163
147
|
```typescript
|
|
164
|
-
const
|
|
148
|
+
const userSchema = {
|
|
149
|
+
_tableName: "users",
|
|
165
150
|
email: shape
|
|
166
151
|
.sql({ type: "varchar", length: 255 })
|
|
167
|
-
.
|
|
168
|
-
|
|
152
|
+
.validation(({ sql }) => sql.email().toLowerCase()),
|
|
153
|
+
password: shape
|
|
154
|
+
.sql({ type: "varchar", length: 255 })
|
|
155
|
+
.validation(({ sql }) =>
|
|
156
|
+
sql
|
|
157
|
+
.min(8)
|
|
158
|
+
.regex(/[A-Z]/, "Must contain uppercase letter")
|
|
159
|
+
.regex(/[0-9]/, "Must contain number")
|
|
160
|
+
),
|
|
161
|
+
birthDate: shape
|
|
162
|
+
.sql({ type: "date" })
|
|
163
|
+
.validation(({ sql }) => sql.min(new Date("1900-01-01")).max(new Date())),
|
|
169
164
|
};
|
|
170
165
|
```
|
|
171
166
|
|
|
@@ -174,12 +169,14 @@ const schema = {
|
|
|
174
169
|
The library provides full type inference:
|
|
175
170
|
|
|
176
171
|
```typescript
|
|
177
|
-
const {
|
|
172
|
+
const { sqlSchema, clientSchema, validationSchema, defaultValues } =
|
|
173
|
+
createSchema(userSchema);
|
|
178
174
|
|
|
179
175
|
// These are fully typed:
|
|
180
|
-
type DBUser = z.infer<typeof
|
|
176
|
+
type DBUser = z.infer<typeof sqlSchema>;
|
|
181
177
|
type ClientUser = z.infer<typeof clientSchema>;
|
|
182
|
-
|
|
178
|
+
type ValidationUser = z.infer<typeof validationSchema>;
|
|
179
|
+
const defaults: typeof defaultValues = {
|
|
183
180
|
// TypeScript will ensure this matches your schema
|
|
184
181
|
};
|
|
185
182
|
```
|