@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,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type converter for transforming TypeScript types to JSON Schema and FormSpec.
|
|
3
|
+
*
|
|
4
|
+
* Converts TypeScript types (extracted via type checker) to:
|
|
5
|
+
* - JSON Schema definitions
|
|
6
|
+
* - FormSpec field definitions
|
|
7
|
+
*/
|
|
8
|
+
import * as ts from "typescript";
|
|
9
|
+
import type { DecoratorInfo } from "./decorator-extractor.js";
|
|
10
|
+
/**
|
|
11
|
+
* JSON Schema type definition.
|
|
12
|
+
*/
|
|
13
|
+
export interface JsonSchema {
|
|
14
|
+
type?: string | string[];
|
|
15
|
+
enum?: unknown[];
|
|
16
|
+
const?: unknown;
|
|
17
|
+
items?: JsonSchema;
|
|
18
|
+
properties?: Record<string, JsonSchema>;
|
|
19
|
+
required?: string[];
|
|
20
|
+
additionalProperties?: boolean | JsonSchema;
|
|
21
|
+
minimum?: number;
|
|
22
|
+
maximum?: number;
|
|
23
|
+
minLength?: number;
|
|
24
|
+
maxLength?: number;
|
|
25
|
+
minItems?: number;
|
|
26
|
+
maxItems?: number;
|
|
27
|
+
pattern?: string;
|
|
28
|
+
title?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
$ref?: string;
|
|
31
|
+
oneOf?: JsonSchema[];
|
|
32
|
+
anyOf?: JsonSchema[];
|
|
33
|
+
allOf?: JsonSchema[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* FormSpec field definition (simplified for output).
|
|
37
|
+
*/
|
|
38
|
+
export interface FormSpecField {
|
|
39
|
+
_field: string;
|
|
40
|
+
id: string;
|
|
41
|
+
label?: string;
|
|
42
|
+
placeholder?: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
required?: boolean;
|
|
45
|
+
min?: number;
|
|
46
|
+
max?: number;
|
|
47
|
+
step?: number;
|
|
48
|
+
minLength?: number;
|
|
49
|
+
maxLength?: number;
|
|
50
|
+
minItems?: number;
|
|
51
|
+
maxItems?: number;
|
|
52
|
+
pattern?: string;
|
|
53
|
+
options?: Array<string | {
|
|
54
|
+
id: string;
|
|
55
|
+
label: string;
|
|
56
|
+
}>;
|
|
57
|
+
showWhen?: object;
|
|
58
|
+
group?: string;
|
|
59
|
+
fields?: FormSpecField[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Result of converting a TypeScript type.
|
|
63
|
+
*/
|
|
64
|
+
export interface TypeConversionResult {
|
|
65
|
+
/** JSON Schema representation */
|
|
66
|
+
jsonSchema: JsonSchema;
|
|
67
|
+
/** FormSpec field type */
|
|
68
|
+
formSpecFieldType: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Converts a TypeScript type to JSON Schema and FormSpec field type.
|
|
72
|
+
*
|
|
73
|
+
* @param type - The TypeScript type to convert
|
|
74
|
+
* @param checker - TypeScript type checker
|
|
75
|
+
* @returns Conversion result with JSON Schema and FormSpec type
|
|
76
|
+
*/
|
|
77
|
+
export declare function convertType(type: ts.Type, checker: ts.TypeChecker): TypeConversionResult;
|
|
78
|
+
/**
|
|
79
|
+
* Creates a FormSpec field definition from a field's type and decorators.
|
|
80
|
+
*
|
|
81
|
+
* @param fieldName - The field name
|
|
82
|
+
* @param type - The TypeScript type
|
|
83
|
+
* @param decorators - Decorators applied to the field
|
|
84
|
+
* @param optional - Whether the field is optional
|
|
85
|
+
* @param checker - TypeScript type checker
|
|
86
|
+
* @returns FormSpec field definition
|
|
87
|
+
*/
|
|
88
|
+
export declare function createFormSpecField(fieldName: string, type: ts.Type, decorators: DecoratorInfo[], optional: boolean, checker: ts.TypeChecker): FormSpecField;
|
|
89
|
+
/**
|
|
90
|
+
* Applies decorator constraints to a JSON Schema.
|
|
91
|
+
*
|
|
92
|
+
* @param schema - The base JSON Schema
|
|
93
|
+
* @param decorators - Decorators to apply
|
|
94
|
+
* @returns Modified JSON Schema with constraints
|
|
95
|
+
*/
|
|
96
|
+
export declare function applyDecoratorsToSchema(schema: JsonSchema, decorators: DecoratorInfo[]): JsonSchema;
|
|
97
|
+
//# sourceMappingURL=type-converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-converter.d.ts","sourceRoot":"","sources":["../../src/analyzer/type-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type converter for transforming TypeScript types to JSON Schema and FormSpec.
|
|
3
|
+
*
|
|
4
|
+
* Converts TypeScript types (extracted via type checker) to:
|
|
5
|
+
* - JSON Schema definitions
|
|
6
|
+
* - FormSpec field definitions
|
|
7
|
+
*/
|
|
8
|
+
import * as ts from "typescript";
|
|
9
|
+
/**
|
|
10
|
+
* Converts a TypeScript type to JSON Schema and FormSpec field type.
|
|
11
|
+
*
|
|
12
|
+
* @param type - The TypeScript type to convert
|
|
13
|
+
* @param checker - TypeScript type checker
|
|
14
|
+
* @returns Conversion result with JSON Schema and FormSpec type
|
|
15
|
+
*/
|
|
16
|
+
export function convertType(type, checker) {
|
|
17
|
+
// Handle primitive types
|
|
18
|
+
if (type.flags & ts.TypeFlags.String) {
|
|
19
|
+
return { jsonSchema: { type: "string" }, formSpecFieldType: "text" };
|
|
20
|
+
}
|
|
21
|
+
if (type.flags & ts.TypeFlags.Number) {
|
|
22
|
+
return { jsonSchema: { type: "number" }, formSpecFieldType: "number" };
|
|
23
|
+
}
|
|
24
|
+
if (type.flags & ts.TypeFlags.Boolean) {
|
|
25
|
+
return { jsonSchema: { type: "boolean" }, formSpecFieldType: "boolean" };
|
|
26
|
+
}
|
|
27
|
+
if (type.flags & ts.TypeFlags.Null) {
|
|
28
|
+
return { jsonSchema: { type: "null" }, formSpecFieldType: "null" };
|
|
29
|
+
}
|
|
30
|
+
if (type.flags & ts.TypeFlags.Undefined) {
|
|
31
|
+
return { jsonSchema: {}, formSpecFieldType: "undefined" };
|
|
32
|
+
}
|
|
33
|
+
// Handle literal types
|
|
34
|
+
if (type.isStringLiteral()) {
|
|
35
|
+
return {
|
|
36
|
+
jsonSchema: { const: type.value },
|
|
37
|
+
formSpecFieldType: "enum",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (type.isNumberLiteral()) {
|
|
41
|
+
return {
|
|
42
|
+
jsonSchema: { const: type.value },
|
|
43
|
+
formSpecFieldType: "number",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Handle union types (including string literal unions for enums)
|
|
47
|
+
if (type.isUnion()) {
|
|
48
|
+
return convertUnionType(type, checker);
|
|
49
|
+
}
|
|
50
|
+
// Handle array types
|
|
51
|
+
if (checker.isArrayType(type)) {
|
|
52
|
+
return convertArrayType(type, checker);
|
|
53
|
+
}
|
|
54
|
+
// Handle object types
|
|
55
|
+
if (type.flags & ts.TypeFlags.Object) {
|
|
56
|
+
return convertObjectType(type, checker);
|
|
57
|
+
}
|
|
58
|
+
// Fallback
|
|
59
|
+
return { jsonSchema: {}, formSpecFieldType: "unknown" };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Converts a union type to JSON Schema.
|
|
63
|
+
*/
|
|
64
|
+
function convertUnionType(type, checker) {
|
|
65
|
+
const types = type.types;
|
|
66
|
+
// Filter out null and undefined for analysis
|
|
67
|
+
// Note: undefined is filtered out since JSON Schema doesn't have an undefined type
|
|
68
|
+
// Optional fields are handled via the 'required' array, not the type
|
|
69
|
+
const nonNullTypes = types.filter((t) => !(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
|
|
70
|
+
const hasNull = types.some((t) => t.flags & ts.TypeFlags.Null);
|
|
71
|
+
// Check if this is a boolean type (true | false in TypeScript)
|
|
72
|
+
// TypeScript represents `boolean` as a union of `true | false` literal types
|
|
73
|
+
const isBooleanUnion = nonNullTypes.length === 2 &&
|
|
74
|
+
nonNullTypes.every((t) => t.flags & ts.TypeFlags.BooleanLiteral);
|
|
75
|
+
if (isBooleanUnion) {
|
|
76
|
+
const result = {
|
|
77
|
+
jsonSchema: { type: "boolean" },
|
|
78
|
+
formSpecFieldType: "boolean",
|
|
79
|
+
};
|
|
80
|
+
if (hasNull) {
|
|
81
|
+
result.jsonSchema = { oneOf: [{ type: "boolean" }, { type: "null" }] };
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
// Check if all types are string literals (enum pattern)
|
|
86
|
+
const allStringLiterals = nonNullTypes.every((t) => t.isStringLiteral());
|
|
87
|
+
if (allStringLiterals && nonNullTypes.length > 0) {
|
|
88
|
+
const enumValues = nonNullTypes.map((t) => t.value);
|
|
89
|
+
const result = {
|
|
90
|
+
jsonSchema: { enum: enumValues },
|
|
91
|
+
formSpecFieldType: "enum",
|
|
92
|
+
};
|
|
93
|
+
if (hasNull) {
|
|
94
|
+
result.jsonSchema = { oneOf: [{ enum: enumValues }, { type: "null" }] };
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
// Check if all types are number literals
|
|
99
|
+
const allNumberLiterals = nonNullTypes.every((t) => t.isNumberLiteral());
|
|
100
|
+
if (allNumberLiterals && nonNullTypes.length > 0) {
|
|
101
|
+
const enumValues = nonNullTypes.map((t) => t.value);
|
|
102
|
+
const result = {
|
|
103
|
+
jsonSchema: { enum: enumValues },
|
|
104
|
+
formSpecFieldType: "enum",
|
|
105
|
+
};
|
|
106
|
+
if (hasNull) {
|
|
107
|
+
result.jsonSchema = { oneOf: [{ enum: enumValues }, { type: "null" }] };
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
// Handle nullable types (T | null or T | undefined) with single non-null type
|
|
112
|
+
if (nonNullTypes.length === 1 && nonNullTypes[0]) {
|
|
113
|
+
const result = convertType(nonNullTypes[0], checker);
|
|
114
|
+
// Make it nullable in JSON Schema
|
|
115
|
+
if (hasNull) {
|
|
116
|
+
result.jsonSchema = { oneOf: [result.jsonSchema, { type: "null" }] };
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
// General union - use oneOf (filter out undefined which isn't valid in JSON Schema)
|
|
121
|
+
const schemas = nonNullTypes.map((t) => convertType(t, checker).jsonSchema);
|
|
122
|
+
if (hasNull) {
|
|
123
|
+
schemas.push({ type: "null" });
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
jsonSchema: { oneOf: schemas },
|
|
127
|
+
formSpecFieldType: "union",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Converts an array type to JSON Schema.
|
|
132
|
+
*/
|
|
133
|
+
function convertArrayType(type, checker) {
|
|
134
|
+
const typeArgs = type.typeArguments;
|
|
135
|
+
const elementType = typeArgs?.[0];
|
|
136
|
+
const itemSchema = elementType
|
|
137
|
+
? convertType(elementType, checker).jsonSchema
|
|
138
|
+
: {};
|
|
139
|
+
return {
|
|
140
|
+
jsonSchema: {
|
|
141
|
+
type: "array",
|
|
142
|
+
items: itemSchema,
|
|
143
|
+
},
|
|
144
|
+
formSpecFieldType: "array",
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Converts an object type to JSON Schema.
|
|
149
|
+
*/
|
|
150
|
+
function convertObjectType(type, checker) {
|
|
151
|
+
const properties = {};
|
|
152
|
+
const required = [];
|
|
153
|
+
const props = type.getProperties();
|
|
154
|
+
for (const prop of props) {
|
|
155
|
+
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration ?? prop.declarations?.[0] ?? {});
|
|
156
|
+
const propSchema = convertType(propType, checker).jsonSchema;
|
|
157
|
+
properties[prop.name] = propSchema;
|
|
158
|
+
// Check if property is optional
|
|
159
|
+
const isOptional = prop.flags & ts.SymbolFlags.Optional;
|
|
160
|
+
if (!isOptional) {
|
|
161
|
+
required.push(prop.name);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
jsonSchema: {
|
|
166
|
+
type: "object",
|
|
167
|
+
properties,
|
|
168
|
+
...(required.length > 0 ? { required } : {}),
|
|
169
|
+
},
|
|
170
|
+
formSpecFieldType: "object",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Creates a FormSpec field definition from a field's type and decorators.
|
|
175
|
+
*
|
|
176
|
+
* @param fieldName - The field name
|
|
177
|
+
* @param type - The TypeScript type
|
|
178
|
+
* @param decorators - Decorators applied to the field
|
|
179
|
+
* @param optional - Whether the field is optional
|
|
180
|
+
* @param checker - TypeScript type checker
|
|
181
|
+
* @returns FormSpec field definition
|
|
182
|
+
*/
|
|
183
|
+
export function createFormSpecField(fieldName, type, decorators, optional, checker) {
|
|
184
|
+
const { formSpecFieldType } = convertType(type, checker);
|
|
185
|
+
const field = {
|
|
186
|
+
_field: formSpecFieldType,
|
|
187
|
+
id: fieldName,
|
|
188
|
+
};
|
|
189
|
+
// Apply optionality
|
|
190
|
+
if (!optional) {
|
|
191
|
+
field.required = true;
|
|
192
|
+
}
|
|
193
|
+
// For object types, recursively add nested fields
|
|
194
|
+
if (formSpecFieldType === "object" && type.flags & ts.TypeFlags.Object) {
|
|
195
|
+
const objectType = type;
|
|
196
|
+
const nestedFields = [];
|
|
197
|
+
for (const prop of objectType.getProperties()) {
|
|
198
|
+
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration ?? prop.declarations?.[0] ?? {});
|
|
199
|
+
const propOptional = !!(prop.flags & ts.SymbolFlags.Optional);
|
|
200
|
+
// Note: We don't have access to decorators on nested class properties here
|
|
201
|
+
// since we're analyzing the type, not the class declaration
|
|
202
|
+
nestedFields.push(createFormSpecField(prop.name, propType, [], propOptional, checker));
|
|
203
|
+
}
|
|
204
|
+
if (nestedFields.length > 0) {
|
|
205
|
+
field.fields = nestedFields;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Apply decorator values
|
|
209
|
+
for (const dec of decorators) {
|
|
210
|
+
applyDecoratorToField(field, dec, type, checker);
|
|
211
|
+
}
|
|
212
|
+
return field;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Applies a decorator's values to a FormSpec field.
|
|
216
|
+
*/
|
|
217
|
+
function applyDecoratorToField(field, decorator, type, checker) {
|
|
218
|
+
const { name, args } = decorator;
|
|
219
|
+
switch (name) {
|
|
220
|
+
case "Label":
|
|
221
|
+
if (typeof args[0] === "string") {
|
|
222
|
+
field.label = args[0];
|
|
223
|
+
}
|
|
224
|
+
break;
|
|
225
|
+
case "Placeholder":
|
|
226
|
+
if (typeof args[0] === "string") {
|
|
227
|
+
field.placeholder = args[0];
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
case "Description":
|
|
231
|
+
if (typeof args[0] === "string") {
|
|
232
|
+
field.description = args[0];
|
|
233
|
+
}
|
|
234
|
+
break;
|
|
235
|
+
case "Min":
|
|
236
|
+
if (typeof args[0] === "number") {
|
|
237
|
+
field.min = args[0];
|
|
238
|
+
}
|
|
239
|
+
break;
|
|
240
|
+
case "Max":
|
|
241
|
+
if (typeof args[0] === "number") {
|
|
242
|
+
field.max = args[0];
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
case "Step":
|
|
246
|
+
if (typeof args[0] === "number") {
|
|
247
|
+
field.step = args[0];
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
case "MinLength":
|
|
251
|
+
if (typeof args[0] === "number") {
|
|
252
|
+
field.minLength = args[0];
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
case "MaxLength":
|
|
256
|
+
if (typeof args[0] === "number") {
|
|
257
|
+
field.maxLength = args[0];
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
case "MinItems":
|
|
261
|
+
if (typeof args[0] === "number") {
|
|
262
|
+
field.minItems = args[0];
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
case "MaxItems":
|
|
266
|
+
if (typeof args[0] === "number") {
|
|
267
|
+
field.maxItems = args[0];
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
270
|
+
case "Pattern":
|
|
271
|
+
if (typeof args[0] === "string") {
|
|
272
|
+
field.pattern = args[0];
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
case "EnumOptions":
|
|
276
|
+
if (Array.isArray(args[0])) {
|
|
277
|
+
field.options = args[0];
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
case "ShowWhen":
|
|
281
|
+
if (typeof args[0] === "object" && args[0] !== null) {
|
|
282
|
+
field.showWhen = args[0];
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
case "Group":
|
|
286
|
+
if (typeof args[0] === "string") {
|
|
287
|
+
field.group = args[0];
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Applies decorator constraints to a JSON Schema.
|
|
294
|
+
*
|
|
295
|
+
* @param schema - The base JSON Schema
|
|
296
|
+
* @param decorators - Decorators to apply
|
|
297
|
+
* @returns Modified JSON Schema with constraints
|
|
298
|
+
*/
|
|
299
|
+
export function applyDecoratorsToSchema(schema, decorators) {
|
|
300
|
+
const result = { ...schema };
|
|
301
|
+
for (const dec of decorators) {
|
|
302
|
+
const { name, args } = dec;
|
|
303
|
+
switch (name) {
|
|
304
|
+
case "Label":
|
|
305
|
+
if (typeof args[0] === "string") {
|
|
306
|
+
result.title = args[0];
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
case "Description":
|
|
310
|
+
if (typeof args[0] === "string") {
|
|
311
|
+
result.description = args[0];
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
case "Min":
|
|
315
|
+
if (typeof args[0] === "number") {
|
|
316
|
+
result.minimum = args[0];
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
319
|
+
case "Max":
|
|
320
|
+
if (typeof args[0] === "number") {
|
|
321
|
+
result.maximum = args[0];
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
case "MinLength":
|
|
325
|
+
if (typeof args[0] === "number") {
|
|
326
|
+
result.minLength = args[0];
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
case "MaxLength":
|
|
330
|
+
if (typeof args[0] === "number") {
|
|
331
|
+
result.maxLength = args[0];
|
|
332
|
+
}
|
|
333
|
+
break;
|
|
334
|
+
case "MinItems":
|
|
335
|
+
if (typeof args[0] === "number") {
|
|
336
|
+
result.minItems = args[0];
|
|
337
|
+
}
|
|
338
|
+
break;
|
|
339
|
+
case "MaxItems":
|
|
340
|
+
if (typeof args[0] === "number") {
|
|
341
|
+
result.maxItems = args[0];
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
case "Pattern":
|
|
345
|
+
if (typeof args[0] === "string") {
|
|
346
|
+
result.pattern = args[0];
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return result;
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=type-converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-converter.js","sourceRoot":"","sources":["../../src/analyzer/type-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code generation for FormSpec type metadata.
|
|
3
|
+
*
|
|
4
|
+
* Generates a TypeScript file that patches decorated classes with
|
|
5
|
+
* their extracted type metadata, enabling runtime schema generation
|
|
6
|
+
* as an alternative to a TypeScript transformer.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* formspec codegen ./src/forms.ts -o ./src/__formspec_types__.ts
|
|
10
|
+
*
|
|
11
|
+
* Then in your code:
|
|
12
|
+
* import './__formspec_types__'; // Patches all decorated classes
|
|
13
|
+
* import { UserForm } from './forms';
|
|
14
|
+
* import { toFormSpec } from '@formspec/decorators';
|
|
15
|
+
* const spec = toFormSpec(UserForm);
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Type metadata format used by @formspec/decorators.
|
|
19
|
+
*
|
|
20
|
+
* Represents the runtime type information for a field that TypeScript
|
|
21
|
+
* normally erases at compile time.
|
|
22
|
+
*/
|
|
23
|
+
export interface TypeMetadata {
|
|
24
|
+
/** Base type: "string", "number", "boolean", "enum", "array", "object", "unknown" */
|
|
25
|
+
type: string;
|
|
26
|
+
/** For enum types, the possible literal values */
|
|
27
|
+
values?: unknown[];
|
|
28
|
+
/** For array types, metadata about the array element type */
|
|
29
|
+
itemType?: TypeMetadata;
|
|
30
|
+
/** For object types, metadata about each property */
|
|
31
|
+
properties?: Record<string, TypeMetadata>;
|
|
32
|
+
/** Whether the field accepts null */
|
|
33
|
+
nullable?: boolean;
|
|
34
|
+
/** Whether the field is optional (T | undefined or ?: modifier) */
|
|
35
|
+
optional?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Information about a decorated class found during codegen analysis.
|
|
39
|
+
*
|
|
40
|
+
* Used to track which classes need type metadata patches and where
|
|
41
|
+
* they are located in the source tree.
|
|
42
|
+
*/
|
|
43
|
+
export interface DecoratedClassInfo {
|
|
44
|
+
/** Class name as it appears in the source file */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Import path to the source file (relative to output, without extension) */
|
|
47
|
+
sourcePath: string;
|
|
48
|
+
/** Type metadata for all decorated properties in the class */
|
|
49
|
+
typeMetadata: Record<string, TypeMetadata>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Options for code generation.
|
|
53
|
+
*/
|
|
54
|
+
export interface CodegenOptions {
|
|
55
|
+
/** Source files to analyze (glob patterns supported) */
|
|
56
|
+
files: string[];
|
|
57
|
+
/** Output file path */
|
|
58
|
+
output: string;
|
|
59
|
+
/** Base directory for relative imports */
|
|
60
|
+
baseDir?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Finds all decorated classes in the given source files.
|
|
64
|
+
*/
|
|
65
|
+
export declare function findDecoratedClasses(files: string[], baseDir: string): DecoratedClassInfo[];
|
|
66
|
+
/**
|
|
67
|
+
* Generates the codegen output file content.
|
|
68
|
+
*/
|
|
69
|
+
export declare function generateCodegenOutput(classes: DecoratedClassInfo[], outputPath: string, baseDir: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Runs the code generation.
|
|
72
|
+
*/
|
|
73
|
+
export declare function runCodegen(options: CodegenOptions): void;
|
|
74
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC1C,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,MAAM,GACd,kBAAkB,EAAE,CAkCtB;AAiKD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,MAAM,CAwER;AAqPD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CA6BxD"}
|