@formspec/build 0.1.0-alpha.5 → 0.1.0-alpha.50
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/LICENSE +21 -0
- package/README.md +238 -93
- package/dist/analyzer/class-analyzer.d.ts +135 -0
- package/dist/analyzer/class-analyzer.d.ts.map +1 -0
- package/dist/analyzer/jsdoc-constraints.d.ts +53 -0
- package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -0
- package/dist/analyzer/program.d.ts +97 -0
- package/dist/analyzer/program.d.ts.map +1 -0
- package/dist/analyzer/tsdoc-parser.d.ts +124 -0
- package/dist/analyzer/tsdoc-parser.d.ts.map +1 -0
- package/dist/browser.cjs +2212 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.ts +74 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +2167 -0
- package/dist/browser.js.map +1 -0
- package/dist/build-alpha.d.ts +2408 -0
- package/dist/build-beta.d.ts +2408 -0
- package/dist/build-internal.d.ts +2408 -0
- package/dist/build.d.ts +2209 -151
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +22 -0
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -0
- package/dist/canonicalize/index.d.ts +8 -0
- package/dist/canonicalize/index.d.ts.map +1 -0
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts +38 -0
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -0
- package/dist/cli.cjs +7111 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.js +7070 -103
- package/dist/cli.js.map +1 -1
- package/dist/extensions/index.d.ts +8 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/registry.d.ts +142 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/resolve-custom-type.d.ts +37 -0
- package/dist/extensions/resolve-custom-type.d.ts.map +1 -0
- package/dist/extensions/symbol-registry.d.ts +33 -0
- package/dist/extensions/symbol-registry.d.ts.map +1 -0
- package/dist/extensions/ts-type-utils.d.ts +40 -0
- package/dist/extensions/ts-type-utils.d.ts.map +1 -0
- package/dist/generators/class-schema.d.ts +392 -0
- package/dist/generators/class-schema.d.ts.map +1 -0
- package/dist/generators/discovered-schema.d.ts +152 -0
- package/dist/generators/discovered-schema.d.ts.map +1 -0
- package/dist/generators/method-schema.d.ts +72 -0
- package/dist/generators/method-schema.d.ts.map +1 -0
- package/dist/generators/mixed-authoring.d.ts +52 -0
- package/dist/generators/mixed-authoring.d.ts.map +1 -0
- package/dist/index.cjs +6786 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +51 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6751 -107
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +5736 -0
- package/dist/internals.cjs.map +1 -0
- package/dist/internals.d.ts +32 -0
- package/dist/internals.d.ts.map +1 -0
- package/dist/internals.js +5706 -0
- package/dist/internals.js.map +1 -0
- package/dist/json-schema/generator.d.ts +32 -6
- package/dist/json-schema/generator.d.ts.map +1 -1
- package/dist/json-schema/ir-generator.d.ts +149 -0
- package/dist/json-schema/ir-generator.d.ts.map +1 -0
- package/dist/json-schema/schema.d.ts +23 -0
- package/dist/json-schema/schema.d.ts.map +1 -0
- package/dist/json-schema/types.d.ts +76 -2
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/metadata/collision-guards.d.ts +3 -0
- package/dist/metadata/collision-guards.d.ts.map +1 -0
- package/dist/metadata/index.d.ts +7 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/policy.d.ts +12 -0
- package/dist/metadata/policy.d.ts.map +1 -0
- package/dist/metadata/resolve.d.ts +21 -0
- package/dist/metadata/resolve.d.ts.map +1 -0
- package/dist/static-build.d.ts +61 -0
- package/dist/static-build.d.ts.map +1 -0
- package/dist/ui-schema/generator.d.ts +18 -2
- package/dist/ui-schema/generator.d.ts.map +1 -1
- package/dist/ui-schema/ir-generator.d.ts +54 -0
- package/dist/ui-schema/ir-generator.d.ts.map +1 -0
- package/dist/ui-schema/schema.d.ts +429 -0
- package/dist/ui-schema/schema.d.ts.map +1 -0
- package/dist/ui-schema/types.d.ts +179 -35
- package/dist/ui-schema/types.d.ts.map +1 -1
- package/dist/validate/constraint-validator.d.ts +85 -0
- package/dist/validate/constraint-validator.d.ts.map +1 -0
- package/dist/validate/index.d.ts +9 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/package.json +30 -11
- package/dist/__tests__/cli.test.d.ts +0 -2
- package/dist/__tests__/cli.test.d.ts.map +0 -1
- package/dist/__tests__/cli.test.js +0 -178
- package/dist/__tests__/cli.test.js.map +0 -1
- package/dist/__tests__/edge-cases.test.d.ts +0 -7
- package/dist/__tests__/edge-cases.test.d.ts.map +0 -1
- package/dist/__tests__/edge-cases.test.js +0 -217
- package/dist/__tests__/edge-cases.test.js.map +0 -1
- package/dist/__tests__/generator.test.d.ts +0 -2
- package/dist/__tests__/generator.test.d.ts.map +0 -1
- package/dist/__tests__/generator.test.js +0 -234
- package/dist/__tests__/generator.test.js.map +0 -1
- package/dist/__tests__/integration.test.d.ts +0 -8
- package/dist/__tests__/integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration.test.js +0 -163
- package/dist/__tests__/integration.test.js.map +0 -1
- package/dist/__tests__/write-schemas.test.d.ts +0 -2
- package/dist/__tests__/write-schemas.test.d.ts.map +0 -1
- package/dist/__tests__/write-schemas.test.js +0 -196
- package/dist/__tests__/write-schemas.test.js.map +0 -1
- package/dist/json-schema/generator.js +0 -167
- package/dist/json-schema/generator.js.map +0 -1
- package/dist/json-schema/types.js +0 -7
- package/dist/json-schema/types.js.map +0 -1
- package/dist/ui-schema/generator.js +0 -150
- package/dist/ui-schema/generator.js.map +0 -1
- package/dist/ui-schema/types.js +0 -8
- package/dist/ui-schema/types.js.map +0 -1
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import * as fs from "node:fs";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
import * as os from "node:os";
|
|
5
|
-
import { writeSchemas } from "../index.js";
|
|
6
|
-
import { formspec, field, group } from "@formspec/dsl";
|
|
7
|
-
describe("writeSchemas", () => {
|
|
8
|
-
let tempDir;
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "formspec-test-"));
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
// Clean up temp directory
|
|
14
|
-
if (fs.existsSync(tempDir)) {
|
|
15
|
-
fs.rmSync(tempDir, { recursive: true });
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
// Positive tests
|
|
19
|
-
describe("positive cases", () => {
|
|
20
|
-
it("should write both schema files to specified directory", () => {
|
|
21
|
-
const form = formspec(field.text("name", { required: true }), field.number("age"));
|
|
22
|
-
const result = writeSchemas(form, {
|
|
23
|
-
outDir: tempDir,
|
|
24
|
-
name: "test",
|
|
25
|
-
});
|
|
26
|
-
expect(fs.existsSync(result.jsonSchemaPath)).toBe(true);
|
|
27
|
-
expect(fs.existsSync(result.uiSchemaPath)).toBe(true);
|
|
28
|
-
expect(result.jsonSchemaPath).toBe(path.join(tempDir, "test-schema.json"));
|
|
29
|
-
expect(result.uiSchemaPath).toBe(path.join(tempDir, "test-uischema.json"));
|
|
30
|
-
});
|
|
31
|
-
it("should create output directory if it doesn't exist", () => {
|
|
32
|
-
const form = formspec(field.text("name"));
|
|
33
|
-
const nestedDir = path.join(tempDir, "nested", "deeply", "output");
|
|
34
|
-
expect(fs.existsSync(nestedDir)).toBe(false);
|
|
35
|
-
writeSchemas(form, {
|
|
36
|
-
outDir: nestedDir,
|
|
37
|
-
name: "test",
|
|
38
|
-
});
|
|
39
|
-
expect(fs.existsSync(nestedDir)).toBe(true);
|
|
40
|
-
});
|
|
41
|
-
it("should use 'schema' as default name when not provided", () => {
|
|
42
|
-
const form = formspec(field.text("name"));
|
|
43
|
-
const result = writeSchemas(form, {
|
|
44
|
-
outDir: tempDir,
|
|
45
|
-
});
|
|
46
|
-
expect(result.jsonSchemaPath).toBe(path.join(tempDir, "schema-schema.json"));
|
|
47
|
-
expect(result.uiSchemaPath).toBe(path.join(tempDir, "schema-uischema.json"));
|
|
48
|
-
});
|
|
49
|
-
it("should use custom indentation when provided", () => {
|
|
50
|
-
const form = formspec(field.text("name"));
|
|
51
|
-
writeSchemas(form, {
|
|
52
|
-
outDir: tempDir,
|
|
53
|
-
name: "test",
|
|
54
|
-
indent: 4,
|
|
55
|
-
});
|
|
56
|
-
const content = fs.readFileSync(path.join(tempDir, "test-schema.json"), "utf-8");
|
|
57
|
-
// With indent 4, we should see 4-space indentation
|
|
58
|
-
expect(content).toContain(" "); // 4 spaces
|
|
59
|
-
});
|
|
60
|
-
it("should generate valid JSON files that can be parsed", () => {
|
|
61
|
-
const form = formspec(field.text("name"), field.enum("status", ["draft", "active"]));
|
|
62
|
-
const result = writeSchemas(form, {
|
|
63
|
-
outDir: tempDir,
|
|
64
|
-
name: "test",
|
|
65
|
-
});
|
|
66
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
67
|
-
const uiSchema = JSON.parse(fs.readFileSync(result.uiSchemaPath, "utf-8"));
|
|
68
|
-
expect(jsonSchema).toHaveProperty("type", "object");
|
|
69
|
-
expect(jsonSchema).toHaveProperty("properties");
|
|
70
|
-
expect(uiSchema).toHaveProperty("type");
|
|
71
|
-
});
|
|
72
|
-
it("should generate correct schema content matching buildFormSchemas output", () => {
|
|
73
|
-
const form = formspec(group("Info", field.text("name", { label: "Name", required: true }), field.number("age", { label: "Age", min: 0 })));
|
|
74
|
-
const result = writeSchemas(form, {
|
|
75
|
-
outDir: tempDir,
|
|
76
|
-
name: "test",
|
|
77
|
-
});
|
|
78
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
79
|
-
expect(jsonSchema.properties).toHaveProperty("name");
|
|
80
|
-
expect(jsonSchema.properties).toHaveProperty("age");
|
|
81
|
-
expect(jsonSchema.required).toContain("name");
|
|
82
|
-
expect(jsonSchema.properties.age).toHaveProperty("minimum", 0);
|
|
83
|
-
});
|
|
84
|
-
it("should handle forms with enum fields", () => {
|
|
85
|
-
const form = formspec(field.enum("status", ["draft", "published", "archived"]));
|
|
86
|
-
const result = writeSchemas(form, {
|
|
87
|
-
outDir: tempDir,
|
|
88
|
-
name: "test",
|
|
89
|
-
});
|
|
90
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
91
|
-
expect(jsonSchema.properties.status).toHaveProperty("enum");
|
|
92
|
-
expect(jsonSchema.properties.status.enum).toEqual(["draft", "published", "archived"]);
|
|
93
|
-
});
|
|
94
|
-
it("should handle forms with nested objects", () => {
|
|
95
|
-
const form = formspec(field.object("address", field.text("street"), field.text("city")));
|
|
96
|
-
const result = writeSchemas(form, {
|
|
97
|
-
outDir: tempDir,
|
|
98
|
-
name: "test",
|
|
99
|
-
});
|
|
100
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
101
|
-
expect(jsonSchema.properties.address).toHaveProperty("type", "object");
|
|
102
|
-
expect(jsonSchema.properties.address.properties).toHaveProperty("street");
|
|
103
|
-
expect(jsonSchema.properties.address.properties).toHaveProperty("city");
|
|
104
|
-
});
|
|
105
|
-
it("should handle forms with arrays", () => {
|
|
106
|
-
const form = formspec(field.array("items", field.text("name"), field.number("quantity")));
|
|
107
|
-
const result = writeSchemas(form, {
|
|
108
|
-
outDir: tempDir,
|
|
109
|
-
name: "test",
|
|
110
|
-
});
|
|
111
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
112
|
-
expect(jsonSchema.properties.items).toHaveProperty("type", "array");
|
|
113
|
-
expect(jsonSchema.properties.items).toHaveProperty("items");
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
// Negative tests
|
|
117
|
-
describe("negative cases", () => {
|
|
118
|
-
it("should overwrite existing files", () => {
|
|
119
|
-
const form1 = formspec(field.text("original"));
|
|
120
|
-
const form2 = formspec(field.text("updated"));
|
|
121
|
-
// Write first version
|
|
122
|
-
writeSchemas(form1, {
|
|
123
|
-
outDir: tempDir,
|
|
124
|
-
name: "test",
|
|
125
|
-
});
|
|
126
|
-
// Write second version
|
|
127
|
-
const result = writeSchemas(form2, {
|
|
128
|
-
outDir: tempDir,
|
|
129
|
-
name: "test",
|
|
130
|
-
});
|
|
131
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
132
|
-
expect(jsonSchema.properties).toHaveProperty("updated");
|
|
133
|
-
expect(jsonSchema.properties).not.toHaveProperty("original");
|
|
134
|
-
});
|
|
135
|
-
it("should handle empty forms", () => {
|
|
136
|
-
const form = formspec();
|
|
137
|
-
const result = writeSchemas(form, {
|
|
138
|
-
outDir: tempDir,
|
|
139
|
-
name: "empty",
|
|
140
|
-
});
|
|
141
|
-
expect(fs.existsSync(result.jsonSchemaPath)).toBe(true);
|
|
142
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
143
|
-
expect(jsonSchema).toHaveProperty("type", "object");
|
|
144
|
-
});
|
|
145
|
-
it("should handle forms with special characters in field names", () => {
|
|
146
|
-
const form = formspec(field.text("field-with-dashes"), field.text("field_with_underscores"));
|
|
147
|
-
const result = writeSchemas(form, {
|
|
148
|
-
outDir: tempDir,
|
|
149
|
-
name: "test",
|
|
150
|
-
});
|
|
151
|
-
const jsonSchema = JSON.parse(fs.readFileSync(result.jsonSchemaPath, "utf-8"));
|
|
152
|
-
expect(jsonSchema.properties).toHaveProperty("field-with-dashes");
|
|
153
|
-
expect(jsonSchema.properties).toHaveProperty("field_with_underscores");
|
|
154
|
-
});
|
|
155
|
-
it("should handle output directory with trailing slash", () => {
|
|
156
|
-
const form = formspec(field.text("name"));
|
|
157
|
-
const result = writeSchemas(form, {
|
|
158
|
-
outDir: tempDir + "/",
|
|
159
|
-
name: "test",
|
|
160
|
-
});
|
|
161
|
-
expect(fs.existsSync(result.jsonSchemaPath)).toBe(true);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
// Edge cases
|
|
165
|
-
describe("edge cases", () => {
|
|
166
|
-
it("should handle name with dots", () => {
|
|
167
|
-
const form = formspec(field.text("name"));
|
|
168
|
-
const result = writeSchemas(form, {
|
|
169
|
-
outDir: tempDir,
|
|
170
|
-
name: "my.form.v1",
|
|
171
|
-
});
|
|
172
|
-
expect(result.jsonSchemaPath).toBe(path.join(tempDir, "my.form.v1-schema.json"));
|
|
173
|
-
});
|
|
174
|
-
it("should return absolute paths", () => {
|
|
175
|
-
const form = formspec(field.text("name"));
|
|
176
|
-
const result = writeSchemas(form, {
|
|
177
|
-
outDir: tempDir,
|
|
178
|
-
name: "test",
|
|
179
|
-
});
|
|
180
|
-
expect(path.isAbsolute(result.jsonSchemaPath)).toBe(true);
|
|
181
|
-
expect(path.isAbsolute(result.uiSchemaPath)).toBe(true);
|
|
182
|
-
});
|
|
183
|
-
it("should handle zero indent (compact JSON)", () => {
|
|
184
|
-
const form = formspec(field.text("name"));
|
|
185
|
-
writeSchemas(form, {
|
|
186
|
-
outDir: tempDir,
|
|
187
|
-
name: "test",
|
|
188
|
-
indent: 0,
|
|
189
|
-
});
|
|
190
|
-
const content = fs.readFileSync(path.join(tempDir, "test-schema.json"), "utf-8");
|
|
191
|
-
// With indent 0, JSON should be on one line (no newlines except at end)
|
|
192
|
-
expect(content.split("\n").length).toBeLessThanOrEqual(2);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
//# sourceMappingURL=write-schemas.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"write-schemas.test.js","sourceRoot":"","sources":["../../src/__tests__/write-schemas.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Schema generator for FormSpec forms.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Generates JSON Schema for nested elements (used for array items and object properties).
|
|
6
|
-
*/
|
|
7
|
-
function generateNestedSchema(elements) {
|
|
8
|
-
const properties = {};
|
|
9
|
-
const required = [];
|
|
10
|
-
collectFields(elements, properties, required);
|
|
11
|
-
// Deduplicate required array (can have duplicates when the same field is defined
|
|
12
|
-
// in multiple branches/containers, e.g., repeated in different conditional branches)
|
|
13
|
-
const uniqueRequired = [...new Set(required)];
|
|
14
|
-
return {
|
|
15
|
-
type: "object",
|
|
16
|
-
properties,
|
|
17
|
-
...(uniqueRequired.length > 0 && { required: uniqueRequired }),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Converts a single field to its JSON Schema representation.
|
|
22
|
-
*/
|
|
23
|
-
function fieldToJsonSchema(field) {
|
|
24
|
-
const base = {};
|
|
25
|
-
if (field.label !== undefined) {
|
|
26
|
-
base.title = field.label;
|
|
27
|
-
}
|
|
28
|
-
switch (field._field) {
|
|
29
|
-
case "text":
|
|
30
|
-
return { ...base, type: "string" };
|
|
31
|
-
case "number":
|
|
32
|
-
return {
|
|
33
|
-
...base,
|
|
34
|
-
type: "number",
|
|
35
|
-
...(field.min !== undefined && { minimum: field.min }),
|
|
36
|
-
...(field.max !== undefined && { maximum: field.max }),
|
|
37
|
-
};
|
|
38
|
-
case "boolean":
|
|
39
|
-
return { ...base, type: "boolean" };
|
|
40
|
-
case "enum": {
|
|
41
|
-
const opts = field.options;
|
|
42
|
-
const isObjectOptions = opts.length > 0 &&
|
|
43
|
-
opts.every((opt) => typeof opt === "object" && opt !== null && "id" in opt && "label" in opt);
|
|
44
|
-
if (isObjectOptions) {
|
|
45
|
-
// Object options with id/label: use oneOf with const/title
|
|
46
|
-
return {
|
|
47
|
-
...base,
|
|
48
|
-
type: "string",
|
|
49
|
-
oneOf: opts.map((o) => ({
|
|
50
|
-
const: o.id,
|
|
51
|
-
title: o.label,
|
|
52
|
-
})),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
return { ...base, type: "string", enum: opts };
|
|
56
|
-
}
|
|
57
|
-
case "dynamic_enum":
|
|
58
|
-
// Dynamic enums are strings at the schema level
|
|
59
|
-
// The actual options are resolved at runtime
|
|
60
|
-
// x-formspec-source indicates the data source key
|
|
61
|
-
// x-formspec-params indicates dependent field names for fetching options
|
|
62
|
-
return {
|
|
63
|
-
...base,
|
|
64
|
-
type: "string",
|
|
65
|
-
"x-formspec-source": field.source,
|
|
66
|
-
...(field.params !== undefined &&
|
|
67
|
-
field.params.length > 0 && { "x-formspec-params": field.params }),
|
|
68
|
-
};
|
|
69
|
-
case "dynamic_schema":
|
|
70
|
-
// Dynamic schemas are objects with unknown properties
|
|
71
|
-
// x-formspec-schemaSource indicates where to load the schema from
|
|
72
|
-
return {
|
|
73
|
-
...base,
|
|
74
|
-
type: "object",
|
|
75
|
-
additionalProperties: true,
|
|
76
|
-
"x-formspec-schemaSource": field.schemaSource,
|
|
77
|
-
};
|
|
78
|
-
case "array": {
|
|
79
|
-
const arrayField = field;
|
|
80
|
-
return {
|
|
81
|
-
...base,
|
|
82
|
-
type: "array",
|
|
83
|
-
items: generateNestedSchema(arrayField.items),
|
|
84
|
-
...(arrayField.minItems !== undefined && { minItems: arrayField.minItems }),
|
|
85
|
-
...(arrayField.maxItems !== undefined && { maxItems: arrayField.maxItems }),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
case "object": {
|
|
89
|
-
const objectField = field;
|
|
90
|
-
const nestedSchema = generateNestedSchema(objectField.properties);
|
|
91
|
-
return {
|
|
92
|
-
...base,
|
|
93
|
-
...nestedSchema,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
default: {
|
|
97
|
-
// Exhaustiveness check
|
|
98
|
-
const _exhaustive = field;
|
|
99
|
-
return _exhaustive;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Visits all elements in a form tree, collecting fields and required fields.
|
|
105
|
-
*/
|
|
106
|
-
function collectFields(elements, properties, required) {
|
|
107
|
-
for (const element of elements) {
|
|
108
|
-
switch (element._type) {
|
|
109
|
-
case "field":
|
|
110
|
-
properties[element.name] = fieldToJsonSchema(element);
|
|
111
|
-
if (element.required === true) {
|
|
112
|
-
required.push(element.name);
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
|
-
case "group":
|
|
116
|
-
// Groups don't affect schema structure, just collect their children
|
|
117
|
-
collectFields(element.elements, properties, required);
|
|
118
|
-
break;
|
|
119
|
-
case "conditional":
|
|
120
|
-
// Conditional fields are still part of the schema
|
|
121
|
-
// They're just hidden/shown in the UI
|
|
122
|
-
collectFields(element
|
|
123
|
-
.elements, properties, required);
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Generates a JSON Schema from a FormSpec.
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```typescript
|
|
133
|
-
* const form = formspec(
|
|
134
|
-
* field.text("name", { label: "Name", required: true }),
|
|
135
|
-
* field.number("age", { min: 0 }),
|
|
136
|
-
* );
|
|
137
|
-
*
|
|
138
|
-
* const schema = generateJsonSchema(form);
|
|
139
|
-
* // {
|
|
140
|
-
* // $schema: "https://json-schema.org/draft-07/schema#",
|
|
141
|
-
* // type: "object",
|
|
142
|
-
* // properties: {
|
|
143
|
-
* // name: { type: "string", title: "Name" },
|
|
144
|
-
* // age: { type: "number", minimum: 0 }
|
|
145
|
-
* // },
|
|
146
|
-
* // required: ["name"]
|
|
147
|
-
* // }
|
|
148
|
-
* ```
|
|
149
|
-
*
|
|
150
|
-
* @param form - The FormSpec to convert
|
|
151
|
-
* @returns A JSON Schema object
|
|
152
|
-
*/
|
|
153
|
-
export function generateJsonSchema(form) {
|
|
154
|
-
const properties = {};
|
|
155
|
-
const required = [];
|
|
156
|
-
collectFields(form.elements, properties, required);
|
|
157
|
-
// Deduplicate required array (can have duplicates when the same field is defined
|
|
158
|
-
// in multiple branches/containers, e.g., repeated in different conditional branches)
|
|
159
|
-
const uniqueRequired = [...new Set(required)];
|
|
160
|
-
return {
|
|
161
|
-
$schema: "https://json-schema.org/draft-07/schema#",
|
|
162
|
-
type: "object",
|
|
163
|
-
properties,
|
|
164
|
-
...(uniqueRequired.length > 0 && { required: uniqueRequired }),
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
//# sourceMappingURL=generator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/json-schema/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/json-schema/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Forms UI Schema generator for FormSpec forms.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Converts a field name to a JSON Pointer scope.
|
|
6
|
-
*/
|
|
7
|
-
function fieldToScope(fieldName) {
|
|
8
|
-
return `#/properties/${fieldName}`;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Creates a rule for conditional visibility.
|
|
12
|
-
*/
|
|
13
|
-
function createShowRule(fieldName, value) {
|
|
14
|
-
return {
|
|
15
|
-
effect: "SHOW",
|
|
16
|
-
condition: {
|
|
17
|
-
scope: fieldToScope(fieldName),
|
|
18
|
-
schema: { const: value },
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Combines two rules into one using allOf.
|
|
24
|
-
*
|
|
25
|
-
* When elements are nested inside multiple conditionals, all conditions
|
|
26
|
-
* must be met for the element to be visible.
|
|
27
|
-
*/
|
|
28
|
-
function combineRules(parentRule, childRule) {
|
|
29
|
-
// Both rules should have the same effect (SHOW)
|
|
30
|
-
// Combine conditions using allOf
|
|
31
|
-
const parentCondition = parentRule.condition;
|
|
32
|
-
const childCondition = childRule.condition;
|
|
33
|
-
return {
|
|
34
|
-
effect: "SHOW",
|
|
35
|
-
condition: {
|
|
36
|
-
scope: "#",
|
|
37
|
-
schema: {
|
|
38
|
-
allOf: [
|
|
39
|
-
{
|
|
40
|
-
properties: {
|
|
41
|
-
[parentCondition.scope.replace("#/properties/", "")]: parentCondition.schema,
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
properties: {
|
|
46
|
-
[childCondition.scope.replace("#/properties/", "")]: childCondition.schema,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Converts form elements to UI Schema elements.
|
|
56
|
-
*
|
|
57
|
-
* @param elements - The form elements to convert
|
|
58
|
-
* @param parentRule - Optional rule inherited from parent conditional
|
|
59
|
-
* @returns Array of UI Schema elements
|
|
60
|
-
*/
|
|
61
|
-
function elementsToUiSchema(elements, parentRule) {
|
|
62
|
-
const result = [];
|
|
63
|
-
for (const element of elements) {
|
|
64
|
-
switch (element._type) {
|
|
65
|
-
case "field": {
|
|
66
|
-
const control = {
|
|
67
|
-
type: "Control",
|
|
68
|
-
scope: fieldToScope(element.name),
|
|
69
|
-
...(element.label !== undefined && { label: element.label }),
|
|
70
|
-
...(parentRule !== undefined && { rule: parentRule }),
|
|
71
|
-
};
|
|
72
|
-
result.push(control);
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
case "group": {
|
|
76
|
-
const groupElement = element;
|
|
77
|
-
const group = {
|
|
78
|
-
type: "Group",
|
|
79
|
-
label: groupElement.label,
|
|
80
|
-
elements: elementsToUiSchema(groupElement.elements, parentRule),
|
|
81
|
-
...(parentRule !== undefined && { rule: parentRule }),
|
|
82
|
-
};
|
|
83
|
-
result.push(group);
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
case "conditional": {
|
|
87
|
-
const conditionalElement = element;
|
|
88
|
-
// Create a rule for this conditional
|
|
89
|
-
const newRule = createShowRule(conditionalElement.field, conditionalElement.value);
|
|
90
|
-
// Combine with parent rule if present (for nested conditionals)
|
|
91
|
-
const combinedRule = parentRule !== undefined
|
|
92
|
-
? combineRules(parentRule, newRule)
|
|
93
|
-
: newRule;
|
|
94
|
-
// Apply the combined rule to all children
|
|
95
|
-
const childElements = elementsToUiSchema(conditionalElement.elements, combinedRule);
|
|
96
|
-
result.push(...childElements);
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Generates a JSON Forms UI Schema from a FormSpec.
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ```typescript
|
|
108
|
-
* const form = formspec(
|
|
109
|
-
* group("Customer",
|
|
110
|
-
* field.text("name", { label: "Name" }),
|
|
111
|
-
* ),
|
|
112
|
-
* when("status", "draft",
|
|
113
|
-
* field.text("notes", { label: "Notes" }),
|
|
114
|
-
* ),
|
|
115
|
-
* );
|
|
116
|
-
*
|
|
117
|
-
* const uiSchema = generateUiSchema(form);
|
|
118
|
-
* // {
|
|
119
|
-
* // type: "VerticalLayout",
|
|
120
|
-
* // elements: [
|
|
121
|
-
* // {
|
|
122
|
-
* // type: "Group",
|
|
123
|
-
* // label: "Customer",
|
|
124
|
-
* // elements: [
|
|
125
|
-
* // { type: "Control", scope: "#/properties/name", label: "Name" }
|
|
126
|
-
* // ]
|
|
127
|
-
* // },
|
|
128
|
-
* // {
|
|
129
|
-
* // type: "Control",
|
|
130
|
-
* // scope: "#/properties/notes",
|
|
131
|
-
* // label: "Notes",
|
|
132
|
-
* // rule: {
|
|
133
|
-
* // effect: "SHOW",
|
|
134
|
-
* // condition: { scope: "#/properties/status", schema: { const: "draft" } }
|
|
135
|
-
* // }
|
|
136
|
-
* // }
|
|
137
|
-
* // ]
|
|
138
|
-
* // }
|
|
139
|
-
* ```
|
|
140
|
-
*
|
|
141
|
-
* @param form - The FormSpec to convert
|
|
142
|
-
* @returns A JSON Forms UI Schema
|
|
143
|
-
*/
|
|
144
|
-
export function generateUiSchema(form) {
|
|
145
|
-
return {
|
|
146
|
-
type: "VerticalLayout",
|
|
147
|
-
elements: elementsToUiSchema(form.elements),
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
//# sourceMappingURL=generator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/ui-schema/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/ui-schema/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ui-schema/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|