sizuku 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +471 -0
- package/dist/common/config/index.d.ts +13 -0
- package/dist/common/config/index.js +13 -0
- package/dist/common/format/index.d.ts +1 -0
- package/dist/common/format/index.js +12 -0
- package/dist/common/generator/generate-field-definitions.d.ts +8 -0
- package/dist/common/generator/generate-field-definitions.js +16 -0
- package/dist/common/helper/get-camel-case-schema-name-helper.d.ts +7 -0
- package/dist/common/helper/get-camel-case-schema-name-helper.js +14 -0
- package/dist/common/helper/get-pascal-case-schema-name-helper.d.ts +8 -0
- package/dist/common/helper/get-pascal-case-schema-name-helper.js +15 -0
- package/dist/common/helper/get-variable-name-helper.d.ts +9 -0
- package/dist/common/helper/get-variable-name-helper.js +15 -0
- package/dist/common/helper/get-variable-schema-name-helper.d.ts +9 -0
- package/dist/common/helper/get-variable-schema-name-helper.js +17 -0
- package/dist/common/text/capitalize.d.ts +18 -0
- package/dist/common/text/capitalize.js +23 -0
- package/dist/common/text/decapitalize.d.ts +17 -0
- package/dist/common/text/decapitalize.js +22 -0
- package/dist/common/type/index.d.ts +9 -0
- package/dist/common/type/index.js +2 -0
- package/dist/generator/mermaid-er/config/index.d.ts +10 -0
- package/dist/generator/mermaid-er/config/index.js +18 -0
- package/dist/generator/mermaid-er/core/extract-relations.d.ts +8 -0
- package/dist/generator/mermaid-er/core/extract-relations.js +20 -0
- package/dist/generator/mermaid-er/generator/generate-er-content.d.ts +9 -0
- package/dist/generator/mermaid-er/generator/generate-er-content.js +27 -0
- package/dist/generator/mermaid-er/generator/generate-relation-line.d.ts +7 -0
- package/dist/generator/mermaid-er/generator/generate-relation-line.js +16 -0
- package/dist/generator/mermaid-er/index.d.ts +7 -0
- package/dist/generator/mermaid-er/index.js +102 -0
- package/dist/generator/mermaid-er/type/index.d.ts +40 -0
- package/dist/generator/mermaid-er/type/index.js +2 -0
- package/dist/generator/mermaid-er/validator/is-relation.d.ts +7 -0
- package/dist/generator/mermaid-er/validator/is-relation.js +40 -0
- package/dist/generator/mermaid-er/validator/parse-relation-line.d.ts +12 -0
- package/dist/generator/mermaid-er/validator/parse-relation-line.js +28 -0
- package/dist/generator/mermaid-er/validator/parse-table-info.d.ts +8 -0
- package/dist/generator/mermaid-er/validator/parse-table-info.js +91 -0
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +7 -0
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.js +12 -0
- package/dist/generator/valibot/config/index.d.ts +7 -0
- package/dist/generator/valibot/config/index.js +19 -0
- package/dist/generator/valibot/core/extract-schema.d.ts +8 -0
- package/dist/generator/valibot/core/extract-schema.js +92 -0
- package/dist/generator/valibot/generator/generate-valibot-code.d.ts +11 -0
- package/dist/generator/valibot/generator/generate-valibot-code.js +21 -0
- package/dist/generator/valibot/generator/generate-valibot-infer-input.d.ts +9 -0
- package/dist/generator/valibot/generator/generate-valibot-infer-input.js +16 -0
- package/dist/generator/valibot/generator/generate-valibot-schema.d.ts +9 -0
- package/dist/generator/valibot/generator/generate-valibot-schema.js +16 -0
- package/dist/generator/valibot/index.d.ts +3 -0
- package/dist/generator/valibot/index.js +77 -0
- package/dist/generator/zod/config/index.d.ts +8 -0
- package/dist/generator/zod/config/index.js +20 -0
- package/dist/generator/zod/core/extract-schema.d.ts +8 -0
- package/dist/generator/zod/core/extract-schema.js +96 -0
- package/dist/generator/zod/generator/generate-z-infer.d.ts +11 -0
- package/dist/generator/zod/generator/generate-z-infer.js +18 -0
- package/dist/generator/zod/generator/generate-zod-code.d.ts +11 -0
- package/dist/generator/zod/generator/generate-zod-code.js +21 -0
- package/dist/generator/zod/generator/generate-zod-schema.d.ts +11 -0
- package/dist/generator/zod/generator/generate-zod-schema.js +17 -0
- package/dist/generator/zod/index.d.ts +3 -0
- package/dist/generator/zod/index.js +77 -0
- package/package.json +55 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decapitalizes the first letter of a string
|
|
3
|
+
*
|
|
4
|
+
* @function decapitalize
|
|
5
|
+
* @param str - String to decapitalize
|
|
6
|
+
* @returns String with the first letter in lowercase
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* decapitalize('Posts') // Returns: 'posts'
|
|
10
|
+
* decapitalize('User') // Returns: 'user'
|
|
11
|
+
* decapitalize('Api') // Returns: 'api'
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* - Leaves the rest of the string unchanged
|
|
15
|
+
* - Returns an empty string if the input is empty
|
|
16
|
+
*/
|
|
17
|
+
export declare function decapitalize(str: string): string
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decapitalize = decapitalize;
|
|
4
|
+
/**
|
|
5
|
+
* Decapitalizes the first letter of a string
|
|
6
|
+
*
|
|
7
|
+
* @function decapitalize
|
|
8
|
+
* @param str - String to decapitalize
|
|
9
|
+
* @returns String with the first letter in lowercase
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* decapitalize('Posts') // Returns: 'posts'
|
|
13
|
+
* decapitalize('User') // Returns: 'user'
|
|
14
|
+
* decapitalize('Api') // Returns: 'api'
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* - Leaves the rest of the string unchanged
|
|
18
|
+
* - Returns an empty string if the input is empty
|
|
19
|
+
*/
|
|
20
|
+
function decapitalize(str) {
|
|
21
|
+
return `${str.charAt(0).toLowerCase()}${str.slice(1)}`;
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
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
|
+
/**
|
|
9
|
+
* Loads the configuration from the `sizuku.json` file or returns the default configuration.
|
|
10
|
+
*
|
|
11
|
+
* @returns The configuration object.
|
|
12
|
+
*/
|
|
13
|
+
function getConfig() {
|
|
14
|
+
const config = node_fs_1.default.existsSync('sizuku-mermaid-er.json')
|
|
15
|
+
? { ...JSON.parse(node_fs_1.default.readFileSync('sizuku-mermaid-er.json', 'utf-8')) }
|
|
16
|
+
: {};
|
|
17
|
+
return config;
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractRelations = extractRelations;
|
|
4
|
+
const parse_relation_line_1 = require("../validator/parse-relation-line");
|
|
5
|
+
/**
|
|
6
|
+
* Extracts relations from the given code.
|
|
7
|
+
*
|
|
8
|
+
* @param code - The code to extract relations from.
|
|
9
|
+
* @returns The extracted relations.
|
|
10
|
+
*/
|
|
11
|
+
function extractRelations(code) {
|
|
12
|
+
const relations = [];
|
|
13
|
+
for (const line of code) {
|
|
14
|
+
const relation = (0, parse_relation_line_1.parseRelationLine)(line);
|
|
15
|
+
if (relation) {
|
|
16
|
+
relations.push(relation);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return relations;
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Relation, TableInfo } from '../type'
|
|
2
|
+
/**
|
|
3
|
+
* Generate ER content
|
|
4
|
+
* @function generateERContent
|
|
5
|
+
* @param relations - The relations to generate the ER content from
|
|
6
|
+
* @param tables - The tables to generate the ER content from
|
|
7
|
+
* @returns The generated ER content
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateERContent(relations: Relation[], tables: TableInfo[]): string
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateERContent = generateERContent;
|
|
4
|
+
const generate_relation_line_1 = require("./generate-relation-line");
|
|
5
|
+
const ER_HEADER = ['```mermaid', 'erDiagram'];
|
|
6
|
+
const ER_FOOTER = ['```'];
|
|
7
|
+
/**
|
|
8
|
+
* Generate ER content
|
|
9
|
+
* @function generateERContent
|
|
10
|
+
* @param relations - The relations to generate the ER content from
|
|
11
|
+
* @param tables - The tables to generate the ER content from
|
|
12
|
+
* @returns The generated ER content
|
|
13
|
+
*/
|
|
14
|
+
function generateERContent(relations, tables) {
|
|
15
|
+
const erContent = [
|
|
16
|
+
...ER_HEADER,
|
|
17
|
+
...relations.map(generate_relation_line_1.generateRelationLine),
|
|
18
|
+
// Generate per-table definitions
|
|
19
|
+
...tables.flatMap((table) => [
|
|
20
|
+
` ${table.name} {`,
|
|
21
|
+
...table.fields.map((field) => ` ${field.type} ${field.name} ${field.description ? `"${field.description}"` : ''}`),
|
|
22
|
+
' }',
|
|
23
|
+
]),
|
|
24
|
+
...ER_FOOTER,
|
|
25
|
+
];
|
|
26
|
+
return erContent.join('\n');
|
|
27
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Relation } from '../type'
|
|
2
|
+
/**
|
|
3
|
+
* Generate a relation line for a relation
|
|
4
|
+
* @param relation - The relation to generate a line for
|
|
5
|
+
* @returns The generated relation line
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateRelationLine(relation: Relation): string
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateRelationLine = generateRelationLine;
|
|
4
|
+
const __1 = require("..");
|
|
5
|
+
/**
|
|
6
|
+
* Generate a relation line for a relation
|
|
7
|
+
* @param relation - The relation to generate a line for
|
|
8
|
+
* @returns The generated relation line
|
|
9
|
+
*/
|
|
10
|
+
function generateRelationLine(relation) {
|
|
11
|
+
const cardinality = __1.CARDINALITY_MAP[relation.type];
|
|
12
|
+
if (!cardinality) {
|
|
13
|
+
throw new Error(`Unknown relation type: ${relation.type}`);
|
|
14
|
+
}
|
|
15
|
+
return ` ${relation.fromModel} ${cardinality} ${relation.toModel} : "(${relation.fromField}) - (${relation.toField})"`;
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import type { Config } from './config'
|
|
3
|
+
import type { RelationType } from './type'
|
|
4
|
+
export declare const CARDINALITY_MAP: Record<RelationType, string>
|
|
5
|
+
export declare const ER_HEADER: readonly ['```mermaid', 'erDiagram']
|
|
6
|
+
export declare const ER_FOOTER: readonly ['```']
|
|
7
|
+
export declare function main(dev?: boolean, config?: Config): Promise<boolean>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ER_FOOTER = exports.ER_HEADER = exports.CARDINALITY_MAP = void 0;
|
|
8
|
+
exports.main = main;
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const generate_er_content_1 = require("./generator/generate-er-content");
|
|
12
|
+
const parse_table_info_1 = require("./validator/parse-table-info");
|
|
13
|
+
const extract_relations_1 = require("./core/extract-relations");
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const node_process_1 = require("node:process");
|
|
16
|
+
exports.CARDINALITY_MAP = {
|
|
17
|
+
// both required
|
|
18
|
+
'one-to-one': '||--||', // 1--1
|
|
19
|
+
'one-to-many': '||--o{', // 1--*
|
|
20
|
+
'many-to-one': '}o--||', // *--1
|
|
21
|
+
'many-to-many': '}o--o{', // *--*
|
|
22
|
+
// one side optional
|
|
23
|
+
'one-to-zero-one': '||--o|', // 1--0..1
|
|
24
|
+
'zero-one-to-one': 'o|--||', // 0..1--1
|
|
25
|
+
'zero-to-many': 'o|--o{', // 0--*
|
|
26
|
+
'many-to-zero-one': '}o--o|', // *--0..1
|
|
27
|
+
'zero-one-to-many': 'o|--o{', // 0..1--*
|
|
28
|
+
// o o
|
|
29
|
+
'zero-to-one': 'o|--o|', // 0--0..1
|
|
30
|
+
'zero-to-zero-one': 'o|--o|', // 0--0..1
|
|
31
|
+
// ..
|
|
32
|
+
'one-to-many-optional': '||..o{', // 1..*
|
|
33
|
+
'one-to-one-optional': '||..||', // 1..1
|
|
34
|
+
'many-to-many-optional': '}o..o{', // *..*
|
|
35
|
+
'zero-one-to-zero-one': 'o|..o|', // 0..1--0..1
|
|
36
|
+
'many-to-zero-many': '}o..o{', // *--0..*
|
|
37
|
+
'zero-many-to-many': 'o{..}o', // 0..*--*
|
|
38
|
+
'zero-many-to-zero-many': 'o{..o{', // 0..*--0..*
|
|
39
|
+
};
|
|
40
|
+
// ER diagram header
|
|
41
|
+
exports.ER_HEADER = ['```mermaid', 'erDiagram'];
|
|
42
|
+
// ER diagram footer
|
|
43
|
+
exports.ER_FOOTER = ['```'];
|
|
44
|
+
async function main(dev = false, config = (0, config_1.getConfig)()) {
|
|
45
|
+
// 1. argv ['**/bin/node', '**/dist/src/generator/mermaid-er/index.js', 'db/schema.ts', '-o', 'mermaid-er/ER.md']
|
|
46
|
+
console.log(config.output);
|
|
47
|
+
if (config.output === undefined && !node_process_1.argv.includes('-o')) {
|
|
48
|
+
console.error('Error: -o is not found');
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// 2. slice [ 'db/schema.ts', '-o', 'mermaid-er/ER.md']
|
|
52
|
+
const args = process.argv.slice(2);
|
|
53
|
+
// 3. input = args[0] = 'db/schema.ts'
|
|
54
|
+
const input = config.input ?? args[0];
|
|
55
|
+
config.input = input;
|
|
56
|
+
// 4. output = 'mermaid-er/ER.md'
|
|
57
|
+
const output = config.output ?? args[args.indexOf('-o') + 1];
|
|
58
|
+
config.output = output;
|
|
59
|
+
try {
|
|
60
|
+
// 5. read db/schema.ts
|
|
61
|
+
const content = (0, node_fs_1.readFileSync)(input, 'utf-8');
|
|
62
|
+
// 6. split lines
|
|
63
|
+
const lines = content.split('\n');
|
|
64
|
+
// 7. create output directory
|
|
65
|
+
const outputDir = node_path_1.default.dirname(output);
|
|
66
|
+
if (!(0, node_fs_1.existsSync)(outputDir)) {
|
|
67
|
+
(0, node_fs_1.mkdirSync)(outputDir, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
// 8. skip import section
|
|
70
|
+
const codeStart = lines.findIndex((line) => !line.trim().startsWith('import') && line.trim() !== '');
|
|
71
|
+
// 9. parse table info
|
|
72
|
+
const tables = (0, parse_table_info_1.parseTableInfo)(lines.slice(codeStart));
|
|
73
|
+
// 10. extract relations
|
|
74
|
+
const relations = (0, extract_relations_1.extractRelations)(lines.slice(codeStart));
|
|
75
|
+
// 11. generate ER content
|
|
76
|
+
const ERContent = (0, generate_er_content_1.generateERContent)(relations, tables);
|
|
77
|
+
// 12. write ER content to output file
|
|
78
|
+
(0, node_fs_1.writeFileSync)(output, ERContent);
|
|
79
|
+
console.log(`Generated ER at: ${output}`);
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
if (e instanceof Error) {
|
|
84
|
+
console.error(e.message);
|
|
85
|
+
if (dev) {
|
|
86
|
+
throw e;
|
|
87
|
+
}
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
if (dev) {
|
|
91
|
+
throw new Error('Unknown error occurred');
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (require.main === module) {
|
|
97
|
+
main().then((success) => {
|
|
98
|
+
if (!success) {
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type RelationType =
|
|
2
|
+
| 'one-to-one'
|
|
3
|
+
| 'one-to-many'
|
|
4
|
+
| 'many-to-one'
|
|
5
|
+
| 'many-to-many'
|
|
6
|
+
| 'one-to-zero-one'
|
|
7
|
+
| 'zero-one-to-one'
|
|
8
|
+
| 'zero-to-many'
|
|
9
|
+
| 'many-to-zero-one'
|
|
10
|
+
| 'zero-one-to-many'
|
|
11
|
+
| 'zero-to-one'
|
|
12
|
+
| 'zero-to-zero-one'
|
|
13
|
+
| 'one-to-many-optional'
|
|
14
|
+
| 'one-to-one-optional'
|
|
15
|
+
| 'many-to-many-optional'
|
|
16
|
+
| 'zero-one-to-zero-one'
|
|
17
|
+
| 'many-to-zero-many'
|
|
18
|
+
| 'zero-many-to-many'
|
|
19
|
+
| 'zero-many-to-zero-many'
|
|
20
|
+
export type Relation = {
|
|
21
|
+
fromModel: string
|
|
22
|
+
toModel: string
|
|
23
|
+
fromField: string
|
|
24
|
+
toField: string
|
|
25
|
+
type: RelationType
|
|
26
|
+
}
|
|
27
|
+
export type ERContent = readonly string[]
|
|
28
|
+
export type TableInfo = {
|
|
29
|
+
name: string
|
|
30
|
+
fields: {
|
|
31
|
+
type: string
|
|
32
|
+
name: string
|
|
33
|
+
description: string | null
|
|
34
|
+
}[]
|
|
35
|
+
}
|
|
36
|
+
export type AccumulatorType = {
|
|
37
|
+
tables: TableInfo[]
|
|
38
|
+
currentTable: TableInfo | null
|
|
39
|
+
currentDescription: string
|
|
40
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RelationType } from '../type'
|
|
2
|
+
/**
|
|
3
|
+
* Validate if a value is a valid relation type
|
|
4
|
+
* @param value - The value to validate
|
|
5
|
+
* @returns True if the value is a valid relation type, false otherwise
|
|
6
|
+
*/
|
|
7
|
+
export declare function isRelation(value: unknown): value is RelationType
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRelation = isRelation;
|
|
4
|
+
const VALID_RELATIONS = new Set([
|
|
5
|
+
// Required Relationships
|
|
6
|
+
'one-to-one',
|
|
7
|
+
'one-to-many',
|
|
8
|
+
'many-to-one',
|
|
9
|
+
'many-to-many',
|
|
10
|
+
'one-to-zero-one',
|
|
11
|
+
'zero-one-to-one',
|
|
12
|
+
'zero-to-one',
|
|
13
|
+
'zero-to-zero-one',
|
|
14
|
+
'zero-to-many',
|
|
15
|
+
'zero-one-to-many',
|
|
16
|
+
'many-to-zero-one',
|
|
17
|
+
// Optional Relationships (using dotted lines)
|
|
18
|
+
'one-to-one-optional',
|
|
19
|
+
'one-to-many-optional',
|
|
20
|
+
'many-to-one-optional',
|
|
21
|
+
'many-to-many-optional',
|
|
22
|
+
'one-to-zero-one-optional',
|
|
23
|
+
'zero-one-to-one-optional',
|
|
24
|
+
'zero-to-one-optional',
|
|
25
|
+
'zero-to-many-optional',
|
|
26
|
+
'zero-one-to-many-optional',
|
|
27
|
+
'many-to-zero-one-optional',
|
|
28
|
+
// Nuanced Patterns (Aliases)
|
|
29
|
+
'many-to-zero-many',
|
|
30
|
+
'zero-many-to-many',
|
|
31
|
+
'zero-many-to-zero-many',
|
|
32
|
+
]);
|
|
33
|
+
/**
|
|
34
|
+
* Validate if a value is a valid relation type
|
|
35
|
+
* @param value - The value to validate
|
|
36
|
+
* @returns True if the value is a valid relation type, false otherwise
|
|
37
|
+
*/
|
|
38
|
+
function isRelation(value) {
|
|
39
|
+
return typeof value === 'string' && VALID_RELATIONS.has(value);
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a relation line
|
|
3
|
+
* @param line - The line to parse
|
|
4
|
+
* @returns The parsed relation
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseRelationLine(line: string): {
|
|
7
|
+
fromModel: string
|
|
8
|
+
fromField: string
|
|
9
|
+
toModel: string
|
|
10
|
+
toField: string
|
|
11
|
+
type: import('../type').RelationType
|
|
12
|
+
} | null
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseRelationLine = parseRelationLine;
|
|
4
|
+
const is_relation_1 = require("./is-relation");
|
|
5
|
+
/**
|
|
6
|
+
* Parse a relation line
|
|
7
|
+
* @param line - The line to parse
|
|
8
|
+
* @returns The parsed relation
|
|
9
|
+
*/
|
|
10
|
+
function parseRelationLine(line) {
|
|
11
|
+
// @relation <fromModel>.<fromField> <toModel>.<toField> <relationType>
|
|
12
|
+
const relationMatch = line.match(/@relation\s+(\w+)\.(\w+)\s+(\w+)\.(\w+)\s+(\w+-to-\w+)/);
|
|
13
|
+
if (relationMatch) {
|
|
14
|
+
const [_, fromModel, fromField, toModel, toField, type] = relationMatch;
|
|
15
|
+
// Validate the relation type
|
|
16
|
+
if (!(0, is_relation_1.isRelation)(type)) {
|
|
17
|
+
throw new Error(`Unknown relation type: ${type}`);
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
fromModel,
|
|
21
|
+
fromField,
|
|
22
|
+
toModel,
|
|
23
|
+
toField,
|
|
24
|
+
type,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TableInfo } from '../type'
|
|
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
|
+
*/
|
|
8
|
+
export declare function parseTableInfo(code: string[]): TableInfo[]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTableInfo = parseTableInfo;
|
|
4
|
+
/**
|
|
5
|
+
* Parse table info from code
|
|
6
|
+
* @function parseTableInfo
|
|
7
|
+
* @param code - The code to parse the table info from
|
|
8
|
+
* @returns The parsed table info
|
|
9
|
+
*/
|
|
10
|
+
function parseTableInfo(code) {
|
|
11
|
+
const initialAccumulator = {
|
|
12
|
+
tables: [],
|
|
13
|
+
currentTable: null,
|
|
14
|
+
currentDescription: '',
|
|
15
|
+
tempFields: [],
|
|
16
|
+
currentTableStartLine: 0,
|
|
17
|
+
};
|
|
18
|
+
const result = code.reduce((acc, line, index) => {
|
|
19
|
+
// extract description
|
|
20
|
+
const descriptionMatch = line.match(/\/\/\/\s*([^@].*)/);
|
|
21
|
+
if (descriptionMatch &&
|
|
22
|
+
!(line.includes('@z.') || line.includes('@v.')) &&
|
|
23
|
+
!line.includes('@relation')) {
|
|
24
|
+
acc.currentDescription = descriptionMatch[1]?.trim() ?? null;
|
|
25
|
+
return acc;
|
|
26
|
+
}
|
|
27
|
+
// extract table name
|
|
28
|
+
const tableMatch = line.match(/export const (\w+)\s*=\s*mysqlTable/);
|
|
29
|
+
if (tableMatch) {
|
|
30
|
+
if (acc.currentTable && acc.tempFields.length > 0) {
|
|
31
|
+
acc.currentTable.fields = acc.tempFields.map((field) => ({
|
|
32
|
+
name: field.name,
|
|
33
|
+
type: field.type,
|
|
34
|
+
description: field.description,
|
|
35
|
+
}));
|
|
36
|
+
acc.tables.push(acc.currentTable);
|
|
37
|
+
}
|
|
38
|
+
acc.currentTable = {
|
|
39
|
+
name: tableMatch[1],
|
|
40
|
+
fields: [],
|
|
41
|
+
};
|
|
42
|
+
acc.tempFields = [];
|
|
43
|
+
acc.currentTableStartLine = index;
|
|
44
|
+
return acc;
|
|
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;
|
|
91
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove duplicate relations
|
|
3
|
+
* @function removeDuplicateRelations
|
|
4
|
+
* @param relations - The relations to remove duplicates from
|
|
5
|
+
* @returns The relations without duplicates
|
|
6
|
+
*/
|
|
7
|
+
export declare function removeDuplicateRelations(relations: readonly string[]): readonly string[]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeDuplicateRelations = removeDuplicateRelations;
|
|
4
|
+
/**
|
|
5
|
+
* Remove duplicate relations
|
|
6
|
+
* @function removeDuplicateRelations
|
|
7
|
+
* @param relations - The relations to remove duplicates from
|
|
8
|
+
* @returns The relations without duplicates
|
|
9
|
+
*/
|
|
10
|
+
function removeDuplicateRelations(relations) {
|
|
11
|
+
return [...new Set(relations)];
|
|
12
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
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");
|
|
9
|
+
/**
|
|
10
|
+
* Loads the configuration from the `sizuku.json` file or returns the default configuration.
|
|
11
|
+
*
|
|
12
|
+
* @returns The configuration object.
|
|
13
|
+
*/
|
|
14
|
+
function getConfig() {
|
|
15
|
+
const config = node_fs_1.default.existsSync('sizuku-valibot.json')
|
|
16
|
+
? { ...config_1.DEFAULT_CONFIG, ...JSON.parse(node_fs_1.default.readFileSync('sizuku-valibot.json', 'utf-8')) }
|
|
17
|
+
: config_1.DEFAULT_CONFIG;
|
|
18
|
+
return config;
|
|
19
|
+
}
|