hekireki 0.7.4 → 0.7.6

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 CHANGED
@@ -301,22 +301,34 @@ export type PostRelations = v.InferOutput<typeof PostRelationsSchema>
301
301
  import { type } from 'arktype'
302
302
 
303
303
  export const UserSchema = type({
304
- /** Primary key */
304
+ /**
305
+ * Primary key
306
+ */
305
307
  id: 'string.uuid',
306
- /** Display name */
308
+ /**
309
+ * Display name
310
+ */
307
311
  name: '1 <= string <= 50',
308
312
  })
309
313
 
310
314
  export type User = typeof UserSchema.infer
311
315
 
312
316
  export const PostSchema = type({
313
- /** Primary key */
317
+ /**
318
+ * Primary key
319
+ */
314
320
  id: 'string.uuid',
315
- /** Article title */
321
+ /**
322
+ * Article title
323
+ */
316
324
  title: '1 <= string <= 100',
317
- /** Body content (no length limit) */
325
+ /**
326
+ * Body content (no length limit)
327
+ */
318
328
  content: 'string',
319
- /** Foreign key referencing User.id */
329
+ /**
330
+ * Foreign key referencing User.id
331
+ */
320
332
  userId: 'string.uuid',
321
333
  })
322
334
 
@@ -369,22 +381,34 @@ export type PostEncoded = typeof PostSchema.Encoded
369
381
  import { type Static, Type } from '@sinclair/typebox'
370
382
 
371
383
  export const UserSchema = Type.Object({
372
- /** Primary key */
384
+ /**
385
+ * Primary key
386
+ */
373
387
  id: Type.String({ format: 'uuid' }),
374
- /** Display name */
388
+ /**
389
+ * Display name
390
+ */
375
391
  name: Type.String({ minLength: 1, maxLength: 50 }),
376
392
  })
377
393
 
378
394
  export type User = Static<typeof UserSchema>
379
395
 
380
396
  export const PostSchema = Type.Object({
381
- /** Primary key */
397
+ /**
398
+ * Primary key
399
+ */
382
400
  id: Type.String({ format: 'uuid' }),
383
- /** Article title */
401
+ /**
402
+ * Article title
403
+ */
384
404
  title: Type.String({ minLength: 1, maxLength: 100 }),
385
- /** Body content (no length limit) */
405
+ /**
406
+ * Body content (no length limit)
407
+ */
386
408
  content: Type.String(),
387
- /** Foreign key referencing User.id */
409
+ /**
410
+ * Foreign key referencing User.id
411
+ */
388
412
  userId: Type.String({ format: 'uuid' }),
389
413
  })
390
414
 
@@ -405,7 +429,7 @@ export const PostRelationsSchema = Type.Object({
405
429
  export type PostRelations = Static<typeof PostRelationsSchema>
406
430
  ```
407
431
 
408
- ### AJV (JSON Schema)
432
+ ### AJV
409
433
 
410
434
  ```ts
411
435
  import type { FromSchema } from 'json-schema-to-ts'
@@ -413,9 +437,13 @@ import type { FromSchema } from 'json-schema-to-ts'
413
437
  export const UserSchema = {
414
438
  type: 'object' as const,
415
439
  properties: {
416
- /** Primary key */
440
+ /**
441
+ * Primary key
442
+ */
417
443
  id: { type: 'string' as const, format: 'uuid' as const },
418
- /** Display name */
444
+ /**
445
+ * Display name
446
+ */
419
447
  name: { type: 'string' as const, minLength: 1, maxLength: 50 },
420
448
  },
421
449
  required: ['id', 'name'] as const,
@@ -427,13 +455,21 @@ export type User = FromSchema<typeof UserSchema>
427
455
  export const PostSchema = {
428
456
  type: 'object' as const,
429
457
  properties: {
430
- /** Primary key */
458
+ /**
459
+ * Primary key
460
+ */
431
461
  id: { type: 'string' as const, format: 'uuid' as const },
432
- /** Article title */
462
+ /**
463
+ * Article title
464
+ */
433
465
  title: { type: 'string' as const, minLength: 1, maxLength: 100 },
434
- /** Body content (no length limit) */
466
+ /**
467
+ * Body content (no length limit)
468
+ */
435
469
  content: { type: 'string' as const },
436
- /** Foreign key referencing User.id */
470
+ /**
471
+ * Foreign key referencing User.id
472
+ */
437
473
  userId: { type: 'string' as const, format: 'uuid' as const },
438
474
  },
439
475
  required: ['id', 'title', 'content', 'userId'] as const,
@@ -1,14 +1,57 @@
1
1
  //#region src/cli/index.d.ts
2
- type Result<T> = {
2
+ declare const HELP_TEXT = "\u26A1\uFE0F hekireki - Prisma schema tools\n\nUsage:\n hekireki <command> [options]\n\nCommands:\n docs serve Start a local server to view the documentation\n\nOptions:\n -p, --port <port> Specify the port (default: 5858)\n -h, --help Show help\n\nExamples:\n hekireki docs serve\n hekireki docs serve -p 3000";
3
+ declare const DOCS_HELP_TEXT = "\u26A1\uFE0F hekireki docs - Documentation tools\n\nUsage:\n hekireki docs serve [options]\n\nCommands:\n serve Start a local server to view the documentation\n\nOptions:\n -p, --port <port> Specify the port (default: 5858)\n -h, --help Show help\n\nExamples:\n hekireki docs serve\n hekireki docs serve -p 3000";
4
+ /**
5
+ * Parse port from CLI arguments.
6
+ */
7
+ declare const parsePort: (args: readonly string[]) => {
8
+ readonly ok: true;
9
+ readonly value: number;
10
+ } | {
11
+ readonly ok: false;
12
+ readonly error: string;
13
+ };
14
+ /**
15
+ * Parse CLI arguments for docs serve command.
16
+ */
17
+ declare const parseDocsServeArgs: (args: readonly string[]) => {
18
+ readonly ok: true;
19
+ readonly value: {
20
+ readonly port: number;
21
+ };
22
+ } | {
23
+ readonly ok: false;
24
+ readonly error: string;
25
+ };
26
+ /**
27
+ * Handle docs subcommand.
28
+ */
29
+ declare const handleDocs: (args: readonly string[]) => {
30
+ readonly ok: true;
31
+ readonly value: string;
32
+ } | {
33
+ readonly ok: false;
34
+ readonly error: string;
35
+ };
36
+ /**
37
+ * Main CLI dispatcher (pure — takes args, returns Result).
38
+ */
39
+ declare const hekirekiCli: (args: readonly string[]) => {
3
40
  readonly ok: true;
4
- readonly value: T;
41
+ readonly value: string;
5
42
  } | {
6
43
  readonly ok: false;
7
44
  readonly error: string;
8
45
  };
9
46
  /**
10
- * Main CLI entry point for hekireki.
47
+ * Main CLI entry point for hekireki (reads process.argv).
11
48
  */
12
- declare const hekireki: () => Result<string>;
49
+ declare const hekireki: () => {
50
+ readonly ok: true;
51
+ readonly value: string;
52
+ } | {
53
+ readonly ok: false;
54
+ readonly error: string;
55
+ };
13
56
  //#endregion
14
- export { hekireki };
57
+ export { DOCS_HELP_TEXT, HELP_TEXT, handleDocs, hekireki, hekirekiCli, parseDocsServeArgs, parsePort };
package/dist/cli/index.js CHANGED
@@ -137,10 +137,9 @@ const handleDocs = (args) => {
137
137
  */
138
138
  const commands = { docs: handleDocs };
139
139
  /**
140
- * Main CLI entry point for hekireki.
140
+ * Main CLI dispatcher (pure takes args, returns Result).
141
141
  */
142
- const hekireki = () => {
143
- const args = process.argv.slice(2);
142
+ const hekirekiCli = (args) => {
144
143
  const command = args[0];
145
144
  if (!command || command === "-h" || command === "--help") return {
146
145
  ok: true,
@@ -153,6 +152,12 @@ const hekireki = () => {
153
152
  };
154
153
  return handler(args.slice(1));
155
154
  };
155
+ /**
156
+ * Main CLI entry point for hekireki (reads process.argv).
157
+ */
158
+ const hekireki = () => {
159
+ return hekirekiCli(process.argv.slice(2));
160
+ };
156
161
  const result = hekireki();
157
162
  if (result.ok) console.log(result.value);
158
163
  else {
@@ -161,4 +166,4 @@ else {
161
166
  }
162
167
 
163
168
  //#endregion
164
- export { hekireki };
169
+ export { DOCS_HELP_TEXT, HELP_TEXT, handleDocs, hekireki, hekirekiCli, parseDocsServeArgs, parsePort };
@@ -1,6 +1,10 @@
1
1
  import { GeneratorOptions } from "@prisma/generator-helper";
2
2
 
3
3
  //#region src/generator/ajv/index.d.ts
4
+ /**
5
+ * Prisma generator entry point for AJV JSON Schema generation
6
+ * @param options - The Prisma generator options
7
+ */
4
8
  declare function main(options: GeneratorOptions): Promise<void>;
5
9
  //#endregion
6
10
  export { main };
@@ -1,17 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { c as parseDocumentWithoutAnnotations, d as mkdir, f as writeFile, s as makeValidationExtractor, t as getBool } from "../../utils-0tE5jzYR.js";
4
- import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-DHllEbMR.js";
3
+ import { l as makeValidationExtractor, m as writeFile, n as getBool, o as makeCommentBlock, p as mkdir, u as parseDocumentWithoutAnnotations } from "../../utils-3ot3YB3D.js";
4
+ import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-o4IvnEUh.js";
5
5
  import path from "node:path";
6
6
  import pkg from "@prisma/generator-helper";
7
7
 
8
8
  //#region src/helper/ajv.ts
9
+ /**
10
+ * Generate AJV type inference using FromSchema
11
+ * @param modelName - The model name to generate type inference for
12
+ */
9
13
  function makeAjvInfer(modelName) {
10
14
  return `export type ${modelName} = FromSchema<typeof ${modelName}Schema>`;
11
15
  }
16
+ /**
17
+ * Generate JSON Schema enum expression for AJV
18
+ * @param values - The enum values to generate expression for
19
+ */
12
20
  function makeAjvEnumExpression(values) {
13
21
  return `{ enum: [${values.map((v) => `'${v}'`).join(", ")}] as const }`;
14
22
  }
23
+ /** Mapping from Prisma scalar types to JSON Schema type expressions */
15
24
  const PRISMA_TO_AJV = {
16
25
  String: "{ type: 'string' as const }",
17
26
  Int: "{ type: 'integer' as const }",
@@ -23,14 +32,25 @@ const PRISMA_TO_AJV = {
23
32
  Json: "{}",
24
33
  Bytes: "{ type: 'string' as const }"
25
34
  };
26
- function makeAjvSchemas(modelFields, comment) {
35
+ /**
36
+ * Generate JSON Schema object definition for a model
37
+ * @param modelFields - The fields of the model
38
+ * @param comment - Whether to include JSDoc comments in the generated code
39
+ */
40
+ function makeAjvSchemas(modelFields, comment, objectType) {
27
41
  const modelName = modelFields[0].modelName;
28
42
  const properties = modelFields.map((field) => {
29
- return `${comment && field.comment.length > 0 ? `${field.comment.map((c) => ` /** ${c} */`).join("\n")}\n` : ""} ${field.fieldName}: ${field.validation ?? "{ type: 'unknown' as const }"},`;
43
+ return `${comment ? makeCommentBlock(field.comment, 4) : ""} ${field.fieldName}: ${field.validation ?? "{ type: 'unknown' as const }"},`;
30
44
  }).join("\n");
31
45
  const requiredFields = modelFields.filter((f) => f.isRequired).map((f) => f.fieldName);
32
- return `export const ${modelName}Schema = {\n type: 'object' as const,\n properties: {\n${properties}\n },${requiredFields.length > 0 ? `\n required: [${requiredFields.map((f) => `'${f}'`).join(", ")}] as const,` : ""}\n additionalProperties: false,\n} as const`;
46
+ return `export const ${modelName}Schema = {\n type: 'object' as const,\n properties: {\n${properties}\n },${requiredFields.length > 0 ? `\n required: [${requiredFields.map((f) => `'${f}'`).join(", ")}] as const,` : ""}\n additionalProperties: ${objectType === "loose" ? "true" : "false"},\n} as const`;
33
47
  }
48
+ /**
49
+ * Generate JSON Schema relation object definition
50
+ * @param model - The model to generate relations for
51
+ * @param relProps - The relation properties
52
+ * @param options - Options for type export generation
53
+ */
34
54
  function makeAjvRelations(model, relProps, options) {
35
55
  if (relProps.length === 0) return null;
36
56
  const base = ` ...${model.name}Schema.properties,`;
@@ -38,6 +58,13 @@ function makeAjvRelations(model, relProps, options) {
38
58
  const typeLine = options?.includeType ? `\n\nexport type ${model.name}Relations = FromSchema<typeof ${model.name}RelationsSchema>` : "";
39
59
  return `export const ${model.name}RelationsSchema = {\n type: 'object' as const,\n properties: {\n${base}\n${rels}\n },\n additionalProperties: false,\n} as const${typeLine}`;
40
60
  }
61
+ /**
62
+ * Generate AJV-compatible JSON Schema validation code from Prisma models
63
+ * @param models - The Prisma data models
64
+ * @param type - Whether to include type inference using FromSchema
65
+ * @param comment - Whether to include JSDoc comments in the generated code
66
+ * @param enums - The Prisma enum definitions
67
+ */
41
68
  function ajv(models, type, comment, enums) {
42
69
  return validationSchemas(models, type, comment, {
43
70
  importStatement: type ? `import type { FromSchema } from 'json-schema-to-ts'` : "",
@@ -55,6 +82,10 @@ function ajv(models, type, comment, enums) {
55
82
  //#endregion
56
83
  //#region src/generator/ajv/index.ts
57
84
  const { generatorHandler } = pkg;
85
+ /**
86
+ * Prisma generator entry point for AJV JSON Schema generation
87
+ * @param options - The Prisma generator options
88
+ */
58
89
  async function main(options) {
59
90
  if (!(options.generator.isCustomOutput && options.generator.output?.value)) throw new Error("output is required for Hekireki-AJV. Please specify output in your generator config.");
60
91
  const output = options.generator.output.value;
@@ -1,6 +1,10 @@
1
1
  import { GeneratorOptions } from "@prisma/generator-helper";
2
2
 
3
3
  //#region src/generator/arktype/index.d.ts
4
+ /**
5
+ * Prisma generator entry point for ArkType schema generation
6
+ * @param options - The Prisma generator options
7
+ */
4
8
  declare function main(options: GeneratorOptions): Promise<void>;
5
9
  //#endregion
6
10
  export { main };
@@ -1,25 +1,44 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { c as parseDocumentWithoutAnnotations, d as mkdir, f as writeFile, l as schemaFromFields, s as makeValidationExtractor, t as getBool } from "../../utils-0tE5jzYR.js";
4
- import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-DHllEbMR.js";
3
+ import { d as schemaFromFields, l as makeValidationExtractor, m as writeFile, n as getBool, o as makeCommentBlock, p as mkdir, u as parseDocumentWithoutAnnotations } from "../../utils-3ot3YB3D.js";
4
+ import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-o4IvnEUh.js";
5
5
  import path from "node:path";
6
6
  import pkg from "@prisma/generator-helper";
7
7
 
8
8
  //#region src/helper/arktype.ts
9
+ /**
10
+ * Generate ArkType type inference
11
+ * @param modelName - The model name to generate type inference for
12
+ */
9
13
  function makeArktypeInfer(modelName) {
10
14
  return `export type ${modelName} = typeof ${modelName}Schema.infer`;
11
15
  }
12
- function makeArktypeSchema(modelName, fields) {
13
- return `export const ${modelName}Schema = type({\n${fields}\n})`;
16
+ /**
17
+ * Generate ArkType type() schema definition
18
+ * @param modelName - The model name for the schema
19
+ * @param fields - The formatted field definitions string
20
+ */
21
+ function makeArktypeSchema(modelName, fields, objectType) {
22
+ return `export const ${modelName}Schema = type({${objectType === "strict" ? "\n \"+\": \"reject\",\n" : objectType === "loose" ? "\n \"+\": \"ignore\",\n" : "\n"}${fields}\n})`;
14
23
  }
24
+ /**
25
+ * Generate ArkType property definitions
26
+ * @param fields - The fields to generate properties for
27
+ * @param comment - Whether to include JSDoc comments in the generated code
28
+ */
15
29
  function makeArktypeProperties(fields, comment) {
16
30
  return fields.map((field) => {
17
- return `${comment && field.comment.length > 0 ? `${field.comment.map((c) => ` /** ${c} */`).join("\n")}\n` : ""} ${field.fieldName}: ${field.validation ?? "\"unknown\""},`;
31
+ return `${comment ? makeCommentBlock(field.comment, 2) : ""} ${field.fieldName}: ${field.validation ?? "\"unknown\""},`;
18
32
  }).join("\n");
19
33
  }
34
+ /**
35
+ * Generate ArkType enum expression using union string syntax
36
+ * @param values - The enum values to generate expression for
37
+ */
20
38
  function makeArktypeEnumExpression(values) {
21
39
  return `"${values.map((v) => `'${v}'`).join(" | ")}"`;
22
40
  }
41
+ /** Mapping from Prisma scalar types to ArkType type expressions */
23
42
  const PRISMA_TO_ARKTYPE = {
24
43
  String: "\"string\"",
25
44
  Int: "\"number\"",
@@ -31,15 +50,33 @@ const PRISMA_TO_ARKTYPE = {
31
50
  Json: "\"unknown\"",
32
51
  Bytes: "\"unknown\""
33
52
  };
34
- function makeArktypeSchemas(modelFields, comment) {
35
- return schemaFromFields(modelFields, comment, makeArktypeSchema, makeArktypeProperties);
53
+ /**
54
+ * Generate ArkType type() schema from model fields
55
+ * @param modelFields - The fields of the model
56
+ * @param comment - Whether to include JSDoc comments in the generated code
57
+ */
58
+ function makeArktypeSchemas(modelFields, comment, objectType) {
59
+ return schemaFromFields(modelFields, comment, makeArktypeSchema, makeArktypeProperties, objectType);
36
60
  }
61
+ /**
62
+ * Generate ArkType relation schema definition
63
+ * @param model - The model to generate relations for
64
+ * @param relProps - The relation properties
65
+ * @param options - Options for type export generation
66
+ */
37
67
  function makeArktypeRelations(model, relProps, options) {
38
68
  if (relProps.length === 0) return null;
39
69
  const fields = `${`...${model.name}Schema.t,`}${relProps.map((r) => `${r.key}:${r.isMany ? `${r.targetModel}Schema.array()` : `${r.targetModel}Schema`},`).join("")}`;
40
70
  const typeLine = options?.includeType ? `\n\nexport type ${model.name}Relations = typeof ${model.name}RelationsSchema.infer` : "";
41
71
  return `export const ${model.name}RelationsSchema = type({${fields}})${typeLine}`;
42
72
  }
73
+ /**
74
+ * Generate ArkType validation code from Prisma models
75
+ * @param models - The Prisma data models
76
+ * @param type - Whether to include type inference
77
+ * @param comment - Whether to include JSDoc comments in the generated code
78
+ * @param enums - The Prisma enum definitions
79
+ */
43
80
  function arktype(models, type, comment, enums) {
44
81
  return validationSchemas(models, type, comment, {
45
82
  importStatement: `import { type } from 'arktype'`,
@@ -57,6 +94,10 @@ function arktype(models, type, comment, enums) {
57
94
  //#endregion
58
95
  //#region src/generator/arktype/index.ts
59
96
  const { generatorHandler } = pkg;
97
+ /**
98
+ * Prisma generator entry point for ArkType schema generation
99
+ * @param options - The Prisma generator options
100
+ */
60
101
  async function main(options) {
61
102
  if (!(options.generator.isCustomOutput && options.generator.output?.value)) throw new Error("output is required for Hekireki-ArkType. Please specify output in your generator config.");
62
103
  const output = options.generator.output.value;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as mkdir, f as writeFile, n as getString, p as writeFileBinary, u as stripAnnotations } from "../../utils-0tE5jzYR.js";
2
+ import { f as stripAnnotations, h as writeFileBinary, m as writeFile, p as mkdir, r as getString } from "../../utils-3ot3YB3D.js";
3
3
  import path from "node:path";
4
4
  import pkg from "@prisma/generator-helper";
5
5
  import { Resvg } from "@resvg/resvg-js";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { d as mkdir, f as writeFile, o as makeSnakeCase } from "../../utils-0tE5jzYR.js";
3
+ import { c as makeSnakeCase, m as writeFile, p as mkdir } from "../../utils-3ot3YB3D.js";
4
4
  import path from "node:path";
5
5
  import pkg from "@prisma/generator-helper";
6
6
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as mkdir, f as writeFile, o as makeSnakeCase } from "../../utils-0tE5jzYR.js";
2
+ import { c as makeSnakeCase, m as writeFile, p as mkdir } from "../../utils-3ot3YB3D.js";
3
3
  import { join } from "node:path";
4
4
  import pkg from "@prisma/generator-helper";
5
5
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { c as parseDocumentWithoutAnnotations, d as mkdir, f as writeFile, l as schemaFromFields, s as makeValidationExtractor, t as getBool } from "../../utils-0tE5jzYR.js";
4
- import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-DHllEbMR.js";
3
+ import { d as schemaFromFields, l as makeValidationExtractor, m as writeFile, n as getBool, o as makeCommentBlock, p as mkdir, u as parseDocumentWithoutAnnotations } from "../../utils-3ot3YB3D.js";
4
+ import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-o4IvnEUh.js";
5
5
  import path from "node:path";
6
6
  import pkg from "@prisma/generator-helper";
7
7
 
@@ -14,7 +14,7 @@ function makeEffectSchema(modelName, fields) {
14
14
  }
15
15
  function makeEffectProperties(fields, comment) {
16
16
  return fields.map((field) => {
17
- return `${comment && field.comment.length > 0 ? ` /**\n${field.comment.map((c) => ` * ${c}`).join("\n")}\n */\n` : ""} ${field.fieldName}: ${field.validation ?? "Schema.Unknown"},`;
17
+ return `${comment ? makeCommentBlock(field.comment, 2) : ""} ${field.fieldName}: ${field.validation ?? "Schema.Unknown"},`;
18
18
  }).join("\n");
19
19
  }
20
20
  function makeEffectEnumExpression(values) {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as mkdir, f as writeFile, n as getString, o as makeSnakeCase } from "../../utils-0tE5jzYR.js";
2
+ import { c as makeSnakeCase, m as writeFile, p as mkdir, r as getString } from "../../utils-3ot3YB3D.js";
3
3
  import path, { dirname } from "node:path";
4
4
  import pkg from "@prisma/generator-helper";
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as mkdir, f as writeFile, u as stripAnnotations } from "../../utils-0tE5jzYR.js";
2
+ import { f as stripAnnotations, m as writeFile, p as mkdir } from "../../utils-3ot3YB3D.js";
3
3
  import path from "node:path";
4
4
  import pkg from "@prisma/generator-helper";
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as mkdir, f as writeFile, n as getString, o as makeSnakeCase } from "../../utils-0tE5jzYR.js";
2
+ import { c as makeSnakeCase, m as writeFile, p as mkdir, r as getString } from "../../utils-3ot3YB3D.js";
3
3
  import { join } from "node:path";
4
4
  import pkg from "@prisma/generator-helper";
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as mkdir, f as writeFile, o as makeSnakeCase } from "../../utils-0tE5jzYR.js";
2
+ import { c as makeSnakeCase, m as writeFile, p as mkdir } from "../../utils-3ot3YB3D.js";
3
3
  import path, { dirname } from "node:path";
4
4
  import pkg from "@prisma/generator-helper";
5
5
 
@@ -1,6 +1,10 @@
1
1
  import { GeneratorOptions } from "@prisma/generator-helper";
2
2
 
3
3
  //#region src/generator/typebox/index.d.ts
4
+ /**
5
+ * Prisma generator entry point for TypeBox schema generation
6
+ * @param options - The Prisma generator options
7
+ */
4
8
  declare function main(options: GeneratorOptions): Promise<void>;
5
9
  //#endregion
6
10
  export { main };
@@ -1,28 +1,48 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { c as parseDocumentWithoutAnnotations, d as mkdir, f as writeFile, l as schemaFromFields, s as makeValidationExtractor, t as getBool } from "../../utils-0tE5jzYR.js";
4
- import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-DHllEbMR.js";
3
+ import { d as schemaFromFields, l as makeValidationExtractor, m as writeFile, n as getBool, o as makeCommentBlock, p as mkdir, u as parseDocumentWithoutAnnotations } from "../../utils-3ot3YB3D.js";
4
+ import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-o4IvnEUh.js";
5
5
  import path from "node:path";
6
6
  import pkg from "@prisma/generator-helper";
7
7
 
8
8
  //#region src/helper/typebox.ts
9
+ /**
10
+ * Generate TypeBox type inference using Static
11
+ * @param modelName - The model name to generate type inference for
12
+ */
9
13
  function makeTypeBoxInfer(modelName) {
10
14
  return `export type ${modelName} = Static<typeof ${modelName}Schema>`;
11
15
  }
12
- function makeTypeBoxSchema(modelName, fields) {
13
- return `export const ${modelName}Schema = Type.Object({\n${fields}\n})`;
16
+ /**
17
+ * Generate TypeBox Type.Object schema definition
18
+ * @param modelName - The model name for the schema
19
+ * @param fields - The formatted field definitions string
20
+ */
21
+ function makeTypeBoxSchema(modelName, fields, objectType) {
22
+ const obj = `Type.Object({\n${fields}\n})`;
23
+ return objectType === "strict" ? `export const ${modelName}Schema = Type.Strict(${obj})` : `export const ${modelName}Schema = ${obj}`;
14
24
  }
25
+ /**
26
+ * Generate TypeBox property definitions with optional wrapping
27
+ * @param fields - The fields to generate properties for
28
+ * @param comment - Whether to include JSDoc comments in the generated code
29
+ */
15
30
  function makeTypeBoxProperties(fields, comment) {
16
31
  return fields.map((field) => {
17
- const commentLines = comment && field.comment.length > 0 ? `${field.comment.map((c) => ` /** ${c} */`).join("\n")}\n` : "";
32
+ const commentBlock = comment ? makeCommentBlock(field.comment, 2) : "";
18
33
  const expr = field.validation ?? "Type.Unknown()";
19
34
  const wrapped = field.isRequired ? expr : `Type.Optional(${expr})`;
20
- return `${commentLines} ${field.fieldName}: ${wrapped},`;
35
+ return `${commentBlock} ${field.fieldName}: ${wrapped},`;
21
36
  }).join("\n");
22
37
  }
38
+ /**
39
+ * Generate TypeBox enum expression using Type.Union with Type.Literal
40
+ * @param values - The enum values to generate expression for
41
+ */
23
42
  function makeTypeBoxEnumExpression(values) {
24
43
  return `Type.Union([${values.map((v) => `Type.Literal('${v}')`).join(", ")}])`;
25
44
  }
45
+ /** Mapping from Prisma scalar types to TypeBox type expressions */
26
46
  const PRISMA_TO_TYPEBOX = {
27
47
  String: "Type.String()",
28
48
  Int: "Type.Integer()",
@@ -34,9 +54,20 @@ const PRISMA_TO_TYPEBOX = {
34
54
  Json: "Type.Unknown()",
35
55
  Bytes: "Type.Any()"
36
56
  };
37
- function makeTypeBoxSchemas(modelFields, comment) {
38
- return schemaFromFields(modelFields, comment, makeTypeBoxSchema, makeTypeBoxProperties);
57
+ /**
58
+ * Generate TypeBox Type.Object schema from model fields
59
+ * @param modelFields - The fields of the model
60
+ * @param comment - Whether to include JSDoc comments in the generated code
61
+ */
62
+ function makeTypeBoxSchemas(modelFields, comment, objectType) {
63
+ return schemaFromFields(modelFields, comment, makeTypeBoxSchema, makeTypeBoxProperties, objectType);
39
64
  }
65
+ /**
66
+ * Generate TypeBox relation schema definition
67
+ * @param model - The model to generate relations for
68
+ * @param relProps - The relation properties
69
+ * @param options - Options for type export generation
70
+ */
40
71
  function makeTypeBoxRelations(model, relProps, options) {
41
72
  if (relProps.length === 0) return null;
42
73
  const base = ` ...${model.name}Schema.properties,`;
@@ -44,6 +75,13 @@ function makeTypeBoxRelations(model, relProps, options) {
44
75
  const typeLine = options?.includeType ? `\n\nexport type ${model.name}Relations = Static<typeof ${model.name}RelationsSchema>` : "";
45
76
  return `export const ${model.name}RelationsSchema = Type.Object({\n${base}\n${rels}\n})${typeLine}`;
46
77
  }
78
+ /**
79
+ * Generate TypeBox validation code from Prisma models
80
+ * @param models - The Prisma data models
81
+ * @param type - Whether to include type inference using Static
82
+ * @param comment - Whether to include JSDoc comments in the generated code
83
+ * @param enums - The Prisma enum definitions
84
+ */
47
85
  function typebox(models, type, comment, enums) {
48
86
  return validationSchemas(models, type, comment, {
49
87
  importStatement: type ? `import { type Static, Type } from '@sinclair/typebox'` : `import { Type } from '@sinclair/typebox'`,
@@ -61,6 +99,10 @@ function typebox(models, type, comment, enums) {
61
99
  //#endregion
62
100
  //#region src/generator/typebox/index.ts
63
101
  const { generatorHandler } = pkg;
102
+ /**
103
+ * Prisma generator entry point for TypeBox schema generation
104
+ * @param options - The Prisma generator options
105
+ */
64
106
  async function main(options) {
65
107
  if (!(options.generator.isCustomOutput && options.generator.output?.value)) throw new Error("output is required for Hekireki-TypeBox. Please specify output in your generator config.");
66
108
  const output = options.generator.output.value;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { a as makePropertiesGenerator, c as parseDocumentWithoutAnnotations, d as mkdir, f as writeFile, l as schemaFromFields, s as makeValidationExtractor, t as getBool } from "../../utils-0tE5jzYR.js";
4
- import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-DHllEbMR.js";
3
+ import { d as schemaFromFields, l as makeValidationExtractor, m as writeFile, n as getBool, p as mkdir, s as makePropertiesGenerator, u as parseDocumentWithoutAnnotations } from "../../utils-3ot3YB3D.js";
4
+ import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-o4IvnEUh.js";
5
5
  import path from "node:path";
6
6
  import pkg from "@prisma/generator-helper";
7
7
 
@@ -9,8 +9,8 @@ import pkg from "@prisma/generator-helper";
9
9
  function makeValibotInfer(modelName) {
10
10
  return `export type ${modelName} = v.InferOutput<typeof ${modelName}Schema>`;
11
11
  }
12
- function makeValibotSchema(modelName, fields) {
13
- return `export const ${modelName}Schema = v.object({\n${fields}\n})`;
12
+ function makeValibotSchema(modelName, fields, objectType) {
13
+ return `export const ${modelName}Schema = v.${objectType === "strict" ? "strictObject" : objectType === "loose" ? "looseObject" : "object"}({\n${fields}\n})`;
14
14
  }
15
15
  function makeValibotEnumExpression(values) {
16
16
  return `picklist([${values.map((v) => `'${v}'`).join(", ")}])`;
@@ -26,8 +26,8 @@ const PRISMA_TO_VALIBOT = {
26
26
  Json: "unknown()",
27
27
  Bytes: "any()"
28
28
  };
29
- function makeValibotSchemas(modelFields, comment) {
30
- return schemaFromFields(modelFields, comment, makeValibotSchema, makePropertiesGenerator("v", (expr, isRequired) => isRequired ? expr : `v.exactOptional(${expr})`));
29
+ function makeValibotSchemas(modelFields, comment, objectType) {
30
+ return schemaFromFields(modelFields, comment, makeValibotSchema, makePropertiesGenerator("v", (expr, isRequired) => isRequired ? expr : `v.exactOptional(${expr})`), objectType);
31
31
  }
32
32
  function makeValibotRelations(model, relProps, options) {
33
33
  if (relProps.length === 0) return null;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as fmt } from "../../format-DwiYldCm.js";
3
- import { a as makePropertiesGenerator, c as parseDocumentWithoutAnnotations, d as mkdir, f as writeFile, l as schemaFromFields, n as getString, s as makeValidationExtractor, t as getBool } from "../../utils-0tE5jzYR.js";
4
- import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-DHllEbMR.js";
3
+ import { d as schemaFromFields, l as makeValidationExtractor, m as writeFile, n as getBool, p as mkdir, r as getString, s as makePropertiesGenerator, u as parseDocumentWithoutAnnotations } from "../../utils-3ot3YB3D.js";
4
+ import { n as validationSchemas, t as makeRelationsOnly } from "../../prisma-o4IvnEUh.js";
5
5
  import path from "node:path";
6
6
  import pkg from "@prisma/generator-helper";
7
7
 
@@ -9,8 +9,8 @@ import pkg from "@prisma/generator-helper";
9
9
  function makeZodInfer(modelName) {
10
10
  return `export type ${modelName} = z.infer<typeof ${modelName}Schema>`;
11
11
  }
12
- function makeZodSchema(modelName, fields) {
13
- return `export const ${modelName}Schema = z.object({\n${fields}\n})`;
12
+ function makeZodSchema(modelName, fields, objectType) {
13
+ return `export const ${modelName}Schema = z.${objectType === "strict" ? "strictObject" : objectType === "loose" ? "looseObject" : "object"}({\n${fields}\n})`;
14
14
  }
15
15
  function makeZodEnumExpression(values) {
16
16
  return `enum([${values.map((v) => `'${v}'`).join(", ")}])`;
@@ -26,8 +26,8 @@ const PRISMA_TO_ZOD = {
26
26
  Json: "unknown()",
27
27
  Bytes: "any()"
28
28
  };
29
- function makeZodSchemas(modelFields, comment) {
30
- return schemaFromFields(modelFields, comment, makeZodSchema, makePropertiesGenerator("z", (expr, isRequired) => isRequired ? expr : `${expr}.exactOptional()`));
29
+ function makeZodSchemas(modelFields, comment, objectType) {
30
+ return schemaFromFields(modelFields, comment, makeZodSchema, makePropertiesGenerator("z", (expr, isRequired) => isRequired ? expr : `${expr}.exactOptional()`), objectType);
31
31
  }
32
32
  function makeZodRelations(model, relProps, options) {
33
33
  if (relProps.length === 0) return null;
@@ -1,4 +1,4 @@
1
- import { i as isFields, r as groupByModel } from "./utils-0tE5jzYR.js";
1
+ import { a as isFields, i as groupByModel, t as extractObjectType } from "./utils-3ot3YB3D.js";
2
2
 
3
3
  //#region src/helper/prisma.ts
4
4
  function collectRelationProps(models) {
@@ -61,10 +61,13 @@ function validationSchemas(models, type, comment, config) {
61
61
  fieldName: f.name
62
62
  })));
63
63
  if (config.onWarning) for (const { modelName, fieldName } of missing) config.onWarning(`Warning: Field "${modelName}.${fieldName}" has no ${config.annotationPrefix} annotation and will be omitted from the schema`);
64
- const schemas = Object.values(groupByModel(isFields(modelFields))).map((fields) => ({
65
- schema: config.schemas(fields, comment),
66
- inferType: type ? config.inferType(fields[0].modelName) : ""
67
- })).flatMap(({ schema, inferType }) => [schema, inferType].filter(Boolean)).join("\n\n");
64
+ const schemas = Object.values(groupByModel(isFields(modelFields))).map((fields) => {
65
+ const objectType = extractObjectType(fields[0].documentation, config.annotationPrefix);
66
+ return {
67
+ schema: config.schemas(fields, comment, objectType),
68
+ inferType: type ? config.inferType(fields[0].modelName) : ""
69
+ };
70
+ }).flatMap(({ schema, inferType }) => [schema, inferType].filter(Boolean)).join("\n\n");
68
71
  return config.importStatement ? [
69
72
  config.importStatement,
70
73
  "",
@@ -56,11 +56,21 @@ function stripAnnotations(doc) {
56
56
  }).join("\n").trim();
57
57
  return result.length > 0 ? result : void 0;
58
58
  }
59
+ /**
60
+ * Generate a JSDoc comment block from comment lines
61
+ * @param lines - The comment lines to include
62
+ * @param indent - The indentation level in spaces
63
+ */
64
+ function makeCommentBlock(lines, indent) {
65
+ if (lines.length === 0) return "";
66
+ const prefix = " ".repeat(indent);
67
+ return `${prefix}/**\n${lines.map((c) => `${prefix} * ${c}`).join("\n")}\n${prefix} */\n`;
68
+ }
59
69
  function makePropertiesGenerator(libraryPrefix, wrapCardinality) {
60
70
  return function makeProperties(modelFields, includeComments) {
61
71
  return modelFields.filter((field) => field.validation).map((field) => {
62
72
  const cleanLines = field.comment.filter((line) => !(line.includes("@relation") || line.includes("@z") || line.includes("@v") || line.includes("@a") || line.includes("@e") || line.includes("@t") || line.includes("@j")));
63
- const docComment = includeComments && cleanLines.length > 0 ? ` /**\n${cleanLines.map((line) => ` * ${line}`).join("\n")}\n */\n` : "";
73
+ const docComment = includeComments ? makeCommentBlock(cleanLines, 2) : "";
64
74
  const base = `${libraryPrefix}.${field.validation}`;
65
75
  const wrapped = wrapCardinality ? wrapCardinality(base, field.isRequired) : base;
66
76
  return `${docComment} ${field.fieldName}: ${wrapped}`;
@@ -74,10 +84,22 @@ function groupByModel(validFields) {
74
84
  function isFields(modelFields) {
75
85
  return modelFields.flat().filter((field) => field.validation !== null);
76
86
  }
77
- function schemaFromFields(modelFields, comment, schemaBuilder, propertiesGenerator) {
87
+ /**
88
+ * Extract object type (strict/loose) from model documentation.
89
+ */
90
+ function extractObjectType(documentation, prefix) {
91
+ if (!documentation) return void 0;
92
+ const lines = documentation.split("\n").map((l) => l.trim());
93
+ const prefixWithoutAt = prefix.slice(1);
94
+ const match = lines.find((line) => line.includes(`${prefixWithoutAt}strictObject`) || line.includes(`${prefixWithoutAt}looseObject`));
95
+ if (!match) return void 0;
96
+ if (match.includes("strictObject")) return "strict";
97
+ if (match.includes("looseObject")) return "loose";
98
+ }
99
+ function schemaFromFields(modelFields, comment, schemaBuilder, propertiesGenerator, objectType) {
78
100
  const modelName = modelFields[0].modelName;
79
- return schemaBuilder(modelName, propertiesGenerator(modelFields, comment));
101
+ return schemaBuilder(modelName, propertiesGenerator(modelFields, comment), objectType);
80
102
  }
81
103
 
82
104
  //#endregion
83
- export { makePropertiesGenerator as a, parseDocumentWithoutAnnotations as c, mkdir as d, writeFile as f, isFields as i, schemaFromFields as l, getString as n, makeSnakeCase as o, writeFileBinary as p, groupByModel as r, makeValidationExtractor as s, getBool as t, stripAnnotations as u };
105
+ export { isFields as a, makeSnakeCase as c, schemaFromFields as d, stripAnnotations as f, writeFileBinary as h, groupByModel as i, makeValidationExtractor as l, writeFile as m, getBool as n, makeCommentBlock as o, mkdir as p, getString as r, makePropertiesGenerator as s, extractObjectType as t, parseDocumentWithoutAnnotations as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hekireki",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Hekireki is a tool that generates validation schemas for Zod, Valibot, ArkType, and Effect Schema, as well as ER diagrams and DBML, from Prisma schemas annotated with comments.",
5
5
  "keywords": [
6
6
  "ajv",