@formspec/cli 0.1.0-alpha.3

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 +314 -0
  2. package/dist/__tests__/analyzer.test.d.ts +5 -0
  3. package/dist/__tests__/analyzer.test.d.ts.map +1 -0
  4. package/dist/__tests__/analyzer.test.js +141 -0
  5. package/dist/__tests__/analyzer.test.js.map +1 -0
  6. package/dist/__tests__/codegen.test.d.ts +5 -0
  7. package/dist/__tests__/codegen.test.d.ts.map +1 -0
  8. package/dist/__tests__/codegen.test.js +482 -0
  9. package/dist/__tests__/codegen.test.js.map +1 -0
  10. package/dist/__tests__/edge-cases.test.d.ts +14 -0
  11. package/dist/__tests__/edge-cases.test.d.ts.map +1 -0
  12. package/dist/__tests__/edge-cases.test.js +432 -0
  13. package/dist/__tests__/edge-cases.test.js.map +1 -0
  14. package/dist/__tests__/fixtures/edge-cases.d.ts +110 -0
  15. package/dist/__tests__/fixtures/edge-cases.d.ts.map +1 -0
  16. package/dist/__tests__/fixtures/edge-cases.js +135 -0
  17. package/dist/__tests__/fixtures/edge-cases.js.map +1 -0
  18. package/dist/__tests__/fixtures/sample-forms.d.ts +55 -0
  19. package/dist/__tests__/fixtures/sample-forms.d.ts.map +1 -0
  20. package/dist/__tests__/fixtures/sample-forms.js +78 -0
  21. package/dist/__tests__/fixtures/sample-forms.js.map +1 -0
  22. package/dist/__tests__/integration.test.d.ts +5 -0
  23. package/dist/__tests__/integration.test.d.ts.map +1 -0
  24. package/dist/__tests__/integration.test.js +159 -0
  25. package/dist/__tests__/integration.test.js.map +1 -0
  26. package/dist/analyzer/class-analyzer.d.ts +75 -0
  27. package/dist/analyzer/class-analyzer.d.ts.map +1 -0
  28. package/dist/analyzer/class-analyzer.js +151 -0
  29. package/dist/analyzer/class-analyzer.js.map +1 -0
  30. package/dist/analyzer/decorator-extractor.d.ts +87 -0
  31. package/dist/analyzer/decorator-extractor.d.ts.map +1 -0
  32. package/dist/analyzer/decorator-extractor.js +193 -0
  33. package/dist/analyzer/decorator-extractor.js.map +1 -0
  34. package/dist/analyzer/program.d.ts +37 -0
  35. package/dist/analyzer/program.d.ts.map +1 -0
  36. package/dist/analyzer/program.js +89 -0
  37. package/dist/analyzer/program.js.map +1 -0
  38. package/dist/analyzer/type-converter.d.ts +97 -0
  39. package/dist/analyzer/type-converter.d.ts.map +1 -0
  40. package/dist/analyzer/type-converter.js +353 -0
  41. package/dist/analyzer/type-converter.js.map +1 -0
  42. package/dist/codegen/index.d.ts +74 -0
  43. package/dist/codegen/index.d.ts.map +1 -0
  44. package/dist/codegen/index.js +501 -0
  45. package/dist/codegen/index.js.map +1 -0
  46. package/dist/generators/class-schema.d.ts +43 -0
  47. package/dist/generators/class-schema.d.ts.map +1 -0
  48. package/dist/generators/class-schema.js +61 -0
  49. package/dist/generators/class-schema.js.map +1 -0
  50. package/dist/generators/method-schema.d.ts +57 -0
  51. package/dist/generators/method-schema.d.ts.map +1 -0
  52. package/dist/generators/method-schema.js +108 -0
  53. package/dist/generators/method-schema.js.map +1 -0
  54. package/dist/index.d.ts +19 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +282 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/output/writer.d.ts +82 -0
  59. package/dist/output/writer.d.ts.map +1 -0
  60. package/dist/output/writer.js +152 -0
  61. package/dist/output/writer.js.map +1 -0
  62. package/dist/runtime/formspec-loader.d.ts +80 -0
  63. package/dist/runtime/formspec-loader.d.ts.map +1 -0
  64. package/dist/runtime/formspec-loader.js +154 -0
  65. package/dist/runtime/formspec-loader.js.map +1 -0
  66. package/package.json +46 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Class analyzer for extracting fields, types, and decorators.
3
+ *
4
+ * Analyzes a TypeScript class declaration to extract:
5
+ * - Field names and TypeScript types
6
+ * - Decorator metadata (Label, Min, Max, etc.)
7
+ * - Field optionality
8
+ */
9
+ import * as ts from "typescript";
10
+ import { extractDecorators } from "./decorator-extractor.js";
11
+ /**
12
+ * Analyzes a class declaration to extract fields and methods.
13
+ *
14
+ * @param classDecl - The class declaration to analyze
15
+ * @param checker - TypeScript type checker
16
+ * @returns Analysis result with fields and methods
17
+ */
18
+ export function analyzeClass(classDecl, checker) {
19
+ const name = classDecl.name?.text ?? "AnonymousClass";
20
+ const fields = [];
21
+ const instanceMethods = [];
22
+ const staticMethods = [];
23
+ for (const member of classDecl.members) {
24
+ if (ts.isPropertyDeclaration(member)) {
25
+ const fieldInfo = analyzeField(member, checker);
26
+ if (fieldInfo) {
27
+ fields.push(fieldInfo);
28
+ }
29
+ }
30
+ else if (ts.isMethodDeclaration(member)) {
31
+ const methodInfo = analyzeMethod(member, checker);
32
+ if (methodInfo) {
33
+ const isStatic = member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword);
34
+ if (isStatic) {
35
+ staticMethods.push(methodInfo);
36
+ }
37
+ else {
38
+ instanceMethods.push(methodInfo);
39
+ }
40
+ }
41
+ }
42
+ }
43
+ return {
44
+ name,
45
+ fields,
46
+ instanceMethods,
47
+ staticMethods,
48
+ };
49
+ }
50
+ /**
51
+ * Analyzes a property declaration to extract field info.
52
+ */
53
+ function analyzeField(prop, checker) {
54
+ // Skip computed property names
55
+ if (!ts.isIdentifier(prop.name)) {
56
+ return null;
57
+ }
58
+ const name = prop.name.text;
59
+ const typeNode = prop.type;
60
+ const type = checker.getTypeAtLocation(prop);
61
+ const optional = prop.questionToken !== undefined;
62
+ const decorators = extractDecorators(prop);
63
+ return {
64
+ name,
65
+ typeNode,
66
+ type,
67
+ optional,
68
+ decorators,
69
+ };
70
+ }
71
+ /**
72
+ * Analyzes a method declaration to extract method info.
73
+ */
74
+ function analyzeMethod(method, checker) {
75
+ // Skip computed method names
76
+ if (!ts.isIdentifier(method.name)) {
77
+ return null;
78
+ }
79
+ const name = method.name.text;
80
+ const parameters = [];
81
+ for (const param of method.parameters) {
82
+ if (ts.isIdentifier(param.name)) {
83
+ const paramInfo = analyzeParameter(param, checker);
84
+ parameters.push(paramInfo);
85
+ }
86
+ }
87
+ const returnTypeNode = method.type;
88
+ const signature = checker.getSignatureFromDeclaration(method);
89
+ const returnType = signature
90
+ ? checker.getReturnTypeOfSignature(signature)
91
+ : checker.getTypeAtLocation(method);
92
+ return {
93
+ name,
94
+ parameters,
95
+ returnTypeNode,
96
+ returnType,
97
+ };
98
+ }
99
+ /**
100
+ * Analyzes a parameter declaration.
101
+ */
102
+ function analyzeParameter(param, checker) {
103
+ const name = ts.isIdentifier(param.name) ? param.name.text : "param";
104
+ const typeNode = param.type;
105
+ const type = checker.getTypeAtLocation(param);
106
+ const formSpecExportName = detectFormSpecReference(typeNode);
107
+ // Parameter is optional if it has a question token or a default value
108
+ const optional = param.questionToken !== undefined || param.initializer !== undefined;
109
+ return {
110
+ name,
111
+ typeNode,
112
+ type,
113
+ formSpecExportName,
114
+ optional,
115
+ };
116
+ }
117
+ /**
118
+ * Detects if a type node is InferSchema<typeof X> or InferFormSchema<typeof X> and extracts X.
119
+ *
120
+ * @param typeNode - The type node to check
121
+ * @returns The export name X, or null if not a FormSpec inference pattern
122
+ */
123
+ function detectFormSpecReference(typeNode) {
124
+ if (!typeNode)
125
+ return null;
126
+ // Looking for: InferSchema<typeof X> or InferFormSchema<typeof X>
127
+ if (!ts.isTypeReferenceNode(typeNode))
128
+ return null;
129
+ // Get the type name - could be Identifier or QualifiedName
130
+ const typeName = ts.isIdentifier(typeNode.typeName)
131
+ ? typeNode.typeName.text
132
+ : ts.isQualifiedName(typeNode.typeName)
133
+ ? typeNode.typeName.right.text
134
+ : null;
135
+ // Support both InferSchema (for elements) and InferFormSchema (for FormSpec)
136
+ if (typeName !== "InferSchema" && typeName !== "InferFormSchema")
137
+ return null;
138
+ const typeArg = typeNode.typeArguments?.[0];
139
+ if (!typeArg || !ts.isTypeQueryNode(typeArg))
140
+ return null;
141
+ // typeArg.exprName is the identifier (e.g., "ActivateParams")
142
+ if (ts.isIdentifier(typeArg.exprName)) {
143
+ return typeArg.exprName.text;
144
+ }
145
+ // Could be qualified name like Namespace.ActivateParams
146
+ if (ts.isQualifiedName(typeArg.exprName)) {
147
+ return typeArg.exprName.right.text;
148
+ }
149
+ return null;
150
+ }
151
+ //# sourceMappingURL=class-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/class-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Decorator extractor for parsing decorator AST nodes.
3
+ *
4
+ * Extracts decorator names and arguments from class field decorators,
5
+ * supporting the FormSpec decorator DSL (@Label, @Min, @Max, etc.).
6
+ */
7
+ import * as ts from "typescript";
8
+ /**
9
+ * Extracted decorator information.
10
+ */
11
+ export interface DecoratorInfo {
12
+ /** Decorator name (e.g., "Label", "Min") */
13
+ name: string;
14
+ /** Decorator arguments as literal values */
15
+ args: DecoratorArg[];
16
+ /** Raw AST node for the decorator */
17
+ node: ts.Decorator;
18
+ }
19
+ /**
20
+ * A decorator argument value.
21
+ * Can be a primitive, array, or object literal.
22
+ */
23
+ export type DecoratorArg = string | number | boolean | null | DecoratorArg[] | {
24
+ [key: string]: DecoratorArg;
25
+ };
26
+ /**
27
+ * Extracts decorators from a class member (property or method).
28
+ *
29
+ * @param member - The class member to extract decorators from
30
+ * @returns Array of extracted decorator info
31
+ */
32
+ export declare function extractDecorators(member: ts.PropertyDeclaration | ts.MethodDeclaration): DecoratorInfo[];
33
+ /**
34
+ * Known FormSpec decorators and their expected argument types.
35
+ */
36
+ export declare const FORMSPEC_DECORATORS: {
37
+ readonly Label: {
38
+ readonly argTypes: readonly ["string"];
39
+ };
40
+ readonly Placeholder: {
41
+ readonly argTypes: readonly ["string"];
42
+ };
43
+ readonly Description: {
44
+ readonly argTypes: readonly ["string"];
45
+ };
46
+ readonly Min: {
47
+ readonly argTypes: readonly ["number"];
48
+ };
49
+ readonly Max: {
50
+ readonly argTypes: readonly ["number"];
51
+ };
52
+ readonly Step: {
53
+ readonly argTypes: readonly ["number"];
54
+ };
55
+ readonly MinItems: {
56
+ readonly argTypes: readonly ["number"];
57
+ };
58
+ readonly MaxItems: {
59
+ readonly argTypes: readonly ["number"];
60
+ };
61
+ readonly MinLength: {
62
+ readonly argTypes: readonly ["number"];
63
+ };
64
+ readonly MaxLength: {
65
+ readonly argTypes: readonly ["number"];
66
+ };
67
+ readonly Pattern: {
68
+ readonly argTypes: readonly ["string"];
69
+ };
70
+ readonly EnumOptions: {
71
+ readonly argTypes: readonly ["array"];
72
+ };
73
+ readonly ShowWhen: {
74
+ readonly argTypes: readonly ["object"];
75
+ };
76
+ readonly Group: {
77
+ readonly argTypes: readonly ["string"];
78
+ };
79
+ readonly Boolean: {
80
+ readonly argTypes: readonly [];
81
+ };
82
+ };
83
+ /**
84
+ * Checks if a decorator name is a known FormSpec decorator.
85
+ */
86
+ export declare function isFormSpecDecorator(name: string): boolean;
87
+ //# sourceMappingURL=decorator-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator-extractor.d.ts","sourceRoot":"","sources":["../../src/analyzer/decorator-extractor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,qCAAqC;IACrC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,YAAY,EAAE,GACd;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,CAAC;AAEpC;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,EAAE,CAAC,mBAAmB,GAAG,EAAE,CAAC,iBAAiB,GACpD,aAAa,EAAE,CAkBjB;AAuJD;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BtB,CAAC;AAEX;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Decorator extractor for parsing decorator AST nodes.
3
+ *
4
+ * Extracts decorator names and arguments from class field decorators,
5
+ * supporting the FormSpec decorator DSL (@Label, @Min, @Max, etc.).
6
+ */
7
+ import * as ts from "typescript";
8
+ /**
9
+ * Extracts decorators from a class member (property or method).
10
+ *
11
+ * @param member - The class member to extract decorators from
12
+ * @returns Array of extracted decorator info
13
+ */
14
+ export function extractDecorators(member) {
15
+ const decorators = [];
16
+ // TC39 decorators are in the modifiers array
17
+ const modifiers = ts.canHaveDecorators(member)
18
+ ? ts.getDecorators(member)
19
+ : undefined;
20
+ if (!modifiers)
21
+ return decorators;
22
+ for (const decorator of modifiers) {
23
+ const info = parseDecorator(decorator);
24
+ if (info) {
25
+ decorators.push(info);
26
+ }
27
+ }
28
+ return decorators;
29
+ }
30
+ /**
31
+ * Parses a single decorator node.
32
+ */
33
+ function parseDecorator(decorator) {
34
+ const expr = decorator.expression;
35
+ // Simple decorator: @Decorator
36
+ if (ts.isIdentifier(expr)) {
37
+ return {
38
+ name: expr.text,
39
+ args: [],
40
+ node: decorator,
41
+ };
42
+ }
43
+ // Call expression: @Decorator(args)
44
+ if (ts.isCallExpression(expr)) {
45
+ const callee = expr.expression;
46
+ // Get decorator name
47
+ let name = null;
48
+ if (ts.isIdentifier(callee)) {
49
+ name = callee.text;
50
+ }
51
+ else if (ts.isPropertyAccessExpression(callee)) {
52
+ // For namespaced decorators like @formspec.Label()
53
+ name = callee.name.text;
54
+ }
55
+ if (!name)
56
+ return null;
57
+ // Extract arguments
58
+ const args = expr.arguments.map(extractArgValue);
59
+ return {
60
+ name,
61
+ args,
62
+ node: decorator,
63
+ };
64
+ }
65
+ return null;
66
+ }
67
+ /**
68
+ * Extracts the value from an expression node.
69
+ * Supports literals, arrays, and object literals.
70
+ */
71
+ function extractArgValue(node) {
72
+ // String literal
73
+ if (ts.isStringLiteral(node)) {
74
+ return node.text;
75
+ }
76
+ // Numeric literal
77
+ if (ts.isNumericLiteral(node)) {
78
+ return Number(node.text);
79
+ }
80
+ // Boolean literals (true/false are identifiers in TS AST)
81
+ if (node.kind === ts.SyntaxKind.TrueKeyword) {
82
+ return true;
83
+ }
84
+ if (node.kind === ts.SyntaxKind.FalseKeyword) {
85
+ return false;
86
+ }
87
+ // Null literal
88
+ if (node.kind === ts.SyntaxKind.NullKeyword) {
89
+ return null;
90
+ }
91
+ // Prefix unary expression (for negative numbers)
92
+ if (ts.isPrefixUnaryExpression(node)) {
93
+ if (node.operator === ts.SyntaxKind.MinusToken &&
94
+ ts.isNumericLiteral(node.operand)) {
95
+ return -Number(node.operand.text);
96
+ }
97
+ if (node.operator === ts.SyntaxKind.PlusToken &&
98
+ ts.isNumericLiteral(node.operand)) {
99
+ return Number(node.operand.text);
100
+ }
101
+ }
102
+ // Array literal
103
+ if (ts.isArrayLiteralExpression(node)) {
104
+ return node.elements.map((el) => {
105
+ if (ts.isSpreadElement(el)) {
106
+ // Can't evaluate spread at compile time
107
+ return null;
108
+ }
109
+ return extractArgValue(el);
110
+ });
111
+ }
112
+ // Object literal
113
+ if (ts.isObjectLiteralExpression(node)) {
114
+ const obj = {};
115
+ for (const prop of node.properties) {
116
+ if (ts.isPropertyAssignment(prop)) {
117
+ const key = getPropertyName(prop.name);
118
+ if (key) {
119
+ obj[key] = extractArgValue(prop.initializer);
120
+ }
121
+ }
122
+ else if (ts.isShorthandPropertyAssignment(prop)) {
123
+ // { foo } shorthand - we can't resolve the value
124
+ const key = prop.name.text;
125
+ obj[key] = null;
126
+ }
127
+ }
128
+ return obj;
129
+ }
130
+ // Template literal (simple case)
131
+ if (ts.isNoSubstitutionTemplateLiteral(node)) {
132
+ return node.text;
133
+ }
134
+ // Identifier - could be an enum member or constant
135
+ // We return null since we can't resolve it statically
136
+ if (ts.isIdentifier(node)) {
137
+ // Return the identifier name for potential later resolution
138
+ return `__identifier:${node.text}`;
139
+ }
140
+ // For other expressions, return null
141
+ return null;
142
+ }
143
+ /**
144
+ * Gets the property name from a property name node.
145
+ */
146
+ function getPropertyName(name) {
147
+ if (ts.isIdentifier(name)) {
148
+ return name.text;
149
+ }
150
+ if (ts.isStringLiteral(name)) {
151
+ return name.text;
152
+ }
153
+ if (ts.isNumericLiteral(name)) {
154
+ return name.text;
155
+ }
156
+ // Computed property names can't be resolved statically
157
+ return null;
158
+ }
159
+ /**
160
+ * Known FormSpec decorators and their expected argument types.
161
+ */
162
+ export const FORMSPEC_DECORATORS = {
163
+ // Metadata decorators
164
+ Label: { argTypes: ["string"] },
165
+ Placeholder: { argTypes: ["string"] },
166
+ Description: { argTypes: ["string"] },
167
+ // Numeric constraints
168
+ Min: { argTypes: ["number"] },
169
+ Max: { argTypes: ["number"] },
170
+ Step: { argTypes: ["number"] },
171
+ // Array constraints
172
+ MinItems: { argTypes: ["number"] },
173
+ MaxItems: { argTypes: ["number"] },
174
+ // String constraints
175
+ MinLength: { argTypes: ["number"] },
176
+ MaxLength: { argTypes: ["number"] },
177
+ Pattern: { argTypes: ["string"] },
178
+ // Enum options
179
+ EnumOptions: { argTypes: ["array"] },
180
+ // Conditional display
181
+ ShowWhen: { argTypes: ["object"] },
182
+ // Grouping
183
+ Group: { argTypes: ["string"] },
184
+ // Type hints (may be removed once CLI handles type inference)
185
+ Boolean: { argTypes: [] },
186
+ };
187
+ /**
188
+ * Checks if a decorator name is a known FormSpec decorator.
189
+ */
190
+ export function isFormSpecDecorator(name) {
191
+ return name in FORMSPEC_DECORATORS;
192
+ }
193
+ //# sourceMappingURL=decorator-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator-extractor.js","sourceRoot":"","sources":["../../src/analyzer/decorator-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * TypeScript program setup for static analysis.
3
+ *
4
+ * Creates a TypeScript program with type checker from a source file,
5
+ * using the project's tsconfig.json for compiler options.
6
+ */
7
+ import * as ts from "typescript";
8
+ /**
9
+ * Result of creating a TypeScript program for analysis.
10
+ */
11
+ export interface ProgramContext {
12
+ /** The TypeScript program */
13
+ program: ts.Program;
14
+ /** Type checker for resolving types */
15
+ checker: ts.TypeChecker;
16
+ /** The source file being analyzed */
17
+ sourceFile: ts.SourceFile;
18
+ }
19
+ /**
20
+ * Creates a TypeScript program for analyzing a source file.
21
+ *
22
+ * Looks for tsconfig.json in the file's directory or parent directories.
23
+ * Falls back to default compiler options if no config is found.
24
+ *
25
+ * @param filePath - Absolute path to the TypeScript source file
26
+ * @returns Program context with checker and source file
27
+ */
28
+ export declare function createProgramContext(filePath: string): ProgramContext;
29
+ /**
30
+ * Finds a class declaration by name in a source file.
31
+ *
32
+ * @param sourceFile - The source file to search
33
+ * @param className - Name of the class to find
34
+ * @returns The class declaration node, or null if not found
35
+ */
36
+ export declare function findClassByName(sourceFile: ts.SourceFile, className: string): ts.ClassDeclaration | null;
37
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/analyzer/program.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;IACpB,uCAAuC;IACvC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC;IACxB,qCAAqC;IACrC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CA6DrE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,SAAS,EAAE,MAAM,GAChB,EAAE,CAAC,gBAAgB,GAAG,IAAI,CAgB5B"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * TypeScript program setup for static analysis.
3
+ *
4
+ * Creates a TypeScript program with type checker from a source file,
5
+ * using the project's tsconfig.json for compiler options.
6
+ */
7
+ import * as ts from "typescript";
8
+ import * as path from "node:path";
9
+ /**
10
+ * Creates a TypeScript program for analyzing a source file.
11
+ *
12
+ * Looks for tsconfig.json in the file's directory or parent directories.
13
+ * Falls back to default compiler options if no config is found.
14
+ *
15
+ * @param filePath - Absolute path to the TypeScript source file
16
+ * @returns Program context with checker and source file
17
+ */
18
+ export function createProgramContext(filePath) {
19
+ const absolutePath = path.resolve(filePath);
20
+ const fileDir = path.dirname(absolutePath);
21
+ // Find tsconfig.json
22
+ const configPath = ts.findConfigFile(fileDir, ts.sys.fileExists, "tsconfig.json");
23
+ let compilerOptions;
24
+ let fileNames;
25
+ if (configPath) {
26
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
27
+ if (configFile.error) {
28
+ throw new Error(`Error reading tsconfig.json: ${ts.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`);
29
+ }
30
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
31
+ if (parsed.errors.length > 0) {
32
+ const errorMessages = parsed.errors
33
+ .map(e => ts.flattenDiagnosticMessageText(e.messageText, "\n"))
34
+ .join("\n");
35
+ throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
36
+ }
37
+ compilerOptions = parsed.options;
38
+ // Include the target file in the program
39
+ fileNames = parsed.fileNames.includes(absolutePath)
40
+ ? parsed.fileNames
41
+ : [...parsed.fileNames, absolutePath];
42
+ }
43
+ else {
44
+ // Fallback to default options
45
+ compilerOptions = {
46
+ target: ts.ScriptTarget.ES2022,
47
+ module: ts.ModuleKind.NodeNext,
48
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
49
+ strict: true,
50
+ esModuleInterop: true,
51
+ skipLibCheck: true,
52
+ declaration: true,
53
+ experimentalDecorators: true, // Required for legacy TypeScript decorators
54
+ };
55
+ fileNames = [absolutePath];
56
+ }
57
+ const program = ts.createProgram(fileNames, compilerOptions);
58
+ const sourceFile = program.getSourceFile(absolutePath);
59
+ if (!sourceFile) {
60
+ throw new Error(`Could not find source file: ${absolutePath}`);
61
+ }
62
+ return {
63
+ program,
64
+ checker: program.getTypeChecker(),
65
+ sourceFile,
66
+ };
67
+ }
68
+ /**
69
+ * Finds a class declaration by name in a source file.
70
+ *
71
+ * @param sourceFile - The source file to search
72
+ * @param className - Name of the class to find
73
+ * @returns The class declaration node, or null if not found
74
+ */
75
+ export function findClassByName(sourceFile, className) {
76
+ let result = null;
77
+ function visit(node) {
78
+ if (result)
79
+ return;
80
+ if (ts.isClassDeclaration(node) && node.name?.text === className) {
81
+ result = node;
82
+ return;
83
+ }
84
+ ts.forEachChild(node, visit);
85
+ }
86
+ visit(sourceFile);
87
+ return result;
88
+ }
89
+ //# sourceMappingURL=program.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/analyzer/program.ts"],"names":[],"mappings":"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"}