hekireki 0.4.2 → 0.5.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 +180 -20
- package/dist/dbml-content-D3ioOw2D.js +151 -0
- package/dist/fsp-DYtOxLN_.js +68 -0
- package/dist/generator/arktype/index.d.ts +6 -0
- package/dist/generator/arktype/index.js +94 -0
- package/dist/generator/dbml/index.d.ts +6 -0
- package/dist/generator/dbml/index.js +49 -0
- package/dist/generator/ecto/index.d.ts +6 -3
- package/dist/generator/ecto/index.js +150 -13
- package/dist/generator/effect/index.d.ts +6 -0
- package/dist/generator/effect/index.js +94 -0
- package/dist/generator/mermaid-er/index.d.ts +6 -3
- package/dist/generator/mermaid-er/index.js +136 -21
- package/dist/generator/svg/index.d.ts +6 -0
- package/dist/generator/svg/index.js +74 -0
- package/dist/generator/valibot/index.d.ts +6 -3
- package/dist/generator/valibot/index.js +91 -45
- package/dist/generator/zod/index.d.ts +6 -3
- package/dist/generator/zod/index.js +98 -56
- package/dist/relations-CxeKj9KD.js +12 -0
- package/dist/utils-CXBzdZih.js +134 -0
- package/package.json +29 -17
- package/dist/generator/ecto/generator/ecto.d.ts +0 -3
- package/dist/generator/ecto/generator/ecto.js +0 -131
- package/dist/generator/ecto/utils/index.d.ts +0 -1
- package/dist/generator/ecto/utils/index.js +0 -1
- package/dist/generator/ecto/utils/prisma-type-to-ecto-type.d.ts +0 -1
- package/dist/generator/ecto/utils/prisma-type-to-ecto-type.js +0 -11
- package/dist/generator/mermaid-er/generator/er-content.d.ts +0 -8
- package/dist/generator/mermaid-er/generator/er-content.js +0 -23
- package/dist/generator/mermaid-er/generator/index.d.ts +0 -4
- package/dist/generator/mermaid-er/generator/index.js +0 -4
- package/dist/generator/mermaid-er/generator/model-fields.d.ts +0 -8
- package/dist/generator/mermaid-er/generator/model-fields.js +0 -25
- package/dist/generator/mermaid-er/generator/model-info.d.ts +0 -8
- package/dist/generator/mermaid-er/generator/model-info.js +0 -10
- package/dist/generator/mermaid-er/generator/relation-line.d.ts +0 -13
- package/dist/generator/mermaid-er/generator/relation-line.js +0 -14
- package/dist/generator/mermaid-er/helper/build-relation-line.d.ts +0 -9
- package/dist/generator/mermaid-er/helper/build-relation-line.js +0 -37
- package/dist/generator/mermaid-er/helper/extract-relations.d.ts +0 -8
- package/dist/generator/mermaid-er/helper/extract-relations.js +0 -22
- package/dist/generator/mermaid-er/utils/index.d.ts +0 -34
- package/dist/generator/mermaid-er/utils/index.js +0 -48
- package/dist/generator/valibot/generator/index.d.ts +0 -3
- package/dist/generator/valibot/generator/index.js +0 -3
- package/dist/generator/valibot/generator/schema.d.ts +0 -16
- package/dist/generator/valibot/generator/schema.js +0 -51
- package/dist/generator/valibot/generator/schemas.d.ts +0 -13
- package/dist/generator/valibot/generator/schemas.js +0 -17
- package/dist/generator/valibot/generator/valibot.d.ts +0 -9
- package/dist/generator/valibot/generator/valibot.js +0 -42
- package/dist/generator/valibot/utils/index.d.ts +0 -44
- package/dist/generator/valibot/utils/index.js +0 -75
- package/dist/generator/zod/generator/index.d.ts +0 -3
- package/dist/generator/zod/generator/index.js +0 -3
- package/dist/generator/zod/generator/schema.d.ts +0 -17
- package/dist/generator/zod/generator/schema.js +0 -38
- package/dist/generator/zod/generator/schemas.d.ts +0 -13
- package/dist/generator/zod/generator/schemas.js +0 -17
- package/dist/generator/zod/generator/zod.d.ts +0 -9
- package/dist/generator/zod/generator/zod.js +0 -47
- package/dist/generator/zod/utils/index.d.ts +0 -46
- package/dist/generator/zod/utils/index.js +0 -75
- package/dist/shared/format/index.d.ts +0 -1
- package/dist/shared/format/index.js +0 -9
- package/dist/shared/generator/index.d.ts +0 -11
- package/dist/shared/generator/index.js +0 -23
- package/dist/shared/helper/relations.d.ts +0 -7
- package/dist/shared/helper/relations.js +0 -5
- package/dist/shared/utils/index.d.ts +0 -61
- package/dist/shared/utils/index.js +0 -63
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import fsp from 'node:fs/promises';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { snakeCase } from '../../../shared/utils/index.js';
|
|
4
|
-
import { prismaTypeToEctoType } from '../utils/prisma-type-to-ecto-type.js';
|
|
5
|
-
function getPrimaryKeyConfig(field) {
|
|
6
|
-
if (field.type === 'String' &&
|
|
7
|
-
field.default &&
|
|
8
|
-
typeof field.default === 'object' &&
|
|
9
|
-
'name' in field.default &&
|
|
10
|
-
field.default.name === 'uuid') {
|
|
11
|
-
return {
|
|
12
|
-
line: '@primary_key {:id, :binary_id, autogenerate: true}',
|
|
13
|
-
typeSpec: 'Ecto.UUID.t()',
|
|
14
|
-
omitIdFieldInSchema: true,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
return {
|
|
18
|
-
line: '@primary_key false',
|
|
19
|
-
typeSpec: 'String.t()',
|
|
20
|
-
omitIdFieldInSchema: false,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function getFieldDefaultOption(field) {
|
|
24
|
-
const def = field.default;
|
|
25
|
-
if (def === undefined || def === null)
|
|
26
|
-
return null;
|
|
27
|
-
if (typeof def === 'string')
|
|
28
|
-
return `default: "${def}"`;
|
|
29
|
-
if (typeof def === 'number' || typeof def === 'boolean')
|
|
30
|
-
return `default: ${def}`;
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
function ectoTypeToTypespec(type) {
|
|
34
|
-
switch (type) {
|
|
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()';
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function buildTimestampsLine(fields) {
|
|
54
|
-
const insertedAliases = ['inserted_at', 'created_at', 'createdAt'];
|
|
55
|
-
const updatedAliases = ['updated_at', 'modified_at', 'updatedAt', 'modifiedAt'];
|
|
56
|
-
const inserted = fields.find((f) => insertedAliases.includes(f.name));
|
|
57
|
-
const updated = fields.find((f) => updatedAliases.includes(f.name));
|
|
58
|
-
const exclude = new Set();
|
|
59
|
-
if (inserted)
|
|
60
|
-
exclude.add(inserted.name);
|
|
61
|
-
if (updated)
|
|
62
|
-
exclude.add(updated.name);
|
|
63
|
-
if (!(inserted || updated))
|
|
64
|
-
return { line: null, exclude };
|
|
65
|
-
if (inserted?.name === 'inserted_at' && updated?.name === 'updated_at') {
|
|
66
|
-
return { line: ' timestamps()', exclude };
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
line: ` timestamps(inserted_at: :${inserted?.name ?? 'inserted_at'}, updated_at: :${updated?.name ?? 'updated_at'})`,
|
|
70
|
-
exclude,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
export function ectoSchemas(models, app) {
|
|
74
|
-
return models
|
|
75
|
-
.map((model) => {
|
|
76
|
-
const idField = model.fields.find((f) => f.isId);
|
|
77
|
-
if (!idField)
|
|
78
|
-
return '';
|
|
79
|
-
const pk = getPrimaryKeyConfig(idField);
|
|
80
|
-
const fields = model.fields.map((f) => ({ ...f }));
|
|
81
|
-
const { line: timestampsLine, exclude: timestampsExclude } = buildTimestampsLine(fields);
|
|
82
|
-
const schemaFieldsRaw = fields.filter((f) => !(f.relationName || (f.isId && pk.omitIdFieldInSchema) || timestampsExclude.has(f.name)));
|
|
83
|
-
const typeSpecFields = [
|
|
84
|
-
`id: ${pk.typeSpec}`,
|
|
85
|
-
...schemaFieldsRaw.map((f) => `${f.name}: ${ectoTypeToTypespec(prismaTypeToEctoType(f.type))}`),
|
|
86
|
-
];
|
|
87
|
-
const typeSpecLines = [
|
|
88
|
-
' @type t :: %__MODULE__{',
|
|
89
|
-
...typeSpecFields.map((line, i) => {
|
|
90
|
-
const isLast = i === typeSpecFields.length - 1;
|
|
91
|
-
return ` ${line}${isLast ? '' : ','}`;
|
|
92
|
-
}),
|
|
93
|
-
' }',
|
|
94
|
-
];
|
|
95
|
-
const schemaFields = schemaFieldsRaw.map((f) => {
|
|
96
|
-
const type = f.isId ? 'binary_id' : prismaTypeToEctoType(f.type);
|
|
97
|
-
const primary = f.isId && !pk.omitIdFieldInSchema ? ', primary_key: true' : '';
|
|
98
|
-
const defaultOpt = getFieldDefaultOption(f);
|
|
99
|
-
const defaultClause = defaultOpt ? `, ${defaultOpt}` : '';
|
|
100
|
-
return ` field(:${f.name}, :${type}${primary}${defaultClause})`;
|
|
101
|
-
});
|
|
102
|
-
const lines = [
|
|
103
|
-
`defmodule ${app}.${model.name} do`,
|
|
104
|
-
' use Ecto.Schema',
|
|
105
|
-
'',
|
|
106
|
-
` ${pk.line}`,
|
|
107
|
-
'',
|
|
108
|
-
...typeSpecLines,
|
|
109
|
-
'',
|
|
110
|
-
` schema "${snakeCase(model.name)}" do`,
|
|
111
|
-
...schemaFields,
|
|
112
|
-
...(timestampsLine ? [timestampsLine] : []),
|
|
113
|
-
' end',
|
|
114
|
-
'end',
|
|
115
|
-
];
|
|
116
|
-
return lines.join('\n');
|
|
117
|
-
})
|
|
118
|
-
.filter(Boolean)
|
|
119
|
-
.join('\n\n');
|
|
120
|
-
}
|
|
121
|
-
export async function writeEctoSchemasToFiles(models, app, outDir) {
|
|
122
|
-
await fsp.mkdir(outDir, { recursive: true });
|
|
123
|
-
for (const model of models) {
|
|
124
|
-
const code = ectoSchemas([model], app);
|
|
125
|
-
if (!code.trim())
|
|
126
|
-
continue;
|
|
127
|
-
const filePath = join(outDir, `${snakeCase(model.name)}.ex`);
|
|
128
|
-
await fsp.writeFile(filePath, code, 'utf8');
|
|
129
|
-
console.log(`✅ wrote ${filePath}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { prismaTypeToEctoType } from './prisma-type-to-ecto-type.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { prismaTypeToEctoType } from './prisma-type-to-ecto-type.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function prismaTypeToEctoType(type: string): 'integer' | 'string' | 'boolean' | 'utc_datetime';
|
|
@@ -1,8 +0,0 @@
|
|
|
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,23 +0,0 @@
|
|
|
1
|
-
import { modelInfo } from '../generator/index.js';
|
|
2
|
-
import { extractRelations } from '../helper/extract-relations.js';
|
|
3
|
-
import { removeDuplicateRelations } from '../utils/index.js';
|
|
4
|
-
// ER diagram header
|
|
5
|
-
const ER_HEADER = ['```mermaid', 'erDiagram'];
|
|
6
|
-
// ER diagram footer
|
|
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
|
-
*/
|
|
14
|
-
export function erContent(models) {
|
|
15
|
-
// extract all relations
|
|
16
|
-
const allRelations = models.flatMap(extractRelations);
|
|
17
|
-
// remove duplicate relations
|
|
18
|
-
const uniqueRelations = removeDuplicateRelations(allRelations);
|
|
19
|
-
// collect all model info
|
|
20
|
-
const modelInfos = models.flatMap(modelInfo);
|
|
21
|
-
// build ER diagram
|
|
22
|
-
return [...ER_HEADER, ...uniqueRelations, ...modelInfos, ...ER_FOOTER];
|
|
23
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
-
/**
|
|
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.
|
|
7
|
-
*/
|
|
8
|
-
export declare function modelFields(model: DMMF.Model): string[];
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
const ZOD_ANNOTATION = '@z.';
|
|
2
|
-
const VALIBOT_ANNOTATION = '@v.';
|
|
3
|
-
/**
|
|
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.
|
|
8
|
-
*/
|
|
9
|
-
export function modelFields(model) {
|
|
10
|
-
return model.fields
|
|
11
|
-
.map((field) => {
|
|
12
|
-
if (field.relationName) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
const commentPart = field.documentation
|
|
16
|
-
? field.documentation
|
|
17
|
-
.split('\n')
|
|
18
|
-
.filter((line) => !(line.includes(ZOD_ANNOTATION) || line.includes(VALIBOT_ANNOTATION)))
|
|
19
|
-
.join('\n')
|
|
20
|
-
.trim()
|
|
21
|
-
: '';
|
|
22
|
-
return ` ${field.type} ${field.name} ${commentPart ? `"${commentPart}"` : ''}`;
|
|
23
|
-
})
|
|
24
|
-
.filter((field) => field !== null);
|
|
25
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
-
/**
|
|
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.
|
|
7
|
-
*/
|
|
8
|
-
export declare function modelInfo(model: DMMF.Model): readonly string[];
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { modelFields } from './index.js';
|
|
2
|
-
/**
|
|
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.
|
|
7
|
-
*/
|
|
8
|
-
export function modelInfo(model) {
|
|
9
|
-
return [` ${model.name} {`, ...modelFields(model), ' }'];
|
|
10
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
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
|
-
*/
|
|
7
|
-
export declare function relationLine(relation: {
|
|
8
|
-
fromModel: string;
|
|
9
|
-
toModel: string;
|
|
10
|
-
fromField: string;
|
|
11
|
-
toField: string;
|
|
12
|
-
type: string;
|
|
13
|
-
}): string;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { buildRelationLine } from '../helper/build-relation-line.js';
|
|
2
|
-
/**
|
|
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.
|
|
7
|
-
*/
|
|
8
|
-
export function relationLine(relation) {
|
|
9
|
-
const cardinality = buildRelationLine(relation.type);
|
|
10
|
-
if (!cardinality) {
|
|
11
|
-
throw new Error(`Unknown relation type: ${relation.type}`);
|
|
12
|
-
}
|
|
13
|
-
return ` ${relation.fromModel} ${cardinality} ${relation.toModel} : "(${relation.fromField}) - (${relation.toField})"`;
|
|
14
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
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,37 +0,0 @@
|
|
|
1
|
-
import { isRelationship } from '../utils/index.js';
|
|
2
|
-
const RELATIONSHIPS = {
|
|
3
|
-
'zero-one': '|o',
|
|
4
|
-
one: '||',
|
|
5
|
-
'zero-many': '}o',
|
|
6
|
-
many: '}|',
|
|
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
|
-
*/
|
|
16
|
-
export function buildRelationLine(input) {
|
|
17
|
-
const parts = input.split('-to-');
|
|
18
|
-
if (parts.length !== 2) {
|
|
19
|
-
throw new Error(`Invalid input format: ${input}`);
|
|
20
|
-
}
|
|
21
|
-
const [toRaw, optionalFlag] = parts[1].includes('-optional')
|
|
22
|
-
? [parts[1].replace('-optional', ''), 'optional']
|
|
23
|
-
: [parts[1], ''];
|
|
24
|
-
const from = parts[0];
|
|
25
|
-
const to = toRaw;
|
|
26
|
-
const isOptional = optionalFlag === 'optional';
|
|
27
|
-
if (!isRelationship(from)) {
|
|
28
|
-
throw new Error(`Invalid relationship: ${from}`);
|
|
29
|
-
}
|
|
30
|
-
if (!isRelationship(to)) {
|
|
31
|
-
throw new Error(`Invalid relationship: ${to}`);
|
|
32
|
-
}
|
|
33
|
-
const fromSymbol = RELATIONSHIPS[from];
|
|
34
|
-
const toSymbol = RELATIONSHIPS[to];
|
|
35
|
-
const connector = isOptional ? '..' : '--';
|
|
36
|
-
return `${fromSymbol}${connector}${toSymbol}`;
|
|
37
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
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,22 +0,0 @@
|
|
|
1
|
-
import { relationLine } from '../generator/relation-line.js';
|
|
2
|
-
import { parseRelation } from '../utils/index.js';
|
|
3
|
-
/**
|
|
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.
|
|
8
|
-
*/
|
|
9
|
-
export function extractRelations(model) {
|
|
10
|
-
const relations = [];
|
|
11
|
-
if (model.documentation) {
|
|
12
|
-
const annotationRelations = model.documentation
|
|
13
|
-
.split('\n')
|
|
14
|
-
.map((line) => {
|
|
15
|
-
const relation = parseRelation(line);
|
|
16
|
-
return relation ? relationLine(relation) : null;
|
|
17
|
-
})
|
|
18
|
-
.filter((line) => line !== null);
|
|
19
|
-
relations.push(...annotationRelations);
|
|
20
|
-
}
|
|
21
|
-
return relations;
|
|
22
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
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[];
|
|
@@ -1,48 +0,0 @@
|
|
|
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,16 +0,0 @@
|
|
|
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;
|
|
10
|
-
/**
|
|
11
|
-
* Generate Valibot schema
|
|
12
|
-
* @param modelName - The name of the model
|
|
13
|
-
* @param fields - The fields of the model
|
|
14
|
-
* @returns The generated Valibot schema
|
|
15
|
-
*/
|
|
16
|
-
export declare function schema(modelName: string, fields: string): string;
|
|
@@ -1,51 +0,0 @@
|
|
|
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
|
|
43
|
-
/**
|
|
44
|
-
* Generate Valibot schema
|
|
45
|
-
* @param modelName - The name of the model
|
|
46
|
-
* @param fields - The fields of the model
|
|
47
|
-
* @returns The generated Valibot schema
|
|
48
|
-
*/
|
|
49
|
-
export function schema(modelName, fields) {
|
|
50
|
-
return `export const ${modelName}Schema = v.object({\n${fields}\n})`;
|
|
51
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* generate valibot schemas
|
|
3
|
-
* @param modelFields
|
|
4
|
-
* @param config
|
|
5
|
-
* @returns
|
|
6
|
-
*/
|
|
7
|
-
export declare function schemas(modelFields: {
|
|
8
|
-
documentation: string;
|
|
9
|
-
modelName: string;
|
|
10
|
-
fieldName: string;
|
|
11
|
-
validation: string | null;
|
|
12
|
-
comment: string[];
|
|
13
|
-
}[], comment: boolean): string;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { properties } from '../utils/index.js';
|
|
2
|
-
import { schema } from './schema.js';
|
|
3
|
-
/**
|
|
4
|
-
* generate valibot schemas
|
|
5
|
-
* @param modelFields
|
|
6
|
-
* @param config
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
export function schemas(modelFields, comment) {
|
|
10
|
-
const modelName = modelFields[0].modelName;
|
|
11
|
-
const modelDoc = modelFields[0].documentation || '';
|
|
12
|
-
const fields = properties(modelFields, comment);
|
|
13
|
-
if (!(modelDoc || !comment)) {
|
|
14
|
-
return schema(modelName, fields);
|
|
15
|
-
}
|
|
16
|
-
return `${schema(modelName, fields)}`;
|
|
17
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { DMMF } from '@prisma/generator-helper';
|
|
2
|
-
/**
|
|
3
|
-
* Generate Valibot schemas and types
|
|
4
|
-
* @param models - The models to generate the Valibot schemas and types for
|
|
5
|
-
* @param type - Whether to generate types
|
|
6
|
-
* @param comment - Whether to include comments in the generated code
|
|
7
|
-
* @returns The generated Valibot schemas and types
|
|
8
|
-
*/
|
|
9
|
-
export declare function valibot(models: readonly Readonly<DMMF.Model>[], type: boolean, comment: boolean): string;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { groupByModel, isFields } from '../../../shared/utils/index.js';
|
|
2
|
-
import { inferInput, isValibot, isValibotDocument } from '../utils/index.js';
|
|
3
|
-
import { schemas } from './schemas.js';
|
|
4
|
-
/**
|
|
5
|
-
* Generate Valibot schemas and types
|
|
6
|
-
* @param models - The models to generate the Valibot schemas and types for
|
|
7
|
-
* @param type - Whether to generate types
|
|
8
|
-
* @param comment - Whether to include comments in the generated code
|
|
9
|
-
* @returns The generated Valibot schemas and types
|
|
10
|
-
*/
|
|
11
|
-
export function valibot(models, type, comment) {
|
|
12
|
-
const modelInfos = models.map((model) => {
|
|
13
|
-
return {
|
|
14
|
-
documentation: model.documentation ?? '',
|
|
15
|
-
name: model.name,
|
|
16
|
-
fields: model.fields,
|
|
17
|
-
};
|
|
18
|
-
});
|
|
19
|
-
const modelFields = modelInfos.map((model) => {
|
|
20
|
-
const fields = model.fields.map((field) => ({
|
|
21
|
-
documentation: model.documentation,
|
|
22
|
-
modelName: model.name,
|
|
23
|
-
fieldName: field.name,
|
|
24
|
-
comment: isValibotDocument(field.documentation),
|
|
25
|
-
validation: isValibot(field.documentation),
|
|
26
|
-
}));
|
|
27
|
-
return fields;
|
|
28
|
-
});
|
|
29
|
-
const valibots = Object.values(groupByModel(isFields(modelFields))).map((fields) => {
|
|
30
|
-
return {
|
|
31
|
-
generateValibotSchema: schemas(fields, comment),
|
|
32
|
-
generateValibotInfer: type ? inferInput(fields[0].modelName) : '',
|
|
33
|
-
};
|
|
34
|
-
});
|
|
35
|
-
return [
|
|
36
|
-
`import * as v from 'valibot'`,
|
|
37
|
-
'',
|
|
38
|
-
valibots
|
|
39
|
-
.flatMap(({ generateValibotSchema, generateValibotInfer }) => [generateValibotSchema, generateValibotInfer].filter(Boolean))
|
|
40
|
-
.join('\n\n'),
|
|
41
|
-
].join('\n');
|
|
42
|
-
}
|