hekireki 0.3.0 → 0.4.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.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Hekireki
2
2
 
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/nakita628/hekireki/refs/heads/main/assets/img/hekireki.png"/>
5
+ </p>
6
+
3
7
  **[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.
4
8
 
5
9
  ## Features
@@ -38,12 +42,14 @@ generator Hekireki-Zod {
38
42
  provider = "hekireki-zod"
39
43
  type = true
40
44
  comment = true
45
+ relation = true
41
46
  }
42
47
 
43
48
  generator Hekireki-Valibot {
44
49
  provider = "hekireki-valibot"
45
50
  type = true
46
51
  comment = true
52
+ relation = true
47
53
  }
48
54
 
49
55
  generator Hekireki-Ecto {
@@ -128,6 +134,20 @@ export const PostSchema = z.object({
128
134
  })
129
135
 
130
136
  export type Post = z.infer<typeof PostSchema>
137
+
138
+ export const UserRelationsSchema = z.object({
139
+ ...UserSchema.shape,
140
+ posts: z.array(PostSchema),
141
+ })
142
+
143
+ export type UserRelations = z.infer<typeof UserRelationsSchema>
144
+
145
+ export const PostRelationsSchema = z.object({
146
+ ...PostSchema.shape,
147
+ user: UserSchema,
148
+ })
149
+
150
+ export type PostRelations = z.infer<typeof PostRelationsSchema>
131
151
  ```
132
152
 
133
153
  ## Valibot
@@ -167,6 +187,14 @@ export const PostSchema = v.object({
167
187
  })
168
188
 
169
189
  export type Post = v.InferInput<typeof PostSchema>
190
+
191
+ export const UserRelationsSchema = v.object({ ...UserSchema.entries, posts: v.array(PostSchema) })
192
+
193
+ export type UserRelations = v.InferInput<typeof UserRelationsSchema>
194
+
195
+ export const PostRelationsSchema = v.object({ ...PostSchema.entries, user: UserSchema })
196
+
197
+ export type PostRelations = v.InferInput<typeof PostRelationsSchema>
170
198
  ```
171
199
 
172
200
  ## Mermaid
@@ -237,6 +265,7 @@ end
237
265
  | `type` | `boolean` | `false` | Generate TypeScript types |
238
266
  | `comment` | `boolean` | `false` | Include schema documentation |
239
267
  | `zod` | `string` | `'v4'` | Zod import version (`'mini'`, `'@hono/zod-openapi'`, or default `'v4'`) |
268
+ | `relation` | `boolean` | `false` | Generate relation schemas |
240
269
 
241
270
  ### Valibot Generator Options
242
271
 
@@ -246,6 +275,7 @@ end
246
275
  | `file` | `string` | `index.ts` | File Name |
247
276
  | `type` | `boolean` | `false` | Generate TypeScript types |
248
277
  | `comment` | `boolean` | `false` | Include schema documentation |
278
+ | `relation` | `boolean` | `false` | Generate relation schemas |
249
279
 
250
280
  ### Mermaid ER Generator Options
251
281
 
@@ -7,8 +7,12 @@ export async function main(options) {
7
7
  const content = erContent(options.dmmf.datamodel.models);
8
8
  const output = options.generator.output?.value ?? './mermaid-er';
9
9
  const file = options.generator.config?.file ?? 'ER.md';
10
- await fsp.mkdir(output, { recursive: true });
11
- await fsp.writeFile(`${output}/${file}`, content.join('\n'), { encoding: 'utf-8' });
10
+ // Handle case where output is a file path (contains extension)
11
+ const isOutputFile = output.includes('.');
12
+ const outputDir = isOutputFile ? '.' : output;
13
+ const outputFile = isOutputFile ? output : `${output}/${file}`;
14
+ await fsp.mkdir(outputDir, { recursive: true });
15
+ await fsp.writeFile(outputFile, content.join('\n'), { encoding: 'utf-8' });
12
16
  }
13
17
  // prisma generator handler
14
18
  generatorHandler({
@@ -1,3 +1,12 @@
1
+ import type { DMMF } from '@prisma/generator-helper';
2
+ export declare function buildValibotModel(model: DMMF.Model): string;
3
+ export declare function buildValibotRelations(model: DMMF.Model, relProps: readonly {
4
+ key: string;
5
+ targetModel: string;
6
+ isMany: boolean;
7
+ }[], options?: Readonly<{
8
+ includeType?: boolean;
9
+ }>): string | null;
1
10
  /**
2
11
  * Generate Valibot schema
3
12
  * @param modelName - The name of the model
@@ -1,3 +1,45 @@
1
+ import { extractAnno, jsdoc } from '../utils/index.js';
2
+ const vPrim = (f) => {
3
+ const anno = extractAnno(f.documentation ?? '', '@v.');
4
+ return wrapV(`v.${anno}`, f);
5
+ };
6
+ const wrapV = (expr, f) => {
7
+ const card = f.isList ? `v.array(${expr})` : expr;
8
+ return f.isRequired ? card : `v.optional(${card})`;
9
+ };
10
+ // jsdoc moved to utils
11
+ export function buildValibotModel(model) {
12
+ const fields = model.fields
13
+ .filter((f) => f.kind !== 'object')
14
+ .map((f) => `${jsdoc(f.documentation)} ${f.name}: ${vPrim(f)},`)
15
+ .join('\n');
16
+ const modelAnno = extractAnno(model.documentation ?? '', '@v.');
17
+ const objectDef = modelAnno === 'strictObject'
18
+ ? `v.strictObject({\n${fields}\n})`
19
+ : modelAnno === 'looseObject'
20
+ ? `v.looseObject({\n${fields}\n})`
21
+ : `v.object({\n${fields}\n})`;
22
+ return `export const ${model.name}Schema = ${objectDef}\n\nexport type ${model.name} = v.InferInput<typeof ${model.name}Schema>`;
23
+ }
24
+ export function buildValibotRelations(model, relProps, options) {
25
+ if (relProps.length === 0)
26
+ return null;
27
+ const base = `...${model.name}Schema.entries`;
28
+ const rels = relProps
29
+ .map((r) => `${r.key}: ${r.isMany ? `v.array(${r.targetModel}Schema)` : `${r.targetModel}Schema`}`)
30
+ .join(', ');
31
+ const modelAnno = extractAnno(model.documentation ?? '', '@v.');
32
+ const objectDef = modelAnno === 'strictObject'
33
+ ? `v.strictObject({ ${base}, ${rels} })`
34
+ : modelAnno === 'looseObject'
35
+ ? `v.looseObject({ ${base}, ${rels} })`
36
+ : `v.object({ ${base}, ${rels} })`;
37
+ const typeLine = options?.includeType
38
+ ? `\n\nexport type ${model.name}Relations = v.InferInput<typeof ${model.name}RelationsSchema>`
39
+ : '';
40
+ return `export const ${model.name}RelationsSchema = ${objectDef}${typeLine}`;
41
+ }
42
+ // extractAnno provided by utils
1
43
  /**
2
44
  * Generate Valibot schema
3
45
  * @param modelName - The name of the model
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import type { GeneratorOptions } from '@prisma/generator-helper';
3
- export declare function main(options: GeneratorOptions): Promise<void>;
3
+ export declare const onGenerate: (options: GeneratorOptions) => Promise<void>;
@@ -1,17 +1,47 @@
1
1
  #!/usr/bin/env node
2
2
  import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
3
4
  import pkg from '@prisma/generator-helper';
4
5
  import { fmt } from '../../shared/format/index.js';
6
+ import { collectRelationProps } from '../../shared/helper/relations.js';
7
+ import { buildValibotRelations } from './generator/schema.js';
5
8
  import { valibot } from './generator/valibot.js';
6
9
  const { generatorHandler } = pkg;
7
- export async function main(options) {
8
- const output = options.generator.output?.value ?? './valibot';
9
- const file = options.generator.config?.file ?? 'index.ts';
10
- const content = valibot(options.dmmf.datamodel.models, options.generator.config?.type === 'true', options.generator.config?.comment === 'true');
11
- const code = await fmt(content);
12
- await fsp.mkdir(output, { recursive: true });
13
- await fsp.writeFile(`${output}/${file}`, code, { encoding: 'utf-8' });
14
- }
10
+ const buildRelationsOnly = (dmmf, includeType) => {
11
+ const models = dmmf.datamodel.models;
12
+ const relIndex = collectRelationProps(models);
13
+ const relByModel = relIndex.reduce((acc, r) => {
14
+ if (!acc[r.model])
15
+ acc[r.model] = [];
16
+ acc[r.model].push(r);
17
+ return acc;
18
+ }, {});
19
+ return models
20
+ .map((model) => buildValibotRelations(model, (relByModel[model.name] ?? []).map(({ key, targetModel, isMany }) => ({
21
+ key,
22
+ targetModel,
23
+ isMany,
24
+ })), { includeType }))
25
+ .filter((code) => Boolean(code))
26
+ .join('\n\n');
27
+ };
28
+ const getString = (v, fallback) => typeof v === 'string' ? v : Array.isArray(v) ? (v[0] ?? fallback) : fallback;
29
+ const getBool = (v, fallback = false) => v === true || v === 'true' || (Array.isArray(v) && v[0] === 'true') ? true : fallback;
30
+ const emit = async (options, enableRelation) => {
31
+ const outDir = options.generator.output?.value ?? './valibot';
32
+ const file = getString(options.generator.config?.file, 'index.ts') ?? 'index.ts';
33
+ const base = valibot(options.dmmf.datamodel.models, getBool(options.generator.config?.type), getBool(options.generator.config?.comment));
34
+ const relations = enableRelation
35
+ ? buildRelationsOnly(options.dmmf, getBool(options.generator.config?.type))
36
+ : '';
37
+ const full = [base, relations].filter(Boolean).join('\n\n');
38
+ const code = await fmt(full);
39
+ await fsp.mkdir(outDir, { recursive: true });
40
+ await fsp.writeFile(path.join(outDir, file), code, 'utf8');
41
+ };
42
+ export const onGenerate = (options) => emit(options, options.generator.config?.relation === 'true' ||
43
+ (Array.isArray(options.generator.config?.relation) &&
44
+ options.generator.config?.relation[0] === 'true'));
15
45
  generatorHandler({
16
46
  onManifest() {
17
47
  return {
@@ -19,5 +49,5 @@ generatorHandler({
19
49
  prettyName: 'Hekireki-Valibot',
20
50
  };
21
51
  },
22
- onGenerate: main,
52
+ onGenerate,
23
53
  });
@@ -40,3 +40,5 @@ export declare function isValibotDocument(documentation?: string): string[];
40
40
  * @returns The Valibot expression without "@v." prefix, or null if not found.
41
41
  */
42
42
  export declare function isValibot(documentation?: string): string | null;
43
+ export declare const extractAnno: (doc: string, tag: "@z." | "@v.") => string | null;
44
+ export declare const jsdoc: (doc?: string) => string;
@@ -59,3 +59,17 @@ export function isValibot(documentation) {
59
59
  const match = documentation.match(/@v\.(.+?)(?:\n|$)/);
60
60
  return match ? match[1].trim() : null;
61
61
  }
62
+ export const extractAnno = (doc, tag) => {
63
+ const line = doc
64
+ .split('\n')
65
+ .map((s) => s.trim())
66
+ .find((l) => l.startsWith(tag));
67
+ return line ? line.slice(tag.length) : null;
68
+ };
69
+ export const jsdoc = (doc) => {
70
+ const lines = (doc ?? '')
71
+ .split('\n')
72
+ .map((s) => s.trim())
73
+ .filter((l) => l && !l.startsWith('@z.') && !l.startsWith('@v.'));
74
+ return lines.length ? `/**\n * ${lines.join('\n * ')}\n */\n` : '';
75
+ };
@@ -1,3 +1,12 @@
1
+ import type { DMMF } from '@prisma/generator-helper';
2
+ export declare function buildZodModel(model: DMMF.Model): Readonly<string>;
3
+ export declare function buildZodRelations(model: DMMF.Model, relProps: readonly {
4
+ key: string;
5
+ targetModel: string;
6
+ isMany: boolean;
7
+ }[], options?: Readonly<{
8
+ includeType?: boolean;
9
+ }>): string | null;
1
10
  /**
2
11
  * Generate Zod schema
3
12
  * @param modelName - The name of the model
@@ -1,3 +1,31 @@
1
+ import { buildZodObject, extractAnno, jsdoc, wrapCardinality } from '../utils/index.js';
2
+ const zPrim = (f) => {
3
+ const anno = extractAnno(f.documentation ?? '', '@z.');
4
+ return wrapCardinality(`z.${anno}`, f);
5
+ };
6
+ // moved to utils
7
+ export function buildZodModel(model) {
8
+ const fields = model.fields
9
+ .filter((f) => f.kind !== 'object')
10
+ .map((f) => `${jsdoc(f.documentation)} ${f.name}: ${zPrim(f)},`)
11
+ .join('\n');
12
+ const objectDef = buildZodObject(fields, model.documentation);
13
+ return `export const ${model.name}Schema = ${objectDef}\n\nexport type ${model.name} = z.infer<typeof ${model.name}Schema>`;
14
+ }
15
+ export function buildZodRelations(model, relProps, options) {
16
+ if (relProps.length === 0)
17
+ return null;
18
+ const base = `...${model.name}Schema.shape`;
19
+ const rels = relProps
20
+ .map((r) => `${r.key}: ${r.isMany ? `z.array(${r.targetModel}Schema)` : `${r.targetModel}Schema`}`)
21
+ .join(', ');
22
+ const objectDef = buildZodObject(`${base}, ${rels}`, model.documentation);
23
+ const typeLine = options?.includeType
24
+ ? `\n\nexport type ${model.name}Relations = z.infer<typeof ${model.name}RelationsSchema>`
25
+ : '';
26
+ return `export const ${model.name}RelationsSchema = ${objectDef}${typeLine}`;
27
+ }
28
+ // moved to utils
1
29
  /**
2
30
  * Generate Zod schema
3
31
  * @param modelName - The name of the model
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import type { GeneratorOptions } from '@prisma/generator-helper';
3
- export declare function main(options: GeneratorOptions): Promise<void>;
3
+ export declare const onGenerate: (options: GeneratorOptions) => Promise<void>;
@@ -1,18 +1,58 @@
1
1
  #!/usr/bin/env node
2
2
  import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
3
4
  import pkg from '@prisma/generator-helper';
4
5
  import { fmt } from '../../shared/format/index.js';
6
+ import { collectRelationProps } from '../../shared/helper/relations.js';
7
+ import { buildZodRelations } from './generator/schema.js';
5
8
  import { zod } from './generator/zod.js';
6
9
  const { generatorHandler } = pkg;
7
- export async function main(options) {
8
- const output = options.generator.output?.value ?? './zod';
9
- const file = options.generator.config?.file ?? 'index.ts';
10
- const zodVersion = options.generator.config?.zod ?? 'v4';
11
- const content = zod(options.dmmf.datamodel.models, options.generator.config?.type === 'true', options.generator.config?.comment === 'true', zodVersion);
12
- const code = await fmt(content);
13
- await fsp.mkdir(output, { recursive: true });
14
- await fsp.writeFile(`${output}/${file}`, code, { encoding: 'utf-8' });
15
- }
10
+ const buildRelationsOnly = (dmmf, includeType) => {
11
+ const models = dmmf.datamodel.models;
12
+ const relIndex = collectRelationProps(models);
13
+ const relByModel = relIndex.reduce((acc, r) => {
14
+ if (!acc[r.model])
15
+ acc[r.model] = [];
16
+ acc[r.model].push(r);
17
+ return acc;
18
+ }, {});
19
+ const blocks = models
20
+ .map((model) => {
21
+ const relProps = (relByModel[model.name] ?? []).map(({ key, targetModel, isMany }) => ({
22
+ key,
23
+ targetModel,
24
+ isMany,
25
+ }));
26
+ if (relProps.length === 0)
27
+ return '';
28
+ const schema = buildZodRelations(model, relProps);
29
+ const typeLine = includeType
30
+ ? `\n\nexport type ${model.name}Relations = z.infer<typeof ${model.name}RelationsSchema>`
31
+ : '';
32
+ return `${schema}${typeLine}`;
33
+ })
34
+ .filter(Boolean);
35
+ return blocks.join('\n\n');
36
+ };
37
+ const getString = (v, fallback) => typeof v === 'string' ? v : Array.isArray(v) ? (v[0] ?? fallback) : fallback;
38
+ const getBool = (v, fallback = false) => v === true || v === 'true' || (Array.isArray(v) && v[0] === 'true') ? true : fallback;
39
+ const emit = async (options, enableRelation) => {
40
+ const outDir = options.generator.output?.value ?? './zod';
41
+ const file = getString(options.generator.config?.file, 'index.ts') ?? 'index.ts';
42
+ const zodVersion = getString(options.generator.config?.zod, 'v4');
43
+ const base = zod(options.dmmf.datamodel.models, getBool(options.generator.config?.type), getBool(options.generator.config?.comment), zodVersion);
44
+ // Respect the `type` flag when generating relation schemas
45
+ const relations = enableRelation
46
+ ? buildRelationsOnly(options.dmmf, getBool(options.generator.config?.type))
47
+ : '';
48
+ const full = [base, relations].filter(Boolean).join('\n\n');
49
+ const code = await fmt(full);
50
+ await fsp.mkdir(outDir, { recursive: true });
51
+ await fsp.writeFile(path.join(outDir, file), code, 'utf8');
52
+ };
53
+ export const onGenerate = (options) => emit(options, options.generator.config?.relation === 'true' ||
54
+ (Array.isArray(options.generator.config?.relation) &&
55
+ options.generator.config?.relation[0] === 'true'));
16
56
  generatorHandler({
17
57
  onManifest() {
18
58
  return {
@@ -20,5 +60,5 @@ generatorHandler({
20
60
  prettyName: 'Hekireki-Zod',
21
61
  };
22
62
  },
23
- onGenerate: main,
63
+ onGenerate,
24
64
  });
@@ -1,3 +1,4 @@
1
+ import type { DMMF } from '@prisma/generator-helper';
1
2
  /**
2
3
  * Generates a `z.infer` type for the specified model.
3
4
  *
@@ -40,3 +41,6 @@ export declare function isZodDocument(documentation?: string): string[];
40
41
  * @returns The Zod validation string without the "@z." prefix, or null if not found.
41
42
  */
42
43
  export declare function isZod(documentation?: string): string | null;
44
+ export { extractAnno, jsdoc } from '../../../shared/utils/index.js';
45
+ export declare const wrapCardinality: (expr: string, field: DMMF.Field) => string;
46
+ export declare const buildZodObject: (inner: string, documentation?: string) => string;
@@ -1,3 +1,4 @@
1
+ import { extractAnno } from '../../../shared/utils/index.js';
1
2
  /**
2
3
  * Generates a `z.infer` type for the specified model.
3
4
  *
@@ -59,3 +60,16 @@ export function isZod(documentation) {
59
60
  const match = documentation.match(/@z\.(.+?)(?:\n|$)/);
60
61
  return match ? match[1].trim() : null;
61
62
  }
63
+ export { extractAnno, jsdoc } from '../../../shared/utils/index.js';
64
+ export const wrapCardinality = (expr, field) => {
65
+ const withList = field.isList ? `z.array(${expr})` : expr;
66
+ return field.isRequired ? withList : `${withList}.optional()`;
67
+ };
68
+ export const buildZodObject = (inner, documentation) => {
69
+ const anno = extractAnno(documentation ?? '', '@z.');
70
+ return anno === 'strictObject'
71
+ ? `z.strictObject({\n${inner}\n})`
72
+ : anno === 'looseObject'
73
+ ? `z.looseObject({\n${inner}\n})`
74
+ : `z.object({\n${inner}\n})`;
75
+ };
@@ -0,0 +1,11 @@
1
+ import type { DMMF, GeneratorOptions } from '@prisma/generator-helper';
2
+ export declare function schemaGenerator(outDir: Readonly<string>, dmmf: Readonly<GeneratorOptions['dmmf']>, importCode: string, buildSchema: (model: DMMF.Model) => Readonly<string>, buildRelations: (model: DMMF.Model, relProps: readonly {
3
+ key: string;
4
+ targetModel: string;
5
+ isMany: boolean;
6
+ }[]) => Readonly<string>, collectRelationProps: (models: readonly DMMF.Model[]) => Readonly<{
7
+ model: string;
8
+ key: string;
9
+ targetModel: string;
10
+ isMany: boolean;
11
+ }[]>): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import fsp from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ export async function schemaGenerator(outDir, dmmf, importCode, buildSchema, buildRelations, collectRelationProps) {
4
+ const models = dmmf.datamodel.models;
5
+ const relIndex = collectRelationProps(models);
6
+ const relByModel = Object.groupBy(relIndex, (r) => r.model);
7
+ const baseSchemas = models.map((m) => buildSchema(m)).join('\n\n');
8
+ const relationSchemas = models
9
+ .map((m) => {
10
+ const relProps = (relByModel[m.name] ?? []).map(({ key, targetModel, isMany }) => ({
11
+ key,
12
+ targetModel,
13
+ isMany,
14
+ }));
15
+ return buildRelations(m, relProps);
16
+ })
17
+ .filter(Boolean)
18
+ .join('\n\n');
19
+ const body = relationSchemas ? `${baseSchemas}\n\n${relationSchemas}` : baseSchemas;
20
+ const code = `${importCode}\n${body}\n`;
21
+ await fsp.mkdir(outDir, { recursive: true });
22
+ await fsp.writeFile(path.join(outDir, 'index.ts'), code, 'utf8');
23
+ }
@@ -0,0 +1,7 @@
1
+ import type { DMMF } from '@prisma/generator-helper';
2
+ export declare function collectRelationProps(models: readonly DMMF.Model[]): Readonly<{
3
+ model: string;
4
+ key: string;
5
+ targetModel: string;
6
+ isMany: boolean;
7
+ }[]>;
@@ -0,0 +1,5 @@
1
+ export function collectRelationProps(models) {
2
+ return models.flatMap((m) => m.fields
3
+ .filter((f) => f.kind === 'object')
4
+ .map((f) => ({ model: m.name, key: f.name, targetModel: f.type, isMany: f.isList })));
5
+ }
@@ -50,3 +50,12 @@ export declare function isFields(modelFields: {
50
50
  comment: string[];
51
51
  validation: string | null;
52
52
  }>[];
53
+ /**
54
+ * Extracts annotation content from documentation lines.
55
+ * Returns the substring after the tag (e.g. '@z.' or '@v.').
56
+ */
57
+ export declare const extractAnno: (doc: string, tag: "@z." | "@v.") => string | null;
58
+ /**
59
+ * Builds JSDoc from documentation, excluding annotation lines like '@z.' and '@v.'.
60
+ */
61
+ export declare const jsdoc: (doc?: string) => string;
@@ -40,3 +40,24 @@ export function groupByModel(validFields) {
40
40
  export function isFields(modelFields) {
41
41
  return modelFields.flat().filter((field) => field.validation !== null);
42
42
  }
43
+ /**
44
+ * Extracts annotation content from documentation lines.
45
+ * Returns the substring after the tag (e.g. '@z.' or '@v.').
46
+ */
47
+ export const extractAnno = (doc, tag) => {
48
+ const line = doc
49
+ .split('\n')
50
+ .map((s) => s.trim())
51
+ .find((l) => l.startsWith(tag));
52
+ return line ? line.slice(tag.length) : null;
53
+ };
54
+ /**
55
+ * Builds JSDoc from documentation, excluding annotation lines like '@z.' and '@v.'.
56
+ */
57
+ export const jsdoc = (doc) => {
58
+ const lines = (doc ?? '')
59
+ .split('\n')
60
+ .map((s) => s.trim())
61
+ .filter((l) => l && !l.startsWith('@z.') && !l.startsWith('@v.'));
62
+ return lines.length ? `/**\n * ${lines.join('\n * ')}\n */\n` : '';
63
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hekireki",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.4.1",
5
5
  "license": "MIT",
6
6
  "description": "Hekireki is a tool that generates validation schemas for Zod and Valibot, as well as ER diagrams, from Prisma schemas annotated with comments.",
7
7
  "keywords": [
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@prisma/client": "^6.10.1",
51
- "@types/node": "^22.15.34",
51
+ "@types/node": "^22.18.0",
52
52
  "@vitest/coverage-v8": "^3.2.4",
53
53
  "prisma": "^6.10.1",
54
54
  "tsx": "^4.20.3",