sizuku 0.1.0 → 0.2.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 (160) hide show
  1. package/README.md +18 -12
  2. package/dist/cli/main.d.ts +10 -0
  3. package/dist/cli/main.js +61 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +51 -0
  6. package/dist/config/index.d.ts +1 -1
  7. package/dist/config/loader.d.ts +19 -0
  8. package/dist/config/loader.js +30 -0
  9. package/dist/generator/engine.d.ts +3 -0
  10. package/dist/generator/engine.js +63 -0
  11. package/dist/generator/mermaid-er/core.d.ts +6 -0
  12. package/dist/generator/mermaid-er/core.js +54 -0
  13. package/dist/generator/mermaid-er/generator/er-content.d.ts +14 -2
  14. package/dist/generator/mermaid-er/generator/index.d.ts +1 -1
  15. package/dist/generator/mermaid-er/generator/index.js +1 -1
  16. package/dist/generator/mermaid-er/generator/relation-line.d.ts +7 -2
  17. package/dist/generator/mermaid-er/generator/relation-line.js +1 -1
  18. package/dist/generator/mermaid-er/generator.d.ts +3 -0
  19. package/dist/generator/mermaid-er/generator.js +14 -0
  20. package/dist/generator/mermaid-er/index.d.ts +7 -1
  21. package/dist/generator/mermaid-er/index.js +21 -4
  22. package/dist/generator/mermaid-er/validator/index.d.ts +8 -4
  23. package/dist/generator/mermaid-er/validator/index.js +71 -4
  24. package/dist/generator/mermaid-er/validator/parse-table-info.js +1 -1
  25. package/dist/generator/valibot/core.d.ts +5 -0
  26. package/dist/generator/valibot/core.js +39 -0
  27. package/dist/generator/valibot/generator/infer-input.js +1 -1
  28. package/dist/generator/valibot/generator/relation-valibot-code.d.ts +13 -0
  29. package/dist/generator/valibot/generator/relation-valibot-code.js +19 -0
  30. package/dist/generator/valibot/generator/valibot-code.d.ts +9 -2
  31. package/dist/generator/valibot/generator/valibot-code.js +1 -1
  32. package/dist/generator/valibot/generator/valibot.d.ts +9 -2
  33. package/dist/generator/valibot/generator/valibot.js +7 -3
  34. package/dist/generator/valibot/generator.d.ts +3 -0
  35. package/dist/generator/valibot/generator.js +14 -0
  36. package/dist/generator/valibot/index.d.ts +7 -2
  37. package/dist/generator/valibot/index.js +36 -8
  38. package/dist/generator/zod/core.d.ts +5 -0
  39. package/dist/generator/zod/core.js +39 -0
  40. package/dist/generator/zod/generator/infer.js +2 -2
  41. package/dist/generator/zod/generator/relation-zod-code.d.ts +13 -0
  42. package/dist/generator/zod/generator/relation-zod-code.js +19 -0
  43. package/dist/generator/zod/generator/zod-code.d.ts +9 -2
  44. package/dist/generator/zod/generator/zod-code.js +1 -1
  45. package/dist/generator/zod/generator/zod.d.ts +9 -2
  46. package/dist/generator/zod/generator/zod.js +7 -3
  47. package/dist/generator/zod/generator.d.ts +3 -0
  48. package/dist/generator/zod/generator.js +14 -0
  49. package/dist/generator/zod/index.d.ts +7 -2
  50. package/dist/generator/zod/index.js +40 -16
  51. package/dist/index.d.ts +7 -2
  52. package/dist/index.js +60 -43
  53. package/dist/shared/format/index.d.ts +15 -2
  54. package/dist/shared/format/index.js +22 -8
  55. package/dist/shared/fs/index.d.ts +7 -2
  56. package/dist/shared/fs/index.js +9 -3
  57. package/dist/shared/fsp/index.d.ts +27 -3
  58. package/dist/shared/fsp/index.js +35 -5
  59. package/dist/shared/generator/field-definitions.d.ts +8 -2
  60. package/dist/shared/helper/ast-parser.d.ts +3 -0
  61. package/dist/shared/helper/ast-parser.js +202 -0
  62. package/dist/shared/helper/build-schema-extractor.d.ts +25 -0
  63. package/dist/shared/helper/build-schema-extractor.js +33 -0
  64. package/dist/shared/helper/create-extract-field-from-property.d.ts +15 -0
  65. package/dist/shared/helper/create-extract-field-from-property.js +20 -0
  66. package/dist/shared/helper/create-extract-fields-from-call-expression.d.ts +14 -0
  67. package/dist/shared/helper/create-extract-fields-from-call-expression.js +14 -0
  68. package/dist/shared/helper/create-extract-relation-field-from-property.d.ts +12 -0
  69. package/dist/shared/helper/create-extract-relation-field-from-property.js +27 -0
  70. package/dist/shared/helper/extract-schemas.d.ts +133 -0
  71. package/dist/shared/helper/extract-schemas.js +445 -0
  72. package/dist/shared/helper/file-writer.d.ts +3 -0
  73. package/dist/shared/helper/file-writer.js +25 -0
  74. package/dist/shared/helper/find-object-literal-expression.d.ts +12 -0
  75. package/dist/shared/helper/find-object-literal-expression.js +31 -0
  76. package/dist/shared/helper/find-object-literalIn-args.d.ts +2 -0
  77. package/dist/shared/helper/find-object-literalIn-args.js +8 -0
  78. package/dist/shared/helper/is-relation-function.d.ts +10 -0
  79. package/dist/shared/helper/is-relation-function.js +16 -0
  80. package/dist/shared/utils/index.d.ts +20 -0
  81. package/dist/shared/utils/index.js +48 -0
  82. package/dist/shared/utils/string-utils.d.ts +8 -0
  83. package/dist/shared/utils/string-utils.js +28 -0
  84. package/dist/shared/utils/types.d.ts +32 -0
  85. package/dist/shared/utils/types.js +2 -0
  86. package/dist/shared/utils/validation-utils.d.ts +8 -0
  87. package/dist/shared/utils/validation-utils.js +25 -0
  88. package/dist/src/config/index.d.ts +18 -0
  89. package/dist/src/config/index.js +13 -0
  90. package/dist/src/generator/mermaid-er/core/extract-relations.d.ts +8 -0
  91. package/dist/src/generator/mermaid-er/core/extract-relations.js +12 -0
  92. package/dist/src/generator/mermaid-er/generator/er-content.d.ts +9 -0
  93. package/dist/src/generator/mermaid-er/generator/er-content.js +25 -0
  94. package/dist/src/generator/mermaid-er/generator/index.d.ts +2 -0
  95. package/dist/src/generator/mermaid-er/generator/index.js +2 -0
  96. package/dist/src/generator/mermaid-er/generator/relation-line.d.ts +8 -0
  97. package/dist/src/generator/mermaid-er/generator/relation-line.js +14 -0
  98. package/dist/src/generator/mermaid-er/index.d.ts +6 -0
  99. package/dist/src/generator/mermaid-er/index.js +16 -0
  100. package/dist/src/generator/mermaid-er/relationship/build-relation-line.d.ts +15 -0
  101. package/dist/src/generator/mermaid-er/relationship/build-relation-line.js +35 -0
  102. package/dist/src/generator/mermaid-er/types.d.ts +21 -0
  103. package/dist/src/generator/mermaid-er/types.js +1 -0
  104. package/dist/src/generator/mermaid-er/validator/index.d.ts +4 -0
  105. package/dist/src/generator/mermaid-er/validator/index.js +4 -0
  106. package/dist/src/generator/mermaid-er/validator/is-relationship.d.ts +8 -0
  107. package/dist/src/generator/mermaid-er/validator/is-relationship.js +9 -0
  108. package/dist/src/generator/mermaid-er/validator/parse-relation-line.d.ts +13 -0
  109. package/dist/src/generator/mermaid-er/validator/parse-relation-line.js +21 -0
  110. package/dist/src/generator/mermaid-er/validator/parse-table-info.d.ts +8 -0
  111. package/dist/src/generator/mermaid-er/validator/parse-table-info.js +91 -0
  112. package/dist/src/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +7 -0
  113. package/dist/src/generator/mermaid-er/validator/remove-duplicate-relations.js +9 -0
  114. package/dist/src/generator/valibot/generator/infer-input.d.ts +5 -0
  115. package/dist/src/generator/valibot/generator/infer-input.js +8 -0
  116. package/dist/src/generator/valibot/generator/valibot-code.d.ts +14 -0
  117. package/dist/src/generator/valibot/generator/valibot-code.js +16 -0
  118. package/dist/src/generator/valibot/generator/valibot.d.ts +13 -0
  119. package/dist/src/generator/valibot/generator/valibot.js +11 -0
  120. package/dist/src/generator/valibot/index.d.ts +9 -0
  121. package/dist/src/generator/valibot/index.js +34 -0
  122. package/dist/src/generator/zod/generator/infer.d.ts +5 -0
  123. package/dist/src/generator/zod/generator/infer.js +8 -0
  124. package/dist/src/generator/zod/generator/zod-code.d.ts +16 -0
  125. package/dist/src/generator/zod/generator/zod-code.js +18 -0
  126. package/dist/src/generator/zod/generator/zod.d.ts +15 -0
  127. package/dist/src/generator/zod/generator/zod.js +12 -0
  128. package/dist/src/generator/zod/index.d.ts +10 -0
  129. package/dist/src/generator/zod/index.js +40 -0
  130. package/dist/src/index.d.ts +10 -0
  131. package/dist/src/index.js +35 -0
  132. package/dist/src/shared/format/index.d.ts +2 -0
  133. package/dist/src/shared/format/index.js +10 -0
  134. package/dist/src/shared/fs/index.d.ts +2 -0
  135. package/dist/src/shared/fs/index.js +10 -0
  136. package/dist/src/shared/fsp/index.d.ts +3 -0
  137. package/dist/src/shared/fsp/index.js +8 -0
  138. package/dist/src/shared/generator/field-definitions.d.ts +12 -0
  139. package/dist/src/shared/generator/field-definitions.js +12 -0
  140. package/dist/src/shared/helper/build-schema-extractor.d.ts +25 -0
  141. package/dist/src/shared/helper/build-schema-extractor.js +33 -0
  142. package/dist/src/shared/helper/create-extract-field-from-property.d.ts +15 -0
  143. package/dist/src/shared/helper/create-extract-field-from-property.js +20 -0
  144. package/dist/src/shared/helper/create-extract-fields-from-call-expression.d.ts +14 -0
  145. package/dist/src/shared/helper/create-extract-fields-from-call-expression.js +14 -0
  146. package/dist/src/shared/helper/create-extract-relation-field-from-property.d.ts +12 -0
  147. package/dist/src/shared/helper/create-extract-relation-field-from-property.js +27 -0
  148. package/dist/src/shared/helper/extract-schemas.d.ts +16 -0
  149. package/dist/src/shared/helper/extract-schemas.js +19 -0
  150. package/dist/src/shared/helper/find-object-literal-expression.d.ts +12 -0
  151. package/dist/src/shared/helper/find-object-literal-expression.js +31 -0
  152. package/dist/src/shared/helper/find-object-literalIn-args.d.ts +2 -0
  153. package/dist/src/shared/helper/find-object-literalIn-args.js +8 -0
  154. package/dist/src/shared/helper/is-relation-function.d.ts +10 -0
  155. package/dist/src/shared/helper/is-relation-function.js +16 -0
  156. package/dist/src/shared/utils/index.d.ts +33 -0
  157. package/dist/src/shared/utils/index.js +61 -0
  158. package/dist/utils/index.d.ts +144 -0
  159. package/dist/utils/index.js +301 -0
  160. package/package.json +2 -6
@@ -0,0 +1,16 @@
1
+ import { inferInput } from './infer-input.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,13 @@
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
+ }, comment: boolean): string;
@@ -0,0 +1,11 @@
1
+ import { fieldDefinitions } from '../../../shared/generator/field-definitions.js';
2
+ import { schemaName } from '../../../shared/utils/index.js';
3
+ /**
4
+ * @param schema
5
+ * @param config
6
+ * @returns
7
+ */
8
+ export function valibot(schema, comment) {
9
+ const res = fieldDefinitions(schema, comment);
10
+ return `export const ${schemaName(schema.name)} = v.object({${res}})`;
11
+ }
@@ -0,0 +1,9 @@
1
+ import type { Result } from 'neverthrow';
2
+ /**
3
+ * Generate Valibot schema
4
+ * @param code - The code to generate Valibot schema from
5
+ * @param output - The output file path
6
+ * @param comment - Whether to include comments in the generated code
7
+ * @param type - Whether to include type information in the generated code
8
+ */
9
+ export declare function sizukuValibot(code: string[], output: `${string}.ts`, comment?: boolean, type?: boolean): Promise<Result<void, Error>>;
@@ -0,0 +1,34 @@
1
+ import path from 'node:path';
2
+ import { fmt } from '../../shared/format/index.js';
3
+ import { mkdir, writeFile } from '../../shared/fsp/index.js';
4
+ import { buildSchemaExtractor } from '../../shared/helper/build-schema-extractor.js';
5
+ import { createExtractFieldFromProperty } from '../../shared/helper/create-extract-field-from-property.js';
6
+ import { createExtractFieldsFromCallExpression } from '../../shared/helper/create-extract-fields-from-call-expression.js';
7
+ import { createExtractRelationFieldFromProperty } from '../../shared/helper/create-extract-relation-field-from-property.js';
8
+ import { extractSchemas } from '../../shared/helper/extract-schemas.js';
9
+ import { findObjectLiteralExpression } from '../../shared/helper/find-object-literal-expression.js';
10
+ import { findObjectLiteralInArgs } from '../../shared/helper/find-object-literalIn-args.js';
11
+ import { isRelationFunctionCall } from '../../shared/helper/is-relation-function.js';
12
+ import { parseFieldComments } from '../../shared/utils/index.js';
13
+ import { valibotCode } from './generator/valibot-code.js';
14
+ /**
15
+ * Generate Valibot schema
16
+ * @param code - The code to generate Valibot schema from
17
+ * @param output - The output file path
18
+ * @param comment - Whether to include comments in the generated code
19
+ * @param type - Whether to include type information in the generated code
20
+ */
21
+ export async function sizukuValibot(code, output, comment, type) {
22
+ const extractField = createExtractFieldFromProperty((lines) => parseFieldComments(lines, '@v.'));
23
+ const extractRelationField = createExtractRelationFieldFromProperty((lines) => parseFieldComments(lines, '@v.'), 'v');
24
+ const extractFieldsFromCall = createExtractFieldsFromCallExpression(extractField, extractRelationField, findObjectLiteralExpression, findObjectLiteralInArgs, isRelationFunctionCall);
25
+ const extractSchema = buildSchemaExtractor(extractFieldsFromCall, extractField);
26
+ const valibotGeneratedCode = [
27
+ 'import * as v from "valibot"',
28
+ '',
29
+ ...extractSchemas(code, extractSchema).map((schema) => valibotCode(schema, comment ?? false, type ?? false)),
30
+ ].join('\n');
31
+ return await mkdir(path.dirname(output))
32
+ .andThen(() => fmt(valibotGeneratedCode))
33
+ .andThen((formatted) => writeFile(output, formatted));
34
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @param name
3
+ * @returns
4
+ */
5
+ export declare function infer(name: string): string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @param name
3
+ * @returns
4
+ */
5
+ export function infer(name) {
6
+ const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
7
+ return `export type ${capitalizedName} = z.infer<typeof ${capitalizedName}Schema>`;
8
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Generates Zod code for a given schema and config.
3
+ *
4
+ * @function generateZodCode
5
+ * @param schema - The schema to generate code for.
6
+ * @param config - The configuration for the code generation.
7
+ * @returns The generated Zod code.
8
+ */
9
+ export declare function zodCode(schema: {
10
+ name: string;
11
+ fields: {
12
+ name: string;
13
+ definition: string;
14
+ description?: string;
15
+ }[];
16
+ }, comment: boolean, type: boolean): string;
@@ -0,0 +1,18 @@
1
+ import { infer } from './infer.js';
2
+ import { zod } from './zod.js';
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 function zodCode(schema, comment, type) {
12
+ const zodSchema = zod(schema, comment);
13
+ if (type) {
14
+ const zInfer = infer(schema.name);
15
+ return `${zodSchema}\n\n${zInfer}\n`;
16
+ }
17
+ return `${zodSchema}\n`;
18
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Generates a Zod schema for a given schema and config.
3
+ *
4
+ * @param schema - The schema to generate code for.
5
+ * @param config - The configuration for the code generation.
6
+ * @returns The generated Zod schema.
7
+ */
8
+ export declare function zod(schema: {
9
+ name: string;
10
+ fields: {
11
+ name: string;
12
+ definition: string;
13
+ description?: string;
14
+ }[];
15
+ }, comment: boolean): string;
@@ -0,0 +1,12 @@
1
+ import { fieldDefinitions } from '../../../shared/generator/field-definitions.js';
2
+ import { schemaName } from '../../../shared/utils/index.js';
3
+ /**
4
+ * Generates a Zod schema for a given schema and config.
5
+ *
6
+ * @param schema - The schema to generate code for.
7
+ * @param config - The configuration for the code generation.
8
+ * @returns The generated Zod schema.
9
+ */
10
+ export function zod(schema, comment) {
11
+ return `export const ${schemaName(schema.name)} = z.object({${fieldDefinitions(schema, comment)}})`;
12
+ }
@@ -0,0 +1,10 @@
1
+ import type { Result } from 'neverthrow';
2
+ /**
3
+ * Generate Zod schema
4
+ * @param code - The code to generate Zod schema from
5
+ * @param output - The output file path
6
+ * @param comment - Whether to include comments in the generated code
7
+ * @param type - Whether to include type information in the generated code
8
+ * @param zod - The Zod version to use
9
+ */
10
+ export declare function sizukuZod(code: string[], output: `${string}.ts`, comment?: boolean, type?: boolean, zod?: 'v4' | 'mini' | '@hono/zod-openapi'): Promise<Result<void, Error>>;
@@ -0,0 +1,40 @@
1
+ import path from 'node:path';
2
+ import { fmt } from '../../shared/format/index.js';
3
+ import { mkdir, writeFile } from '../../shared/fsp/index.js';
4
+ import { buildSchemaExtractor } from '../../shared/helper/build-schema-extractor.js';
5
+ import { createExtractFieldFromProperty } from '../../shared/helper/create-extract-field-from-property.js';
6
+ import { createExtractFieldsFromCallExpression } from '../../shared/helper/create-extract-fields-from-call-expression.js';
7
+ import { createExtractRelationFieldFromProperty } from '../../shared/helper/create-extract-relation-field-from-property.js';
8
+ import { extractSchemas } from '../../shared/helper/extract-schemas.js';
9
+ import { findObjectLiteralExpression } from '../../shared/helper/find-object-literal-expression.js';
10
+ import { findObjectLiteralInArgs } from '../../shared/helper/find-object-literalIn-args.js';
11
+ import { isRelationFunctionCall } from '../../shared/helper/is-relation-function.js';
12
+ import { parseFieldComments } from '../../shared/utils/index.js';
13
+ import { zodCode } from './generator/zod-code.js';
14
+ /**
15
+ * Generate Zod schema
16
+ * @param code - The code to generate Zod schema from
17
+ * @param output - The output file path
18
+ * @param comment - Whether to include comments in the generated code
19
+ * @param type - Whether to include type information in the generated code
20
+ * @param zod - The Zod version to use
21
+ */
22
+ export async function sizukuZod(code, output, comment, type, zod) {
23
+ const extractField = createExtractFieldFromProperty((lines) => parseFieldComments(lines, '@z.'));
24
+ const extractRelationField = createExtractRelationFieldFromProperty((lines) => parseFieldComments(lines, '@z.'), 'z');
25
+ const extractFieldsFromCall = createExtractFieldsFromCallExpression(extractField, extractRelationField, findObjectLiteralExpression, findObjectLiteralInArgs, isRelationFunctionCall);
26
+ const extractSchema = buildSchemaExtractor(extractFieldsFromCall, extractField);
27
+ const importLine = zod === 'mini'
28
+ ? `import * as z from 'zod/mini'`
29
+ : zod === '@hono/zod-openapi'
30
+ ? `import { z } from '@hono/zod-openapi'`
31
+ : `import * as z from 'zod'`;
32
+ const zodGeneratedCode = [
33
+ importLine,
34
+ '',
35
+ ...extractSchemas(code, extractSchema).map((schema) => zodCode(schema, comment ?? false, type ?? false)),
36
+ ].join('\n');
37
+ return await mkdir(path.dirname(output))
38
+ .andThen(() => fmt(zodGeneratedCode))
39
+ .andThen((formatted) => writeFile(output, formatted));
40
+ }
@@ -0,0 +1,10 @@
1
+ import type { Result } from 'neverthrow';
2
+ import type { Config } from './config/index.js';
3
+ /**
4
+ * Generate schemas from Drizzle table definitions.
5
+ *
6
+ * @param code - The code lines to process.
7
+ * @param config - The configuration object.
8
+ * @returns A Result indicating success or failure.
9
+ */
10
+ export declare function generateSchemas(code: string[], config: Config): Promise<Result<void, Error>>;
@@ -0,0 +1,35 @@
1
+ import { err, ok } from 'neverthrow';
2
+ import { sizukuMermaidER } from './generator/mermaid-er/index.js';
3
+ import { sizukuValibot } from './generator/valibot/index.js';
4
+ import { sizukuZod } from './generator/zod/index.js';
5
+ /**
6
+ * Generate schemas from Drizzle table definitions.
7
+ *
8
+ * @param code - The code lines to process.
9
+ * @param config - The configuration object.
10
+ * @returns A Result indicating success or failure.
11
+ */
12
+ export async function generateSchemas(code, config) {
13
+ if (!config.input) {
14
+ return err(new Error('input is not found'));
15
+ }
16
+ const zodResult = config.zod?.output
17
+ ? await sizukuZod(code, config.zod.output, config.zod.comment, config.zod.type, config.zod.zod)
18
+ : ok(undefined);
19
+ if (zodResult.isErr()) {
20
+ return err(zodResult.error);
21
+ }
22
+ const valibotResult = config.valibot?.output
23
+ ? await sizukuValibot(code, config.valibot.output, config.valibot.comment, config.valibot.type)
24
+ : ok(undefined);
25
+ if (valibotResult.isErr()) {
26
+ return err(valibotResult.error);
27
+ }
28
+ const mermaidResult = config.mermaid?.output
29
+ ? await sizukuMermaidER(code, config.mermaid.output)
30
+ : ok(undefined);
31
+ if (mermaidResult.isErr()) {
32
+ return err(mermaidResult.error);
33
+ }
34
+ return ok(undefined);
35
+ }
@@ -0,0 +1,2 @@
1
+ import { ResultAsync } from 'neverthrow';
2
+ export declare function fmt(code: string): ResultAsync<string, Error>;
@@ -0,0 +1,10 @@
1
+ import { ResultAsync } from 'neverthrow';
2
+ import { format } from 'prettier';
3
+ export function fmt(code) {
4
+ return ResultAsync.fromPromise(format(code, {
5
+ parser: 'typescript',
6
+ printWidth: 100,
7
+ singleQuote: true,
8
+ semi: false,
9
+ }), (e) => new Error(String(e)));
10
+ }
@@ -0,0 +1,2 @@
1
+ import type { Result } from 'neverthrow';
2
+ export declare function readFileSync(path: string): Result<string, Error>;
@@ -0,0 +1,10 @@
1
+ import fs from 'node:fs';
2
+ import { err, ok } from 'neverthrow';
3
+ export function readFileSync(path) {
4
+ try {
5
+ return ok(fs.readFileSync(path, 'utf-8'));
6
+ }
7
+ catch (e) {
8
+ return err(new Error(String(e)));
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ import { ResultAsync } from 'neverthrow';
2
+ export declare function mkdir(path: string): ResultAsync<string | undefined, Error>;
3
+ export declare function writeFile(path: string, data: string): ResultAsync<void, Error>;
@@ -0,0 +1,8 @@
1
+ import fsp from 'node:fs/promises';
2
+ import { ResultAsync } from 'neverthrow';
3
+ export function mkdir(path) {
4
+ return ResultAsync.fromPromise(fsp.mkdir(path, { recursive: true }), (e) => new Error(String(e)));
5
+ }
6
+ export function writeFile(path, data) {
7
+ return ResultAsync.fromPromise(fsp.writeFile(path, data), (e) => new Error(String(e)));
8
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @param schema
3
+ * @returns
4
+ */
5
+ export declare function fieldDefinitions(schema: {
6
+ name: string;
7
+ fields: {
8
+ name: string;
9
+ definition: string;
10
+ description?: string;
11
+ }[];
12
+ }, comment: boolean): string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @param schema
3
+ * @returns
4
+ */
5
+ export function fieldDefinitions(schema, comment) {
6
+ return schema.fields
7
+ .map(({ name, definition, description }) => {
8
+ const commentCode = description && comment ? `/**\n* ${description}\n*/\n` : '';
9
+ return `${commentCode}${name}:${definition}`;
10
+ })
11
+ .join(',\n');
12
+ }
@@ -0,0 +1,25 @@
1
+ import type { CallExpression } from 'ts-morph';
2
+ import { Node } from 'ts-morph';
3
+ /**
4
+ * Creates a schema extractor from customizable strategies.
5
+ *
6
+ * @param extractFieldsFromCall - Function to extract fields from a call expression (e.g. mysqlTable(...)).
7
+ * @param extractFieldFromProperty - Function to extract a single field from an object literal property.
8
+ * @returns A function that extracts a schema from a variable declaration node.
9
+ */
10
+ export declare function buildSchemaExtractor(extractFieldsFromCall: (call: CallExpression, sourceText: string) => {
11
+ name: string;
12
+ definition: string;
13
+ description?: string;
14
+ }[], extractFieldFromProperty: (prop: Node, sourceText: string) => {
15
+ name: string;
16
+ definition: string;
17
+ description?: string;
18
+ } | null): (declaration: Node, sourceText: string) => {
19
+ name: string;
20
+ fields: {
21
+ name: string;
22
+ definition: string;
23
+ description?: string;
24
+ }[];
25
+ } | null;
@@ -0,0 +1,33 @@
1
+ import { Node } from 'ts-morph';
2
+ import { isRelationFunctionCall } from '../../shared/helper/is-relation-function.js';
3
+ /**
4
+ * Creates a schema extractor from customizable strategies.
5
+ *
6
+ * @param extractFieldsFromCall - Function to extract fields from a call expression (e.g. mysqlTable(...)).
7
+ * @param extractFieldFromProperty - Function to extract a single field from an object literal property.
8
+ * @returns A function that extracts a schema from a variable declaration node.
9
+ */
10
+ export function buildSchemaExtractor(extractFieldsFromCall, extractFieldFromProperty) {
11
+ return (declaration, sourceText) => {
12
+ if (!Node.isVariableDeclaration(declaration))
13
+ return null;
14
+ const name = declaration.getName();
15
+ if (!name)
16
+ return null;
17
+ const initializer = declaration.getInitializer();
18
+ if (Node.isCallExpression(initializer)) {
19
+ if (isRelationFunctionCall(initializer))
20
+ return null;
21
+ const fields = extractFieldsFromCall(initializer, sourceText);
22
+ return { name, fields };
23
+ }
24
+ if (Node.isObjectLiteralExpression(initializer)) {
25
+ const fields = initializer
26
+ .getProperties()
27
+ .map((prop) => extractFieldFromProperty(prop, sourceText))
28
+ .filter((field) => field !== null);
29
+ return { name, fields };
30
+ }
31
+ return { name, fields: [] };
32
+ };
33
+ }
@@ -0,0 +1,15 @@
1
+ import { Node } from 'ts-morph';
2
+ /**
3
+ * Creates a field extractor function using a custom parseFieldComments implementation.
4
+ *
5
+ * @param parseFieldComments - A function that parses comment lines into { definition, description }
6
+ * @returns A property node extractor function.
7
+ */
8
+ export declare function createExtractFieldFromProperty(parseFieldComments: (commentLines: string[]) => {
9
+ definition: string;
10
+ description?: string;
11
+ }): (property: Node, sourceText: string) => {
12
+ name: string;
13
+ definition: string;
14
+ description?: string;
15
+ } | null;
@@ -0,0 +1,20 @@
1
+ import { Node } from 'ts-morph';
2
+ import { extractFieldComments } from '../../shared/utils/index.js';
3
+ /**
4
+ * Creates a field extractor function using a custom parseFieldComments implementation.
5
+ *
6
+ * @param parseFieldComments - A function that parses comment lines into { definition, description }
7
+ * @returns A property node extractor function.
8
+ */
9
+ export function createExtractFieldFromProperty(parseFieldComments) {
10
+ return (property, sourceText) => {
11
+ if (!Node.isPropertyAssignment(property))
12
+ return null;
13
+ const name = property.getName();
14
+ if (!name)
15
+ return null;
16
+ const commentLines = extractFieldComments(sourceText, property.getStart());
17
+ const { definition, description } = parseFieldComments(commentLines);
18
+ return { name, definition, description };
19
+ };
20
+ }
@@ -0,0 +1,14 @@
1
+ import type { CallExpression, Node, ObjectLiteralExpression } from 'ts-morph';
2
+ export declare function createExtractFieldsFromCallExpression(extractFieldFromProperty: (property: Node, sourceText: string) => {
3
+ name: string;
4
+ definition: string;
5
+ description?: string;
6
+ } | null, extractRelationFieldFromProperty: (property: Node, sourceText: string) => {
7
+ name: string;
8
+ definition: string;
9
+ description?: string;
10
+ } | null, findObjectLiteralExpression: (expr: Node) => ObjectLiteralExpression | null, findObjectLiteralInArgs: (call: CallExpression, finder: (expr: Node) => ObjectLiteralExpression | null) => ObjectLiteralExpression | null, isRelationFunctionCall: (call: CallExpression) => boolean): (callExpr: CallExpression, sourceText: string) => {
11
+ name: string;
12
+ definition: string;
13
+ description?: string;
14
+ }[];
@@ -0,0 +1,14 @@
1
+ export function createExtractFieldsFromCallExpression(extractFieldFromProperty, extractRelationFieldFromProperty, findObjectLiteralExpression, findObjectLiteralInArgs, isRelationFunctionCall) {
2
+ return (callExpr, sourceText) => {
3
+ const objectLiteral = findObjectLiteralInArgs(callExpr, findObjectLiteralExpression);
4
+ if (!objectLiteral)
5
+ return [];
6
+ const isRelation = isRelationFunctionCall(callExpr);
7
+ return objectLiteral
8
+ .getProperties()
9
+ .map((prop) => isRelation
10
+ ? extractRelationFieldFromProperty(prop, sourceText)
11
+ : extractFieldFromProperty(prop, sourceText))
12
+ .filter((field) => field !== null);
13
+ };
14
+ }
@@ -0,0 +1,12 @@
1
+ import { Node } from 'ts-morph';
2
+ export declare const createExtractRelationFieldFromProperty: (parseFieldComments: (lines: string[]) => {
3
+ definition: string;
4
+ description?: string;
5
+ }, prefix: "v" | "z") => (property: Node, sourceText: string) => {
6
+ name: string;
7
+ fields: {
8
+ name: string;
9
+ definition: string;
10
+ description?: string;
11
+ }[];
12
+ }["fields"][0] | null;
@@ -0,0 +1,27 @@
1
+ import { Node } from 'ts-morph';
2
+ import { extractFieldComments, schemaName } from '../utils/index.js';
3
+ export const createExtractRelationFieldFromProperty = (parseFieldComments, prefix) => {
4
+ return (property, sourceText) => {
5
+ if (!Node.isPropertyAssignment(property))
6
+ return null;
7
+ const name = property.getName();
8
+ if (!name)
9
+ return null;
10
+ const init = property.getInitializer();
11
+ if (!Node.isCallExpression(init))
12
+ return { name, definition: '', description: undefined };
13
+ const expr = init.getExpression();
14
+ if (!Node.isIdentifier(expr))
15
+ return { name, definition: '', description: undefined };
16
+ const fnName = expr.getText();
17
+ const args = init.getArguments();
18
+ if (!(args.length && Node.isIdentifier(args[0]))) {
19
+ return { name, definition: '', description: undefined };
20
+ }
21
+ const refTable = args[0].getText();
22
+ const schema = schemaName(refTable);
23
+ const definition = fnName === 'many' ? `${prefix}.array(${schema})` : fnName === 'one' ? schema : '';
24
+ const { description } = parseFieldComments(extractFieldComments(sourceText, property.getStart()));
25
+ return { name, definition, description };
26
+ };
27
+ };
@@ -0,0 +1,16 @@
1
+ import type { Node } from 'ts-morph';
2
+ export declare function extractSchemas(lines: string[], extractFn: (declaration: Node, sourceText: string) => {
3
+ name: string;
4
+ fields: {
5
+ name: string;
6
+ definition: string;
7
+ description?: string;
8
+ }[];
9
+ } | null): {
10
+ name: string;
11
+ fields: {
12
+ name: string;
13
+ definition: string;
14
+ description?: string;
15
+ }[];
16
+ }[];
@@ -0,0 +1,19 @@
1
+ import { Project } from 'ts-morph';
2
+ export function extractSchemas(lines, extractFn) {
3
+ const sourceCode = lines.join('\n');
4
+ const project = new Project({
5
+ useInMemoryFileSystem: true,
6
+ compilerOptions: {
7
+ allowJs: true,
8
+ skipLibCheck: true,
9
+ },
10
+ });
11
+ const sourceFile = project.createSourceFile('temp.ts', sourceCode);
12
+ const sourceText = sourceFile.getFullText();
13
+ return sourceFile
14
+ .getVariableStatements()
15
+ .filter((stmt) => stmt.hasExportKeyword())
16
+ .flatMap((stmt) => stmt.getDeclarations())
17
+ .map((decl) => extractFn(decl, sourceText))
18
+ .filter((schema) => schema !== null);
19
+ }
@@ -0,0 +1,12 @@
1
+ import type { ObjectLiteralExpression } from 'ts-morph';
2
+ import { Node } from 'ts-morph';
3
+ /**
4
+ * Recursively extracts an `ObjectLiteralExpression` from a given AST node.
5
+ *
6
+ * Supports direct object literals, parenthesized expressions,
7
+ * arrow functions returning object literals (including wrapped and block bodies).
8
+ *
9
+ * @param expr - The root `Node` to search.
10
+ * @returns The found `ObjectLiteralExpression`, or `null` if not found.
11
+ */
12
+ export declare function findObjectLiteralExpression(expr: Node): ObjectLiteralExpression | null;
@@ -0,0 +1,31 @@
1
+ import { Node } from 'ts-morph';
2
+ /**
3
+ * Recursively extracts an `ObjectLiteralExpression` from a given AST node.
4
+ *
5
+ * Supports direct object literals, parenthesized expressions,
6
+ * arrow functions returning object literals (including wrapped and block bodies).
7
+ *
8
+ * @param expr - The root `Node` to search.
9
+ * @returns The found `ObjectLiteralExpression`, or `null` if not found.
10
+ */
11
+ export function findObjectLiteralExpression(expr) {
12
+ if (Node.isObjectLiteralExpression(expr))
13
+ return expr;
14
+ if (Node.isParenthesizedExpression(expr))
15
+ return findObjectLiteralExpression(expr.getExpression());
16
+ if (Node.isArrowFunction(expr)) {
17
+ const body = expr.getBody();
18
+ if (Node.isObjectLiteralExpression(body))
19
+ return body;
20
+ if (Node.isParenthesizedExpression(body))
21
+ return findObjectLiteralExpression(body.getExpression());
22
+ if (Node.isBlock(body)) {
23
+ const ret = body.getStatements().find(Node.isReturnStatement);
24
+ if (ret && Node.isReturnStatement(ret)) {
25
+ const re = ret.getExpression();
26
+ return re && Node.isObjectLiteralExpression(re) ? re : null;
27
+ }
28
+ }
29
+ }
30
+ return null;
31
+ }
@@ -0,0 +1,2 @@
1
+ import type { CallExpression, Node, ObjectLiteralExpression } from 'ts-morph';
2
+ export declare function findObjectLiteralInArgs(call: CallExpression, finder: (expr: Node) => ObjectLiteralExpression | null): ObjectLiteralExpression | null;
@@ -0,0 +1,8 @@
1
+ export function findObjectLiteralInArgs(call, finder) {
2
+ for (const arg of call.getArguments()) {
3
+ const obj = finder(arg);
4
+ if (obj)
5
+ return obj;
6
+ }
7
+ return null;
8
+ }
@@ -0,0 +1,10 @@
1
+ import type { CallExpression } from 'ts-morph';
2
+ /**
3
+ * Determines whether a given `CallExpression` is a relation-related function call.
4
+ *
5
+ * This checks if the function name is either `"relations"` or contains the substring `"relation"`.
6
+ *
7
+ * @param callExpr - The call expression node to check.
8
+ * @returns `true` if the function is a relation function; otherwise, `false`.
9
+ */
10
+ export declare function isRelationFunctionCall(callExpr: CallExpression): boolean;