hekireki 0.4.2 โ†’ 0.5.1

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.
Files changed (72) hide show
  1. package/README.md +200 -47
  2. package/dist/cli/index.d.ts +14 -0
  3. package/dist/cli/index.js +164 -0
  4. package/dist/fsp-FOfmtPYd.js +68 -0
  5. package/dist/generator/arktype/index.d.ts +6 -0
  6. package/dist/generator/arktype/index.js +121 -0
  7. package/dist/generator/dbml/index.d.ts +9 -0
  8. package/dist/generator/dbml/index.js +221 -0
  9. package/dist/generator/docs/index.d.ts +1 -0
  10. package/dist/generator/docs/index.js +1103 -0
  11. package/dist/generator/ecto/index.d.ts +6 -3
  12. package/dist/generator/ecto/index.js +150 -13
  13. package/dist/generator/effect/index.d.ts +6 -0
  14. package/dist/generator/effect/index.js +121 -0
  15. package/dist/generator/mermaid-er/index.d.ts +6 -3
  16. package/dist/generator/mermaid-er/index.js +136 -21
  17. package/dist/generator/valibot/index.d.ts +6 -3
  18. package/dist/generator/valibot/index.js +90 -45
  19. package/dist/generator/zod/index.d.ts +6 -3
  20. package/dist/generator/zod/index.js +97 -56
  21. package/dist/utils-BHGDO4qk.js +145 -0
  22. package/package.json +34 -17
  23. package/dist/generator/ecto/generator/ecto.d.ts +0 -3
  24. package/dist/generator/ecto/generator/ecto.js +0 -131
  25. package/dist/generator/ecto/utils/index.d.ts +0 -1
  26. package/dist/generator/ecto/utils/index.js +0 -1
  27. package/dist/generator/ecto/utils/prisma-type-to-ecto-type.d.ts +0 -1
  28. package/dist/generator/ecto/utils/prisma-type-to-ecto-type.js +0 -11
  29. package/dist/generator/mermaid-er/generator/er-content.d.ts +0 -8
  30. package/dist/generator/mermaid-er/generator/er-content.js +0 -23
  31. package/dist/generator/mermaid-er/generator/index.d.ts +0 -4
  32. package/dist/generator/mermaid-er/generator/index.js +0 -4
  33. package/dist/generator/mermaid-er/generator/model-fields.d.ts +0 -8
  34. package/dist/generator/mermaid-er/generator/model-fields.js +0 -25
  35. package/dist/generator/mermaid-er/generator/model-info.d.ts +0 -8
  36. package/dist/generator/mermaid-er/generator/model-info.js +0 -10
  37. package/dist/generator/mermaid-er/generator/relation-line.d.ts +0 -13
  38. package/dist/generator/mermaid-er/generator/relation-line.js +0 -14
  39. package/dist/generator/mermaid-er/helper/build-relation-line.d.ts +0 -9
  40. package/dist/generator/mermaid-er/helper/build-relation-line.js +0 -37
  41. package/dist/generator/mermaid-er/helper/extract-relations.d.ts +0 -8
  42. package/dist/generator/mermaid-er/helper/extract-relations.js +0 -22
  43. package/dist/generator/mermaid-er/utils/index.d.ts +0 -34
  44. package/dist/generator/mermaid-er/utils/index.js +0 -48
  45. package/dist/generator/valibot/generator/index.d.ts +0 -3
  46. package/dist/generator/valibot/generator/index.js +0 -3
  47. package/dist/generator/valibot/generator/schema.d.ts +0 -16
  48. package/dist/generator/valibot/generator/schema.js +0 -51
  49. package/dist/generator/valibot/generator/schemas.d.ts +0 -13
  50. package/dist/generator/valibot/generator/schemas.js +0 -17
  51. package/dist/generator/valibot/generator/valibot.d.ts +0 -9
  52. package/dist/generator/valibot/generator/valibot.js +0 -42
  53. package/dist/generator/valibot/utils/index.d.ts +0 -44
  54. package/dist/generator/valibot/utils/index.js +0 -75
  55. package/dist/generator/zod/generator/index.d.ts +0 -3
  56. package/dist/generator/zod/generator/index.js +0 -3
  57. package/dist/generator/zod/generator/schema.d.ts +0 -17
  58. package/dist/generator/zod/generator/schema.js +0 -38
  59. package/dist/generator/zod/generator/schemas.d.ts +0 -13
  60. package/dist/generator/zod/generator/schemas.js +0 -17
  61. package/dist/generator/zod/generator/zod.d.ts +0 -9
  62. package/dist/generator/zod/generator/zod.js +0 -47
  63. package/dist/generator/zod/utils/index.d.ts +0 -46
  64. package/dist/generator/zod/utils/index.js +0 -75
  65. package/dist/shared/format/index.d.ts +0 -1
  66. package/dist/shared/format/index.js +0 -9
  67. package/dist/shared/generator/index.d.ts +0 -11
  68. package/dist/shared/generator/index.js +0 -23
  69. package/dist/shared/helper/relations.d.ts +0 -7
  70. package/dist/shared/helper/relations.js +0 -5
  71. package/dist/shared/utils/index.d.ts +0 -61
  72. package/dist/shared/utils/index.js +0 -63
package/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # Hekireki
2
2
 
3
- **[Hekireki](https://www.npmjs.com/package/hekireki)** is a tool that generates validation schemas for Zod and Valibot, as well as ER diagrams, from [Prisma](https://www.prisma.io/) schemas annotated with comments.
3
+ **[Hekireki](https://www.npmjs.com/package/hekireki)** is a tool that generates validation schemas for Zod, Valibot, ArkType, and Effect Schema, as well as ER diagrams, from [Prisma](https://www.prisma.io/) schemas annotated with comments.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - ๐Ÿ’Ž Automatically generates [Zod](https://zod.dev/) schemas from your Prisma schema
8
8
  - ๐Ÿค– Automatically generates [Valibot](https://valibot.dev/) schemas from your Prisma schema
9
- - ๐Ÿ“Š Creates [Mermaid](https://mermaid.js.org/) ER diagrams
9
+ - ๐Ÿน Automatically generates [ArkType](https://arktype.io/) schemas from your Prisma schema
10
+ - โšก Automatically generates [Effect Schema](https://effect.website/docs/schema/introduction/) from your Prisma schema
11
+ - ๐Ÿ“Š Creates [Mermaid](https://mermaid.js.org/) ER diagrams with PK/FK markers
12
+ - ๐Ÿ“ Generates [DBML](https://dbml.dbdiagram.io/) (Database Markup Language) files
13
+ - ๐Ÿ–ผ๏ธ Outputs ER diagrams as **PNG/SVG** images using [dbml-renderer](https://github.com/softwaretechnik-berlin/dbml-renderer)
10
14
  - ๐Ÿงช Generates [Ecto](https://hexdocs.pm/ecto/Ecto.Schema.html) schemas for Elixir projects
11
15
  โš ๏ธ Foreign key constraints are **not** included โ€” manage relationships in your application logic
12
16
 
@@ -21,13 +25,8 @@ npm install -D hekireki
21
25
  Prepare `schema.prisma`:
22
26
 
23
27
  ```prisma
24
- generator client {
25
- provider = "prisma-client-js"
26
- }
27
-
28
28
  datasource db {
29
29
  provider = "sqlite"
30
- url = env("DATABASE_URL")
31
30
  }
32
31
 
33
32
  generator Hekireki-ER {
@@ -48,42 +47,75 @@ generator Hekireki-Valibot {
48
47
  relation = true
49
48
  }
50
49
 
50
+ generator Hekireki-ArkType {
51
+ provider = "hekireki-arktype"
52
+ type = true
53
+ comment = true
54
+ }
55
+
56
+ generator Hekireki-Effect {
57
+ provider = "hekireki-effect"
58
+ type = true
59
+ comment = true
60
+ }
61
+
51
62
  generator Hekireki-Ecto {
52
63
  provider = "hekireki-ecto"
53
64
  output = "schema"
54
65
  app = "DBSchema"
55
66
  }
56
67
 
68
+ generator Hekireki-DBML {
69
+ provider = "hekireki-dbml"
70
+ }
71
+
72
+ generator Hekireki-SVG {
73
+ provider = "hekireki-svg"
74
+ output = "docs"
75
+ format = "png"
76
+ }
77
+
57
78
  model User {
58
79
  /// Primary key
59
80
  /// @z.uuid()
60
81
  /// @v.pipe(v.string(), v.uuid())
82
+ /// @a."string.uuid"
83
+ /// @e.Schema.UUID
61
84
  id String @id @default(uuid())
62
85
  /// Display name
63
86
  /// @z.string().min(1).max(50)
64
87
  /// @v.pipe(v.string(), v.minLength(1), v.maxLength(50))
88
+ /// @a."1 <= string <= 50"
89
+ /// @e.Schema.String.pipe(Schema.minLength(1), Schema.maxLength(50))
65
90
  name String
66
91
  /// One-to-many relation to Post
67
92
  posts Post[]
68
93
  }
69
94
 
70
- /// @relation User.id Post.userId one-to-many
71
95
  model Post {
72
96
  /// Primary key
73
97
  /// @z.uuid()
74
98
  /// @v.pipe(v.string(), v.uuid())
99
+ /// @a."string.uuid"
100
+ /// @e.Schema.UUID
75
101
  id String @id @default(uuid())
76
102
  /// Article title
77
103
  /// @z.string().min(1).max(100)
78
104
  /// @v.pipe(v.string(), v.minLength(1), v.maxLength(100))
105
+ /// @a."1 <= string <= 100"
106
+ /// @e.Schema.String.pipe(Schema.minLength(1), Schema.maxLength(100))
79
107
  title String
80
108
  /// Body content (no length limit)
81
109
  /// @z.string()
82
110
  /// @v.string()
111
+ /// @a."string"
112
+ /// @e.Schema.String
83
113
  content String
84
114
  /// Foreign key referencing User.id
85
115
  /// @z.uuid()
86
116
  /// @v.pipe(v.string(), v.uuid())
117
+ /// @a."string.uuid"
118
+ /// @e.Schema.UUID
87
119
  userId String
88
120
  /// Prisma relation definition
89
121
  user User @relation(fields: [userId], references: [id])
@@ -147,6 +179,7 @@ export type PostRelations = z.infer<typeof PostRelationsSchema>
147
179
  ```
148
180
 
149
181
  ## Valibot
182
+
150
183
  ```ts
151
184
  import * as v from 'valibot'
152
185
 
@@ -184,29 +217,91 @@ export const PostSchema = v.object({
184
217
 
185
218
  export type Post = v.InferInput<typeof PostSchema>
186
219
 
187
- export const UserRelationsSchema = v.object({ ...UserSchema.entries, posts: v.array(PostSchema) })
220
+ export const UserRelationsSchema = v.object({
221
+ ...UserSchema.entries,
222
+ posts: v.array(PostSchema),
223
+ })
188
224
 
189
225
  export type UserRelations = v.InferInput<typeof UserRelationsSchema>
190
226
 
191
- export const PostRelationsSchema = v.object({ ...PostSchema.entries, user: UserSchema })
227
+ export const PostRelationsSchema = v.object({
228
+ ...PostSchema.entries,
229
+ user: UserSchema,
230
+ })
192
231
 
193
232
  export type PostRelations = v.InferInput<typeof PostRelationsSchema>
194
233
  ```
195
234
 
235
+ ## ArkType
236
+
237
+ ```ts
238
+ import { type } from 'arktype'
239
+
240
+ export const UserSchema = type({
241
+ /** Primary key */
242
+ id: 'string.uuid',
243
+ /** Display name */
244
+ name: '1 <= string <= 50',
245
+ })
246
+
247
+ export type User = typeof UserSchema.infer
248
+
249
+ export const PostSchema = type({
250
+ /** Primary key */
251
+ id: 'string.uuid',
252
+ /** Article title */
253
+ title: '1 <= string <= 100',
254
+ /** Body content (no length limit) */
255
+ content: 'string',
256
+ /** Foreign key referencing User.id */
257
+ userId: 'string.uuid',
258
+ })
259
+
260
+ export type Post = typeof PostSchema.infer
261
+ ```
262
+
263
+ ## Effect Schema
264
+
265
+ ```ts
266
+ import { Schema } from 'effect'
267
+
268
+ export const UserSchema = Schema.Struct({
269
+ /** Primary key */
270
+ id: Schema.UUID,
271
+ /** Display name */
272
+ name: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(50)),
273
+ })
274
+
275
+ export type User = Schema.Schema.Type<typeof UserSchema>
276
+
277
+ export const PostSchema = Schema.Struct({
278
+ /** Primary key */
279
+ id: Schema.UUID,
280
+ /** Article title */
281
+ title: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(100)),
282
+ /** Body content (no length limit) */
283
+ content: Schema.String,
284
+ /** Foreign key referencing User.id */
285
+ userId: Schema.UUID,
286
+ })
287
+
288
+ export type Post = Schema.Schema.Type<typeof PostSchema>
289
+ ```
290
+
196
291
  ## Mermaid
197
292
 
198
293
  ```mermaid
199
294
  erDiagram
200
295
  User ||--}| Post : "(id) - (userId)"
201
296
  User {
202
- String id "Primary key"
203
- String name "Display name"
297
+ string id PK "Primary key"
298
+ string name "Display name"
204
299
  }
205
300
  Post {
206
- String id "Primary key"
207
- String title "Article title"
208
- String content "Body content (no length limit)"
209
- String userId "Foreign key referencing User.id"
301
+ string id PK "Primary key"
302
+ string title "Article title"
303
+ string content "Body content (no length limit)"
304
+ string userId FK "Foreign key referencing User.id"
210
305
  }
211
306
  ```
212
307
 
@@ -250,48 +345,106 @@ defmodule DBSchema.Post do
250
345
  end
251
346
  ```
252
347
 
253
- ## Configuration
348
+ ## DBML
349
+
350
+ ```dbml
351
+ Table User {
352
+ id String [pk, note: 'Primary key']
353
+ name String [not null, note: 'Display name']
354
+ posts Post [not null, note: 'One-to-many relation to Post']
355
+ }
356
+
357
+ Table Post {
358
+ id String [pk, note: 'Primary key']
359
+ title String [not null, note: 'Article title']
360
+ content String [not null, note: 'Body content (no length limit)']
361
+ userId String [not null, note: 'Foreign key referencing User.id']
362
+ user User [not null, note: 'Prisma relation definition']
363
+ }
364
+
365
+ Ref Post_userId_fk: Post.userId > User.id
366
+ ```
367
+
368
+ ## PNG/SVG
254
369
 
255
- ### Zod Generator Options
370
+ The `hekireki-svg` generator outputs ER diagrams as PNG or SVG images using [dbml-renderer](https://github.com/softwaretechnik-berlin/dbml-renderer).
256
371
 
257
- | Option | Type | Default | Description |
258
- |--------------|-----------|-------------------------------------|--------------------------------------------------|
259
- | `output` | `string` | `./zod` | Output directory |
260
- | `file` | `string` | `index.ts` | File Name |
261
- | `type` | `boolean` | `false` | Generate TypeScript types |
262
- | `comment` | `boolean` | `false` | Include schema documentation |
263
- | `zod` | `string` | `'v4'` | Zod import version (`'mini'`, `'@hono/zod-openapi'`, or default `'v4'`) |
264
- | `relation` | `boolean` | `false` | Generate relation schemas |
372
+ Output: `docs/er-diagram.png`
265
373
 
266
- ### Valibot Generator Options
374
+ ## Configuration
375
+
376
+ Configure each generator directly in your `schema.prisma` file:
267
377
 
268
- | Option | Type | Default | Description |
269
- |--------------|-----------|-------------------------------------|--------------------------------------------------|
270
- | `output` | `string` | `./valibot` | Output directory |
271
- | `file` | `string` | `index.ts` | File Name |
272
- | `type` | `boolean` | `false` | Generate TypeScript types |
273
- | `comment` | `boolean` | `false` | Include schema documentation |
274
- | `relation` | `boolean` | `false` | Generate relation schemas |
378
+ ```prisma
379
+ // Zod Generator
380
+ generator Hekireki-Zod {
381
+ provider = "hekireki-zod"
382
+ output = "./zod" // Output directory (default: ./zod)
383
+ file = "index.ts" // File name (default: index.ts)
384
+ type = true // Generate TypeScript types (default: false)
385
+ comment = true // Include schema documentation (default: false)
386
+ zod = "v4" // Zod import: "v4", "mini", or "@hono/zod-openapi" (default: v4)
387
+ relation = true // Generate relation schemas (default: false)
388
+ }
275
389
 
276
- ### Mermaid ER Generator Options
390
+ // Valibot Generator
391
+ generator Hekireki-Valibot {
392
+ provider = "hekireki-valibot"
393
+ output = "./valibot" // Output directory (default: ./valibot)
394
+ file = "index.ts" // File name (default: index.ts)
395
+ type = true // Generate TypeScript types (default: false)
396
+ comment = true // Include schema documentation (default: false)
397
+ relation = true // Generate relation schemas (default: false)
398
+ }
277
399
 
278
- | Option | Type | Default | Description |
279
- |--------------|-----------|-------------------------------------|--------------------------------------------------|
280
- | `output` | `string` | `./mermaid-er` | Output directory |
281
- | `file` | `string` | `ER.md` | File Name |
400
+ // ArkType Generator
401
+ generator Hekireki-ArkType {
402
+ provider = "hekireki-arktype"
403
+ output = "./arktype" // Output directory (default: ./arktype)
404
+ file = "index.ts" // File name (default: index.ts)
405
+ type = true // Generate TypeScript types (default: false)
406
+ comment = true // Include schema documentation (default: false)
407
+ }
282
408
 
283
- ### Ecto Generator Options
409
+ // Effect Schema Generator
410
+ generator Hekireki-Effect {
411
+ provider = "hekireki-effect"
412
+ output = "./effect" // Output directory (default: ./effect)
413
+ file = "index.ts" // File name (default: index.ts)
414
+ type = true // Generate TypeScript types (default: false)
415
+ comment = true // Include schema documentation (default: false)
416
+ }
284
417
 
285
- | Option | Type | Default | Description |
286
- |--------------|-----------|-------------------------------------|--------------------------------------------------|
287
- | `output` | `string` | `./ecto` | Output directory |
288
- | `app` | `string` | `MyApp` | App Name |
418
+ // Mermaid ER Generator
419
+ generator Hekireki-ER {
420
+ provider = "hekireki-mermaid-er"
421
+ output = "./mermaid-er" // Output directory (default: ./mermaid-er)
422
+ file = "ER.md" // File name (default: ER.md)
423
+ }
289
424
 
290
- โš ๏ธ WARNING: Potential Breaking Changes Without Notice
425
+ // Ecto Generator
426
+ generator Hekireki-Ecto {
427
+ provider = "hekireki-ecto"
428
+ output = "./ecto" // Output directory (default: ./ecto)
429
+ app = "MyApp" // App name (default: MyApp)
430
+ }
291
431
 
292
- This project is in **early development** and being maintained by a developer with about 2 years of experience. While I'm doing my best to create a useful tool:
432
+ // DBML Generator
433
+ generator Hekireki-DBML {
434
+ provider = "hekireki-dbml"
435
+ output = "./dbml" // Output directory (default: ./dbml)
436
+ file = "schema.dbml" // File name (default: schema.dbml)
437
+ }
293
438
 
439
+ // SVG/PNG Generator
440
+ generator Hekireki-SVG {
441
+ provider = "hekireki-svg"
442
+ output = "./docs" // Output directory (default: ./docs)
443
+ file = "er-diagram" // File name without extension (default: er-diagram)
444
+ format = "png" // Output format: "png", "svg", or "dot" (default: png)
445
+ }
446
+ ```
294
447
 
295
448
  ## License
296
449
 
297
- Distributed under the MIT License. See [LICENSE](https://github.com/nakita628/hekireki?tab=MIT-1-ov-file) for more information.
450
+ Distributed under the MIT License. See [LICENSE](https://github.com/nakita628/hekireki?tab=MIT-1-ov-file) for more information.
@@ -0,0 +1,14 @@
1
+ //#region src/cli/index.d.ts
2
+ type Result<T> = {
3
+ readonly ok: true;
4
+ readonly value: T;
5
+ } | {
6
+ readonly ok: false;
7
+ readonly error: string;
8
+ };
9
+ /**
10
+ * Main CLI entry point for hekireki.
11
+ */
12
+ declare const hekireki: () => Result<string>;
13
+ //#endregion
14
+ export { hekireki };
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { serve } from "@hono/node-server";
5
+ import { serveStatic } from "@hono/node-server/serve-static";
6
+ import { Hono } from "hono";
7
+
8
+ //#region src/cli/index.ts
9
+ /**
10
+ * CLI module for hekireki.
11
+ *
12
+ * Provides the main entry point for the hekireki CLI tool.
13
+ *
14
+ * @module cli
15
+ */
16
+ const HELP_TEXT = `โšก๏ธ hekireki - Prisma schema tools
17
+
18
+ Usage:
19
+ hekireki <command> [options]
20
+
21
+ Commands:
22
+ docs serve Start a local server to view the documentation
23
+
24
+ Options:
25
+ -p, --port <port> Specify the port (default: 5858)
26
+ -h, --help Show help
27
+
28
+ Examples:
29
+ hekireki docs serve
30
+ hekireki docs serve -p 3000`;
31
+ const DOCS_HELP_TEXT = `โšก๏ธ hekireki docs - Documentation tools
32
+
33
+ Usage:
34
+ hekireki docs serve [options]
35
+
36
+ Commands:
37
+ serve Start a local server to view the documentation
38
+
39
+ Options:
40
+ -p, --port <port> Specify the port (default: 5858)
41
+ -h, --help Show help
42
+
43
+ Examples:
44
+ hekireki docs serve
45
+ hekireki docs serve -p 3000`;
46
+ /**
47
+ * Parse port from CLI arguments.
48
+ */
49
+ const parsePort = (args) => {
50
+ const portIndex = args.findIndex((arg) => arg === "-p" || arg === "--port");
51
+ if (portIndex === -1) return {
52
+ ok: true,
53
+ value: 5858
54
+ };
55
+ const portStr = args[portIndex + 1];
56
+ if (!portStr || portStr.startsWith("-")) return {
57
+ ok: false,
58
+ error: "โŒ Error: --port requires a number"
59
+ };
60
+ const port = parseInt(portStr, 10);
61
+ if (isNaN(port)) return {
62
+ ok: false,
63
+ error: `โŒ Error: Invalid port number: ${portStr}`
64
+ };
65
+ return {
66
+ ok: true,
67
+ value: port
68
+ };
69
+ };
70
+ /**
71
+ * Parse CLI arguments for docs serve command.
72
+ */
73
+ const parseDocsServeArgs = (args) => {
74
+ const portResult = parsePort(args);
75
+ if (!portResult.ok) return portResult;
76
+ return {
77
+ ok: true,
78
+ value: { port: portResult.value }
79
+ };
80
+ };
81
+ /**
82
+ * Start the documentation server.
83
+ */
84
+ const startDocsServer = (options) => {
85
+ const absolutePath = path.resolve("./docs");
86
+ if (!fs.existsSync(absolutePath)) return {
87
+ ok: false,
88
+ error: `โŒ Error: Directory not found: ${absolutePath}\n Run "prisma generate" first to generate the documentation.`
89
+ };
90
+ const indexPath = path.join(absolutePath, "index.html");
91
+ if (!fs.existsSync(indexPath)) return {
92
+ ok: false,
93
+ error: `โŒ Error: index.html not found in ${absolutePath}\n Run "prisma generate" first to generate the documentation.`
94
+ };
95
+ const app = new Hono();
96
+ app.get("/", (c) => {
97
+ const html = fs.readFileSync(indexPath, "utf-8");
98
+ return c.html(html);
99
+ });
100
+ app.use("/*", serveStatic({ root: absolutePath }));
101
+ const server = serve({
102
+ fetch: app.fetch,
103
+ port: options.port
104
+ });
105
+ process.on("SIGTERM", () => {
106
+ server.close();
107
+ process.exit(0);
108
+ });
109
+ process.on("SIGINT", () => {
110
+ server.close();
111
+ process.exit(0);
112
+ });
113
+ return {
114
+ ok: true,
115
+ value: `โšก๏ธ Hekireki Docs Server started at http://localhost:${options.port}\n๐Ÿ“‚ Serving documentation from: ${absolutePath}`
116
+ };
117
+ };
118
+ /**
119
+ * Handle docs subcommand.
120
+ */
121
+ const handleDocs = (args) => {
122
+ const subcommand = args[0];
123
+ if (!subcommand || subcommand === "-h" || subcommand === "--help") return {
124
+ ok: true,
125
+ value: DOCS_HELP_TEXT
126
+ };
127
+ if (subcommand !== "serve") return {
128
+ ok: false,
129
+ error: `โŒ Unknown command: docs ${subcommand}\n\n${DOCS_HELP_TEXT}`
130
+ };
131
+ const parseResult = parseDocsServeArgs(args.slice(1));
132
+ if (!parseResult.ok) return parseResult;
133
+ return startDocsServer(parseResult.value);
134
+ };
135
+ /**
136
+ * Command handlers map.
137
+ */
138
+ const commands = { docs: handleDocs };
139
+ /**
140
+ * Main CLI entry point for hekireki.
141
+ */
142
+ const hekireki = () => {
143
+ const args = process.argv.slice(2);
144
+ const command = args[0];
145
+ if (!command || command === "-h" || command === "--help") return {
146
+ ok: true,
147
+ value: HELP_TEXT
148
+ };
149
+ const handler = commands[command];
150
+ if (!handler) return {
151
+ ok: false,
152
+ error: `โŒ Unknown command: ${command}\n\n${HELP_TEXT}`
153
+ };
154
+ return handler(args.slice(1));
155
+ };
156
+ const result = hekireki();
157
+ if (result.ok) console.log(result.value);
158
+ else {
159
+ console.error(result.error);
160
+ process.exit(1);
161
+ }
162
+
163
+ //#endregion
164
+ export { hekireki };
@@ -0,0 +1,68 @@
1
+ import fs from "node:fs/promises";
2
+
3
+ //#region src/shared/fsp/index.ts
4
+ /**
5
+ * Creates a directory if it does not already exist.
6
+ *
7
+ * @param dir - Directory path to create.
8
+ * @returns A `Result` that is `ok` on success, otherwise an error message.
9
+ */
10
+ async function mkdir(dir) {
11
+ try {
12
+ await fs.mkdir(dir, { recursive: true });
13
+ return {
14
+ ok: true,
15
+ value: void 0
16
+ };
17
+ } catch (e) {
18
+ return {
19
+ ok: false,
20
+ error: e instanceof Error ? e.message : String(e)
21
+ };
22
+ }
23
+ }
24
+ /**
25
+ * Writes UTF-8 text to a file, creating it if necessary.
26
+ *
27
+ * @param path - File path to write.
28
+ * @param data - Text data to write.
29
+ * @returns A `Result` that is `ok` on success, otherwise an error message.
30
+ */
31
+ async function writeFile(path, data) {
32
+ try {
33
+ await fs.writeFile(path, data, "utf-8");
34
+ return {
35
+ ok: true,
36
+ value: void 0
37
+ };
38
+ } catch (e) {
39
+ return {
40
+ ok: false,
41
+ error: e instanceof Error ? e.message : String(e)
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Writes binary data to a file, creating it if necessary.
47
+ *
48
+ * @param path - File path to write.
49
+ * @param data - Binary data to write.
50
+ * @returns A `Result` that is `ok` on success, otherwise an error message.
51
+ */
52
+ async function writeFileBinary(path, data) {
53
+ try {
54
+ await fs.writeFile(path, data);
55
+ return {
56
+ ok: true,
57
+ value: void 0
58
+ };
59
+ } catch (e) {
60
+ return {
61
+ ok: false,
62
+ error: e instanceof Error ? e.message : String(e)
63
+ };
64
+ }
65
+ }
66
+
67
+ //#endregion
68
+ export { writeFile as n, writeFileBinary as r, mkdir as t };
@@ -0,0 +1,6 @@
1
+ import { GeneratorOptions } from "@prisma/generator-helper";
2
+
3
+ //#region src/generator/arktype/index.d.ts
4
+ declare const onGenerate: (options: GeneratorOptions) => Promise<void>;
5
+ //#endregion
6
+ export { onGenerate };