sizuku 0.4.1 → 0.5.0
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 +134 -61
- package/dist/config/index.d.mts +4 -2
- package/dist/config/index.mjs +7 -6
- package/dist/index.d.mts +1 -10
- package/dist/index.mjs +299 -390
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Sizuku
|
|
4
4
|
|
|
5
|
-
**[Sizuku](https://www.npmjs.com/package/sizuku)** is a tool that generates validation schemas for Zod and
|
|
5
|
+
**[Sizuku](https://www.npmjs.com/package/sizuku)** is a tool that generates validation schemas for Zod, Valibot, ArkType, and Effect Schema, as well as ER diagrams, from [Drizzle](https://orm.drizzle.team/) schemas.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
- ⚡ Automatically generates [Effect Schema](https://effect.website/docs/schema/introduction/) from your Drizzle schema
|
|
13
13
|
- 📊 Creates [Mermaid](https://mermaid.js.org/) ER diagrams
|
|
14
14
|
- 📝 Generates [DBML](https://dbml.dbdiagram.io/) (Database Markup Language) files
|
|
15
|
-
- 🖼️ Outputs ER diagrams as **PNG
|
|
16
|
-
|
|
15
|
+
- 🖼️ Outputs ER diagrams as **PNG** images using [dbml-renderer](https://github.com/softwaretechnik-berlin/dbml-renderer)
|
|
17
16
|
|
|
18
17
|
## Getting Started
|
|
19
18
|
|
|
@@ -37,10 +36,14 @@ export const user = mysqlTable('user', {
|
|
|
37
36
|
/// Primary key
|
|
38
37
|
/// @z.uuid()
|
|
39
38
|
/// @v.pipe(v.string(), v.uuid())
|
|
39
|
+
/// @a."string.uuid"
|
|
40
|
+
/// @e.Schema.UUID
|
|
40
41
|
id: varchar('id', { length: 36 }).primaryKey(),
|
|
41
42
|
/// Display name
|
|
42
43
|
/// @z.string().min(1).max(50)
|
|
43
44
|
/// @v.pipe(v.string(), v.minLength(1), v.maxLength(50))
|
|
45
|
+
/// @a."1 <= string <= 50"
|
|
46
|
+
/// @e.Schema.String.pipe(Schema.minLength(1), Schema.maxLength(50))
|
|
44
47
|
name: varchar('name', { length: 50 }).notNull(),
|
|
45
48
|
})
|
|
46
49
|
|
|
@@ -49,18 +52,26 @@ export const post = mysqlTable('post', {
|
|
|
49
52
|
/// Primary key
|
|
50
53
|
/// @z.uuid()
|
|
51
54
|
/// @v.pipe(v.string(), v.uuid())
|
|
55
|
+
/// @a."string.uuid"
|
|
56
|
+
/// @e.Schema.UUID
|
|
52
57
|
id: varchar('id', { length: 36 }).primaryKey(),
|
|
53
58
|
/// Article title
|
|
54
59
|
/// @z.string().min(1).max(100)
|
|
55
60
|
/// @v.pipe(v.string(), v.minLength(1), v.maxLength(100))
|
|
61
|
+
/// @a."1 <= string <= 100"
|
|
62
|
+
/// @e.Schema.String.pipe(Schema.minLength(1), Schema.maxLength(100))
|
|
56
63
|
title: varchar('title', { length: 100 }).notNull(),
|
|
57
64
|
/// Body content (no length limit)
|
|
58
65
|
/// @z.string().min(1).max(65535)
|
|
59
66
|
/// @v.pipe(v.string(), v.minLength(1), v.maxLength(65535))
|
|
67
|
+
/// @a."1 <= string <= 65535"
|
|
68
|
+
/// @e.Schema.String.pipe(Schema.minLength(1), Schema.maxLength(65535))
|
|
60
69
|
content: varchar('content', { length: 65535 }).notNull(),
|
|
61
70
|
/// Foreign key referencing User.id
|
|
62
71
|
/// @z.uuid()
|
|
63
72
|
/// @v.pipe(v.string(), v.uuid())
|
|
73
|
+
/// @a."string.uuid"
|
|
74
|
+
/// @e.Schema.UUID
|
|
64
75
|
userId: varchar('user_id', { length: 36 }).notNull(),
|
|
65
76
|
})
|
|
66
77
|
|
|
@@ -100,21 +111,19 @@ export default defineConfig({
|
|
|
100
111
|
output: 'arktype/index.ts',
|
|
101
112
|
comment: true,
|
|
102
113
|
type: true,
|
|
114
|
+
relation: true,
|
|
103
115
|
},
|
|
104
116
|
effect: {
|
|
105
117
|
output: 'effect/index.ts',
|
|
106
118
|
comment: true,
|
|
107
119
|
type: true,
|
|
120
|
+
relation: true,
|
|
108
121
|
},
|
|
109
122
|
mermaid: {
|
|
110
123
|
output: 'mermaid-er/ER.md',
|
|
111
124
|
},
|
|
112
125
|
dbml: {
|
|
113
|
-
output: '
|
|
114
|
-
},
|
|
115
|
-
svg: {
|
|
116
|
-
output: 'docs/er-diagram.png',
|
|
117
|
-
format: 'png',
|
|
126
|
+
output: 'docs/schema.dbml',
|
|
118
127
|
},
|
|
119
128
|
})
|
|
120
129
|
```
|
|
@@ -125,6 +134,16 @@ Run Sizuku:
|
|
|
125
134
|
npx sizuku
|
|
126
135
|
```
|
|
127
136
|
|
|
137
|
+
Output:
|
|
138
|
+
```
|
|
139
|
+
💧 Generated Zod schema at: zod/index.ts
|
|
140
|
+
💧 Generated Valibot schema at: valibot/index.ts
|
|
141
|
+
💧 Generated ArkType schema at: arktype/index.ts
|
|
142
|
+
💧 Generated Effect schema at: effect/index.ts
|
|
143
|
+
💧 Generated Mermaid ER at: mermaid-er/ER.md
|
|
144
|
+
💧 Generated DBML at: docs/schema.dbml
|
|
145
|
+
```
|
|
146
|
+
|
|
128
147
|
### Zod
|
|
129
148
|
|
|
130
149
|
```ts
|
|
@@ -221,6 +240,62 @@ export const PostRelationsSchema = v.object({ ...PostSchema.entries, user: UserS
|
|
|
221
240
|
export type PostRelations = v.InferInput<typeof PostRelationsSchema>
|
|
222
241
|
```
|
|
223
242
|
|
|
243
|
+
### ArkType
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import { type } from 'arktype'
|
|
247
|
+
|
|
248
|
+
export const UserSchema = type({
|
|
249
|
+
/** Primary key */
|
|
250
|
+
id: 'string.uuid',
|
|
251
|
+
/** Display name */
|
|
252
|
+
name: '1 <= string <= 50',
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
export type User = typeof UserSchema.infer
|
|
256
|
+
|
|
257
|
+
export const PostSchema = type({
|
|
258
|
+
/** Primary key */
|
|
259
|
+
id: 'string.uuid',
|
|
260
|
+
/** Article title */
|
|
261
|
+
title: '1 <= string <= 100',
|
|
262
|
+
/** Body content (no length limit) */
|
|
263
|
+
content: '1 <= string <= 65535',
|
|
264
|
+
/** Foreign key referencing User.id */
|
|
265
|
+
userId: 'string.uuid',
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
export type Post = typeof PostSchema.infer
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Effect Schema
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import { Schema } from 'effect'
|
|
275
|
+
|
|
276
|
+
export const UserSchema = Schema.Struct({
|
|
277
|
+
/** Primary key */
|
|
278
|
+
id: Schema.UUID,
|
|
279
|
+
/** Display name */
|
|
280
|
+
name: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(50)),
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
export type User = Schema.Schema.Type<typeof UserSchema>
|
|
284
|
+
|
|
285
|
+
export const PostSchema = Schema.Struct({
|
|
286
|
+
/** Primary key */
|
|
287
|
+
id: Schema.UUID,
|
|
288
|
+
/** Article title */
|
|
289
|
+
title: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(100)),
|
|
290
|
+
/** Body content (no length limit) */
|
|
291
|
+
content: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(65535)),
|
|
292
|
+
/** Foreign key referencing User.id */
|
|
293
|
+
userId: Schema.UUID,
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
export type Post = Schema.Schema.Type<typeof PostSchema>
|
|
297
|
+
```
|
|
298
|
+
|
|
224
299
|
### Mermaid ER
|
|
225
300
|
|
|
226
301
|
```mermaid
|
|
@@ -240,6 +315,11 @@ erDiagram
|
|
|
240
315
|
|
|
241
316
|
### DBML
|
|
242
317
|
|
|
318
|
+
The `dbml` generator outputs a DBML schema file or ER diagram PNG depending on the file extension:
|
|
319
|
+
|
|
320
|
+
- `.dbml` extension: outputs a DBML schema file
|
|
321
|
+
- `.png` extension: outputs an ER diagram PNG image
|
|
322
|
+
|
|
243
323
|
```dbml
|
|
244
324
|
Table user {
|
|
245
325
|
id varchar [pk, note: 'Primary key']
|
|
@@ -256,67 +336,60 @@ Table post {
|
|
|
256
336
|
Ref post_userId_user_id_fk: post.userId > user.id
|
|
257
337
|
```
|
|
258
338
|
|
|
259
|
-
### PNG/SVG
|
|
260
|
-
|
|
261
|
-
The `svg` generator outputs ER diagrams as PNG or SVG images using [dbml-renderer](https://github.com/softwaretechnik-berlin/dbml-renderer).
|
|
262
|
-
|
|
263
|
-
Output: `docs/er-diagram.png`
|
|
264
|
-
|
|
265
339
|
## Configuration
|
|
266
340
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
| Option | Type | Default | Description |
|
|
270
|
-
|------------|-----------|----------------|------------------------------------------------------------------|
|
|
271
|
-
| `output` | `string` | `zod/index.ts` | Output file path |
|
|
272
|
-
| `type` | `boolean` | `false` | Generate TypeScript types |
|
|
273
|
-
| `comment` | `boolean` | `false` | Include schema documentation |
|
|
274
|
-
| `zod` | `string` | `'v4'` | Zod import version (`'mini'`, `'@hono/zod-openapi'`, or `'v4'`) |
|
|
275
|
-
| `relation` | `boolean` | `false` | Generate relation schemas |
|
|
276
|
-
|
|
277
|
-
### Valibot Options
|
|
278
|
-
|
|
279
|
-
| Option | Type | Default | Description |
|
|
280
|
-
|------------|-----------|--------------------|------------------------------|
|
|
281
|
-
| `output` | `string` | `valibot/index.ts` | Output file path |
|
|
282
|
-
| `type` | `boolean` | `false` | Generate TypeScript types |
|
|
283
|
-
| `comment` | `boolean` | `false` | Include schema documentation |
|
|
284
|
-
| `relation` | `boolean` | `false` | Generate relation schemas |
|
|
285
|
-
|
|
286
|
-
### ArkType Options
|
|
287
|
-
|
|
288
|
-
| Option | Type | Default | Description |
|
|
289
|
-
|-----------|-----------|--------------------|------------------------------|
|
|
290
|
-
| `output` | `string` | `arktype/index.ts` | Output file path |
|
|
291
|
-
| `type` | `boolean` | `false` | Generate TypeScript types |
|
|
292
|
-
| `comment` | `boolean` | `false` | Include schema documentation |
|
|
293
|
-
|
|
294
|
-
### Effect Options
|
|
341
|
+
```typescript
|
|
342
|
+
import { defineConfig } from 'sizuku/config'
|
|
295
343
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
| `type` | `boolean` | `false` | Generate TypeScript types |
|
|
300
|
-
| `comment` | `boolean` | `false` | Include schema documentation |
|
|
344
|
+
export default defineConfig({
|
|
345
|
+
// Input: Path to Drizzle schema file (must end with .ts)
|
|
346
|
+
input: 'db/schema.ts',
|
|
301
347
|
|
|
302
|
-
|
|
348
|
+
// Zod Schema Generator
|
|
349
|
+
zod: {
|
|
350
|
+
output: 'zod/index.ts', // Output file path (must end with .ts)
|
|
351
|
+
comment: true, // Include schema documentation (default: false)
|
|
352
|
+
type: true, // Generate TypeScript types (default: false)
|
|
353
|
+
zod: 'v4', // Zod import: 'v4' | 'mini' | '@hono/zod-openapi' (default: 'v4')
|
|
354
|
+
relation: true, // Generate relation schemas (default: false)
|
|
355
|
+
},
|
|
303
356
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
357
|
+
// Valibot Schema Generator
|
|
358
|
+
valibot: {
|
|
359
|
+
output: 'valibot/index.ts',
|
|
360
|
+
comment: true,
|
|
361
|
+
type: true,
|
|
362
|
+
relation: true,
|
|
363
|
+
},
|
|
307
364
|
|
|
308
|
-
|
|
365
|
+
// ArkType Schema Generator
|
|
366
|
+
arktype: {
|
|
367
|
+
output: 'arktype/index.ts',
|
|
368
|
+
comment: true,
|
|
369
|
+
type: true,
|
|
370
|
+
relation: true, // Generate relation schemas (default: false)
|
|
371
|
+
},
|
|
309
372
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
373
|
+
// Effect Schema Generator
|
|
374
|
+
effect: {
|
|
375
|
+
output: 'effect/index.ts',
|
|
376
|
+
comment: true,
|
|
377
|
+
type: true,
|
|
378
|
+
relation: true, // Generate relation schemas (default: false)
|
|
379
|
+
},
|
|
313
380
|
|
|
314
|
-
|
|
381
|
+
// Mermaid ER Diagram Generator
|
|
382
|
+
mermaid: {
|
|
383
|
+
output: 'mermaid-er/ER.md', // Output file path
|
|
384
|
+
},
|
|
315
385
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
386
|
+
// DBML / ER Diagram PNG Generator
|
|
387
|
+
// Use .dbml extension for DBML text, .png extension for ER diagram image
|
|
388
|
+
dbml: {
|
|
389
|
+
output: 'docs/schema.dbml', // Output file path (must end with .dbml or .png)
|
|
390
|
+
},
|
|
391
|
+
})
|
|
392
|
+
```
|
|
320
393
|
|
|
321
394
|
### ⚠️ WARNING: Potential Breaking Changes Without Notice
|
|
322
395
|
|
|
@@ -324,4 +397,4 @@ This package is in active development and may introduce breaking changes without
|
|
|
324
397
|
|
|
325
398
|
## License
|
|
326
399
|
|
|
327
|
-
Distributed under the MIT License. See [LICENSE](https://github.com/nakita628/
|
|
400
|
+
Distributed under the MIT License. See [LICENSE](https://github.com/nakita628/sizuku?tab=MIT-1-ov-file) for more information.
|
package/dist/config/index.d.mts
CHANGED
|
@@ -24,11 +24,13 @@ declare const configSchema: z.ZodObject<{
|
|
|
24
24
|
output: z.ZodType<`${string}.ts`, unknown, z.core.$ZodTypeInternals<`${string}.ts`, unknown>>;
|
|
25
25
|
comment: z.ZodOptional<z.ZodBoolean>;
|
|
26
26
|
type: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
+
relation: z.ZodOptional<z.ZodBoolean>;
|
|
27
28
|
}, z.core.$strip>>;
|
|
28
29
|
effect: z.ZodOptional<z.ZodObject<{
|
|
29
30
|
output: z.ZodType<`${string}.ts`, unknown, z.core.$ZodTypeInternals<`${string}.ts`, unknown>>;
|
|
30
31
|
comment: z.ZodOptional<z.ZodBoolean>;
|
|
31
32
|
type: z.ZodOptional<z.ZodBoolean>;
|
|
33
|
+
relation: z.ZodOptional<z.ZodBoolean>;
|
|
32
34
|
}, z.core.$strip>>;
|
|
33
35
|
mermaid: z.ZodOptional<z.ZodObject<{
|
|
34
36
|
output: z.ZodString;
|
|
@@ -38,7 +40,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
38
40
|
}, z.core.$strip>>;
|
|
39
41
|
}, z.core.$strip>;
|
|
40
42
|
type Config = z.infer<typeof configSchema>;
|
|
41
|
-
declare function
|
|
43
|
+
declare function readConfig(): Promise<{
|
|
42
44
|
readonly ok: true;
|
|
43
45
|
readonly value: Config;
|
|
44
46
|
} | {
|
|
@@ -47,4 +49,4 @@ declare function config(): Promise<{
|
|
|
47
49
|
}>;
|
|
48
50
|
declare function defineConfig(config: Config): Config;
|
|
49
51
|
//#endregion
|
|
50
|
-
export { Config,
|
|
52
|
+
export { Config, defineConfig, readConfig };
|
package/dist/config/index.mjs
CHANGED
|
@@ -6,7 +6,6 @@ import { z } from "zod";
|
|
|
6
6
|
|
|
7
7
|
//#region src/config/index.ts
|
|
8
8
|
const tsFileSchema = z.string().endsWith(".ts");
|
|
9
|
-
const directorySchema = z.string();
|
|
10
9
|
const zodConfigSchema = z.object({
|
|
11
10
|
output: tsFileSchema,
|
|
12
11
|
comment: z.boolean().optional(),
|
|
@@ -27,15 +26,17 @@ const valibotConfigSchema = z.object({
|
|
|
27
26
|
const arktypeConfigSchema = z.object({
|
|
28
27
|
output: tsFileSchema,
|
|
29
28
|
comment: z.boolean().optional(),
|
|
30
|
-
type: z.boolean().optional()
|
|
29
|
+
type: z.boolean().optional(),
|
|
30
|
+
relation: z.boolean().optional()
|
|
31
31
|
}).optional();
|
|
32
32
|
const effectConfigSchema = z.object({
|
|
33
33
|
output: tsFileSchema,
|
|
34
34
|
comment: z.boolean().optional(),
|
|
35
|
-
type: z.boolean().optional()
|
|
35
|
+
type: z.boolean().optional(),
|
|
36
|
+
relation: z.boolean().optional()
|
|
36
37
|
}).optional();
|
|
37
38
|
const mermaidConfigSchema = z.object({ output: z.string() }).optional();
|
|
38
|
-
const dbmlConfigSchema = z.object({ output:
|
|
39
|
+
const dbmlConfigSchema = z.object({ output: z.string().refine((s) => s.endsWith(".dbml") || s.endsWith(".png"), { message: "output must end with .dbml or .png" }) }).optional();
|
|
39
40
|
const configSchema = z.object({
|
|
40
41
|
input: tsFileSchema,
|
|
41
42
|
zod: zodConfigSchema,
|
|
@@ -45,7 +46,7 @@ const configSchema = z.object({
|
|
|
45
46
|
mermaid: mermaidConfigSchema,
|
|
46
47
|
dbml: dbmlConfigSchema
|
|
47
48
|
});
|
|
48
|
-
async function
|
|
49
|
+
async function readConfig() {
|
|
49
50
|
const abs = resolve(process.cwd(), "sizuku.config.ts");
|
|
50
51
|
if (!existsSync(abs)) return {
|
|
51
52
|
ok: false,
|
|
@@ -83,4 +84,4 @@ function defineConfig(config) {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
//#endregion
|
|
86
|
-
export {
|
|
87
|
+
export { defineConfig, readConfig };
|