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.
Files changed (66) hide show
  1. package/README.md +471 -0
  2. package/dist/common/config/index.d.ts +13 -0
  3. package/dist/common/config/index.js +13 -0
  4. package/dist/common/format/index.d.ts +1 -0
  5. package/dist/common/format/index.js +12 -0
  6. package/dist/common/generator/generate-field-definitions.d.ts +8 -0
  7. package/dist/common/generator/generate-field-definitions.js +16 -0
  8. package/dist/common/helper/get-camel-case-schema-name-helper.d.ts +7 -0
  9. package/dist/common/helper/get-camel-case-schema-name-helper.js +14 -0
  10. package/dist/common/helper/get-pascal-case-schema-name-helper.d.ts +8 -0
  11. package/dist/common/helper/get-pascal-case-schema-name-helper.js +15 -0
  12. package/dist/common/helper/get-variable-name-helper.d.ts +9 -0
  13. package/dist/common/helper/get-variable-name-helper.js +15 -0
  14. package/dist/common/helper/get-variable-schema-name-helper.d.ts +9 -0
  15. package/dist/common/helper/get-variable-schema-name-helper.js +17 -0
  16. package/dist/common/text/capitalize.d.ts +18 -0
  17. package/dist/common/text/capitalize.js +23 -0
  18. package/dist/common/text/decapitalize.d.ts +17 -0
  19. package/dist/common/text/decapitalize.js +22 -0
  20. package/dist/common/type/index.d.ts +9 -0
  21. package/dist/common/type/index.js +2 -0
  22. package/dist/generator/mermaid-er/config/index.d.ts +10 -0
  23. package/dist/generator/mermaid-er/config/index.js +18 -0
  24. package/dist/generator/mermaid-er/core/extract-relations.d.ts +8 -0
  25. package/dist/generator/mermaid-er/core/extract-relations.js +20 -0
  26. package/dist/generator/mermaid-er/generator/generate-er-content.d.ts +9 -0
  27. package/dist/generator/mermaid-er/generator/generate-er-content.js +27 -0
  28. package/dist/generator/mermaid-er/generator/generate-relation-line.d.ts +7 -0
  29. package/dist/generator/mermaid-er/generator/generate-relation-line.js +16 -0
  30. package/dist/generator/mermaid-er/index.d.ts +7 -0
  31. package/dist/generator/mermaid-er/index.js +102 -0
  32. package/dist/generator/mermaid-er/type/index.d.ts +40 -0
  33. package/dist/generator/mermaid-er/type/index.js +2 -0
  34. package/dist/generator/mermaid-er/validator/is-relation.d.ts +7 -0
  35. package/dist/generator/mermaid-er/validator/is-relation.js +40 -0
  36. package/dist/generator/mermaid-er/validator/parse-relation-line.d.ts +12 -0
  37. package/dist/generator/mermaid-er/validator/parse-relation-line.js +28 -0
  38. package/dist/generator/mermaid-er/validator/parse-table-info.d.ts +8 -0
  39. package/dist/generator/mermaid-er/validator/parse-table-info.js +91 -0
  40. package/dist/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +7 -0
  41. package/dist/generator/mermaid-er/validator/remove-duplicate-relations.js +12 -0
  42. package/dist/generator/valibot/config/index.d.ts +7 -0
  43. package/dist/generator/valibot/config/index.js +19 -0
  44. package/dist/generator/valibot/core/extract-schema.d.ts +8 -0
  45. package/dist/generator/valibot/core/extract-schema.js +92 -0
  46. package/dist/generator/valibot/generator/generate-valibot-code.d.ts +11 -0
  47. package/dist/generator/valibot/generator/generate-valibot-code.js +21 -0
  48. package/dist/generator/valibot/generator/generate-valibot-infer-input.d.ts +9 -0
  49. package/dist/generator/valibot/generator/generate-valibot-infer-input.js +16 -0
  50. package/dist/generator/valibot/generator/generate-valibot-schema.d.ts +9 -0
  51. package/dist/generator/valibot/generator/generate-valibot-schema.js +16 -0
  52. package/dist/generator/valibot/index.d.ts +3 -0
  53. package/dist/generator/valibot/index.js +77 -0
  54. package/dist/generator/zod/config/index.d.ts +8 -0
  55. package/dist/generator/zod/config/index.js +20 -0
  56. package/dist/generator/zod/core/extract-schema.d.ts +8 -0
  57. package/dist/generator/zod/core/extract-schema.js +96 -0
  58. package/dist/generator/zod/generator/generate-z-infer.d.ts +11 -0
  59. package/dist/generator/zod/generator/generate-z-infer.js +18 -0
  60. package/dist/generator/zod/generator/generate-zod-code.d.ts +11 -0
  61. package/dist/generator/zod/generator/generate-zod-code.js +21 -0
  62. package/dist/generator/zod/generator/generate-zod-schema.d.ts +11 -0
  63. package/dist/generator/zod/generator/generate-zod-schema.js +17 -0
  64. package/dist/generator/zod/index.d.ts +3 -0
  65. package/dist/generator/zod/index.js +77 -0
  66. package/package.json +55 -0
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractSchemas = extractSchemas;
4
+ /**
5
+ * Check if line contains metadata
6
+ */
7
+ const isMetadataComment = (line) => {
8
+ return line.includes('@z.') || line.includes('@v.') || line.includes('@relation.');
9
+ };
10
+ /**
11
+ * Extract schemas from lines of code
12
+ * @function extractSchemas
13
+ * @param lines - Lines of code
14
+ * @returns Schemas
15
+ */
16
+ function extractSchemas(lines) {
17
+ const process = (i, acc) => {
18
+ if (i >= lines.length) {
19
+ return acc;
20
+ }
21
+ const line = lines[i];
22
+ // extract schema name
23
+ const schemaMatch = line.match(/export const (\w+)\s*=/);
24
+ if (schemaMatch) {
25
+ if (acc.currentSchema) {
26
+ acc.schemas.push(acc.currentSchema);
27
+ }
28
+ acc.currentSchema = { name: schemaMatch[1], fields: [] };
29
+ acc.pendingDescription = undefined;
30
+ return process(i + 1, acc);
31
+ }
32
+ // handle comment line
33
+ if (line.trim().startsWith('///')) {
34
+ // detect valibot comment
35
+ const valibotComment = line.match(/\/\/\/\s*@(v\.[^\n]+)/);
36
+ if (valibotComment && acc.currentSchema) {
37
+ // find next field definition line
38
+ const remainingCandidates = lines.slice(i + 1);
39
+ const foundRelative = remainingCandidates.findIndex((candidate) => {
40
+ const trimmed = candidate.trim();
41
+ return trimmed !== '' && !trimmed.startsWith('///');
42
+ });
43
+ if (foundRelative !== -1) {
44
+ const j = i + 1 + foundRelative;
45
+ const candidate = lines[j].trim();
46
+ const fieldMatch = candidate.match(/^(\w+)\s*:/);
47
+ if (fieldMatch) {
48
+ const newField = {
49
+ name: fieldMatch[1],
50
+ definition: valibotComment[1],
51
+ description: acc.pendingDescription,
52
+ };
53
+ acc.currentSchema.fields.push(newField);
54
+ acc.pendingDescription = undefined;
55
+ return process(i + 1, acc);
56
+ }
57
+ }
58
+ }
59
+ else {
60
+ // ignore comment line except metadata
61
+ if (!isMetadataComment(line)) {
62
+ const commentText = line.replace('///', '').trim();
63
+ acc.pendingDescription = acc.pendingDescription
64
+ ? `${acc.pendingDescription} ${commentText}`
65
+ : commentText;
66
+ return process(i + 1, acc);
67
+ }
68
+ }
69
+ return process(i + 1, acc);
70
+ }
71
+ // if field definition is found in non-comment line, use pending comment as field information
72
+ if (acc.currentSchema && acc.pendingDescription) {
73
+ const fieldMatch = line.match(/^(\w+)\s*:/);
74
+ if (fieldMatch) {
75
+ const newField = {
76
+ name: fieldMatch[1],
77
+ definition: '',
78
+ description: acc.pendingDescription,
79
+ };
80
+ acc.currentSchema.fields.push(newField);
81
+ acc.pendingDescription = undefined;
82
+ return process(i + 1, acc);
83
+ }
84
+ }
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
+ }
91
+ return finalAcc.schemas;
92
+ }
@@ -0,0 +1,11 @@
1
+ import type { Schema } from '../../../common/type'
2
+ import type { Config } from '../../../common/config'
3
+ /**
4
+ * Generates Valibot code for a given schema and config.
5
+ *
6
+ * @function generateValibotCode
7
+ * @param schema - The schema to generate code for.
8
+ * @param config - The configuration for the code generation.
9
+ * @returns The generated Valibot code.
10
+ */
11
+ export declare function generateValibotCode(schema: Schema, config: Config): string
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateValibotCode = generateValibotCode;
4
+ const generate_valibot_infer_input_1 = require("./generate-valibot-infer-input");
5
+ const generate_valibot_schema_1 = require("./generate-valibot-schema");
6
+ /**
7
+ * Generates Valibot code for a given schema and config.
8
+ *
9
+ * @function generateValibotCode
10
+ * @param schema - The schema to generate code for.
11
+ * @param config - The configuration for the code generation.
12
+ * @returns The generated Valibot code.
13
+ */
14
+ function generateValibotCode(schema, config) {
15
+ const valibotSchema = (0, generate_valibot_schema_1.generateValibotSchema)(schema, config);
16
+ const valibotInfer = (0, generate_valibot_infer_input_1.generateValibotInferInput)(schema, config);
17
+ if (config.type.export) {
18
+ return `${valibotSchema}\n\n${valibotInfer}\n`;
19
+ }
20
+ return `${valibotSchema}\n`;
21
+ }
@@ -0,0 +1,9 @@
1
+ import type { Schema } from '../../../common/type'
2
+ import type { Config } from '../../../common/config'
3
+ /**
4
+ * @function generateValibotInferInput
5
+ * @param schema
6
+ * @param config
7
+ * @returns
8
+ */
9
+ export declare function generateValibotInferInput(schema: Schema, config: Config): string
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateValibotInferInput = generateValibotInferInput;
4
+ const get_variable_name_helper_1 = require("../../../common/helper/get-variable-name-helper");
5
+ const get_variable_schema_name_helper_1 = require("../../../common/helper/get-variable-schema-name-helper");
6
+ /**
7
+ * @function generateValibotInferInput
8
+ * @param schema
9
+ * @param config
10
+ * @returns
11
+ */
12
+ function generateValibotInferInput(schema, config) {
13
+ const typeName = (0, get_variable_name_helper_1.getVariableNameHelper)(schema.name, config);
14
+ const schemaName = (0, get_variable_schema_name_helper_1.getVariableSchemaNameHelper)(schema.name, config);
15
+ return `export type ${typeName} = v.InferInput<typeof ${schemaName}>`;
16
+ }
@@ -0,0 +1,9 @@
1
+ import type { Schema } from '../../../common/type'
2
+ import type { Config } from '../../../common/config'
3
+ /**
4
+ * @function generateValibotSchema
5
+ * @param schema
6
+ * @param config
7
+ * @returns
8
+ */
9
+ export declare function generateValibotSchema(schema: Schema, config: Config): string
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateValibotSchema = generateValibotSchema;
4
+ const generate_field_definitions_1 = require("../../../common/generator/generate-field-definitions");
5
+ const get_variable_schema_name_helper_1 = require("../../../common/helper/get-variable-schema-name-helper");
6
+ /**
7
+ * @function generateValibotSchema
8
+ * @param schema
9
+ * @param config
10
+ * @returns
11
+ */
12
+ function generateValibotSchema(schema, config) {
13
+ const schemaName = (0, get_variable_schema_name_helper_1.getVariableSchemaNameHelper)(schema.name, config);
14
+ const res = (0, generate_field_definitions_1.generateFieldDefinitions)(schema, config);
15
+ return `export const ${schemaName} = v.object({${res}})`;
16
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import type { Config } from '../../common/config'
3
+ export declare function main(dev?: boolean, config?: Config): Promise<boolean>
@@ -0,0 +1,77 @@
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.main = main;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const extract_schema_1 = require("./core/extract-schema");
11
+ const format_1 = require("../../common/format");
12
+ const config_1 = require("./config");
13
+ const node_process_1 = require("node:process");
14
+ const generate_valibot_code_1 = require("./generator/generate-valibot-code");
15
+ const IMPORT_VALIBOT = 'import * as v from "valibot"';
16
+ async function main(dev = false, config = (0, config_1.getConfig)()) {
17
+ // 1. argv ['**/bin/node', ''/workspaces/sizuku-test/packages/sizuku/dist/generator/zod/index.js',', 'db/schema.ts', '-o', 'zod/index.ts']
18
+ if (config.output === undefined && !node_process_1.argv.includes('-o')) {
19
+ console.error('Error: -o is not found');
20
+ return false;
21
+ }
22
+ // 2. slice ['db/schema.ts', '-o', 'zod/index.ts']
23
+ const args = process.argv.slice(2);
24
+ // 3. input = args[0] = 'db/schema.ts'
25
+ const input = config.input ?? args[0];
26
+ config.input = input;
27
+ // 4. output = 'zod/index.ts'
28
+ const output = config.output ?? args[args.indexOf('-o') + 1];
29
+ config.output = output;
30
+ try {
31
+ // 5. read db/schema.ts
32
+ const content = (0, node_fs_1.readFileSync)(input, 'utf-8');
33
+ // 6. split lines
34
+ const lines = content.split('\n');
35
+ // 7. create output directory
36
+ const outputDir = node_path_1.default.dirname(output);
37
+ if (!(0, node_fs_1.existsSync)(outputDir)) {
38
+ (0, node_fs_1.mkdirSync)(outputDir, { recursive: true });
39
+ }
40
+ // 8. skip import section
41
+ const codeStart = lines.findIndex((line) => !line.trim().startsWith('import') && line.trim() !== '');
42
+ // 9. extract schemas
43
+ const schemas = (0, extract_schema_1.extractSchemas)(lines.slice(codeStart));
44
+ // 10. generate zod code
45
+ const generatedCode = [
46
+ IMPORT_VALIBOT,
47
+ '',
48
+ ...schemas.map((schema) => (0, generate_valibot_code_1.generateValibotCode)(schema, config)),
49
+ ].join('\n');
50
+ // 11. format code
51
+ const code = await (0, format_1.formatCode)(generatedCode);
52
+ // 12. write to output file
53
+ (0, node_fs_1.writeFileSync)(output, code);
54
+ console.log(`Generated Valibot schema at: ${output}`);
55
+ return true;
56
+ }
57
+ catch (e) {
58
+ if (e instanceof Error) {
59
+ console.error(e.message);
60
+ if (dev) {
61
+ throw e;
62
+ }
63
+ process.exit(1);
64
+ }
65
+ if (dev) {
66
+ throw new Error('Unknown error occurred');
67
+ }
68
+ return false;
69
+ }
70
+ }
71
+ if (require.main === module) {
72
+ main().then((success) => {
73
+ if (!success) {
74
+ process.exit(1);
75
+ }
76
+ });
77
+ }
@@ -0,0 +1,8 @@
1
+ import type { Config } from '../../../common/config'
2
+ /**
3
+ * Loads the configuration from the `sizuku.json` file or returns the default configuration.
4
+ *
5
+ * @function getConfig
6
+ * @returns The configuration object.
7
+ */
8
+ export declare function getConfig(): Config
@@ -0,0 +1,20 @@
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
+ * @function getConfig
13
+ * @returns The configuration object.
14
+ */
15
+ function getConfig() {
16
+ const config = node_fs_1.default.existsSync('sizuku-zod.json')
17
+ ? { ...config_1.DEFAULT_CONFIG, ...JSON.parse(node_fs_1.default.readFileSync('sizuku-zod.json', 'utf-8')) }
18
+ : config_1.DEFAULT_CONFIG;
19
+ return config;
20
+ }
@@ -0,0 +1,8 @@
1
+ import type { Schema } from '../../../common/type'
2
+ /**
3
+ * Extract schemas from lines of code
4
+ * @function extractSchemas
5
+ * @param lines - Lines of code
6
+ * @returns Schemas
7
+ */
8
+ export declare function extractSchemas(lines: string[]): Schema[]
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractSchemas = extractSchemas;
4
+ /**
5
+ * Check if line contains metadata
6
+ */
7
+ const isMetadataComment = (line) => {
8
+ return line.includes('@z.') || line.includes('@v.') || line.includes('@relation.');
9
+ };
10
+ /**
11
+ * Check if line is a non-comment line
12
+ */
13
+ const isNonCommentLine = (line) => {
14
+ const trimmed = line.trim();
15
+ return trimmed !== '' && !trimmed.startsWith('///');
16
+ };
17
+ /**
18
+ * Extract schemas from lines of code
19
+ * @function extractSchemas
20
+ * @param lines - Lines of code
21
+ * @returns Schemas
22
+ */
23
+ function extractSchemas(lines) {
24
+ const process = (i, acc) => {
25
+ if (i >= lines.length) {
26
+ return acc;
27
+ }
28
+ const line = lines[i];
29
+ // extract schema
30
+ const schemaMatch = line.match(/export const (\w+)\s*=/);
31
+ if (schemaMatch) {
32
+ if (acc.currentSchema) {
33
+ acc.schemas.push(acc.currentSchema);
34
+ }
35
+ acc.currentSchema = { name: schemaMatch[1], fields: [] };
36
+ acc.pendingDescription = undefined;
37
+ return process(i + 1, acc);
38
+ }
39
+ // process comment
40
+ if (line.trim().startsWith('///')) {
41
+ // zod comment
42
+ const zodComment = line.match(/\/\/\/\s*(@z\.(?:[^()]+|\([^)]*\))+)/);
43
+ if (zodComment && acc.currentSchema) {
44
+ // find next field definition line
45
+ const remainingCandidates = lines.slice(i + 1);
46
+ const foundRelative = remainingCandidates.findIndex(isNonCommentLine);
47
+ if (foundRelative !== -1) {
48
+ const j = i + 1 + foundRelative;
49
+ const candidate = lines[j].trim();
50
+ const fieldMatch = candidate.match(/^(\w+)\s*:/);
51
+ if (fieldMatch) {
52
+ const newField = {
53
+ name: fieldMatch[1],
54
+ definition: zodComment[1].replace('@', ''),
55
+ description: acc.pendingDescription,
56
+ };
57
+ acc.currentSchema.fields.push(newField);
58
+ acc.pendingDescription = undefined;
59
+ return process(i + 1, acc);
60
+ }
61
+ }
62
+ }
63
+ else {
64
+ // comments other than metadata are pending
65
+ if (!isMetadataComment(line)) {
66
+ const commentText = line.replace('///', '').trim();
67
+ acc.pendingDescription = acc.pendingDescription
68
+ ? `${acc.pendingDescription} ${commentText}`
69
+ : commentText;
70
+ return process(i + 1, acc);
71
+ }
72
+ }
73
+ return process(i + 1, acc);
74
+ }
75
+ // if there is a field definition other than comment, use the pending comment as field information
76
+ if (acc.currentSchema && acc.pendingDescription) {
77
+ const fieldMatch = line.match(/^(\w+)\s*:/);
78
+ if (fieldMatch) {
79
+ const newField = {
80
+ name: fieldMatch[1],
81
+ definition: '',
82
+ description: acc.pendingDescription,
83
+ };
84
+ acc.currentSchema.fields.push(newField);
85
+ acc.pendingDescription = undefined;
86
+ return process(i + 1, acc);
87
+ }
88
+ }
89
+ return process(i + 1, acc);
90
+ };
91
+ const finalAcc = process(0, { currentSchema: null, pendingDescription: undefined, schemas: [] });
92
+ if (finalAcc.currentSchema) {
93
+ finalAcc.schemas.push(finalAcc.currentSchema);
94
+ }
95
+ return finalAcc.schemas;
96
+ }
@@ -0,0 +1,11 @@
1
+ import type { Schema } from '../../../common/type'
2
+ import type { Config } from '../../../common/config'
3
+ /**
4
+ * Generates a Zod infer type for a given schema and config.
5
+ *
6
+ * @function generateZInfer
7
+ * @param schema - The schema to generate code for.
8
+ * @param config - The configuration for the code generation.
9
+ * @returns The generated Zod infer type.
10
+ */
11
+ export declare function generateZInfer(schema: Schema, config: Config): string
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateZInfer = generateZInfer;
4
+ const get_variable_name_helper_1 = require("../../../common/helper/get-variable-name-helper");
5
+ const get_variable_schema_name_helper_1 = require("../../../common/helper/get-variable-schema-name-helper");
6
+ /**
7
+ * Generates a Zod infer type for a given schema and config.
8
+ *
9
+ * @function generateZInfer
10
+ * @param schema - The schema to generate code for.
11
+ * @param config - The configuration for the code generation.
12
+ * @returns The generated Zod infer type.
13
+ */
14
+ function generateZInfer(schema, config) {
15
+ const typeName = (0, get_variable_name_helper_1.getVariableNameHelper)(schema.name, config);
16
+ const schemaName = (0, get_variable_schema_name_helper_1.getVariableSchemaNameHelper)(schema.name, config);
17
+ return `export type ${typeName} = z.infer<typeof ${schemaName}>`;
18
+ }
@@ -0,0 +1,11 @@
1
+ import type { Schema } from '../../../common/type'
2
+ import type { Config } from '../../../common/config'
3
+ /**
4
+ * Generates Zod code for a given schema and config.
5
+ *
6
+ * @function generateZodCode
7
+ * @param schema - The schema to generate code for.
8
+ * @param config - The configuration for the code generation.
9
+ * @returns The generated Zod code.
10
+ */
11
+ export declare function generateZodCode(schema: Schema, config: Config): string
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateZodCode = generateZodCode;
4
+ const generate_z_infer_1 = require("./generate-z-infer");
5
+ const generate_zod_schema_1 = require("./generate-zod-schema");
6
+ /**
7
+ * Generates Zod code for a given schema and config.
8
+ *
9
+ * @function generateZodCode
10
+ * @param schema - The schema to generate code for.
11
+ * @param config - The configuration for the code generation.
12
+ * @returns The generated Zod code.
13
+ */
14
+ function generateZodCode(schema, config) {
15
+ const zodSchema = (0, generate_zod_schema_1.generateZodSchema)(schema, config);
16
+ const zInfer = (0, generate_z_infer_1.generateZInfer)(schema, config);
17
+ if (config.type.export) {
18
+ return `${zodSchema}\n\n${zInfer}\n`;
19
+ }
20
+ return `${zodSchema}\n`;
21
+ }
@@ -0,0 +1,11 @@
1
+ import type { Schema } from '../../../common/type'
2
+ import type { Config } from '../../../common/config'
3
+ /**
4
+ * Generates a Zod schema for a given schema and config.
5
+ *
6
+ * @function generateZodSchema
7
+ * @param schema - The schema to generate code for.
8
+ * @param config - The configuration for the code generation.
9
+ * @returns The generated Zod schema.
10
+ */
11
+ export declare function generateZodSchema(schema: Schema, config: Config): string
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateZodSchema = generateZodSchema;
4
+ const get_variable_schema_name_helper_1 = require("../../../common/helper/get-variable-schema-name-helper");
5
+ const generate_field_definitions_1 = require("../../../common/generator/generate-field-definitions");
6
+ /**
7
+ * Generates a Zod schema for a given schema and config.
8
+ *
9
+ * @function generateZodSchema
10
+ * @param schema - The schema to generate code for.
11
+ * @param config - The configuration for the code generation.
12
+ * @returns The generated Zod schema.
13
+ */
14
+ function generateZodSchema(schema, config) {
15
+ const schemaName = (0, get_variable_schema_name_helper_1.getVariableSchemaNameHelper)(schema.name, config);
16
+ return `export const ${schemaName} = z.object({${(0, generate_field_definitions_1.generateFieldDefinitions)(schema, config)}})`;
17
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import type { Config } from '../../common/config'
3
+ export declare function main(dev?: boolean, config?: Config): Promise<boolean>
@@ -0,0 +1,77 @@
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.main = main;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const extract_schema_1 = require("./core/extract-schema");
11
+ const generate_zod_code_1 = require("./generator/generate-zod-code");
12
+ const format_1 = require("../../common/format");
13
+ const config_1 = require("./config");
14
+ const node_process_1 = require("node:process");
15
+ const IMPORT_ZOD = 'import { z } from "zod"';
16
+ async function main(dev = false, config = (0, config_1.getConfig)()) {
17
+ // 1. argv ['**/bin/node', ''/workspaces/sizuku-test/packages/sizuku/dist/generator/zod/index.js',', 'db/schema.ts', '-o', 'zod/index.ts']
18
+ if (config.output === undefined && !node_process_1.argv.includes('-o')) {
19
+ console.error('Error: -o is not found');
20
+ return false;
21
+ }
22
+ // 2. slice ['db/schema.ts', '-o', 'zod/index.ts']
23
+ const args = process.argv.slice(2);
24
+ // 3. input = args[0] = 'db/schema.ts'
25
+ const input = config.input ?? args[0];
26
+ config.input = input;
27
+ // 4. output = 'zod/index.ts'
28
+ const output = config.output ?? args[args.indexOf('-o') + 1];
29
+ config.output = output;
30
+ try {
31
+ // 5. read db/schema.ts
32
+ const content = (0, node_fs_1.readFileSync)(input, 'utf-8');
33
+ // 6. split lines
34
+ const lines = content.split('\n');
35
+ // 7. create output directory
36
+ const outputDir = node_path_1.default.dirname(output);
37
+ if (!(0, node_fs_1.existsSync)(outputDir)) {
38
+ (0, node_fs_1.mkdirSync)(outputDir, { recursive: true });
39
+ }
40
+ // 8. skip import section
41
+ const codeStart = lines.findIndex((line) => !line.trim().startsWith('import') && line.trim() !== '');
42
+ // 9. extract schemas
43
+ const schemas = (0, extract_schema_1.extractSchemas)(lines.slice(codeStart));
44
+ // 10. generate zod code
45
+ const generatedCode = [
46
+ IMPORT_ZOD,
47
+ '',
48
+ ...schemas.map((schema) => (0, generate_zod_code_1.generateZodCode)(schema, config)),
49
+ ].join('\n');
50
+ // 11. format code
51
+ const code = await (0, format_1.formatCode)(generatedCode);
52
+ // 12. write to output file
53
+ (0, node_fs_1.writeFileSync)(output, code);
54
+ console.log(`Generated Zod schema at: ${output}`);
55
+ return true;
56
+ }
57
+ catch (e) {
58
+ if (e instanceof Error) {
59
+ console.error(e.message);
60
+ if (dev) {
61
+ throw e;
62
+ }
63
+ process.exit(1);
64
+ }
65
+ if (dev) {
66
+ throw new Error('Unknown error occurred');
67
+ }
68
+ return false;
69
+ }
70
+ }
71
+ if (require.main === module) {
72
+ main().then((success) => {
73
+ if (!success) {
74
+ process.exit(1);
75
+ }
76
+ });
77
+ }
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "sizuku",
3
+ "version": "0.0.1",
4
+ "license": "MIT",
5
+ "keywords": [
6
+ "drizzle",
7
+ "zod",
8
+ "valibot",
9
+ "mermaid"
10
+ ],
11
+ "homepage": "https://github.com/nakita628/sizuku",
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/nakita628/sizuku.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/nakita628/sizuku/issues"
21
+ },
22
+ "main": "dist/index.js",
23
+ "types": "dist/index.d.ts",
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "bin": {
28
+ "sizuku-zod": "dist/generator/zod/index.js",
29
+ "sizuku-valibot": "dist/generator/valibot/index.js",
30
+ "sizuku-mermaid-er": "dist/generator/mermaid-er/index.js"
31
+ },
32
+ "scripts": {
33
+ "deps": "rm -rf node_modules && pnpm install",
34
+ "demo-er": "sizuku-mermaid-er db/schema.ts -o mermaid-er/ER.md",
35
+ "demo-z": "sizuku-zod db/schema.ts -o zod/index.ts",
36
+ "demo-v": "sizuku-valibot db/schema.ts -o valibot/index.ts",
37
+ "build": "tsc",
38
+ "typecheck": "tsc --noEmit",
39
+ "dev": "pnpm --filter sizuku-test dev",
40
+ "test": "vitest run",
41
+ "coverage": "vitest run --coverage",
42
+ "release": "npm pkg fix && npm publish"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.13.8",
46
+ "@vitest/coverage-v8": "^3.0.7",
47
+ "drizzle-orm": "^0.40.0",
48
+ "valibot": "1.0.0-rc.3",
49
+ "vitest": "^3.0.7",
50
+ "zod": "^3.24.2"
51
+ },
52
+ "dependencies": {
53
+ "prettier": "^3.5.3"
54
+ }
55
+ }