hekireki 0.3.0 → 0.4.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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # Hekireki
2
2
 
3
+ ![img](https://raw.githubusercontent.com/nakita628/hekireki/refs/heads/main/assets/img/hekireki.png)
4
+
3
5
  **[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
6
 
5
7
  ## Features
@@ -38,12 +40,14 @@ generator Hekireki-Zod {
38
40
  provider = "hekireki-zod"
39
41
  type = true
40
42
  comment = true
43
+ relation = true
41
44
  }
42
45
 
43
46
  generator Hekireki-Valibot {
44
47
  provider = "hekireki-valibot"
45
48
  type = true
46
49
  comment = true
50
+ relation = true
47
51
  }
48
52
 
49
53
  generator Hekireki-Ecto {
@@ -128,6 +132,20 @@ export const PostSchema = z.object({
128
132
  })
129
133
 
130
134
  export type Post = z.infer<typeof PostSchema>
135
+
136
+ export const UserRelationsSchema = z.object({
137
+ ...UserSchema.shape,
138
+ posts: z.array(PostSchema),
139
+ })
140
+
141
+ export type UserRelations = z.infer<typeof UserRelationsSchema>
142
+
143
+ export const PostRelationsSchema = z.object({
144
+ ...PostSchema.shape,
145
+ user: UserSchema,
146
+ })
147
+
148
+ export type PostRelations = z.infer<typeof PostRelationsSchema>
131
149
  ```
132
150
 
133
151
  ## Valibot
@@ -167,6 +185,14 @@ export const PostSchema = v.object({
167
185
  })
168
186
 
169
187
  export type Post = v.InferInput<typeof PostSchema>
188
+
189
+ export const UserRelationsSchema = v.object({ ...UserSchema.entries, posts: v.array(PostSchema) })
190
+
191
+ export type UserRelations = v.InferInput<typeof UserRelationsSchema>
192
+
193
+ export const PostRelationsSchema = v.object({ ...PostSchema.entries, user: UserSchema })
194
+
195
+ export type PostRelations = v.InferInput<typeof PostRelationsSchema>
170
196
  ```
171
197
 
172
198
  ## Mermaid
@@ -237,6 +263,7 @@ end
237
263
  | `type` | `boolean` | `false` | Generate TypeScript types |
238
264
  | `comment` | `boolean` | `false` | Include schema documentation |
239
265
  | `zod` | `string` | `'v4'` | Zod import version (`'mini'`, `'@hono/zod-openapi'`, or default `'v4'`) |
266
+ | `relation` | `boolean` | `false` | Generate relation schemas |
240
267
 
241
268
  ### Valibot Generator Options
242
269
 
@@ -246,6 +273,7 @@ end
246
273
  | `file` | `string` | `index.ts` | File Name |
247
274
  | `type` | `boolean` | `false` | Generate TypeScript types |
248
275
  | `comment` | `boolean` | `false` | Include schema documentation |
276
+ | `relation` | `boolean` | `false` | Generate relation schemas |
249
277
 
250
278
  ### Mermaid ER Generator Options
251
279
 
@@ -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.0",
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",