sizuku 0.0.7 → 0.2.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 +96 -344
- package/dist/cli/main.d.ts +10 -0
- package/dist/cli/main.js +61 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +51 -0
- package/dist/config/index.d.ts +18 -0
- package/dist/config/index.js +13 -0
- package/dist/config/loader.d.ts +19 -0
- package/dist/config/loader.js +30 -0
- package/dist/generator/engine.d.ts +3 -0
- package/dist/generator/engine.js +63 -0
- package/dist/generator/mermaid-er/config/index.d.ts +4 -4
- package/dist/generator/mermaid-er/config/index.js +4 -10
- package/dist/generator/mermaid-er/core/extract-relations.d.ts +1 -1
- package/dist/generator/mermaid-er/core/extract-relations.js +3 -6
- package/dist/generator/mermaid-er/core.d.ts +6 -0
- package/dist/generator/mermaid-er/core.js +54 -0
- package/dist/generator/mermaid-er/generator/er-content.d.ts +20 -0
- package/dist/generator/mermaid-er/generator/{generate-er-content.js → er-content.js} +3 -7
- package/dist/generator/mermaid-er/generator/index.d.ts +2 -0
- package/dist/generator/mermaid-er/generator/index.js +2 -0
- package/dist/generator/mermaid-er/generator/relation-line.d.ts +12 -0
- package/dist/generator/mermaid-er/generator/{generate-relation-line.js → relation-line.js} +3 -6
- package/dist/generator/mermaid-er/generator.d.ts +3 -0
- package/dist/generator/mermaid-er/generator.js +14 -0
- package/dist/generator/mermaid-er/index.d.ts +12 -5
- package/dist/generator/mermaid-er/index.js +30 -74
- package/dist/generator/mermaid-er/relationship/build-relation-line.js +3 -6
- package/dist/generator/mermaid-er/types.js +1 -0
- package/dist/generator/mermaid-er/validator/index.d.ts +8 -0
- package/dist/generator/mermaid-er/validator/index.js +71 -0
- package/dist/generator/mermaid-er/validator/is-relationship.d.ts +1 -1
- package/dist/generator/mermaid-er/validator/is-relationship.js +1 -4
- package/dist/generator/mermaid-er/validator/parse-relation-line.js +1 -4
- package/dist/generator/mermaid-er/validator/parse-table-info.d.ts +1 -7
- package/dist/generator/mermaid-er/validator/parse-table-info.js +69 -89
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.js +1 -4
- package/dist/generator/valibot/config/index.d.ts +2 -2
- package/dist/generator/valibot/config/index.js +6 -12
- package/dist/generator/valibot/core/extract-schema.d.ts +2 -5
- package/dist/generator/valibot/core/extract-schema.js +162 -81
- package/dist/generator/valibot/core.d.ts +5 -0
- package/dist/generator/valibot/core.js +39 -0
- package/dist/generator/valibot/generator/infer-input.d.ts +5 -0
- package/dist/generator/valibot/generator/infer-input.js +8 -0
- package/dist/generator/valibot/generator/relation-valibot-code.d.ts +13 -0
- package/dist/generator/valibot/generator/relation-valibot-code.js +19 -0
- package/dist/generator/valibot/generator/valibot-code.d.ts +15 -0
- package/dist/generator/valibot/generator/valibot-code.js +16 -0
- package/dist/generator/valibot/generator/valibot.d.ts +14 -0
- package/dist/generator/valibot/generator/valibot.js +15 -0
- package/dist/generator/valibot/generator.d.ts +3 -0
- package/dist/generator/valibot/generator.js +14 -0
- package/dist/generator/valibot/index.d.ts +14 -3
- package/dist/generator/valibot/index.js +46 -73
- package/dist/generator/zod/config/index.d.ts +2 -2
- package/dist/generator/zod/config/index.js +6 -12
- package/dist/generator/zod/core/extract-schema.d.ts +1 -2
- package/dist/generator/zod/core/extract-schema.js +228 -81
- package/dist/generator/zod/core.d.ts +5 -0
- package/dist/generator/zod/core.js +39 -0
- package/dist/generator/zod/generator/infer.d.ts +5 -0
- package/dist/generator/zod/generator/infer.js +8 -0
- package/dist/generator/zod/generator/relation-zod-code.d.ts +13 -0
- package/dist/generator/zod/generator/relation-zod-code.js +19 -0
- package/dist/generator/zod/generator/zod-code.d.ts +17 -0
- package/dist/generator/zod/generator/zod-code.js +18 -0
- package/dist/generator/zod/generator/zod.d.ts +16 -0
- package/dist/generator/zod/generator/zod.js +16 -0
- package/dist/generator/zod/generator.d.ts +3 -0
- package/dist/generator/zod/generator.js +14 -0
- package/dist/generator/zod/index.d.ts +15 -3
- package/dist/generator/zod/index.js +50 -73
- package/dist/index.d.ts +8 -0
- package/dist/index.js +71 -0
- package/dist/shared/config/index.d.ts +13 -0
- package/dist/{common → shared}/config/index.js +1 -4
- package/dist/shared/format/index.d.ts +15 -0
- package/dist/shared/format/index.js +24 -0
- package/dist/shared/fs/index.d.ts +7 -0
- package/dist/shared/fs/index.js +16 -0
- package/dist/shared/fsp/index.d.ts +27 -0
- package/dist/shared/fsp/index.js +38 -0
- package/dist/shared/generator/field-definitions.d.ts +12 -0
- package/dist/shared/generator/field-definitions.js +12 -0
- package/dist/shared/helper/ast-parser.d.ts +3 -0
- package/dist/shared/helper/ast-parser.js +202 -0
- package/dist/shared/helper/build-schema-extractor.d.ts +25 -0
- package/dist/shared/helper/build-schema-extractor.js +33 -0
- package/dist/shared/helper/create-extract-field-from-property.d.ts +15 -0
- package/dist/shared/helper/create-extract-field-from-property.js +20 -0
- package/dist/shared/helper/create-extract-fields-from-call-expression.d.ts +14 -0
- package/dist/shared/helper/create-extract-fields-from-call-expression.js +14 -0
- package/dist/shared/helper/create-extract-relation-field-from-property.d.ts +12 -0
- package/dist/shared/helper/create-extract-relation-field-from-property.js +27 -0
- package/dist/shared/helper/extract-schemas.d.ts +133 -0
- package/dist/shared/helper/extract-schemas.js +445 -0
- package/dist/shared/helper/file-writer.d.ts +3 -0
- package/dist/shared/helper/file-writer.js +25 -0
- package/dist/shared/helper/find-object-literal-expression.d.ts +12 -0
- package/dist/shared/helper/find-object-literal-expression.js +31 -0
- package/dist/shared/helper/find-object-literalIn-args.d.ts +2 -0
- package/dist/shared/helper/find-object-literalIn-args.js +8 -0
- package/dist/shared/helper/is-relation-function.d.ts +10 -0
- package/dist/shared/helper/is-relation-function.js +16 -0
- package/dist/shared/types.js +1 -0
- package/dist/{common/text → shared/utils}/capitalize.js +1 -4
- package/dist/shared/utils/compose.d.ts +101 -0
- package/dist/shared/utils/compose.js +124 -0
- package/dist/shared/utils/file.d.ts +92 -0
- package/dist/shared/utils/file.js +177 -0
- package/dist/shared/utils/functional.d.ts +118 -0
- package/dist/shared/utils/functional.js +96 -0
- package/dist/shared/utils/index.d.ts +20 -0
- package/dist/shared/utils/index.js +48 -0
- package/dist/shared/utils/string-utils.d.ts +8 -0
- package/dist/shared/utils/string-utils.js +28 -0
- package/dist/shared/utils/types.d.ts +32 -0
- package/dist/shared/utils/types.js +2 -0
- package/dist/shared/utils/validation-utils.d.ts +8 -0
- package/dist/shared/utils/validation-utils.js +25 -0
- package/dist/src/config/index.d.ts +18 -0
- package/dist/src/config/index.js +13 -0
- package/dist/src/generator/mermaid-er/core/extract-relations.d.ts +8 -0
- package/dist/src/generator/mermaid-er/core/extract-relations.js +12 -0
- package/dist/src/generator/mermaid-er/generator/er-content.d.ts +9 -0
- package/dist/src/generator/mermaid-er/generator/er-content.js +25 -0
- package/dist/src/generator/mermaid-er/generator/index.d.ts +2 -0
- package/dist/src/generator/mermaid-er/generator/index.js +2 -0
- package/dist/src/generator/mermaid-er/generator/relation-line.d.ts +8 -0
- package/dist/src/generator/mermaid-er/generator/relation-line.js +14 -0
- package/dist/src/generator/mermaid-er/index.d.ts +6 -0
- package/dist/src/generator/mermaid-er/index.js +16 -0
- package/dist/src/generator/mermaid-er/relationship/build-relation-line.d.ts +15 -0
- package/dist/src/generator/mermaid-er/relationship/build-relation-line.js +35 -0
- package/dist/src/generator/mermaid-er/types.d.ts +21 -0
- package/dist/src/generator/mermaid-er/types.js +1 -0
- package/dist/src/generator/mermaid-er/validator/index.d.ts +4 -0
- package/dist/src/generator/mermaid-er/validator/index.js +4 -0
- package/dist/src/generator/mermaid-er/validator/is-relationship.d.ts +8 -0
- package/dist/src/generator/mermaid-er/validator/is-relationship.js +9 -0
- package/dist/src/generator/mermaid-er/validator/parse-relation-line.d.ts +13 -0
- package/dist/src/generator/mermaid-er/validator/parse-relation-line.js +21 -0
- package/dist/src/generator/mermaid-er/validator/parse-table-info.d.ts +8 -0
- package/dist/src/generator/mermaid-er/validator/parse-table-info.js +91 -0
- package/dist/src/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +7 -0
- package/dist/src/generator/mermaid-er/validator/remove-duplicate-relations.js +9 -0
- package/dist/src/generator/valibot/generator/infer-input.d.ts +5 -0
- package/dist/src/generator/valibot/generator/infer-input.js +8 -0
- package/dist/src/generator/valibot/generator/valibot-code.d.ts +14 -0
- package/dist/src/generator/valibot/generator/valibot-code.js +16 -0
- package/dist/src/generator/valibot/generator/valibot.d.ts +13 -0
- package/dist/src/generator/valibot/generator/valibot.js +11 -0
- package/dist/src/generator/valibot/index.d.ts +9 -0
- package/dist/src/generator/valibot/index.js +34 -0
- package/dist/src/generator/zod/generator/infer.d.ts +5 -0
- package/dist/src/generator/zod/generator/infer.js +8 -0
- package/dist/{generator/zod/generator/generate-zod-code.d.ts → src/generator/zod/generator/zod-code.d.ts} +8 -3
- package/dist/src/generator/zod/generator/zod-code.js +18 -0
- package/dist/{generator/zod/generator/generate-zod-schema.d.ts → src/generator/zod/generator/zod.d.ts} +8 -4
- package/dist/src/generator/zod/generator/zod.js +12 -0
- package/dist/src/generator/zod/index.d.ts +10 -0
- package/dist/src/generator/zod/index.js +40 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +35 -0
- package/dist/src/shared/format/index.d.ts +2 -0
- package/dist/src/shared/format/index.js +10 -0
- package/dist/src/shared/fs/index.d.ts +2 -0
- package/dist/src/shared/fs/index.js +10 -0
- package/dist/src/shared/fsp/index.d.ts +3 -0
- package/dist/src/shared/fsp/index.js +8 -0
- package/dist/src/shared/generator/field-definitions.d.ts +12 -0
- package/dist/src/shared/generator/field-definitions.js +12 -0
- package/dist/src/shared/helper/build-schema-extractor.d.ts +25 -0
- package/dist/src/shared/helper/build-schema-extractor.js +33 -0
- package/dist/src/shared/helper/create-extract-field-from-property.d.ts +15 -0
- package/dist/src/shared/helper/create-extract-field-from-property.js +20 -0
- package/dist/src/shared/helper/create-extract-fields-from-call-expression.d.ts +14 -0
- package/dist/src/shared/helper/create-extract-fields-from-call-expression.js +14 -0
- package/dist/src/shared/helper/create-extract-relation-field-from-property.d.ts +12 -0
- package/dist/src/shared/helper/create-extract-relation-field-from-property.js +27 -0
- package/dist/src/shared/helper/extract-schemas.d.ts +16 -0
- package/dist/src/shared/helper/extract-schemas.js +19 -0
- package/dist/src/shared/helper/find-object-literal-expression.d.ts +12 -0
- package/dist/src/shared/helper/find-object-literal-expression.js +31 -0
- package/dist/src/shared/helper/find-object-literalIn-args.d.ts +2 -0
- package/dist/src/shared/helper/find-object-literalIn-args.js +8 -0
- package/dist/src/shared/helper/is-relation-function.d.ts +10 -0
- package/dist/src/shared/helper/is-relation-function.js +16 -0
- package/dist/src/shared/utils/index.d.ts +33 -0
- package/dist/src/shared/utils/index.js +61 -0
- package/dist/utils/index.d.ts +144 -0
- package/dist/utils/index.js +301 -0
- package/package.json +10 -13
- package/dist/common/config/index.d.ts +0 -13
- package/dist/common/format/index.d.ts +0 -1
- package/dist/common/format/index.js +0 -12
- package/dist/common/generator/generate-field-definitions.d.ts +0 -8
- package/dist/common/generator/generate-field-definitions.js +0 -16
- package/dist/common/helper/get-camel-case-schema-name-helper.d.ts +0 -7
- package/dist/common/helper/get-camel-case-schema-name-helper.js +0 -14
- package/dist/common/helper/get-pascal-case-schema-name-helper.d.ts +0 -8
- package/dist/common/helper/get-pascal-case-schema-name-helper.js +0 -15
- package/dist/common/helper/get-variable-name-helper.d.ts +0 -9
- package/dist/common/helper/get-variable-name-helper.js +0 -15
- package/dist/common/helper/get-variable-schema-name-helper.d.ts +0 -9
- package/dist/common/helper/get-variable-schema-name-helper.js +0 -17
- package/dist/common/text/decapitalize.d.ts +0 -17
- package/dist/common/text/decapitalize.js +0 -22
- package/dist/common/type/index.js +0 -2
- package/dist/generator/mermaid-er/generator/generate-er-content.d.ts +0 -9
- package/dist/generator/mermaid-er/generator/generate-relation-line.d.ts +0 -7
- package/dist/generator/mermaid-er/type/index.js +0 -2
- package/dist/generator/mermaid-er/validator/is-relation.d.ts +0 -7
- package/dist/generator/mermaid-er/validator/is-relation.js +0 -40
- package/dist/generator/valibot/generator/generate-valibot-code.d.ts +0 -11
- package/dist/generator/valibot/generator/generate-valibot-code.js +0 -21
- package/dist/generator/valibot/generator/generate-valibot-infer-input.d.ts +0 -9
- package/dist/generator/valibot/generator/generate-valibot-infer-input.js +0 -16
- package/dist/generator/valibot/generator/generate-valibot-schema.d.ts +0 -9
- package/dist/generator/valibot/generator/generate-valibot-schema.js +0 -16
- package/dist/generator/zod/generator/generate-z-infer.d.ts +0 -11
- package/dist/generator/zod/generator/generate-z-infer.js +0 -18
- package/dist/generator/zod/generator/generate-zod-code.js +0 -21
- package/dist/generator/zod/generator/generate-zod-schema.js +0 -17
- /package/dist/generator/mermaid-er/{type/index.d.ts → types.d.ts} +0 -0
- /package/dist/{common/type/index.d.ts → shared/types.d.ts} +0 -0
- /package/dist/{common/text → shared/utils}/capitalize.d.ts +0 -0
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
import type { TableInfo } from '../
|
|
2
|
-
/**
|
|
3
|
-
* Parse table info from code
|
|
4
|
-
* @function parseTableInfo
|
|
5
|
-
* @param code - The code to parse the table info from
|
|
6
|
-
* @returns The parsed table info
|
|
7
|
-
*/
|
|
1
|
+
import type { TableInfo } from '../types.js';
|
|
8
2
|
export declare function parseTableInfo(code: string[]): TableInfo[];
|
|
@@ -1,91 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function parseTableInfo(code) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
import { Node, Project } from 'ts-morph';
|
|
2
|
+
const baseBuilderName = (expr) => {
|
|
3
|
+
if (Node.isIdentifier(expr))
|
|
4
|
+
return expr.getText();
|
|
5
|
+
if (Node.isCallExpression(expr) || Node.isPropertyAccessExpression(expr))
|
|
6
|
+
return baseBuilderName(expr.getExpression());
|
|
7
|
+
return '';
|
|
8
|
+
};
|
|
9
|
+
const isFieldInfo = (v) => v !== null;
|
|
10
|
+
export function parseTableInfo(code) {
|
|
11
|
+
const source = code.join('\n');
|
|
12
|
+
const file = new Project({ useInMemoryFileSystem: true }).createSourceFile('temp.ts', source);
|
|
13
|
+
return file
|
|
14
|
+
.getVariableStatements()
|
|
15
|
+
.filter((stmt) => stmt.isExported())
|
|
16
|
+
.flatMap((stmt) => {
|
|
17
|
+
const decl = stmt.getDeclarations()[0];
|
|
18
|
+
if (!Node.isVariableDeclaration(decl))
|
|
19
|
+
return [];
|
|
20
|
+
const varName = decl.getName();
|
|
21
|
+
if (varName.toLowerCase().includes('relation'))
|
|
22
|
+
return [];
|
|
23
|
+
const init = decl.getInitializer();
|
|
24
|
+
if (!(init && Node.isCallExpression(init)))
|
|
25
|
+
return [];
|
|
26
|
+
const callee = init.getExpression().getText();
|
|
27
|
+
if (!callee.endsWith('Table') || callee === 'relations')
|
|
28
|
+
return [];
|
|
29
|
+
const objLit = init.getArguments()[1];
|
|
30
|
+
if (!(objLit && Node.isObjectLiteralExpression(objLit)))
|
|
31
|
+
return [];
|
|
32
|
+
const fields = objLit
|
|
33
|
+
.getProperties()
|
|
34
|
+
.filter(Node.isPropertyAssignment)
|
|
35
|
+
.map((prop) => {
|
|
36
|
+
const keyNode = prop.getNameNode();
|
|
37
|
+
if (!Node.isIdentifier(keyNode))
|
|
38
|
+
return null;
|
|
39
|
+
const fieldName = keyNode.getText();
|
|
40
|
+
const initExpr = prop.getInitializer();
|
|
41
|
+
if (!(initExpr && Node.isCallExpression(initExpr)))
|
|
42
|
+
return null;
|
|
43
|
+
const fieldType = baseBuilderName(initExpr);
|
|
44
|
+
const initText = initExpr.getText();
|
|
45
|
+
const lineIdx = prop.getStartLineNumber() - 1;
|
|
46
|
+
const baseDesc = code
|
|
47
|
+
.slice(0, lineIdx)
|
|
48
|
+
.reverse()
|
|
49
|
+
.find((line) => {
|
|
50
|
+
const t = line.trim();
|
|
51
|
+
return (t.startsWith('///') &&
|
|
52
|
+
!t.includes('@z.') &&
|
|
53
|
+
!t.includes('@v.') &&
|
|
54
|
+
!t.includes('@relation'));
|
|
55
|
+
})
|
|
56
|
+
?.replace(/^\s*\/\/\/\s*/, '') ?? '';
|
|
57
|
+
const prefix = initText.includes('.primaryKey()')
|
|
58
|
+
? '(PK) '
|
|
59
|
+
: initText.includes('.references(')
|
|
60
|
+
? '(FK) '
|
|
61
|
+
: '';
|
|
62
|
+
return {
|
|
63
|
+
name: fieldName,
|
|
64
|
+
type: fieldType,
|
|
65
|
+
description: `${prefix}${baseDesc}`.trim(),
|
|
41
66
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// field info extraction
|
|
47
|
-
if (!acc.currentTable) {
|
|
48
|
-
return acc;
|
|
49
|
-
}
|
|
50
|
-
const fieldMatch = line.match(/^\s*([^:]+):\s*([^(]+)\(/);
|
|
51
|
-
if (fieldMatch) {
|
|
52
|
-
const [_, fieldName, fieldType] = fieldMatch;
|
|
53
|
-
const description = line.includes('.primaryKey()')
|
|
54
|
-
? `(PK) ${acc.currentDescription || ''}`
|
|
55
|
-
: acc.currentDescription || '';
|
|
56
|
-
acc.tempFields.push({
|
|
57
|
-
name: fieldName.trim(),
|
|
58
|
-
type: fieldType.trim(),
|
|
59
|
-
description,
|
|
60
|
-
line: index,
|
|
61
|
-
});
|
|
62
|
-
acc.currentDescription = '';
|
|
63
|
-
return acc;
|
|
64
|
-
}
|
|
65
|
-
// detect foreign key constraint
|
|
66
|
-
if (line.includes('.references') || line.includes('relations')) {
|
|
67
|
-
const lastIndex = acc.tempFields.length - 1;
|
|
68
|
-
if (lastIndex >= 0) {
|
|
69
|
-
const lastField = acc.tempFields[lastIndex];
|
|
70
|
-
acc.tempFields[lastIndex] = {
|
|
71
|
-
name: lastField.name,
|
|
72
|
-
type: lastField.type,
|
|
73
|
-
description: `(FK) ${lastField.description}`,
|
|
74
|
-
line: lastField.line,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
return acc;
|
|
78
|
-
}
|
|
79
|
-
return acc;
|
|
80
|
-
}, initialAccumulator);
|
|
81
|
-
// process fields of the last table
|
|
82
|
-
if (result.currentTable && result.tempFields.length > 0) {
|
|
83
|
-
result.currentTable.fields = result.tempFields.map((field) => ({
|
|
84
|
-
name: field.name,
|
|
85
|
-
type: field.type,
|
|
86
|
-
description: field.description,
|
|
87
|
-
}));
|
|
88
|
-
result.tables.push(result.currentTable);
|
|
89
|
-
}
|
|
90
|
-
return result.tables;
|
|
67
|
+
})
|
|
68
|
+
.filter(isFieldInfo);
|
|
69
|
+
return [{ name: varName, fields }];
|
|
70
|
+
});
|
|
91
71
|
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.removeDuplicateRelations = removeDuplicateRelations;
|
|
4
1
|
/**
|
|
5
2
|
* Remove duplicate relations
|
|
6
3
|
* @function removeDuplicateRelations
|
|
7
4
|
* @param relations - The relations to remove duplicates from
|
|
8
5
|
* @returns The relations without duplicates
|
|
9
6
|
*/
|
|
10
|
-
function removeDuplicateRelations(relations) {
|
|
7
|
+
export function removeDuplicateRelations(relations) {
|
|
11
8
|
return [...new Set(relations)];
|
|
12
9
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Config } from '../../../
|
|
1
|
+
import type { Config } from '../../../shared/config/index.js'
|
|
2
2
|
/**
|
|
3
3
|
* Loads the configuration from the `sizuku.json` file or returns the default configuration.
|
|
4
4
|
*
|
|
5
5
|
* @returns The configuration object.
|
|
6
6
|
*/
|
|
7
|
-
export declare function getConfig(): Config
|
|
7
|
+
export declare function getConfig(): Config
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getConfig = getConfig;
|
|
7
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const config_1 = require("../../../common/config");
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { DEFAULT_CONFIG } from '../../../shared/config/index.js';
|
|
9
3
|
/**
|
|
10
4
|
* Loads the configuration from the `sizuku.json` file or returns the default configuration.
|
|
11
5
|
*
|
|
12
6
|
* @returns The configuration object.
|
|
13
7
|
*/
|
|
14
|
-
function getConfig() {
|
|
15
|
-
const config =
|
|
16
|
-
? { ...
|
|
17
|
-
:
|
|
8
|
+
export function getConfig() {
|
|
9
|
+
const config = fs.existsSync('sizuku-valibot.json')
|
|
10
|
+
? { ...DEFAULT_CONFIG, ...JSON.parse(fs.readFileSync('sizuku-valibot.json', 'utf-8')) }
|
|
11
|
+
: DEFAULT_CONFIG;
|
|
18
12
|
return config;
|
|
19
13
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import type { Schema } from '../../../
|
|
1
|
+
import type { Schema } from '../../../shared/types.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* @function extractSchemas
|
|
5
|
-
* @param lines - Lines of code
|
|
6
|
-
* @returns Schemas
|
|
3
|
+
* Public API: extract schemas from code lines
|
|
7
4
|
*/
|
|
8
5
|
export declare function extractSchemas(lines: string[]): Schema[];
|
|
@@ -1,92 +1,173 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractSchemas = extractSchemas;
|
|
1
|
+
import { Node, Project } from 'ts-morph';
|
|
4
2
|
/**
|
|
5
|
-
* Check if line
|
|
3
|
+
* Check if the comment line is metadata (Zod / Valibot / relation helper)
|
|
6
4
|
*/
|
|
7
|
-
const isMetadataComment = (
|
|
8
|
-
return
|
|
5
|
+
const isMetadataComment = (text) => {
|
|
6
|
+
return text.includes('@z.') || text.includes('@v.') || text.includes('@relation.');
|
|
9
7
|
};
|
|
10
8
|
/**
|
|
11
|
-
*
|
|
12
|
-
* @function extractSchemas
|
|
13
|
-
* @param lines - Lines of code
|
|
14
|
-
* @returns Schemas
|
|
9
|
+
* Collect consecutive `///` comment lines that appear immediately above a field.
|
|
15
10
|
*/
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
11
|
+
const extractFieldComments = (sourceText, fieldStartPos) => {
|
|
12
|
+
const beforeField = sourceText.substring(0, fieldStartPos);
|
|
13
|
+
const lines = beforeField.split('\n');
|
|
14
|
+
return lines
|
|
15
|
+
.map((line) => line.trim())
|
|
16
|
+
.reverse()
|
|
17
|
+
.reduce((acc, line) => {
|
|
18
|
+
if (acc.stop)
|
|
19
19
|
return acc;
|
|
20
|
+
if (line.startsWith('///')) {
|
|
21
|
+
return { commentLines: [line, ...acc.commentLines], stop: false };
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
23
|
+
if (line === '')
|
|
24
|
+
return acc;
|
|
25
|
+
return { commentLines: acc.commentLines, stop: true };
|
|
26
|
+
}, { commentLines: [], stop: false }).commentLines;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Parse the collected comment lines -> { valibotDefinition, description }
|
|
30
|
+
*/
|
|
31
|
+
const parseFieldComments = (commentLines) => {
|
|
32
|
+
const cleaned = commentLines.map((l) => l.replace(/^\/\/\/\s*/, '').trim()).filter(Boolean);
|
|
33
|
+
const valibotDefinition = cleaned.find((l) => l.startsWith('@v.'))?.replace(/^@/, '') ?? '';
|
|
34
|
+
const descriptionLines = cleaned.filter((l) => !isMetadataComment(l));
|
|
35
|
+
const description = descriptionLines.length ? descriptionLines.join(' ') : undefined;
|
|
36
|
+
return { valibotDefinition, description };
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Convert table name to Schema name (e.g. `user` -> `UserSchema`)
|
|
40
|
+
*/
|
|
41
|
+
const toSchemaName = (table) => `${table.charAt(0).toUpperCase() + table.slice(1)}Schema`;
|
|
42
|
+
/**
|
|
43
|
+
* Extract an ordinary column field.
|
|
44
|
+
*/
|
|
45
|
+
const extractFieldFromProperty = (property, sourceText) => {
|
|
46
|
+
if (!Node.isPropertyAssignment(property))
|
|
47
|
+
return null;
|
|
48
|
+
const name = property.getName();
|
|
49
|
+
if (!name)
|
|
50
|
+
return null;
|
|
51
|
+
const commentLines = extractFieldComments(sourceText, property.getStart());
|
|
52
|
+
const { valibotDefinition, description } = parseFieldComments(commentLines);
|
|
53
|
+
return { name, definition: valibotDefinition, description };
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Extract a relation field (many / one) and infer Valibot schema.
|
|
57
|
+
*/
|
|
58
|
+
const extractRelationFieldFromProperty = (property, sourceText) => {
|
|
59
|
+
if (!Node.isPropertyAssignment(property))
|
|
60
|
+
return null;
|
|
61
|
+
const name = property.getName();
|
|
62
|
+
if (!name)
|
|
63
|
+
return null;
|
|
64
|
+
const init = property.getInitializer();
|
|
65
|
+
if (!Node.isCallExpression(init))
|
|
66
|
+
return { name, definition: '', description: undefined };
|
|
67
|
+
const expr = init.getExpression();
|
|
68
|
+
if (!Node.isIdentifier(expr))
|
|
69
|
+
return { name, definition: '', description: undefined };
|
|
70
|
+
const fnName = expr.getText();
|
|
71
|
+
const args = init.getArguments();
|
|
72
|
+
if (!(args.length && Node.isIdentifier(args[0])))
|
|
73
|
+
return { name, definition: '', description: undefined };
|
|
74
|
+
const refTable = args[0].getText();
|
|
75
|
+
const schemaName = toSchemaName(refTable);
|
|
76
|
+
const definition = fnName === 'many' ? `v.array(${schemaName})` : fnName === 'one' ? schemaName : '';
|
|
77
|
+
const commentLines = extractFieldComments(sourceText, property.getStart());
|
|
78
|
+
const { description } = parseFieldComments(commentLines);
|
|
79
|
+
return { name, definition, description };
|
|
80
|
+
};
|
|
81
|
+
/** Utility: unwrap arrow / paren / etc. until ObjectLiteralExpression or null */
|
|
82
|
+
const extractObjectLiteralFromExpression = (expr) => {
|
|
83
|
+
if (Node.isObjectLiteralExpression(expr))
|
|
84
|
+
return expr;
|
|
85
|
+
if (Node.isParenthesizedExpression(expr))
|
|
86
|
+
return extractObjectLiteralFromExpression(expr.getExpression());
|
|
87
|
+
if (Node.isArrowFunction(expr)) {
|
|
88
|
+
const body = expr.getBody();
|
|
89
|
+
if (Node.isObjectLiteralExpression(body))
|
|
90
|
+
return body;
|
|
91
|
+
if (Node.isParenthesizedExpression(body))
|
|
92
|
+
return extractObjectLiteralFromExpression(body.getExpression());
|
|
93
|
+
if (Node.isBlock(body)) {
|
|
94
|
+
const ret = body.getStatements().find(Node.isReturnStatement);
|
|
95
|
+
if (ret && Node.isReturnStatement(ret)) {
|
|
96
|
+
const re = ret.getExpression();
|
|
97
|
+
return re && Node.isObjectLiteralExpression(re) ? re : null;
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
|
-
return process(i + 1, acc);
|
|
86
|
-
};
|
|
87
|
-
const finalAcc = process(0, { currentSchema: null, pendingDescription: undefined, schemas: [] });
|
|
88
|
-
if (finalAcc.currentSchema) {
|
|
89
|
-
finalAcc.schemas.push(finalAcc.currentSchema);
|
|
90
100
|
}
|
|
91
|
-
return
|
|
101
|
+
return null;
|
|
102
|
+
};
|
|
103
|
+
/** find the first object literal among call expression arguments */
|
|
104
|
+
const findObjectLiteralInArgs = (call) => {
|
|
105
|
+
for (const arg of call.getArguments()) {
|
|
106
|
+
const obj = extractObjectLiteralFromExpression(arg);
|
|
107
|
+
if (obj)
|
|
108
|
+
return obj;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
};
|
|
112
|
+
/** recognise `relations()` / `somethingRelation*` helpers */
|
|
113
|
+
const isRelationFunction = (call) => {
|
|
114
|
+
const expr = call.getExpression();
|
|
115
|
+
return (Node.isIdentifier(expr) &&
|
|
116
|
+
(expr.getText() === 'relations' || expr.getText().includes('relation')));
|
|
117
|
+
};
|
|
118
|
+
/** extract fields from mysqlTable / relations call expression */
|
|
119
|
+
const extractFieldsFromCallExpression = (call, sourceText) => {
|
|
120
|
+
const obj = findObjectLiteralInArgs(call);
|
|
121
|
+
if (!obj)
|
|
122
|
+
return [];
|
|
123
|
+
const relation = isRelationFunction(call);
|
|
124
|
+
return obj
|
|
125
|
+
.getProperties()
|
|
126
|
+
.map((p) => relation
|
|
127
|
+
? extractRelationFieldFromProperty(p, sourceText)
|
|
128
|
+
: extractFieldFromProperty(p, sourceText))
|
|
129
|
+
.filter((f) => f !== null);
|
|
130
|
+
};
|
|
131
|
+
/** extract a single schema from variable declaration */
|
|
132
|
+
const extractSchemaFromDeclaration = (decl, sourceText) => {
|
|
133
|
+
if (!Node.isVariableDeclaration(decl))
|
|
134
|
+
return null;
|
|
135
|
+
const name = decl.getName();
|
|
136
|
+
if (!name)
|
|
137
|
+
return null;
|
|
138
|
+
const init = decl.getInitializer();
|
|
139
|
+
// Handle call expressions (mysqlTable, relations, etc.)
|
|
140
|
+
if (Node.isCallExpression(init)) {
|
|
141
|
+
// ⛔ Skip relation helper exports (userRelations / postRelations ...)
|
|
142
|
+
if (isRelationFunction(init))
|
|
143
|
+
return null;
|
|
144
|
+
const fields = extractFieldsFromCallExpression(init, sourceText);
|
|
145
|
+
return { name, fields };
|
|
146
|
+
}
|
|
147
|
+
// Direct object literal export
|
|
148
|
+
if (Node.isObjectLiteralExpression(init)) {
|
|
149
|
+
const fields = init
|
|
150
|
+
.getProperties()
|
|
151
|
+
.map((p) => extractFieldFromProperty(p, sourceText))
|
|
152
|
+
.filter((f) => f !== null);
|
|
153
|
+
return { name, fields };
|
|
154
|
+
}
|
|
155
|
+
return { name, fields: [] };
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Public API: extract schemas from code lines
|
|
159
|
+
*/
|
|
160
|
+
export function extractSchemas(lines) {
|
|
161
|
+
const project = new Project({
|
|
162
|
+
useInMemoryFileSystem: true,
|
|
163
|
+
compilerOptions: { allowJs: true, skipLibCheck: true },
|
|
164
|
+
});
|
|
165
|
+
const file = project.createSourceFile('temp.ts', lines.join('\n'));
|
|
166
|
+
const fullText = file.getFullText();
|
|
167
|
+
return file
|
|
168
|
+
.getVariableStatements()
|
|
169
|
+
.filter((s) => s.hasExportKeyword())
|
|
170
|
+
.flatMap((s) => s.getDeclarations())
|
|
171
|
+
.map((d) => extractSchemaFromDeclaration(d, fullText))
|
|
172
|
+
.filter((s) => s !== null);
|
|
92
173
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TableInfo, ColumnInfo } from '../../shared/utils/types.js';
|
|
2
|
+
export declare const generateValibotSchema: (table: TableInfo) => string;
|
|
3
|
+
export declare const generateValibotProperty: (column: ColumnInfo) => string;
|
|
4
|
+
export declare const generateDefaultValibotSchema: (column: ColumnInfo) => string;
|
|
5
|
+
export declare const generateValibotFile: (tables: TableInfo[]) => string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// 完全純粋なValibotスキーマ生成ユーティリティ - 外部import禁止
|
|
2
|
+
import { toPascalCase } from '../../shared/utils/string-utils.js';
|
|
3
|
+
export const generateValibotSchema = (table) => {
|
|
4
|
+
const schemaName = `${toPascalCase(table.name)}Schema`;
|
|
5
|
+
const typeName = toPascalCase(table.name);
|
|
6
|
+
const properties = table.columns.map(column => generateValibotProperty(column)).join('\n ');
|
|
7
|
+
return `export const ${schemaName} = v.object({
|
|
8
|
+
${properties}
|
|
9
|
+
})
|
|
10
|
+
export type ${typeName} = v.InferInput<typeof ${schemaName}>`;
|
|
11
|
+
};
|
|
12
|
+
export const generateValibotProperty = (column) => {
|
|
13
|
+
const comment = column.comment ? `/** ${column.comment} */\n ` : '';
|
|
14
|
+
const schema = column.valibotSchema || generateDefaultValibotSchema(column);
|
|
15
|
+
return `${comment}${column.name}: ${schema},`;
|
|
16
|
+
};
|
|
17
|
+
export const generateDefaultValibotSchema = (column) => {
|
|
18
|
+
if (column.type === 'varchar') {
|
|
19
|
+
if (column.length === 36) {
|
|
20
|
+
return 'v.pipe(v.string(), v.uuid())';
|
|
21
|
+
}
|
|
22
|
+
if (column.length) {
|
|
23
|
+
return `v.pipe(v.string(), v.maxLength(${column.length}))`;
|
|
24
|
+
}
|
|
25
|
+
return 'v.string()';
|
|
26
|
+
}
|
|
27
|
+
if (column.type === 'int') {
|
|
28
|
+
return 'v.pipe(v.number(), v.integer())';
|
|
29
|
+
}
|
|
30
|
+
if (column.type === 'text') {
|
|
31
|
+
return 'v.string()';
|
|
32
|
+
}
|
|
33
|
+
return 'v.unknown()';
|
|
34
|
+
};
|
|
35
|
+
export const generateValibotFile = (tables) => {
|
|
36
|
+
const imports = 'import * as v from \'valibot\'\n\n';
|
|
37
|
+
const schemas = tables.map(table => generateValibotSchema(table)).join('\n\n');
|
|
38
|
+
return imports + schemas;
|
|
39
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates Valibot relation schema code from a relation schema AST extraction.
|
|
3
|
+
*/
|
|
4
|
+
export declare function relationValibotCode(schema: {
|
|
5
|
+
name: string;
|
|
6
|
+
baseName: string;
|
|
7
|
+
fields: {
|
|
8
|
+
name: string;
|
|
9
|
+
definition: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
}[];
|
|
12
|
+
objectType?: 'strict' | 'loose';
|
|
13
|
+
}, withType: boolean): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { capitalize, inferInput } from '../../../utils/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Valibot relation schema code from a relation schema AST extraction.
|
|
4
|
+
*/
|
|
5
|
+
export function relationValibotCode(schema, withType) {
|
|
6
|
+
const base = schema.baseName;
|
|
7
|
+
const relName = `${schema.name}Schema`;
|
|
8
|
+
const baseSchema = `${capitalize(base)}Schema`;
|
|
9
|
+
const fields = schema.fields.map((f) => `${f.name}:${f.definition}`).join(',');
|
|
10
|
+
const objectType = schema.objectType === 'strict'
|
|
11
|
+
? 'strictObject'
|
|
12
|
+
: schema.objectType === 'loose'
|
|
13
|
+
? 'looseObject'
|
|
14
|
+
: 'object';
|
|
15
|
+
const obj = `\nexport const ${capitalize(relName)} = v.${objectType}({...${baseSchema}.entries,${fields}})`;
|
|
16
|
+
if (withType)
|
|
17
|
+
return `${obj}\n\n${inferInput(schema.name)}\n`;
|
|
18
|
+
return `${obj}`;
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param schema
|
|
3
|
+
* @param comment
|
|
4
|
+
* @param type
|
|
5
|
+
* @returns
|
|
6
|
+
*/
|
|
7
|
+
export declare function valibotCode(schema: {
|
|
8
|
+
name: string;
|
|
9
|
+
fields: {
|
|
10
|
+
name: string;
|
|
11
|
+
definition: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
}[];
|
|
14
|
+
objectType?: 'strict' | 'loose';
|
|
15
|
+
}, comment: boolean, type: boolean): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { inferInput } from '../../../utils/index.js';
|
|
2
|
+
import { valibot } from './valibot.js';
|
|
3
|
+
/**
|
|
4
|
+
* @param schema
|
|
5
|
+
* @param comment
|
|
6
|
+
* @param type
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export function valibotCode(schema, comment, type) {
|
|
10
|
+
const valibotSchema = valibot(schema, comment);
|
|
11
|
+
if (type) {
|
|
12
|
+
const valibotInfer = inferInput(schema.name);
|
|
13
|
+
return `${valibotSchema}\n\n${valibotInfer}\n`;
|
|
14
|
+
}
|
|
15
|
+
return `${valibotSchema}\n`;
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param schema
|
|
3
|
+
* @param config
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export declare function valibot(schema: {
|
|
7
|
+
name: string;
|
|
8
|
+
fields: {
|
|
9
|
+
name: string;
|
|
10
|
+
definition: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
}[];
|
|
13
|
+
objectType?: 'strict' | 'loose';
|
|
14
|
+
}, comment: boolean): string;
|