hekireki 0.2.7 → 0.2.8
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 +2 -2
- package/dist/generator/ecto/generator/ecto.js +17 -11
- package/dist/generator/mermaid-er/generator/er-content.d.ts +8 -2
- package/dist/generator/mermaid-er/generator/er-content.js +8 -6
- package/dist/generator/mermaid-er/generator/index.d.ts +1 -1
- package/dist/generator/mermaid-er/generator/index.js +1 -1
- package/dist/generator/mermaid-er/generator/model-fields.d.ts +4 -3
- package/dist/generator/mermaid-er/generator/model-fields.js +4 -3
- package/dist/generator/mermaid-er/generator/model-info.d.ts +6 -5
- package/dist/generator/mermaid-er/generator/model-info.js +4 -3
- package/dist/generator/mermaid-er/generator/relation-line.d.ts +11 -5
- package/dist/generator/mermaid-er/generator/relation-line.js +5 -4
- package/dist/generator/mermaid-er/helper/build-relation-line.d.ts +9 -0
- package/dist/generator/mermaid-er/{relationship → helper}/build-relation-line.js +9 -1
- package/dist/generator/mermaid-er/helper/extract-relations.d.ts +8 -0
- package/dist/generator/mermaid-er/{validator → helper}/extract-relations.js +5 -5
- package/dist/generator/mermaid-er/index.js +1 -1
- package/dist/generator/mermaid-er/utils/index.d.ts +34 -0
- package/dist/generator/mermaid-er/utils/index.js +48 -0
- package/dist/generator/valibot/generator/index.d.ts +0 -2
- package/dist/generator/valibot/generator/index.js +0 -2
- package/dist/generator/valibot/generator/schemas.js +1 -1
- package/dist/generator/valibot/generator/valibot.d.ts +2 -2
- package/dist/generator/valibot/generator/valibot.js +4 -12
- package/dist/generator/valibot/index.js +1 -1
- package/dist/generator/valibot/utils/index.d.ts +42 -0
- package/dist/generator/valibot/utils/index.js +61 -0
- package/dist/generator/zod/generator/index.d.ts +1 -3
- package/dist/generator/zod/generator/index.js +1 -3
- package/dist/generator/zod/generator/schemas.js +2 -1
- package/dist/generator/zod/generator/zod.d.ts +2 -2
- package/dist/generator/zod/generator/zod.js +8 -16
- package/dist/generator/zod/index.js +1 -1
- package/dist/generator/zod/utils/index.d.ts +42 -0
- package/dist/generator/zod/utils/index.js +61 -0
- package/dist/shared/utils/index.d.ts +52 -3
- package/dist/shared/utils/index.js +42 -3
- package/package.json +6 -6
- package/dist/generator/mermaid-er/relationship/build-relation-line.d.ts +0 -9
- package/dist/generator/mermaid-er/types.d.ts +0 -10
- package/dist/generator/mermaid-er/types.js +0 -1
- package/dist/generator/mermaid-er/validator/exclude-many-to-one-relations.d.ts +0 -7
- package/dist/generator/mermaid-er/validator/exclude-many-to-one-relations.js +0 -9
- package/dist/generator/mermaid-er/validator/extract-relations.d.ts +0 -7
- package/dist/generator/mermaid-er/validator/index.d.ts +0 -5
- package/dist/generator/mermaid-er/validator/index.js +0 -5
- package/dist/generator/mermaid-er/validator/is-relationship.d.ts +0 -7
- package/dist/generator/mermaid-er/validator/is-relationship.js +0 -8
- package/dist/generator/mermaid-er/validator/parse-relation.d.ts +0 -8
- package/dist/generator/mermaid-er/validator/parse-relation.js +0 -21
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +0 -6
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.js +0 -8
- package/dist/generator/valibot/generator/infer-input.d.ts +0 -7
- package/dist/generator/valibot/generator/infer-input.js +0 -9
- package/dist/generator/valibot/generator/properties.d.ts +0 -7
- package/dist/generator/valibot/generator/properties.js +0 -15
- package/dist/generator/valibot/validator/index.d.ts +0 -2
- package/dist/generator/valibot/validator/index.js +0 -2
- package/dist/generator/valibot/validator/is-valibot-document.d.ts +0 -1
- package/dist/generator/valibot/validator/is-valibot-document.js +0 -10
- package/dist/generator/valibot/validator/is-valibot.d.ts +0 -6
- package/dist/generator/valibot/validator/is-valibot.js +0 -11
- package/dist/generator/zod/generator/infer.d.ts +0 -7
- package/dist/generator/zod/generator/infer.js +0 -9
- package/dist/generator/zod/generator/properties.d.ts +0 -13
- package/dist/generator/zod/generator/properties.js +0 -21
- package/dist/generator/zod/validator/index.d.ts +0 -2
- package/dist/generator/zod/validator/index.js +0 -2
- package/dist/generator/zod/validator/is-zod-document.d.ts +0 -6
- package/dist/generator/zod/validator/is-zod-document.js +0 -15
- package/dist/generator/zod/validator/is-zod.d.ts +0 -6
- package/dist/generator/zod/validator/is-zod.js +0 -11
- package/dist/shared/helper/group-by-model.d.ts +0 -8
- package/dist/shared/helper/group-by-model.js +0 -15
- package/dist/shared/types.d.ts +0 -16
- package/dist/shared/types.js +0 -1
- package/dist/shared/utils/capitalize.d.ts +0 -16
- package/dist/shared/utils/capitalize.js +0 -18
- package/dist/shared/utils/decapitalize.d.ts +0 -15
- package/dist/shared/utils/decapitalize.js +0 -17
- package/dist/shared/utils/snake-case.d.ts +0 -1
- package/dist/shared/utils/snake-case.js +0 -3
- package/dist/shared/validator/is-fields.d.ts +0 -12
- package/dist/shared/validator/is-fields.js +0 -8
package/README.md
CHANGED
|
@@ -93,7 +93,7 @@ model Post {
|
|
|
93
93
|
## Zod
|
|
94
94
|
|
|
95
95
|
```ts
|
|
96
|
-
import
|
|
96
|
+
import * as z from 'zod'
|
|
97
97
|
|
|
98
98
|
export const UserSchema = z.object({
|
|
99
99
|
/**
|
|
@@ -236,7 +236,7 @@ end
|
|
|
236
236
|
| `file` | `string` | `index.ts` | File Name |
|
|
237
237
|
| `type` | `boolean` | `false` | Generate TypeScript types |
|
|
238
238
|
| `comment` | `boolean` | `false` | Include schema documentation |
|
|
239
|
-
| `zod` | `string` | `'v4'` | Zod import version (`'
|
|
239
|
+
| `zod` | `string` | `'v4'` | Zod import version (`'mini'`, `'@hono/zod-openapi'`, or default `'v4'`) |
|
|
240
240
|
|
|
241
241
|
### Valibot Generator Options
|
|
242
242
|
|
|
@@ -32,14 +32,22 @@ function getFieldDefaultOption(field) {
|
|
|
32
32
|
}
|
|
33
33
|
function ectoTypeToTypespec(type) {
|
|
34
34
|
switch (type) {
|
|
35
|
-
case 'string':
|
|
36
|
-
|
|
37
|
-
case '
|
|
38
|
-
|
|
39
|
-
case '
|
|
40
|
-
|
|
41
|
-
case '
|
|
42
|
-
|
|
35
|
+
case 'string':
|
|
36
|
+
return 'String.t()';
|
|
37
|
+
case 'integer':
|
|
38
|
+
return 'integer()';
|
|
39
|
+
case 'float':
|
|
40
|
+
return 'float()';
|
|
41
|
+
case 'boolean':
|
|
42
|
+
return 'boolean()';
|
|
43
|
+
case 'binary_id':
|
|
44
|
+
return 'Ecto.UUID.t()';
|
|
45
|
+
case 'naive_datetime':
|
|
46
|
+
return 'NaiveDateTime.t()';
|
|
47
|
+
case 'utc_datetime':
|
|
48
|
+
return 'DateTime.t()';
|
|
49
|
+
default:
|
|
50
|
+
return 'term()';
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
function buildTimestampsLine(fields) {
|
|
@@ -71,9 +79,7 @@ export function ectoSchemas(models, app) {
|
|
|
71
79
|
const pk = getPrimaryKeyConfig(idField);
|
|
72
80
|
const fields = model.fields.map((f) => ({ ...f }));
|
|
73
81
|
const { line: timestampsLine, exclude: timestampsExclude } = buildTimestampsLine(fields);
|
|
74
|
-
const schemaFieldsRaw = fields.filter((f) => !(f.relationName ||
|
|
75
|
-
(f.isId && pk.omitIdFieldInSchema) ||
|
|
76
|
-
timestampsExclude.has(f.name)));
|
|
82
|
+
const schemaFieldsRaw = fields.filter((f) => !(f.relationName || (f.isId && pk.omitIdFieldInSchema) || timestampsExclude.has(f.name)));
|
|
77
83
|
const typeSpecFields = [
|
|
78
84
|
`id: ${pk.typeSpec}`,
|
|
79
85
|
...schemaFieldsRaw.map((f) => `${f.name}: ${ectoTypeToTypespec(prismaTypeToEctoType(f.type))}`),
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
+
/**
|
|
3
|
+
* Generate Mermaid ER diagram content from Prisma models.
|
|
4
|
+
*
|
|
5
|
+
* @param models - The list of Prisma DMMF models.
|
|
6
|
+
* @returns An array of Mermaid ER diagram lines.
|
|
7
|
+
*/
|
|
8
|
+
export declare function erContent(models: readonly DMMF.Model[]): readonly string[];
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { modelInfo } from '../generator/index.js';
|
|
2
|
-
import { extractRelations
|
|
3
|
-
|
|
4
|
-
* generate ER content
|
|
5
|
-
* @param { readonly Model[] } models - models
|
|
6
|
-
* @returns { ERContent } - ER content
|
|
7
|
-
*/
|
|
2
|
+
import { extractRelations } from '../helper/extract-relations.js';
|
|
3
|
+
import { removeDuplicateRelations } from '../utils/index.js';
|
|
8
4
|
// ER diagram header
|
|
9
5
|
const ER_HEADER = ['```mermaid', 'erDiagram'];
|
|
10
6
|
// ER diagram footer
|
|
11
7
|
const ER_FOOTER = ['```'];
|
|
8
|
+
/**
|
|
9
|
+
* Generate Mermaid ER diagram content from Prisma models.
|
|
10
|
+
*
|
|
11
|
+
* @param models - The list of Prisma DMMF models.
|
|
12
|
+
* @returns An array of Mermaid ER diagram lines.
|
|
13
|
+
*/
|
|
12
14
|
export function erContent(models) {
|
|
13
15
|
// extract all relations
|
|
14
16
|
const allRelations = models.flatMap(extractRelations);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { DMMF } from '@prisma/generator-helper';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
3
|
+
* Generate Mermaid ER field lines from a Prisma model.
|
|
4
|
+
*
|
|
5
|
+
* @param model - A Prisma DMMF model definition.
|
|
6
|
+
* @returns An array of strings representing each field in Mermaid ER syntax, excluding relation fields and annotations.
|
|
6
7
|
*/
|
|
7
8
|
export declare function modelFields(model: DMMF.Model): string[];
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const ZOD_ANNOTATION = '@z.';
|
|
2
2
|
const VALIBOT_ANNOTATION = '@v.';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @
|
|
4
|
+
* Generate Mermaid ER field lines from a Prisma model.
|
|
5
|
+
*
|
|
6
|
+
* @param model - A Prisma DMMF model definition.
|
|
7
|
+
* @returns An array of strings representing each field in Mermaid ER syntax, excluding relation fields and annotations.
|
|
7
8
|
*/
|
|
8
9
|
export function modelFields(model) {
|
|
9
10
|
return model.fields
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
3
|
+
* Generate Mermaid ER diagram model block from a Prisma model.
|
|
4
|
+
*
|
|
5
|
+
* @param model - A Prisma DMMF model definition.
|
|
6
|
+
* @returns An array of strings representing the model block in Mermaid ER syntax.
|
|
6
7
|
*/
|
|
7
|
-
export declare function modelInfo(model: Model): readonly string[];
|
|
8
|
+
export declare function modelInfo(model: DMMF.Model): readonly string[];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { modelFields } from './index.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
3
|
+
* Generate Mermaid ER diagram model block from a Prisma model.
|
|
4
|
+
*
|
|
5
|
+
* @param model - A Prisma DMMF model definition.
|
|
6
|
+
* @returns An array of strings representing the model block in Mermaid ER syntax.
|
|
6
7
|
*/
|
|
7
8
|
export function modelInfo(model) {
|
|
8
9
|
return [` ${model.name} {`, ...modelFields(model), ' }'];
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import type { Relation } from '../types.js';
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
2
|
+
* Generate a Mermaid ER diagram relation line from a relation definition.
|
|
3
|
+
*
|
|
4
|
+
* @param relation - The relation definition including model and field names.
|
|
5
|
+
* @returns A string representing the relation line in Mermaid ER syntax.
|
|
6
6
|
*/
|
|
7
|
-
export declare function relationLine(relation:
|
|
7
|
+
export declare function relationLine(relation: {
|
|
8
|
+
fromModel: string;
|
|
9
|
+
toModel: string;
|
|
10
|
+
fromField: string;
|
|
11
|
+
toField: string;
|
|
12
|
+
type: string;
|
|
13
|
+
}): string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { buildRelationLine } from '../
|
|
1
|
+
import { buildRelationLine } from '../helper/build-relation-line.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
3
|
+
* Generate a Mermaid ER diagram relation line from a relation definition.
|
|
4
|
+
*
|
|
5
|
+
* @param relation - The relation definition including model and field names.
|
|
6
|
+
* @returns A string representing the relation line in Mermaid ER syntax.
|
|
6
7
|
*/
|
|
7
8
|
export function relationLine(relation) {
|
|
8
9
|
const cardinality = buildRelationLine(relation.type);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a Mermaid ER diagram relation connector from a custom relationship string.
|
|
3
|
+
*
|
|
4
|
+
* @param input - A relationship string like `"one-to-many"` or `"zero-one-to-one-optional"`.
|
|
5
|
+
* @returns The Mermaid connector string (e.g., `"||--}|"` or `"|o..}o"`).
|
|
6
|
+
*
|
|
7
|
+
* @throws If the input format is invalid or contains unknown relationship types.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildRelationLine(input: string): string;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import { isRelationship } from '../
|
|
1
|
+
import { isRelationship } from '../utils/index.js';
|
|
2
2
|
const RELATIONSHIPS = {
|
|
3
3
|
'zero-one': '|o',
|
|
4
4
|
one: '||',
|
|
5
5
|
'zero-many': '}o',
|
|
6
6
|
many: '}|',
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Mermaid ER diagram relation connector from a custom relationship string.
|
|
10
|
+
*
|
|
11
|
+
* @param input - A relationship string like `"one-to-many"` or `"zero-one-to-one-optional"`.
|
|
12
|
+
* @returns The Mermaid connector string (e.g., `"||--}|"` or `"|o..}o"`).
|
|
13
|
+
*
|
|
14
|
+
* @throws If the input format is invalid or contains unknown relationship types.
|
|
15
|
+
*/
|
|
8
16
|
export function buildRelationLine(input) {
|
|
9
17
|
const parts = input.split('-to-');
|
|
10
18
|
if (parts.length !== 2) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
+
/**
|
|
3
|
+
* Extract Mermaid ER diagram relation lines from a Prisma model.
|
|
4
|
+
*
|
|
5
|
+
* @param model - A Prisma DMMF model definition.
|
|
6
|
+
* @returns An array of Mermaid ER diagram relation lines based on `@relation` annotations.
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractRelations(model: DMMF.Model): readonly string[];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { relationLine } from '../generator/relation-line.js';
|
|
2
|
-
import { parseRelation } from '
|
|
2
|
+
import { parseRelation } from '../utils/index.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @
|
|
4
|
+
* Extract Mermaid ER diagram relation lines from a Prisma model.
|
|
5
|
+
*
|
|
6
|
+
* @param model - A Prisma DMMF model definition.
|
|
7
|
+
* @returns An array of Mermaid ER diagram relation lines based on `@relation` annotations.
|
|
7
8
|
*/
|
|
8
9
|
export function extractRelations(model) {
|
|
9
10
|
const relations = [];
|
|
10
|
-
// @relation annotation
|
|
11
11
|
if (model.documentation) {
|
|
12
12
|
const annotationRelations = model.documentation
|
|
13
13
|
.split('\n')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { erContent } from './generator/er-content.js';
|
|
3
2
|
import fsp from 'node:fs/promises';
|
|
4
3
|
import pkg from '@prisma/generator-helper';
|
|
4
|
+
import { erContent } from './generator/er-content.js';
|
|
5
5
|
const { generatorHandler } = pkg;
|
|
6
6
|
export async function main(options) {
|
|
7
7
|
const content = erContent(options.dmmf.datamodel.models);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove duplicate relations and exclude any that are many-to-one.
|
|
3
|
+
*
|
|
4
|
+
* @param relations - An array of Mermaid ER diagram relation lines.
|
|
5
|
+
* @returns A filtered array excluding 'many-to-one' relations.
|
|
6
|
+
*/
|
|
7
|
+
export declare function excludeManyToOneRelations(relations: readonly string[]): readonly string[];
|
|
8
|
+
/**
|
|
9
|
+
* Check if the given key is a valid relationship type.
|
|
10
|
+
*
|
|
11
|
+
* @param key - The key to check.
|
|
12
|
+
* @returns `true` if the key is one of the valid relationship types, otherwise `false`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isRelationship(key: string): key is 'zero-one' | 'one' | 'zero-many' | 'many';
|
|
15
|
+
/**
|
|
16
|
+
* Parse a `@relation` annotation line into a structured relation object.
|
|
17
|
+
*
|
|
18
|
+
* @param line - A string representing a single `@relation` annotation.
|
|
19
|
+
* @returns An object containing relation details if the line is valid, otherwise `null`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseRelation(line: string): {
|
|
22
|
+
fromModel: string;
|
|
23
|
+
fromField: string;
|
|
24
|
+
toModel: string;
|
|
25
|
+
toField: string;
|
|
26
|
+
type: string;
|
|
27
|
+
} | null;
|
|
28
|
+
/**
|
|
29
|
+
* Remove duplicate relation lines from an array of Mermaid ER diagram relations.
|
|
30
|
+
*
|
|
31
|
+
* @param relations - An array of relation lines (e.g., generated from `relationLine`).
|
|
32
|
+
* @returns A new array with duplicates removed, preserving insertion order.
|
|
33
|
+
*/
|
|
34
|
+
export declare function removeDuplicateRelations(relations: readonly string[]): readonly string[];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove duplicate relations and exclude any that are many-to-one.
|
|
3
|
+
*
|
|
4
|
+
* @param relations - An array of Mermaid ER diagram relation lines.
|
|
5
|
+
* @returns A filtered array excluding 'many-to-one' relations.
|
|
6
|
+
*/
|
|
7
|
+
export function excludeManyToOneRelations(relations) {
|
|
8
|
+
return [...new Set(relations)].filter((r) => !r.includes('many-to-one'));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Check if the given key is a valid relationship type.
|
|
12
|
+
*
|
|
13
|
+
* @param key - The key to check.
|
|
14
|
+
* @returns `true` if the key is one of the valid relationship types, otherwise `false`.
|
|
15
|
+
*/
|
|
16
|
+
export function isRelationship(key) {
|
|
17
|
+
return ['zero-one', 'one', 'zero-many', 'many'].includes(key);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse a `@relation` annotation line into a structured relation object.
|
|
21
|
+
*
|
|
22
|
+
* @param line - A string representing a single `@relation` annotation.
|
|
23
|
+
* @returns An object containing relation details if the line is valid, otherwise `null`.
|
|
24
|
+
*/
|
|
25
|
+
export function parseRelation(line) {
|
|
26
|
+
const relationRegex = /^@relation\s+(\w+)\.(\w+)\s+(\w+)\.(\w+)\s+(\w+-to-\w+)$/;
|
|
27
|
+
const match = line.trim().match(relationRegex);
|
|
28
|
+
if (!match) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const [, fromModel, fromField, toModel, toField, relationType] = match;
|
|
32
|
+
return {
|
|
33
|
+
fromModel,
|
|
34
|
+
fromField,
|
|
35
|
+
toModel,
|
|
36
|
+
toField,
|
|
37
|
+
type: relationType,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Remove duplicate relation lines from an array of Mermaid ER diagram relations.
|
|
42
|
+
*
|
|
43
|
+
* @param relations - An array of relation lines (e.g., generated from `relationLine`).
|
|
44
|
+
* @returns A new array with duplicates removed, preserving insertion order.
|
|
45
|
+
*/
|
|
46
|
+
export function removeDuplicateRelations(relations) {
|
|
47
|
+
return [...new Set(relations)];
|
|
48
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
2
|
/**
|
|
3
3
|
* Generate Valibot schemas and types
|
|
4
4
|
* @param models - The models to generate the Valibot schemas and types for
|
|
@@ -6,4 +6,4 @@ import type { Model } from '../../mermaid-er/types.js';
|
|
|
6
6
|
* @param comment - Whether to include comments in the generated code
|
|
7
7
|
* @returns The generated Valibot schemas and types
|
|
8
8
|
*/
|
|
9
|
-
export declare function valibot(models: readonly Model[], type: boolean, comment: boolean): string;
|
|
9
|
+
export declare function valibot(models: readonly Readonly<DMMF.Model>[], type: boolean, comment: boolean): string;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { groupByModel, isFields } from '../../../shared/utils/index.js';
|
|
2
|
+
import { inferInput, isValibot, isValibotDocument } from '../utils/index.js';
|
|
2
3
|
import { schemas } from './schemas.js';
|
|
3
|
-
import { groupByModel } from '../../../shared/helper/group-by-model.js';
|
|
4
|
-
import { isFields } from '../../../shared/validator/is-fields.js';
|
|
5
|
-
import { inferInput } from './infer-input.js';
|
|
6
|
-
import { isValibotDocument } from '../validator/is-valibot-document.js';
|
|
7
|
-
const VALIBOT_IMPORT = `import * as v from 'valibot'\n`;
|
|
8
4
|
/**
|
|
9
5
|
* Generate Valibot schemas and types
|
|
10
6
|
* @param models - The models to generate the Valibot schemas and types for
|
|
@@ -30,18 +26,14 @@ export function valibot(models, type, comment) {
|
|
|
30
26
|
}));
|
|
31
27
|
return fields;
|
|
32
28
|
});
|
|
33
|
-
|
|
34
|
-
const validFields = isFields(modelFields);
|
|
35
|
-
// group by model
|
|
36
|
-
const groupedByModel = groupByModel(validFields);
|
|
37
|
-
const valibots = Object.values(groupedByModel).map((fields) => {
|
|
29
|
+
const valibots = Object.values(groupByModel(isFields(modelFields))).map((fields) => {
|
|
38
30
|
return {
|
|
39
31
|
generateValibotSchema: schemas(fields, comment),
|
|
40
32
|
generateValibotInfer: type ? inferInput(fields[0].modelName) : '',
|
|
41
33
|
};
|
|
42
34
|
});
|
|
43
35
|
return [
|
|
44
|
-
|
|
36
|
+
`import * as v from 'valibot'`,
|
|
45
37
|
'',
|
|
46
38
|
valibots
|
|
47
39
|
.flatMap(({ generateValibotSchema, generateValibotInfer }) => [generateValibotSchema, generateValibotInfer].filter(Boolean))
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { valibot } from './generator/valibot.js';
|
|
3
2
|
import fsp from 'node:fs/promises';
|
|
4
3
|
import pkg from '@prisma/generator-helper';
|
|
5
4
|
import { fmt } from '../../shared/format/index.js';
|
|
5
|
+
import { valibot } from './generator/valibot.js';
|
|
6
6
|
const { generatorHandler } = pkg;
|
|
7
7
|
export async function main(options) {
|
|
8
8
|
const output = options.generator.output?.value ?? './valibot';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a `v.InferInput` type for the specified model.
|
|
3
|
+
*
|
|
4
|
+
* @param modelName - The name of the model.
|
|
5
|
+
* @returns The generated TypeScript type definition line.
|
|
6
|
+
*/
|
|
7
|
+
export declare function inferInput(modelName: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Generates Valibot property definitions from model fields.
|
|
10
|
+
*
|
|
11
|
+
* Filters out fields without validation, removes documentation tags like
|
|
12
|
+
* @relation, @v, @z, and optionally includes doc comments.
|
|
13
|
+
*
|
|
14
|
+
* @param modelFields - The list of model fields with metadata.
|
|
15
|
+
* @param comment - Whether to include documentation comments.
|
|
16
|
+
* @returns A string containing formatted Valibot property definitions.
|
|
17
|
+
*/
|
|
18
|
+
export declare function properties(modelFields: {
|
|
19
|
+
documentation: string;
|
|
20
|
+
modelName: string;
|
|
21
|
+
fieldName: string;
|
|
22
|
+
validation: string | null;
|
|
23
|
+
comment: string[];
|
|
24
|
+
}[], comment: boolean): string;
|
|
25
|
+
/**
|
|
26
|
+
* Parses documentation lines and filters out Valibot validation entries.
|
|
27
|
+
*
|
|
28
|
+
* Lines containing "@v." will be excluded.
|
|
29
|
+
*
|
|
30
|
+
* @param documentation - The raw documentation string.
|
|
31
|
+
* @returns An array of non-Valibot documentation lines.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isValibotDocument(documentation?: string): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Extracts the Valibot validation expression from a documentation string.
|
|
36
|
+
*
|
|
37
|
+
* Searches for a line starting with "@v." and returns the expression that follows.
|
|
38
|
+
*
|
|
39
|
+
* @param documentation - The documentation string to search.
|
|
40
|
+
* @returns The Valibot expression without "@v." prefix, or null if not found.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isValibot(documentation?: string): string | null;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a `v.InferInput` type for the specified model.
|
|
3
|
+
*
|
|
4
|
+
* @param modelName - The name of the model.
|
|
5
|
+
* @returns The generated TypeScript type definition line.
|
|
6
|
+
*/
|
|
7
|
+
export function inferInput(modelName) {
|
|
8
|
+
return `export type ${modelName} = v.InferInput<typeof ${modelName}Schema>`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generates Valibot property definitions from model fields.
|
|
12
|
+
*
|
|
13
|
+
* Filters out fields without validation, removes documentation tags like
|
|
14
|
+
* @relation, @v, @z, and optionally includes doc comments.
|
|
15
|
+
*
|
|
16
|
+
* @param modelFields - The list of model fields with metadata.
|
|
17
|
+
* @param comment - Whether to include documentation comments.
|
|
18
|
+
* @returns A string containing formatted Valibot property definitions.
|
|
19
|
+
*/
|
|
20
|
+
export function properties(modelFields, comment) {
|
|
21
|
+
const fields = modelFields
|
|
22
|
+
.filter((field) => field.validation)
|
|
23
|
+
.map((field) => {
|
|
24
|
+
const cleanDoc = field.comment
|
|
25
|
+
.filter((line) => !(line.includes('@relation') || line.includes('@v') || line.includes('@z')))
|
|
26
|
+
.join('\n')
|
|
27
|
+
.trim();
|
|
28
|
+
const docComment = comment && cleanDoc ? ` /**\n * ${cleanDoc}\n */\n` : '';
|
|
29
|
+
return `${docComment} ${field.fieldName}: v.${field.validation}`;
|
|
30
|
+
})
|
|
31
|
+
.join(',\n');
|
|
32
|
+
return fields;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parses documentation lines and filters out Valibot validation entries.
|
|
36
|
+
*
|
|
37
|
+
* Lines containing "@v." will be excluded.
|
|
38
|
+
*
|
|
39
|
+
* @param documentation - The raw documentation string.
|
|
40
|
+
* @returns An array of non-Valibot documentation lines.
|
|
41
|
+
*/
|
|
42
|
+
export function isValibotDocument(documentation) {
|
|
43
|
+
return (documentation
|
|
44
|
+
?.split('\n')
|
|
45
|
+
.map((line) => line.trim())
|
|
46
|
+
.filter((line) => line && !line.includes('@v.')) ?? []);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extracts the Valibot validation expression from a documentation string.
|
|
50
|
+
*
|
|
51
|
+
* Searches for a line starting with "@v." and returns the expression that follows.
|
|
52
|
+
*
|
|
53
|
+
* @param documentation - The documentation string to search.
|
|
54
|
+
* @returns The Valibot expression without "@v." prefix, or null if not found.
|
|
55
|
+
*/
|
|
56
|
+
export function isValibot(documentation) {
|
|
57
|
+
if (!documentation)
|
|
58
|
+
return null;
|
|
59
|
+
const match = documentation.match(/@v\.(.+?)(?:\n|$)/);
|
|
60
|
+
return match ? match[1].trim() : null;
|
|
61
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DMMF } from '@prisma/generator-helper';
|
|
2
2
|
/**
|
|
3
3
|
* Generate Zod schemas and types
|
|
4
4
|
* @param models - The models to generate the Zod schemas and types for
|
|
@@ -6,4 +6,4 @@ import type { Model } from '../../../shared/types.js';
|
|
|
6
6
|
* @param comment - Whether to include comments in the generated code
|
|
7
7
|
* @returns The generated Zod schemas and types
|
|
8
8
|
*/
|
|
9
|
-
export declare function zod(models: readonly Model[], type: boolean, comment: boolean, zodVersion?: string | string[]): string;
|
|
9
|
+
export declare function zod(models: readonly Readonly<DMMF.Model>[], type: boolean, comment: boolean, zodVersion?: string | string[]): string;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { infer, schemas } from './index.js';
|
|
5
|
-
const ZODV4_IMPORT = `import { z } from 'zod/v4'\n`;
|
|
6
|
-
const ZODV4_MINI_IMPORT = `import { z } from 'zod/v4-mini'\n`;
|
|
7
|
-
const ZOD_OPENAPI_HONO_IMPORT = `import { z } from '@hono/zod-openapi'\n`;
|
|
1
|
+
import { groupByModel, isFields } from '../../../shared/utils/index.js';
|
|
2
|
+
import { infer, isZod, isZodDocument } from '../utils/index.js';
|
|
3
|
+
import { schemas } from './schemas.js';
|
|
8
4
|
/**
|
|
9
5
|
* Generate Zod schemas and types
|
|
10
6
|
* @param models - The models to generate the Zod schemas and types for
|
|
@@ -30,21 +26,17 @@ export function zod(models, type, comment, zodVersion) {
|
|
|
30
26
|
}));
|
|
31
27
|
return fields;
|
|
32
28
|
});
|
|
33
|
-
|
|
34
|
-
const validFields = isFields(modelFields);
|
|
35
|
-
// group by model
|
|
36
|
-
const groupedByModel = groupByModel(validFields);
|
|
37
|
-
const zods = Object.values(groupedByModel).map((fields) => {
|
|
29
|
+
const zods = Object.values(groupByModel(isFields(modelFields))).map((fields) => {
|
|
38
30
|
return {
|
|
39
31
|
generateZodSchema: schemas(fields, comment),
|
|
40
32
|
generateZodInfer: type ? infer(fields[0].modelName) : '',
|
|
41
33
|
};
|
|
42
34
|
});
|
|
43
|
-
const importStatement = zodVersion === '
|
|
44
|
-
?
|
|
35
|
+
const importStatement = zodVersion === 'mini'
|
|
36
|
+
? `import * as z from 'zod/mini'`
|
|
45
37
|
: zodVersion === '@hono/zod-openapi'
|
|
46
|
-
?
|
|
47
|
-
:
|
|
38
|
+
? `import { z } from '@hono/zod-openapi'`
|
|
39
|
+
: `import * as z from 'zod'`;
|
|
48
40
|
return [
|
|
49
41
|
importStatement,
|
|
50
42
|
'',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { zod } from './generator/zod.js';
|
|
3
2
|
import fsp from 'node:fs/promises';
|
|
4
3
|
import pkg from '@prisma/generator-helper';
|
|
5
4
|
import { fmt } from '../../shared/format/index.js';
|
|
5
|
+
import { zod } from './generator/zod.js';
|
|
6
6
|
const { generatorHandler } = pkg;
|
|
7
7
|
export async function main(options) {
|
|
8
8
|
const output = options.generator.output?.value ?? './zod';
|