sizuku 0.3.2 → 0.4.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 +103 -0
- package/dist/config/index.d.mts +58 -0
- package/dist/config/index.mjs +95 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +1615 -0
- package/package.json +31 -17
- package/dist/cli/main.d.ts +0 -10
- package/dist/cli/main.js +0 -61
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -51
- package/dist/config/index.d.ts +0 -27
- package/dist/config/index.js +0 -85
- package/dist/config/loader.d.ts +0 -19
- package/dist/config/loader.js +0 -30
- package/dist/generator/engine.d.ts +0 -3
- package/dist/generator/engine.js +0 -63
- package/dist/generator/mermaid-er/config/index.d.ts +0 -10
- package/dist/generator/mermaid-er/config/index.js +0 -12
- package/dist/generator/mermaid-er/core/extract-relations.d.ts +0 -8
- package/dist/generator/mermaid-er/core/extract-relations.js +0 -17
- package/dist/generator/mermaid-er/core.d.ts +0 -6
- package/dist/generator/mermaid-er/core.js +0 -54
- package/dist/generator/mermaid-er/generator/er-content.d.ts +0 -20
- package/dist/generator/mermaid-er/generator/er-content.js +0 -23
- package/dist/generator/mermaid-er/generator/index.d.ts +0 -2
- package/dist/generator/mermaid-er/generator/index.js +0 -2
- package/dist/generator/mermaid-er/generator/relation-line.d.ts +0 -12
- package/dist/generator/mermaid-er/generator/relation-line.js +0 -13
- package/dist/generator/mermaid-er/generator.d.ts +0 -3
- package/dist/generator/mermaid-er/generator.js +0 -14
- package/dist/generator/mermaid-er/index.d.ts +0 -12
- package/dist/generator/mermaid-er/index.js +0 -33
- package/dist/generator/mermaid-er/relationship/build-relation-line.d.ts +0 -14
- package/dist/generator/mermaid-er/relationship/build-relation-line.js +0 -34
- package/dist/generator/mermaid-er/types.d.ts +0 -21
- package/dist/generator/mermaid-er/types.js +0 -1
- package/dist/generator/mermaid-er/validator/index.d.ts +0 -8
- package/dist/generator/mermaid-er/validator/index.js +0 -74
- package/dist/generator/mermaid-er/validator/is-relationship.d.ts +0 -7
- package/dist/generator/mermaid-er/validator/is-relationship.js +0 -8
- package/dist/generator/mermaid-er/validator/parse-relation-line.d.ts +0 -12
- package/dist/generator/mermaid-er/validator/parse-relation-line.js +0 -20
- package/dist/generator/mermaid-er/validator/parse-table-info.d.ts +0 -2
- package/dist/generator/mermaid-er/validator/parse-table-info.js +0 -71
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +0 -7
- package/dist/generator/mermaid-er/validator/remove-duplicate-relations.js +0 -9
- package/dist/generator/valibot/config/index.d.ts +0 -7
- package/dist/generator/valibot/config/index.js +0 -13
- package/dist/generator/valibot/core/extract-schema.d.ts +0 -5
- package/dist/generator/valibot/core/extract-schema.js +0 -173
- package/dist/generator/valibot/core.d.ts +0 -5
- package/dist/generator/valibot/core.js +0 -39
- package/dist/generator/valibot/generator/infer-input.d.ts +0 -5
- package/dist/generator/valibot/generator/infer-input.js +0 -8
- package/dist/generator/valibot/generator/relation-valibot-code.d.ts +0 -13
- package/dist/generator/valibot/generator/relation-valibot-code.js +0 -19
- package/dist/generator/valibot/generator/valibot-code.d.ts +0 -15
- package/dist/generator/valibot/generator/valibot-code.js +0 -16
- package/dist/generator/valibot/generator/valibot.d.ts +0 -14
- package/dist/generator/valibot/generator/valibot.js +0 -15
- package/dist/generator/valibot/generator.d.ts +0 -3
- package/dist/generator/valibot/generator.js +0 -14
- package/dist/generator/valibot/index.d.ts +0 -14
- package/dist/generator/valibot/index.js +0 -50
- package/dist/generator/zod/config/index.d.ts +0 -8
- package/dist/generator/zod/config/index.js +0 -14
- package/dist/generator/zod/core/extract-schema.d.ts +0 -7
- package/dist/generator/zod/core/extract-schema.js +0 -243
- package/dist/generator/zod/core.d.ts +0 -5
- package/dist/generator/zod/core.js +0 -39
- package/dist/generator/zod/generator/infer.d.ts +0 -5
- package/dist/generator/zod/generator/infer.js +0 -8
- package/dist/generator/zod/generator/relation-zod-code.d.ts +0 -13
- package/dist/generator/zod/generator/relation-zod-code.js +0 -19
- package/dist/generator/zod/generator/zod-code.d.ts +0 -17
- package/dist/generator/zod/generator/zod-code.js +0 -18
- package/dist/generator/zod/generator/zod.d.ts +0 -16
- package/dist/generator/zod/generator/zod.js +0 -16
- package/dist/generator/zod/generator.d.ts +0 -3
- package/dist/generator/zod/generator.js +0 -14
- package/dist/generator/zod/index.d.ts +0 -15
- package/dist/generator/zod/index.js +0 -54
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -73
- package/dist/shared/config/index.d.ts +0 -13
- package/dist/shared/config/index.js +0 -10
- package/dist/shared/format/index.d.ts +0 -13
- package/dist/shared/format/index.js +0 -24
- package/dist/shared/fs/index.d.ts +0 -7
- package/dist/shared/fs/index.js +0 -16
- package/dist/shared/fsp/index.d.ts +0 -27
- package/dist/shared/fsp/index.js +0 -38
- package/dist/shared/generator/field-definitions.d.ts +0 -12
- package/dist/shared/generator/field-definitions.js +0 -12
- package/dist/shared/helper/ast-parser.d.ts +0 -3
- package/dist/shared/helper/ast-parser.js +0 -202
- package/dist/shared/helper/build-schema-extractor.d.ts +0 -25
- package/dist/shared/helper/build-schema-extractor.js +0 -33
- package/dist/shared/helper/create-extract-field-from-property.d.ts +0 -15
- package/dist/shared/helper/create-extract-field-from-property.js +0 -20
- package/dist/shared/helper/create-extract-fields-from-call-expression.d.ts +0 -14
- package/dist/shared/helper/create-extract-fields-from-call-expression.js +0 -14
- package/dist/shared/helper/create-extract-relation-field-from-property.d.ts +0 -12
- package/dist/shared/helper/create-extract-relation-field-from-property.js +0 -27
- package/dist/shared/helper/extract-schemas.d.ts +0 -133
- package/dist/shared/helper/extract-schemas.js +0 -445
- package/dist/shared/helper/file-writer.d.ts +0 -3
- package/dist/shared/helper/file-writer.js +0 -25
- package/dist/shared/helper/find-object-literal-expression.d.ts +0 -12
- package/dist/shared/helper/find-object-literal-expression.js +0 -31
- package/dist/shared/helper/find-object-literalIn-args.d.ts +0 -2
- package/dist/shared/helper/find-object-literalIn-args.js +0 -8
- package/dist/shared/helper/is-relation-function.d.ts +0 -10
- package/dist/shared/helper/is-relation-function.js +0 -16
- package/dist/shared/types.d.ts +0 -9
- package/dist/shared/types.js +0 -1
- package/dist/shared/utils/capitalize.d.ts +0 -18
- package/dist/shared/utils/capitalize.js +0 -20
- package/dist/shared/utils/compose.d.ts +0 -101
- package/dist/shared/utils/compose.js +0 -124
- package/dist/shared/utils/file.d.ts +0 -92
- package/dist/shared/utils/file.js +0 -177
- package/dist/shared/utils/functional.d.ts +0 -118
- package/dist/shared/utils/functional.js +0 -96
- package/dist/shared/utils/index.d.ts +0 -20
- package/dist/shared/utils/index.js +0 -48
- package/dist/shared/utils/string-utils.d.ts +0 -8
- package/dist/shared/utils/string-utils.js +0 -28
- package/dist/shared/utils/types.d.ts +0 -32
- package/dist/shared/utils/types.js +0 -2
- package/dist/shared/utils/validation-utils.d.ts +0 -8
- package/dist/shared/utils/validation-utils.js +0 -25
- package/dist/src/config/index.d.ts +0 -18
- package/dist/src/config/index.js +0 -13
- package/dist/src/generator/mermaid-er/core/extract-relations.d.ts +0 -8
- package/dist/src/generator/mermaid-er/core/extract-relations.js +0 -12
- package/dist/src/generator/mermaid-er/generator/er-content.d.ts +0 -9
- package/dist/src/generator/mermaid-er/generator/er-content.js +0 -25
- package/dist/src/generator/mermaid-er/generator/index.d.ts +0 -2
- package/dist/src/generator/mermaid-er/generator/index.js +0 -2
- package/dist/src/generator/mermaid-er/generator/relation-line.d.ts +0 -8
- package/dist/src/generator/mermaid-er/generator/relation-line.js +0 -14
- package/dist/src/generator/mermaid-er/index.d.ts +0 -6
- package/dist/src/generator/mermaid-er/index.js +0 -16
- package/dist/src/generator/mermaid-er/relationship/build-relation-line.d.ts +0 -15
- package/dist/src/generator/mermaid-er/relationship/build-relation-line.js +0 -35
- package/dist/src/generator/mermaid-er/types.d.ts +0 -21
- package/dist/src/generator/mermaid-er/types.js +0 -1
- package/dist/src/generator/mermaid-er/validator/index.d.ts +0 -4
- package/dist/src/generator/mermaid-er/validator/index.js +0 -4
- package/dist/src/generator/mermaid-er/validator/is-relationship.d.ts +0 -8
- package/dist/src/generator/mermaid-er/validator/is-relationship.js +0 -9
- package/dist/src/generator/mermaid-er/validator/parse-relation-line.d.ts +0 -13
- package/dist/src/generator/mermaid-er/validator/parse-relation-line.js +0 -21
- package/dist/src/generator/mermaid-er/validator/parse-table-info.d.ts +0 -8
- package/dist/src/generator/mermaid-er/validator/parse-table-info.js +0 -91
- package/dist/src/generator/mermaid-er/validator/remove-duplicate-relations.d.ts +0 -7
- package/dist/src/generator/mermaid-er/validator/remove-duplicate-relations.js +0 -9
- package/dist/src/generator/valibot/generator/infer-input.d.ts +0 -5
- package/dist/src/generator/valibot/generator/infer-input.js +0 -8
- package/dist/src/generator/valibot/generator/valibot-code.d.ts +0 -14
- package/dist/src/generator/valibot/generator/valibot-code.js +0 -16
- package/dist/src/generator/valibot/generator/valibot.d.ts +0 -13
- package/dist/src/generator/valibot/generator/valibot.js +0 -11
- package/dist/src/generator/valibot/index.d.ts +0 -9
- package/dist/src/generator/valibot/index.js +0 -34
- package/dist/src/generator/zod/generator/infer.d.ts +0 -5
- package/dist/src/generator/zod/generator/infer.js +0 -8
- package/dist/src/generator/zod/generator/zod-code.d.ts +0 -16
- package/dist/src/generator/zod/generator/zod-code.js +0 -18
- package/dist/src/generator/zod/generator/zod.d.ts +0 -15
- package/dist/src/generator/zod/generator/zod.js +0 -12
- package/dist/src/generator/zod/index.d.ts +0 -10
- package/dist/src/generator/zod/index.js +0 -40
- package/dist/src/index.d.ts +0 -10
- package/dist/src/index.js +0 -35
- package/dist/src/shared/format/index.d.ts +0 -2
- package/dist/src/shared/format/index.js +0 -10
- package/dist/src/shared/fs/index.d.ts +0 -2
- package/dist/src/shared/fs/index.js +0 -10
- package/dist/src/shared/fsp/index.d.ts +0 -3
- package/dist/src/shared/fsp/index.js +0 -8
- package/dist/src/shared/generator/field-definitions.d.ts +0 -12
- package/dist/src/shared/generator/field-definitions.js +0 -12
- package/dist/src/shared/helper/build-schema-extractor.d.ts +0 -25
- package/dist/src/shared/helper/build-schema-extractor.js +0 -33
- package/dist/src/shared/helper/create-extract-field-from-property.d.ts +0 -15
- package/dist/src/shared/helper/create-extract-field-from-property.js +0 -20
- package/dist/src/shared/helper/create-extract-fields-from-call-expression.d.ts +0 -14
- package/dist/src/shared/helper/create-extract-fields-from-call-expression.js +0 -14
- package/dist/src/shared/helper/create-extract-relation-field-from-property.d.ts +0 -12
- package/dist/src/shared/helper/create-extract-relation-field-from-property.js +0 -27
- package/dist/src/shared/helper/extract-schemas.d.ts +0 -16
- package/dist/src/shared/helper/extract-schemas.js +0 -19
- package/dist/src/shared/helper/find-object-literal-expression.d.ts +0 -12
- package/dist/src/shared/helper/find-object-literal-expression.js +0 -31
- package/dist/src/shared/helper/find-object-literalIn-args.d.ts +0 -2
- package/dist/src/shared/helper/find-object-literalIn-args.js +0 -8
- package/dist/src/shared/helper/is-relation-function.d.ts +0 -10
- package/dist/src/shared/helper/is-relation-function.js +0 -16
- package/dist/src/shared/utils/index.d.ts +0 -33
- package/dist/src/shared/utils/index.js +0 -61
- package/dist/utils/index.d.ts +0 -144
- package/dist/utils/index.js +0 -250
|
@@ -1,27 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Supported validation library types.
|
|
3
|
-
*/
|
|
4
|
-
export type ValidationLibrary = 'zod' | 'valibot';
|
|
5
|
-
/**
|
|
6
|
-
* Schema extraction result type containing table name and field definitions.
|
|
7
|
-
*/
|
|
8
|
-
export type SchemaExtractionResult = {
|
|
9
|
-
/** The name of the table/schema */
|
|
10
|
-
name: string;
|
|
11
|
-
/** Optional base schema/table name (used for relations) */
|
|
12
|
-
baseName?: string;
|
|
13
|
-
/** Array of field definitions with name, validation definition, and description */
|
|
14
|
-
fields: {
|
|
15
|
-
/** Field name */
|
|
16
|
-
name: string;
|
|
17
|
-
/** Validation definition (e.g., 'z.uuid()', 'v.pipe(v.string(), v.uuid())') */
|
|
18
|
-
definition: string;
|
|
19
|
-
/** Optional field description from comments */
|
|
20
|
-
description?: string;
|
|
21
|
-
}[];
|
|
22
|
-
/** Object type for schema generation ('strict' | 'loose' | undefined) */
|
|
23
|
-
objectType?: 'strict' | 'loose';
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Relation schema extraction result with required base name.
|
|
27
|
-
*/
|
|
28
|
-
export type RelationSchemaExtractionResult = {
|
|
29
|
-
name: string;
|
|
30
|
-
baseName: string;
|
|
31
|
-
fields: {
|
|
32
|
-
name: string;
|
|
33
|
-
definition: string;
|
|
34
|
-
description?: string;
|
|
35
|
-
}[];
|
|
36
|
-
/** Object type for schema generation ('strict' | 'loose' | undefined) */
|
|
37
|
-
objectType?: 'strict' | 'loose';
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Extracts schemas from TypeScript source code using AST analysis.
|
|
41
|
-
*
|
|
42
|
-
* This function processes exported variable declarations to extract table schemas
|
|
43
|
-
* with their field definitions and comments. It supports both Zod and Valibot schema extraction.
|
|
44
|
-
*
|
|
45
|
-
* @param lines - Array of source code lines to process
|
|
46
|
-
* @param library - The validation library to extract schemas for ('zod' or 'valibot')
|
|
47
|
-
* @returns Array of extracted schemas with field definitions
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```typescript
|
|
51
|
-
* // For Zod schemas
|
|
52
|
-
* const zodSchemas = extractSchemas(sourceLines, 'zod')
|
|
53
|
-
*
|
|
54
|
-
* // For Valibot schemas
|
|
55
|
-
* const valibotSchemas = extractSchemas(sourceLines, 'valibot')
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
export declare function extractSchemas(lines: string[], library: ValidationLibrary): SchemaExtractionResult[];
|
|
59
|
-
/**
|
|
60
|
-
* Extracts Zod schemas from TypeScript source code using AST analysis.
|
|
61
|
-
*
|
|
62
|
-
* This function processes exported variable declarations to extract table schemas
|
|
63
|
-
* with their field definitions and comments. It automatically handles Zod schema extraction.
|
|
64
|
-
*
|
|
65
|
-
* @param lines - Array of source code lines to process
|
|
66
|
-
* @returns Array of extracted schemas with field definitions
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```typescript
|
|
70
|
-
* const schemas = extractZodSchemas(sourceLines)
|
|
71
|
-
* // Returns: [{ name: 'user', fields: [{ name: 'id', definition: 'z.uuid()', description: 'Primary key' }] }]
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
74
|
-
export declare function extractZodSchemas(lines: string[]): SchemaExtractionResult[];
|
|
75
|
-
/**
|
|
76
|
-
* Extracts Valibot schemas from TypeScript source code using AST analysis.
|
|
77
|
-
*
|
|
78
|
-
* This function processes exported variable declarations to extract table schemas
|
|
79
|
-
* with their field definitions and comments. It automatically handles Valibot schema extraction.
|
|
80
|
-
*
|
|
81
|
-
* @param lines - Array of source code lines to process
|
|
82
|
-
* @returns Array of extracted schemas with field definitions
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* ```typescript
|
|
86
|
-
* const schemas = extractValibotSchemas(sourceLines)
|
|
87
|
-
* // Returns: [{ name: 'user', fields: [{ name: 'id', definition: 'v.pipe(v.string(), v.uuid())', description: 'Primary key' }] }]
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
|
-
export declare function extractValibotSchemas(lines: string[]): SchemaExtractionResult[];
|
|
91
|
-
/**
|
|
92
|
-
* Extracts relation schemas from `relations(...)` declarations using AST analysis.
|
|
93
|
-
*
|
|
94
|
-
* This returns entries like `userRelations` and `postRelations` with fields
|
|
95
|
-
* resolved to either `z.array(OtherSchema)` / `v.array(OtherSchema)` or direct
|
|
96
|
-
* `OtherSchema` based on `many`/`one`.
|
|
97
|
-
*
|
|
98
|
-
* Note: Base table schemas are not included here; use `extractSchemas` for those.
|
|
99
|
-
*/
|
|
100
|
-
export declare function extractRelationSchemas(lines: string[], library: ValidationLibrary): RelationSchemaExtractionResult[];
|
|
101
|
-
/**
|
|
102
|
-
* Extracts relations from the given code.
|
|
103
|
-
*
|
|
104
|
-
* @param code - The code to extract relations from.
|
|
105
|
-
* @returns The extracted relations.
|
|
106
|
-
*/
|
|
107
|
-
export declare function extractRelations(code: string[]): {
|
|
108
|
-
fromModel: string;
|
|
109
|
-
toModel: string;
|
|
110
|
-
fromField: string;
|
|
111
|
-
toField: string;
|
|
112
|
-
type: string;
|
|
113
|
-
}[];
|
|
114
|
-
/**
|
|
115
|
-
* Parse relation line and extract components.
|
|
116
|
-
*
|
|
117
|
-
* @param line - The line to parse.
|
|
118
|
-
* @returns Parsed relation or null if not a relation line.
|
|
119
|
-
*/
|
|
120
|
-
export declare function parseRelationLine(line: string): {
|
|
121
|
-
fromModel: string;
|
|
122
|
-
toModel: string;
|
|
123
|
-
fromField: string;
|
|
124
|
-
toField: string;
|
|
125
|
-
type: string;
|
|
126
|
-
} | null;
|
|
127
|
-
/**
|
|
128
|
-
* Build a relation line from a string.
|
|
129
|
-
*
|
|
130
|
-
* @param input - The input string.
|
|
131
|
-
* @returns The built relation line.
|
|
132
|
-
*/
|
|
133
|
-
export declare function buildRelationLine(input: string): string;
|
|
@@ -1,445 +0,0 @@
|
|
|
1
|
-
import { Node, Project } from 'ts-morph';
|
|
2
|
-
import { capitalize, containsSubstring, extractFieldComments, parseFieldComments, removeOptionalSuffix, splitByDot, splitByTo, splitByWhitespace, startsWith, trimString, } from '../../utils/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Generates relation definition based on function name and reference table.
|
|
5
|
-
*
|
|
6
|
-
* @param fnName - The relation function name ('many' or 'one')
|
|
7
|
-
* @param refTable - The referenced table name
|
|
8
|
-
* @param prefix - Schema prefix ('v' or 'z') for validation library
|
|
9
|
-
* @returns The generated relation definition string
|
|
10
|
-
*/
|
|
11
|
-
function generateRelationDefinition(fnName, refTable, prefix) {
|
|
12
|
-
const schema = `${capitalize(refTable)}Schema`;
|
|
13
|
-
return fnName === 'many' ? `${prefix}.array(${schema})` : fnName === 'one' ? schema : '';
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Processes arrow function body to find object literal expression.
|
|
17
|
-
*
|
|
18
|
-
* @param body - The arrow function body node
|
|
19
|
-
* @returns The found object literal expression, or null if not found
|
|
20
|
-
*/
|
|
21
|
-
function processArrowFunctionBody(body) {
|
|
22
|
-
if (Node.isObjectLiteralExpression(body))
|
|
23
|
-
return body;
|
|
24
|
-
if (Node.isParenthesizedExpression(body)) {
|
|
25
|
-
return findObjectLiteralExpression(body.getExpression());
|
|
26
|
-
}
|
|
27
|
-
if (Node.isBlock(body)) {
|
|
28
|
-
const ret = body.getStatements().find(Node.isReturnStatement);
|
|
29
|
-
if (ret && Node.isReturnStatement(ret)) {
|
|
30
|
-
const re = ret.getExpression();
|
|
31
|
-
return re && Node.isObjectLiteralExpression(re) ? re : null;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Recursively extracts an `ObjectLiteralExpression` from a given AST node.
|
|
38
|
-
*
|
|
39
|
-
* @param expr - The root `Node` to search for object literals
|
|
40
|
-
* @returns The found `ObjectLiteralExpression`, or `null` if not found
|
|
41
|
-
*/
|
|
42
|
-
function findObjectLiteralExpression(expr) {
|
|
43
|
-
if (Node.isObjectLiteralExpression(expr))
|
|
44
|
-
return expr;
|
|
45
|
-
if (Node.isParenthesizedExpression(expr)) {
|
|
46
|
-
return findObjectLiteralExpression(expr.getExpression());
|
|
47
|
-
}
|
|
48
|
-
if (Node.isArrowFunction(expr)) {
|
|
49
|
-
return processArrowFunctionBody(expr.getBody());
|
|
50
|
-
}
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Finds an object literal expression in call expression arguments.
|
|
55
|
-
*
|
|
56
|
-
* @param call - The call expression to search for object literals in its arguments
|
|
57
|
-
* @param finder - Function to find object literal in a node
|
|
58
|
-
* @returns The found object literal, or `null` if not found in any argument
|
|
59
|
-
*/
|
|
60
|
-
function findObjectLiteralInArgs(call, finder) {
|
|
61
|
-
for (const arg of call.getArguments()) {
|
|
62
|
-
const obj = finder(arg);
|
|
63
|
-
if (obj)
|
|
64
|
-
return obj;
|
|
65
|
-
}
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Determines whether a given `CallExpression` is a relation-related function call.
|
|
70
|
-
*
|
|
71
|
-
* @param callExpr - The call expression node to check for relation functions
|
|
72
|
-
* @returns `true` if the function is a relation function; otherwise, `false`
|
|
73
|
-
*/
|
|
74
|
-
function isRelationFunctionCall(callExpr) {
|
|
75
|
-
const expression = callExpr.getExpression();
|
|
76
|
-
if (!Node.isIdentifier(expression))
|
|
77
|
-
return false;
|
|
78
|
-
const functionName = expression.getText();
|
|
79
|
-
return functionName === 'relations' || functionName.includes('relation');
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Creates a field extractor function using a custom parseFieldComments implementation.
|
|
83
|
-
*
|
|
84
|
-
* @param parseFieldComments - A function that parses comment lines into { definition, description, objectType }
|
|
85
|
-
* @returns A property node extractor function
|
|
86
|
-
*/
|
|
87
|
-
function createExtractFieldFromProperty(parseFieldComments) {
|
|
88
|
-
return (property, sourceText) => {
|
|
89
|
-
if (!Node.isPropertyAssignment(property))
|
|
90
|
-
return null;
|
|
91
|
-
const name = property.getName();
|
|
92
|
-
if (!name)
|
|
93
|
-
return null;
|
|
94
|
-
const commentLines = extractFieldComments(sourceText, property.getStart());
|
|
95
|
-
const { definition, description } = parseFieldComments(commentLines);
|
|
96
|
-
return { name, definition, description };
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Creates a relation field extractor function.
|
|
101
|
-
*
|
|
102
|
-
* @param parseFieldComments - Function to parse field comments
|
|
103
|
-
* @param prefix - Schema prefix ('v' or 'z') for validation library
|
|
104
|
-
* @returns Function that extracts relation fields from property
|
|
105
|
-
*/
|
|
106
|
-
function createExtractRelationFieldFromProperty(parseFieldComments, prefix) {
|
|
107
|
-
return (property, sourceText) => {
|
|
108
|
-
if (!Node.isPropertyAssignment(property))
|
|
109
|
-
return null;
|
|
110
|
-
const name = property.getName();
|
|
111
|
-
if (!name)
|
|
112
|
-
return null;
|
|
113
|
-
const init = property.getInitializer();
|
|
114
|
-
if (!Node.isCallExpression(init)) {
|
|
115
|
-
return { name, definition: '', description: undefined };
|
|
116
|
-
}
|
|
117
|
-
const expr = init.getExpression();
|
|
118
|
-
if (!Node.isIdentifier(expr)) {
|
|
119
|
-
return { name, definition: '', description: undefined };
|
|
120
|
-
}
|
|
121
|
-
const fnName = expr.getText();
|
|
122
|
-
const args = init.getArguments();
|
|
123
|
-
if (!(args.length && Node.isIdentifier(args[0]))) {
|
|
124
|
-
return { name, definition: '', description: undefined };
|
|
125
|
-
}
|
|
126
|
-
const refTable = args[0].getText();
|
|
127
|
-
const definition = generateRelationDefinition(fnName, refTable, prefix);
|
|
128
|
-
const { description } = parseFieldComments(extractFieldComments(sourceText, property.getStart()));
|
|
129
|
-
return { name, definition, description };
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Extracts fields from object literal properties using appropriate extractor.
|
|
134
|
-
*
|
|
135
|
-
* @param properties - Array of object literal properties
|
|
136
|
-
* @param isRelation - Whether this is a relation function call
|
|
137
|
-
* @param extractFieldFromProperty - Function to extract regular fields
|
|
138
|
-
* @param extractRelationFieldFromProperty - Function to extract relation fields
|
|
139
|
-
* @param sourceText - The source text for comment extraction
|
|
140
|
-
* @returns Array of extracted field results
|
|
141
|
-
*/
|
|
142
|
-
function extractFieldsFromProperties(properties, isRelation, extractFieldFromProperty, extractRelationFieldFromProperty, sourceText) {
|
|
143
|
-
return properties
|
|
144
|
-
.map((prop) => isRelation
|
|
145
|
-
? extractRelationFieldFromProperty(prop, sourceText)
|
|
146
|
-
: extractFieldFromProperty(prop, sourceText))
|
|
147
|
-
.filter((field) => field !== null);
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Creates a field extractor for call expressions with customizable strategies.
|
|
151
|
-
*
|
|
152
|
-
* @param extractFieldFromProperty - Function to extract field from property
|
|
153
|
-
* @param extractRelationFieldFromProperty - Function to extract relation field from property
|
|
154
|
-
* @param findObjectLiteralExpression - Function to find object literal expression
|
|
155
|
-
* @param findObjectLiteralInArgs - Function to find object literal in call arguments
|
|
156
|
-
* @param isRelationFunctionCall - Function to check if call is relation function
|
|
157
|
-
* @returns Function that extracts fields from call expression
|
|
158
|
-
*/
|
|
159
|
-
function createExtractFieldsFromCallExpression(extractFieldFromProperty, extractRelationFieldFromProperty, findObjectLiteralExpression, findObjectLiteralInArgs, isRelationFunctionCall) {
|
|
160
|
-
return (callExpr, sourceText) => {
|
|
161
|
-
const objectLiteral = findObjectLiteralInArgs(callExpr, findObjectLiteralExpression);
|
|
162
|
-
if (!objectLiteral)
|
|
163
|
-
return [];
|
|
164
|
-
const isRelation = isRelationFunctionCall(callExpr);
|
|
165
|
-
const properties = objectLiteral.getProperties();
|
|
166
|
-
return extractFieldsFromProperties(properties, isRelation, extractFieldFromProperty, extractRelationFieldFromProperty, sourceText);
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Creates a schema extractor from customizable strategies.
|
|
171
|
-
*
|
|
172
|
-
* @param extractFieldsFromCall - Function to extract fields from a call expression
|
|
173
|
-
* @param extractFieldFromProperty - Function to extract a single field from an object literal property
|
|
174
|
-
* @param parseFieldComments - Function to parse field comments with object type support
|
|
175
|
-
* @param commentPrefix - The comment prefix to use for parsing
|
|
176
|
-
* @returns A function that extracts a schema from a variable declaration node
|
|
177
|
-
*/
|
|
178
|
-
function buildSchemaExtractor(extractFieldsFromCall, extractFieldFromProperty, parseFieldComments, commentPrefix) {
|
|
179
|
-
return (variableStatement, sourceText, originalSourceCode) => {
|
|
180
|
-
if (!Node.isVariableStatement(variableStatement))
|
|
181
|
-
return null;
|
|
182
|
-
const declarations = variableStatement.getDeclarations();
|
|
183
|
-
if (declarations.length === 0)
|
|
184
|
-
return null;
|
|
185
|
-
const declaration = declarations[0];
|
|
186
|
-
const name = declaration.getName();
|
|
187
|
-
if (!name)
|
|
188
|
-
return null;
|
|
189
|
-
// Extract object type from table-level comments
|
|
190
|
-
// Since ts-morph doesn't capture all comments properly, we'll parse the original source
|
|
191
|
-
const statementStart = variableStatement.getStart();
|
|
192
|
-
const originalSourceLines = originalSourceCode.split('\n'); // Use original source, not AST sourceText
|
|
193
|
-
const commentLines = [];
|
|
194
|
-
// Find the line number where this statement starts
|
|
195
|
-
let lineNumber = 0;
|
|
196
|
-
let charCount = 0;
|
|
197
|
-
for (let i = 0; i < originalSourceLines.length; i++) {
|
|
198
|
-
if (charCount >= statementStart) {
|
|
199
|
-
lineNumber = i;
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
charCount += originalSourceLines[i].length + 1; // +1 for newline
|
|
203
|
-
}
|
|
204
|
-
// Collect comments immediately before the statement
|
|
205
|
-
for (let i = lineNumber - 1; i >= 0; i--) {
|
|
206
|
-
const line = originalSourceLines[i];
|
|
207
|
-
const trimmedLine = trimString(line);
|
|
208
|
-
// Skip empty lines
|
|
209
|
-
if (trimmedLine === '')
|
|
210
|
-
continue;
|
|
211
|
-
// If it's a comment line, add it to our collection
|
|
212
|
-
if (startsWith(trimmedLine, '///')) {
|
|
213
|
-
commentLines.unshift(line);
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
// If we hit a non-comment line, stop collecting
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
const { objectType } = parseFieldComments(commentLines, commentPrefix);
|
|
221
|
-
const initializer = declaration.getInitializer();
|
|
222
|
-
if (Node.isCallExpression(initializer)) {
|
|
223
|
-
if (isRelationFunctionCall(initializer))
|
|
224
|
-
return null;
|
|
225
|
-
const fields = extractFieldsFromCall(initializer, sourceText);
|
|
226
|
-
return { name, fields, objectType };
|
|
227
|
-
}
|
|
228
|
-
if (Node.isObjectLiteralExpression(initializer)) {
|
|
229
|
-
const fields = initializer
|
|
230
|
-
.getProperties()
|
|
231
|
-
.map((prop) => extractFieldFromProperty(prop, sourceText))
|
|
232
|
-
.filter((field) => field !== null);
|
|
233
|
-
return { name, fields, objectType };
|
|
234
|
-
}
|
|
235
|
-
return { name, fields: [], objectType };
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Extracts schemas from TypeScript source code using AST analysis.
|
|
240
|
-
*
|
|
241
|
-
* This function processes exported variable declarations to extract table schemas
|
|
242
|
-
* with their field definitions and comments. It supports both Zod and Valibot schema extraction.
|
|
243
|
-
*
|
|
244
|
-
* @param lines - Array of source code lines to process
|
|
245
|
-
* @param library - The validation library to extract schemas for ('zod' or 'valibot')
|
|
246
|
-
* @returns Array of extracted schemas with field definitions
|
|
247
|
-
*
|
|
248
|
-
* @example
|
|
249
|
-
* ```typescript
|
|
250
|
-
* // For Zod schemas
|
|
251
|
-
* const zodSchemas = extractSchemas(sourceLines, 'zod')
|
|
252
|
-
*
|
|
253
|
-
* // For Valibot schemas
|
|
254
|
-
* const valibotSchemas = extractSchemas(sourceLines, 'valibot')
|
|
255
|
-
* ```
|
|
256
|
-
*/
|
|
257
|
-
export function extractSchemas(lines, library) {
|
|
258
|
-
const sourceCode = lines.join('\n');
|
|
259
|
-
const project = new Project({
|
|
260
|
-
useInMemoryFileSystem: true,
|
|
261
|
-
compilerOptions: {
|
|
262
|
-
allowJs: true,
|
|
263
|
-
skipLibCheck: true,
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
const sourceFile = project.createSourceFile('temp.ts', sourceCode);
|
|
267
|
-
const sourceText = sourceFile.getFullText();
|
|
268
|
-
const commentPrefix = library === 'zod' ? '@z.' : '@v.';
|
|
269
|
-
const schemaPrefix = library === 'zod' ? 'z' : 'v';
|
|
270
|
-
const extractField = createExtractFieldFromProperty((lines) => parseFieldComments(lines, commentPrefix));
|
|
271
|
-
const extractRelationField = createExtractRelationFieldFromProperty((lines) => parseFieldComments(lines, commentPrefix), schemaPrefix);
|
|
272
|
-
const extractFieldsFromCall = createExtractFieldsFromCallExpression(extractField, extractRelationField, findObjectLiteralExpression, findObjectLiteralInArgs, isRelationFunctionCall);
|
|
273
|
-
const extractSchema = buildSchemaExtractor(extractFieldsFromCall, extractField, parseFieldComments, commentPrefix);
|
|
274
|
-
return sourceFile
|
|
275
|
-
.getVariableStatements()
|
|
276
|
-
.filter((stmt) => stmt.hasExportKeyword())
|
|
277
|
-
.map((stmt) => extractSchema(stmt, sourceText, sourceCode))
|
|
278
|
-
.filter((schema) => schema !== null);
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Extracts Zod schemas from TypeScript source code using AST analysis.
|
|
282
|
-
*
|
|
283
|
-
* This function processes exported variable declarations to extract table schemas
|
|
284
|
-
* with their field definitions and comments. It automatically handles Zod schema extraction.
|
|
285
|
-
*
|
|
286
|
-
* @param lines - Array of source code lines to process
|
|
287
|
-
* @returns Array of extracted schemas with field definitions
|
|
288
|
-
*
|
|
289
|
-
* @example
|
|
290
|
-
* ```typescript
|
|
291
|
-
* const schemas = extractZodSchemas(sourceLines)
|
|
292
|
-
* // Returns: [{ name: 'user', fields: [{ name: 'id', definition: 'z.uuid()', description: 'Primary key' }] }]
|
|
293
|
-
* ```
|
|
294
|
-
*/
|
|
295
|
-
export function extractZodSchemas(lines) {
|
|
296
|
-
return extractSchemas(lines, 'zod');
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Extracts Valibot schemas from TypeScript source code using AST analysis.
|
|
300
|
-
*
|
|
301
|
-
* This function processes exported variable declarations to extract table schemas
|
|
302
|
-
* with their field definitions and comments. It automatically handles Valibot schema extraction.
|
|
303
|
-
*
|
|
304
|
-
* @param lines - Array of source code lines to process
|
|
305
|
-
* @returns Array of extracted schemas with field definitions
|
|
306
|
-
*
|
|
307
|
-
* @example
|
|
308
|
-
* ```typescript
|
|
309
|
-
* const schemas = extractValibotSchemas(sourceLines)
|
|
310
|
-
* // Returns: [{ name: 'user', fields: [{ name: 'id', definition: 'v.pipe(v.string(), v.uuid())', description: 'Primary key' }] }]
|
|
311
|
-
* ```
|
|
312
|
-
*/
|
|
313
|
-
export function extractValibotSchemas(lines) {
|
|
314
|
-
return extractSchemas(lines, 'valibot');
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Extracts relation schemas from `relations(...)` declarations using AST analysis.
|
|
318
|
-
*
|
|
319
|
-
* This returns entries like `userRelations` and `postRelations` with fields
|
|
320
|
-
* resolved to either `z.array(OtherSchema)` / `v.array(OtherSchema)` or direct
|
|
321
|
-
* `OtherSchema` based on `many`/`one`.
|
|
322
|
-
*
|
|
323
|
-
* Note: Base table schemas are not included here; use `extractSchemas` for those.
|
|
324
|
-
*/
|
|
325
|
-
export function extractRelationSchemas(lines, library) {
|
|
326
|
-
const sourceCode = lines.join('\n');
|
|
327
|
-
const project = new Project({
|
|
328
|
-
useInMemoryFileSystem: true,
|
|
329
|
-
compilerOptions: { allowJs: true, skipLibCheck: true },
|
|
330
|
-
});
|
|
331
|
-
const sourceFile = project.createSourceFile('temp.ts', sourceCode);
|
|
332
|
-
const sourceText = sourceFile.getFullText();
|
|
333
|
-
const commentPrefix = library === 'zod' ? '@z.' : '@v.';
|
|
334
|
-
const schemaPrefix = library === 'zod' ? 'z' : 'v';
|
|
335
|
-
// First, extract base schemas to get their objectType
|
|
336
|
-
const baseSchemas = extractSchemas(lines, library);
|
|
337
|
-
const baseSchemaMap = new Map(baseSchemas.map((schema) => [schema.name, schema.objectType]));
|
|
338
|
-
const extractField = createExtractFieldFromProperty((lines) => parseFieldComments(lines, commentPrefix));
|
|
339
|
-
const extractRelationField = createExtractRelationFieldFromProperty((lines) => parseFieldComments(lines, commentPrefix), schemaPrefix);
|
|
340
|
-
const extractFieldsFromCall = createExtractFieldsFromCallExpression(extractField, extractRelationField, findObjectLiteralExpression, findObjectLiteralInArgs, isRelationFunctionCall);
|
|
341
|
-
function extract(declaration) {
|
|
342
|
-
if (!Node.isVariableDeclaration(declaration))
|
|
343
|
-
return null;
|
|
344
|
-
const name = declaration.getName();
|
|
345
|
-
if (!name)
|
|
346
|
-
return null;
|
|
347
|
-
const initializer = declaration.getInitializer();
|
|
348
|
-
if (!Node.isCallExpression(initializer))
|
|
349
|
-
return null;
|
|
350
|
-
if (!isRelationFunctionCall(initializer))
|
|
351
|
-
return null;
|
|
352
|
-
const relArgs = initializer.getArguments();
|
|
353
|
-
const baseIdentifier = relArgs.length && Node.isIdentifier(relArgs[0]) ? relArgs[0] : undefined;
|
|
354
|
-
if (!baseIdentifier)
|
|
355
|
-
return null;
|
|
356
|
-
const baseName = baseIdentifier.getText();
|
|
357
|
-
const fields = extractFieldsFromCall(initializer, sourceText);
|
|
358
|
-
// Inherit objectType from the base schema
|
|
359
|
-
const objectType = baseSchemaMap.get(baseName);
|
|
360
|
-
return { name, baseName, fields, objectType };
|
|
361
|
-
}
|
|
362
|
-
return sourceFile
|
|
363
|
-
.getVariableStatements()
|
|
364
|
-
.filter((stmt) => stmt.hasExportKeyword())
|
|
365
|
-
.flatMap((stmt) => stmt.getDeclarations())
|
|
366
|
-
.map((decl) => extract(decl))
|
|
367
|
-
.filter((schema) => schema !== null);
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Extracts relations from the given code.
|
|
371
|
-
*
|
|
372
|
-
* @param code - The code to extract relations from.
|
|
373
|
-
* @returns The extracted relations.
|
|
374
|
-
*/
|
|
375
|
-
export function extractRelations(code) {
|
|
376
|
-
const relations = [];
|
|
377
|
-
for (const line of code) {
|
|
378
|
-
const relation = parseRelationLine(line);
|
|
379
|
-
if (relation) {
|
|
380
|
-
relations.push(relation);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return relations;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Parse relation line and extract components.
|
|
387
|
-
*
|
|
388
|
-
* @param line - The line to parse.
|
|
389
|
-
* @returns Parsed relation or null if not a relation line.
|
|
390
|
-
*/
|
|
391
|
-
export function parseRelationLine(line) {
|
|
392
|
-
const trimmedLine = trimString(line);
|
|
393
|
-
const cleanLine = startsWith(trimmedLine, '///') ? trimmedLine.substring(3) : trimmedLine;
|
|
394
|
-
const finalLine = trimString(cleanLine);
|
|
395
|
-
if (!startsWith(finalLine, '@relation'))
|
|
396
|
-
return null;
|
|
397
|
-
const parts = splitByWhitespace(finalLine);
|
|
398
|
-
if (parts.length < 4)
|
|
399
|
-
return null;
|
|
400
|
-
const fromParts = splitByDot(parts[1]);
|
|
401
|
-
const toParts = splitByDot(parts[2]);
|
|
402
|
-
if (fromParts.length !== 2 || toParts.length !== 2)
|
|
403
|
-
return null;
|
|
404
|
-
return {
|
|
405
|
-
fromModel: fromParts[0],
|
|
406
|
-
fromField: fromParts[1],
|
|
407
|
-
toModel: toParts[0],
|
|
408
|
-
toField: toParts[1],
|
|
409
|
-
type: parts[3],
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Build a relation line from a string.
|
|
414
|
-
*
|
|
415
|
-
* @param input - The input string.
|
|
416
|
-
* @returns The built relation line.
|
|
417
|
-
*/
|
|
418
|
-
export function buildRelationLine(input) {
|
|
419
|
-
const toSymbol = (r) => r === 'zero-one'
|
|
420
|
-
? '|o'
|
|
421
|
-
: r === 'one'
|
|
422
|
-
? '||'
|
|
423
|
-
: r === 'zero-many'
|
|
424
|
-
? '}o'
|
|
425
|
-
: r === 'many'
|
|
426
|
-
? '}|'
|
|
427
|
-
: (() => {
|
|
428
|
-
throw new Error(`Invalid relationship: ${r}`);
|
|
429
|
-
})();
|
|
430
|
-
const isRelationship = (r) => ['zero-one', 'one', 'zero-many', 'many'].includes(r);
|
|
431
|
-
const parts = splitByTo(input);
|
|
432
|
-
if (!parts)
|
|
433
|
-
throw new Error(`Invalid input format: ${input}`);
|
|
434
|
-
const [fromRaw, toRawWithOptional] = parts;
|
|
435
|
-
const [toRaw, isOptional] = containsSubstring(toRawWithOptional, '-optional')
|
|
436
|
-
? [removeOptionalSuffix(toRawWithOptional), true]
|
|
437
|
-
: [toRawWithOptional, false];
|
|
438
|
-
if (!(isRelationship(fromRaw) && isRelationship(toRaw))) {
|
|
439
|
-
throw new Error(`Invalid relationship string: ${input}`);
|
|
440
|
-
}
|
|
441
|
-
const fromSymbol = toSymbol(fromRaw);
|
|
442
|
-
const toSymbolStr = toSymbol(toRaw);
|
|
443
|
-
const connector = isOptional ? '..' : '--';
|
|
444
|
-
return `${fromSymbol}${connector}${toSymbolStr}`;
|
|
445
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { writeFile, mkdir } from 'fs/promises';
|
|
2
|
-
import { dirname } from 'path';
|
|
3
|
-
import { Result, err, ok } from 'neverthrow';
|
|
4
|
-
export const writeFileSafely = async (filePath, content) => {
|
|
5
|
-
try {
|
|
6
|
-
// ディレクトリが存在しない場合は作成
|
|
7
|
-
const directory = dirname(filePath);
|
|
8
|
-
await mkdir(directory, { recursive: true });
|
|
9
|
-
// ファイルを書き込み
|
|
10
|
-
await writeFile(filePath, content, 'utf-8');
|
|
11
|
-
return ok(undefined);
|
|
12
|
-
}
|
|
13
|
-
catch (error) {
|
|
14
|
-
return err(new Error(`Failed to write file ${filePath}: ${error instanceof Error ? error.message : String(error)}`));
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
export const ensureDirectoryExists = async (directory) => {
|
|
18
|
-
try {
|
|
19
|
-
await mkdir(directory, { recursive: true });
|
|
20
|
-
return ok(undefined);
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
return err(new Error(`Failed to create directory ${directory}: ${error instanceof Error ? error.message : String(error)}`));
|
|
24
|
-
}
|
|
25
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
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;
|
|
@@ -1,31 +0,0 @@
|
|
|
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
|
-
}
|