@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.
- package/README.md +314 -0
- package/dist/__tests__/analyzer.test.d.ts +5 -0
- package/dist/__tests__/analyzer.test.d.ts.map +1 -0
- package/dist/__tests__/analyzer.test.js +141 -0
- package/dist/__tests__/analyzer.test.js.map +1 -0
- package/dist/__tests__/codegen.test.d.ts +5 -0
- package/dist/__tests__/codegen.test.d.ts.map +1 -0
- package/dist/__tests__/codegen.test.js +482 -0
- package/dist/__tests__/codegen.test.js.map +1 -0
- package/dist/__tests__/edge-cases.test.d.ts +14 -0
- package/dist/__tests__/edge-cases.test.d.ts.map +1 -0
- package/dist/__tests__/edge-cases.test.js +432 -0
- package/dist/__tests__/edge-cases.test.js.map +1 -0
- package/dist/__tests__/fixtures/edge-cases.d.ts +110 -0
- package/dist/__tests__/fixtures/edge-cases.d.ts.map +1 -0
- package/dist/__tests__/fixtures/edge-cases.js +135 -0
- package/dist/__tests__/fixtures/edge-cases.js.map +1 -0
- package/dist/__tests__/fixtures/sample-forms.d.ts +55 -0
- package/dist/__tests__/fixtures/sample-forms.d.ts.map +1 -0
- package/dist/__tests__/fixtures/sample-forms.js +78 -0
- package/dist/__tests__/fixtures/sample-forms.js.map +1 -0
- package/dist/__tests__/integration.test.d.ts +5 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +159 -0
- package/dist/__tests__/integration.test.js.map +1 -0
- package/dist/analyzer/class-analyzer.d.ts +75 -0
- package/dist/analyzer/class-analyzer.d.ts.map +1 -0
- package/dist/analyzer/class-analyzer.js +151 -0
- package/dist/analyzer/class-analyzer.js.map +1 -0
- package/dist/analyzer/decorator-extractor.d.ts +87 -0
- package/dist/analyzer/decorator-extractor.d.ts.map +1 -0
- package/dist/analyzer/decorator-extractor.js +193 -0
- package/dist/analyzer/decorator-extractor.js.map +1 -0
- package/dist/analyzer/program.d.ts +37 -0
- package/dist/analyzer/program.d.ts.map +1 -0
- package/dist/analyzer/program.js +89 -0
- package/dist/analyzer/program.js.map +1 -0
- package/dist/analyzer/type-converter.d.ts +97 -0
- package/dist/analyzer/type-converter.d.ts.map +1 -0
- package/dist/analyzer/type-converter.js +353 -0
- package/dist/analyzer/type-converter.js.map +1 -0
- package/dist/codegen/index.d.ts +74 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +501 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/generators/class-schema.d.ts +43 -0
- package/dist/generators/class-schema.d.ts.map +1 -0
- package/dist/generators/class-schema.js +61 -0
- package/dist/generators/class-schema.js.map +1 -0
- package/dist/generators/method-schema.d.ts +57 -0
- package/dist/generators/method-schema.d.ts.map +1 -0
- package/dist/generators/method-schema.js +108 -0
- package/dist/generators/method-schema.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +282 -0
- package/dist/index.js.map +1 -0
- package/dist/output/writer.d.ts +82 -0
- package/dist/output/writer.d.ts.map +1 -0
- package/dist/output/writer.js +152 -0
- package/dist/output/writer.js.map +1 -0
- package/dist/runtime/formspec-loader.d.ts +80 -0
- package/dist/runtime/formspec-loader.d.ts.map +1 -0
- package/dist/runtime/formspec-loader.js +154 -0
- package/dist/runtime/formspec-loader.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Method schema generator.
|
|
3
|
+
*
|
|
4
|
+
* Generates schemas for method parameters and return types:
|
|
5
|
+
* - Parameters using FormSpec (InferSchema<typeof X>) → runtime generation
|
|
6
|
+
* - Parameters with regular types → static type conversion
|
|
7
|
+
* - Return types → static type conversion
|
|
8
|
+
*/
|
|
9
|
+
import type * as ts from "typescript";
|
|
10
|
+
import type { MethodInfo } from "../analyzer/class-analyzer.js";
|
|
11
|
+
import { type JsonSchema } from "../analyzer/type-converter.js";
|
|
12
|
+
import type { FormSpecSchemas } from "../runtime/formspec-loader.js";
|
|
13
|
+
/**
|
|
14
|
+
* Generated schemas for a method.
|
|
15
|
+
*/
|
|
16
|
+
export interface MethodSchemas {
|
|
17
|
+
/** Method name */
|
|
18
|
+
name: string;
|
|
19
|
+
/** Parameter schemas (from FormSpec or static analysis) */
|
|
20
|
+
params: MethodParamsSchemas | null;
|
|
21
|
+
/** Return type schema */
|
|
22
|
+
returnType: JsonSchema;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parameter schemas for a method.
|
|
26
|
+
*/
|
|
27
|
+
export interface MethodParamsSchemas {
|
|
28
|
+
/** JSON Schema for parameters */
|
|
29
|
+
jsonSchema: JsonSchema;
|
|
30
|
+
/** UI Schema / FormSpec for parameters (if available) */
|
|
31
|
+
uxSpec: object | null;
|
|
32
|
+
/** Name of the FormSpec export used (if any) */
|
|
33
|
+
formSpecExport: string | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generates schemas for a method's parameters and return type.
|
|
37
|
+
*
|
|
38
|
+
* If a parameter references a FormSpec via `InferSchema<typeof X>`,
|
|
39
|
+
* the schemas are taken from the loaded FormSpec at runtime.
|
|
40
|
+
* Otherwise, schemas are generated from static type analysis.
|
|
41
|
+
*
|
|
42
|
+
* @param method - The method information from static analysis
|
|
43
|
+
* @param checker - TypeScript type checker
|
|
44
|
+
* @param loadedFormSpecs - Map of FormSpec export names to their schemas
|
|
45
|
+
* @returns Generated method schemas
|
|
46
|
+
*/
|
|
47
|
+
export declare function generateMethodSchemas(method: MethodInfo, checker: ts.TypeChecker, loadedFormSpecs: Map<string, FormSpecSchemas>): MethodSchemas;
|
|
48
|
+
/**
|
|
49
|
+
* Collects all FormSpec export names referenced by methods.
|
|
50
|
+
*
|
|
51
|
+
* Use this to determine which exports to load at runtime.
|
|
52
|
+
*
|
|
53
|
+
* @param methods - Array of method infos
|
|
54
|
+
* @returns Set of FormSpec export names
|
|
55
|
+
*/
|
|
56
|
+
export declare function collectFormSpecReferences(methods: MethodInfo[]): Set<string>;
|
|
57
|
+
//# sourceMappingURL=method-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-schema.d.ts","sourceRoot":"","sources":["../../src/generators/method-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,yBAAyB;IACzB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,yDAAyD;IACzD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gDAAgD;IAChD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,EAAE,CAAC,WAAW,EACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAC5C,aAAa,CAYf;AAuED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,UAAU,EAAE,GACpB,GAAG,CAAC,MAAM,CAAC,CAYb"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Method schema generator.
|
|
3
|
+
*
|
|
4
|
+
* Generates schemas for method parameters and return types:
|
|
5
|
+
* - Parameters using FormSpec (InferSchema<typeof X>) → runtime generation
|
|
6
|
+
* - Parameters with regular types → static type conversion
|
|
7
|
+
* - Return types → static type conversion
|
|
8
|
+
*/
|
|
9
|
+
import { convertType } from "../analyzer/type-converter.js";
|
|
10
|
+
/**
|
|
11
|
+
* Generates schemas for a method's parameters and return type.
|
|
12
|
+
*
|
|
13
|
+
* If a parameter references a FormSpec via `InferSchema<typeof X>`,
|
|
14
|
+
* the schemas are taken from the loaded FormSpec at runtime.
|
|
15
|
+
* Otherwise, schemas are generated from static type analysis.
|
|
16
|
+
*
|
|
17
|
+
* @param method - The method information from static analysis
|
|
18
|
+
* @param checker - TypeScript type checker
|
|
19
|
+
* @param loadedFormSpecs - Map of FormSpec export names to their schemas
|
|
20
|
+
* @returns Generated method schemas
|
|
21
|
+
*/
|
|
22
|
+
export function generateMethodSchemas(method, checker, loadedFormSpecs) {
|
|
23
|
+
// Generate return type schema from static analysis
|
|
24
|
+
const returnType = convertType(method.returnType, checker).jsonSchema;
|
|
25
|
+
// Handle parameters
|
|
26
|
+
const params = generateParamsSchemas(method.parameters, checker, loadedFormSpecs);
|
|
27
|
+
return {
|
|
28
|
+
name: method.name,
|
|
29
|
+
params,
|
|
30
|
+
returnType,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generates schemas for method parameters.
|
|
35
|
+
*/
|
|
36
|
+
function generateParamsSchemas(parameters, checker, loadedFormSpecs) {
|
|
37
|
+
if (parameters.length === 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// Check if any parameter uses InferSchema<typeof X>
|
|
41
|
+
for (const param of parameters) {
|
|
42
|
+
if (param.formSpecExportName) {
|
|
43
|
+
const formSpec = loadedFormSpecs.get(param.formSpecExportName);
|
|
44
|
+
if (formSpec) {
|
|
45
|
+
// Use runtime-generated schemas from FormSpec
|
|
46
|
+
// Cast JSONSchema7 to our JsonSchema type (structurally compatible)
|
|
47
|
+
return {
|
|
48
|
+
jsonSchema: formSpec.jsonSchema,
|
|
49
|
+
uxSpec: formSpec.uiSchema,
|
|
50
|
+
formSpecExport: param.formSpecExportName,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// FormSpec not found - fall back to static analysis
|
|
54
|
+
console.warn(`Warning: FormSpec export "${param.formSpecExportName}" not found, using static analysis`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Generate from static type analysis
|
|
58
|
+
if (parameters.length === 1 && parameters[0]) {
|
|
59
|
+
// Single parameter - use its type directly
|
|
60
|
+
const param = parameters[0];
|
|
61
|
+
const jsonSchema = convertType(param.type, checker).jsonSchema;
|
|
62
|
+
return {
|
|
63
|
+
jsonSchema,
|
|
64
|
+
uxSpec: null,
|
|
65
|
+
formSpecExport: null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Multiple parameters - create object schema
|
|
69
|
+
const properties = {};
|
|
70
|
+
const required = [];
|
|
71
|
+
for (const param of parameters) {
|
|
72
|
+
const paramSchema = convertType(param.type, checker).jsonSchema;
|
|
73
|
+
properties[param.name] = paramSchema;
|
|
74
|
+
// Only non-optional parameters should be marked as required
|
|
75
|
+
if (!param.optional) {
|
|
76
|
+
required.push(param.name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
jsonSchema: {
|
|
81
|
+
type: "object",
|
|
82
|
+
properties,
|
|
83
|
+
required,
|
|
84
|
+
},
|
|
85
|
+
uxSpec: null,
|
|
86
|
+
formSpecExport: null,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Collects all FormSpec export names referenced by methods.
|
|
91
|
+
*
|
|
92
|
+
* Use this to determine which exports to load at runtime.
|
|
93
|
+
*
|
|
94
|
+
* @param methods - Array of method infos
|
|
95
|
+
* @returns Set of FormSpec export names
|
|
96
|
+
*/
|
|
97
|
+
export function collectFormSpecReferences(methods) {
|
|
98
|
+
const references = new Set();
|
|
99
|
+
for (const method of methods) {
|
|
100
|
+
for (const param of method.parameters) {
|
|
101
|
+
if (param.formSpecExportName) {
|
|
102
|
+
references.add(param.formSpecExportName);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return references;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=method-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-schema.js","sourceRoot":"","sources":["../../src/generators/method-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* FormSpec CLI - Generate JSON Schema and FormSpec from TypeScript
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* formspec generate <file> [className] [-o <outDir>]
|
|
7
|
+
*
|
|
8
|
+
* Examples:
|
|
9
|
+
* # Generate schemas from a class with decorators
|
|
10
|
+
* formspec generate ./src/forms.ts InstallmentPlan -o ./generated
|
|
11
|
+
*
|
|
12
|
+
* # Generate schemas from all FormSpec exports in a file (chain DSL)
|
|
13
|
+
* formspec generate ./src/forms.ts -o ./generated
|
|
14
|
+
*
|
|
15
|
+
* # Generate schemas from both classes and FormSpec exports
|
|
16
|
+
* formspec generate ./src/forms.ts MyClass -o ./generated
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* FormSpec CLI - Generate JSON Schema and FormSpec from TypeScript
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* formspec generate <file> [className] [-o <outDir>]
|
|
7
|
+
*
|
|
8
|
+
* Examples:
|
|
9
|
+
* # Generate schemas from a class with decorators
|
|
10
|
+
* formspec generate ./src/forms.ts InstallmentPlan -o ./generated
|
|
11
|
+
*
|
|
12
|
+
* # Generate schemas from all FormSpec exports in a file (chain DSL)
|
|
13
|
+
* formspec generate ./src/forms.ts -o ./generated
|
|
14
|
+
*
|
|
15
|
+
* # Generate schemas from both classes and FormSpec exports
|
|
16
|
+
* formspec generate ./src/forms.ts MyClass -o ./generated
|
|
17
|
+
*/
|
|
18
|
+
import { createProgramContext, findClassByName } from "./analyzer/program.js";
|
|
19
|
+
import { analyzeClass } from "./analyzer/class-analyzer.js";
|
|
20
|
+
import { generateClassSchemas } from "./generators/class-schema.js";
|
|
21
|
+
import { generateMethodSchemas, collectFormSpecReferences, } from "./generators/method-schema.js";
|
|
22
|
+
import { loadFormSpecs, loadNamedFormSpecs, resolveCompiledPath, } from "./runtime/formspec-loader.js";
|
|
23
|
+
import { writeClassSchemas, writeFormSpecSchemas, } from "./output/writer.js";
|
|
24
|
+
import { runCodegen } from "./codegen/index.js";
|
|
25
|
+
/**
|
|
26
|
+
* Parses codegen command arguments.
|
|
27
|
+
*/
|
|
28
|
+
function parseCodegenArgs(args) {
|
|
29
|
+
const files = [];
|
|
30
|
+
let output = "./__formspec_types__.ts";
|
|
31
|
+
for (let i = 0; i < args.length; i++) {
|
|
32
|
+
const arg = args[i];
|
|
33
|
+
if (!arg)
|
|
34
|
+
continue;
|
|
35
|
+
if (arg === "-o" || arg === "--output") {
|
|
36
|
+
const nextArg = args[++i];
|
|
37
|
+
if (nextArg)
|
|
38
|
+
output = nextArg;
|
|
39
|
+
}
|
|
40
|
+
else if (arg.startsWith("-")) {
|
|
41
|
+
console.error(`Unknown option: ${arg}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
files.push(arg);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (files.length === 0) {
|
|
49
|
+
console.error("Error: No source files provided");
|
|
50
|
+
console.error("Usage: formspec codegen <files...> [-o <output>]");
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
return { command: "codegen", files, output };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parses command line arguments.
|
|
57
|
+
*/
|
|
58
|
+
function parseArgs(args) {
|
|
59
|
+
const [command, ...rest] = args;
|
|
60
|
+
if (!command || command === "--help" || command === "-h") {
|
|
61
|
+
printHelp();
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
// Handle codegen command
|
|
65
|
+
if (command === "codegen") {
|
|
66
|
+
return parseCodegenArgs(rest);
|
|
67
|
+
}
|
|
68
|
+
// Accept both "generate" (primary) and "analyze" (alias for backwards compatibility)
|
|
69
|
+
if (command !== "generate" && command !== "analyze") {
|
|
70
|
+
console.error(`Unknown command: ${command}`);
|
|
71
|
+
console.error('Use "formspec generate" or "formspec codegen"');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
let filePath;
|
|
75
|
+
let className;
|
|
76
|
+
let outDir = "./generated";
|
|
77
|
+
let compiledPath;
|
|
78
|
+
for (let i = 0; i < rest.length; i++) {
|
|
79
|
+
const arg = rest[i];
|
|
80
|
+
if (!arg)
|
|
81
|
+
continue;
|
|
82
|
+
if (arg === "-o" || arg === "--output") {
|
|
83
|
+
const nextArg = rest[++i];
|
|
84
|
+
if (nextArg)
|
|
85
|
+
outDir = nextArg;
|
|
86
|
+
}
|
|
87
|
+
else if (arg === "--compiled" || arg === "-c") {
|
|
88
|
+
const nextArg = rest[++i];
|
|
89
|
+
if (nextArg)
|
|
90
|
+
compiledPath = nextArg;
|
|
91
|
+
}
|
|
92
|
+
else if (arg.startsWith("-")) {
|
|
93
|
+
console.error(`Unknown option: ${arg}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
else if (!filePath) {
|
|
97
|
+
filePath = arg;
|
|
98
|
+
}
|
|
99
|
+
else if (!className) {
|
|
100
|
+
className = arg;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!filePath) {
|
|
104
|
+
console.error("Error: No file path provided");
|
|
105
|
+
console.error('Usage: formspec generate <file> [className] [-o <outDir>]');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
command,
|
|
110
|
+
filePath,
|
|
111
|
+
className,
|
|
112
|
+
outDir,
|
|
113
|
+
compiledPath,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Prints help message.
|
|
118
|
+
*/
|
|
119
|
+
function printHelp() {
|
|
120
|
+
console.log(`
|
|
121
|
+
FormSpec CLI - Generate JSON Schema and FormSpec from TypeScript
|
|
122
|
+
|
|
123
|
+
COMMANDS:
|
|
124
|
+
generate Generate JSON Schema and UI Schema files from TypeScript
|
|
125
|
+
codegen Generate type metadata file for runtime schema generation
|
|
126
|
+
|
|
127
|
+
USAGE:
|
|
128
|
+
formspec generate <file> [className] [options]
|
|
129
|
+
formspec codegen <files...> [-o <output>]
|
|
130
|
+
|
|
131
|
+
GENERATE COMMAND:
|
|
132
|
+
Arguments:
|
|
133
|
+
<file> Path to TypeScript source file
|
|
134
|
+
[className] Optional class name (if omitted, generates from FormSpec exports only)
|
|
135
|
+
|
|
136
|
+
Options:
|
|
137
|
+
-o, --output <dir> Output directory (default: ./generated)
|
|
138
|
+
-c, --compiled <path> Path to compiled JS file (auto-detected if omitted)
|
|
139
|
+
|
|
140
|
+
Examples:
|
|
141
|
+
formspec generate ./src/forms.ts InstallmentPlan -o ./generated
|
|
142
|
+
formspec generate ./src/forms.ts -o ./generated
|
|
143
|
+
|
|
144
|
+
CODEGEN COMMAND:
|
|
145
|
+
Generate a TypeScript file that patches decorated classes with type metadata.
|
|
146
|
+
This enables runtime schema generation with toFormSpec() from @formspec/decorators.
|
|
147
|
+
|
|
148
|
+
Arguments:
|
|
149
|
+
<files...> TypeScript source files to analyze
|
|
150
|
+
|
|
151
|
+
Options:
|
|
152
|
+
-o, --output <file> Output file (default: ./__formspec_types__.ts)
|
|
153
|
+
|
|
154
|
+
Examples:
|
|
155
|
+
formspec codegen ./src/forms.ts -o ./src/__formspec_types__.ts
|
|
156
|
+
formspec codegen ./src/**/*.ts -o ./src/__formspec_types__.ts
|
|
157
|
+
|
|
158
|
+
Usage in code:
|
|
159
|
+
// Import once at application entry point
|
|
160
|
+
import './__formspec_types__';
|
|
161
|
+
|
|
162
|
+
// Then use toFormSpec() normally
|
|
163
|
+
import { UserForm } from './forms';
|
|
164
|
+
import { toFormSpec } from '@formspec/decorators';
|
|
165
|
+
const spec = toFormSpec(UserForm);
|
|
166
|
+
|
|
167
|
+
ALIASES:
|
|
168
|
+
formspec analyze Same as 'generate' (for backwards compatibility)
|
|
169
|
+
`);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Main CLI entry point.
|
|
173
|
+
*/
|
|
174
|
+
async function main() {
|
|
175
|
+
const args = process.argv.slice(2);
|
|
176
|
+
const options = parseArgs(args);
|
|
177
|
+
// Handle codegen command
|
|
178
|
+
if (options.command === "codegen") {
|
|
179
|
+
const codegenOptions = options;
|
|
180
|
+
runCodegen({
|
|
181
|
+
files: codegenOptions.files,
|
|
182
|
+
output: codegenOptions.output,
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Handle generate command
|
|
187
|
+
const generateOptions = options;
|
|
188
|
+
console.log(`Generating schemas from: ${generateOptions.filePath}`);
|
|
189
|
+
if (generateOptions.className) {
|
|
190
|
+
console.log(`Class: ${generateOptions.className}`);
|
|
191
|
+
}
|
|
192
|
+
console.log(`Output: ${generateOptions.outDir}`);
|
|
193
|
+
console.log();
|
|
194
|
+
try {
|
|
195
|
+
// Step 1: Static analysis with TypeScript
|
|
196
|
+
const ctx = createProgramContext(generateOptions.filePath);
|
|
197
|
+
console.log("✓ Created TypeScript program");
|
|
198
|
+
// Step 2: Resolve compiled JS path for runtime loading
|
|
199
|
+
const compiledPath = generateOptions.compiledPath ?? resolveCompiledPath(generateOptions.filePath);
|
|
200
|
+
// Step 3: Load all FormSpec exports from compiled module
|
|
201
|
+
let loadedFormSpecs = new Map();
|
|
202
|
+
try {
|
|
203
|
+
const { formSpecs } = await loadFormSpecs(compiledPath);
|
|
204
|
+
loadedFormSpecs = formSpecs;
|
|
205
|
+
console.log(`✓ Loaded ${formSpecs.size} FormSpec export(s) from module`);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// This is not an error - runtime loading is only needed for:
|
|
209
|
+
// 1. Chain DSL FormSpec exports (formspec(...))
|
|
210
|
+
// 2. Method parameters using InferSchema<typeof X>
|
|
211
|
+
// Static class analysis works without compiled output
|
|
212
|
+
}
|
|
213
|
+
// Step 4: If className specified, analyze the class
|
|
214
|
+
if (!generateOptions.className && loadedFormSpecs.size === 0) {
|
|
215
|
+
// No class name and no FormSpec exports - warn the user
|
|
216
|
+
console.warn("⚠️ No class name specified and no FormSpec exports found.");
|
|
217
|
+
console.warn(" For decorated classes, specify the class name:");
|
|
218
|
+
console.warn(` formspec generate ${generateOptions.filePath} <ClassName> -o ${generateOptions.outDir}`);
|
|
219
|
+
console.warn(" For chain DSL, export a FormSpec from your file:");
|
|
220
|
+
console.warn(" export const MyForm = formspec(...);");
|
|
221
|
+
console.warn();
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
if (generateOptions.className) {
|
|
225
|
+
const classDecl = findClassByName(ctx.sourceFile, generateOptions.className);
|
|
226
|
+
if (!classDecl) {
|
|
227
|
+
console.error(`Error: Class "${generateOptions.className}" not found in ${generateOptions.filePath}`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
// Analyze class
|
|
231
|
+
const analysis = analyzeClass(classDecl, ctx.checker);
|
|
232
|
+
console.log(`✓ Analyzed class "${analysis.name}" with ${analysis.fields.length} field(s)`);
|
|
233
|
+
console.log(` Instance methods: ${analysis.instanceMethods.length}`);
|
|
234
|
+
console.log(` Static methods: ${analysis.staticMethods.length}`);
|
|
235
|
+
// Collect FormSpec references from methods
|
|
236
|
+
const allMethods = [...analysis.instanceMethods, ...analysis.staticMethods];
|
|
237
|
+
const formSpecRefs = collectFormSpecReferences(allMethods);
|
|
238
|
+
if (formSpecRefs.size > 0) {
|
|
239
|
+
console.log(` FormSpec refs: ${Array.from(formSpecRefs).join(", ")}`);
|
|
240
|
+
// Load specific FormSpecs if not already loaded
|
|
241
|
+
const missing = Array.from(formSpecRefs).filter((name) => !loadedFormSpecs.has(name));
|
|
242
|
+
if (missing.length > 0) {
|
|
243
|
+
try {
|
|
244
|
+
const namedFormSpecs = await loadNamedFormSpecs(compiledPath, missing);
|
|
245
|
+
for (const [name, schemas] of namedFormSpecs) {
|
|
246
|
+
loadedFormSpecs.set(name, schemas);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// Already warned about module loading
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Generate class schemas
|
|
255
|
+
const classSchemas = generateClassSchemas(analysis, ctx.checker);
|
|
256
|
+
// Generate method schemas
|
|
257
|
+
const instanceMethodSchemas = analysis.instanceMethods.map((m) => generateMethodSchemas(m, ctx.checker, loadedFormSpecs));
|
|
258
|
+
const staticMethodSchemas = analysis.staticMethods.map((m) => generateMethodSchemas(m, ctx.checker, loadedFormSpecs));
|
|
259
|
+
// Write class output
|
|
260
|
+
const classResult = writeClassSchemas(analysis.name, classSchemas, instanceMethodSchemas, staticMethodSchemas, { outDir: generateOptions.outDir });
|
|
261
|
+
console.log(`✓ Wrote ${classResult.files.length} file(s) to ${classResult.dir}`);
|
|
262
|
+
}
|
|
263
|
+
// Step 5: Write standalone FormSpec exports (chain DSL)
|
|
264
|
+
if (loadedFormSpecs.size > 0) {
|
|
265
|
+
const formSpecResult = writeFormSpecSchemas(loadedFormSpecs, {
|
|
266
|
+
outDir: generateOptions.outDir,
|
|
267
|
+
});
|
|
268
|
+
if (formSpecResult.files.length > 0) {
|
|
269
|
+
console.log(`✓ Wrote ${formSpecResult.files.length} FormSpec file(s) to ${formSpecResult.dir}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
console.log();
|
|
273
|
+
console.log("Done!");
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Run CLI
|
|
281
|
+
void main();
|
|
282
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output writer for creating the schema folder structure.
|
|
3
|
+
*
|
|
4
|
+
* Creates directories and writes JSON files for:
|
|
5
|
+
* - Class schema and UI Schema
|
|
6
|
+
* - Instance method schemas
|
|
7
|
+
* - Static method schemas
|
|
8
|
+
* - Standalone FormSpec exports (chain DSL)
|
|
9
|
+
*/
|
|
10
|
+
import type { ClassSchemas } from "../generators/class-schema.js";
|
|
11
|
+
import type { MethodSchemas } from "../generators/method-schema.js";
|
|
12
|
+
import type { FormSpecSchemas } from "../runtime/formspec-loader.js";
|
|
13
|
+
/**
|
|
14
|
+
* Options for writing output files.
|
|
15
|
+
*/
|
|
16
|
+
export interface WriteOptions {
|
|
17
|
+
/** Output directory path */
|
|
18
|
+
outDir: string;
|
|
19
|
+
/** JSON indentation (default: 2) */
|
|
20
|
+
indent?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of writing a class's schemas.
|
|
24
|
+
*/
|
|
25
|
+
export interface ClassWriteResult {
|
|
26
|
+
/** Path to the class output directory */
|
|
27
|
+
dir: string;
|
|
28
|
+
/** Files that were written */
|
|
29
|
+
files: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Result of writing standalone FormSpec schemas.
|
|
33
|
+
*/
|
|
34
|
+
export interface FormSpecWriteResult {
|
|
35
|
+
/** Path to the output directory */
|
|
36
|
+
dir: string;
|
|
37
|
+
/** Files that were written */
|
|
38
|
+
files: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Writes all schemas for a class to the output directory.
|
|
42
|
+
*
|
|
43
|
+
* Creates the following structure:
|
|
44
|
+
* ```
|
|
45
|
+
* {outDir}/{className}/
|
|
46
|
+
* ├── schema.json
|
|
47
|
+
* ├── ux_spec.json
|
|
48
|
+
* ├── instance_methods/
|
|
49
|
+
* │ └── {methodName}/
|
|
50
|
+
* │ ├── params.schema.json
|
|
51
|
+
* │ ├── params.ux_spec.json (if FormSpec-based)
|
|
52
|
+
* │ └── return_type.schema.json
|
|
53
|
+
* └── static_methods/
|
|
54
|
+
* └── {methodName}/
|
|
55
|
+
* └── ...
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @param className - Name of the class
|
|
59
|
+
* @param classSchemas - Generated class schemas
|
|
60
|
+
* @param instanceMethods - Instance method schemas
|
|
61
|
+
* @param staticMethods - Static method schemas
|
|
62
|
+
* @param options - Write options
|
|
63
|
+
* @returns Write result with paths
|
|
64
|
+
*/
|
|
65
|
+
export declare function writeClassSchemas(className: string, classSchemas: ClassSchemas, instanceMethods: MethodSchemas[], staticMethods: MethodSchemas[], options: WriteOptions): ClassWriteResult;
|
|
66
|
+
/**
|
|
67
|
+
* Writes standalone FormSpec schemas (chain DSL exports).
|
|
68
|
+
*
|
|
69
|
+
* Creates the following structure:
|
|
70
|
+
* ```
|
|
71
|
+
* {outDir}/formspecs/
|
|
72
|
+
* └── {exportName}/
|
|
73
|
+
* ├── schema.json
|
|
74
|
+
* └── ux_spec.json
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @param formSpecs - Map of FormSpec export names to their schemas
|
|
78
|
+
* @param options - Write options
|
|
79
|
+
* @returns Write result with paths
|
|
80
|
+
*/
|
|
81
|
+
export declare function writeFormSpecSchemas(formSpecs: Map<string, FormSpecSchemas>, options: WriteOptions): FormSpecWriteResult;
|
|
82
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/output/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,aAAa,EAAE,EAChC,aAAa,EAAE,aAAa,EAAE,EAC9B,OAAO,EAAE,YAAY,GACpB,gBAAgB,CAyClB;AAyCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACvC,OAAO,EAAE,YAAY,GACpB,mBAAmB,CA2BrB"}
|