@formspec/build 0.1.0-alpha.10 → 0.1.0-alpha.12

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 (210) hide show
  1. package/README.md +51 -15
  2. package/dist/__tests__/chain-dsl-canonicalizer.test.d.ts +2 -0
  3. package/dist/__tests__/chain-dsl-canonicalizer.test.d.ts.map +1 -0
  4. package/dist/__tests__/constraint-validator.test.d.ts +2 -0
  5. package/dist/__tests__/constraint-validator.test.d.ts.map +1 -0
  6. package/dist/__tests__/extension-api.test.d.ts +2 -0
  7. package/dist/__tests__/extension-api.test.d.ts.map +1 -0
  8. package/dist/__tests__/fixtures/example-a-builtins.d.ts +18 -0
  9. package/dist/__tests__/fixtures/example-a-builtins.d.ts.map +1 -1
  10. package/dist/__tests__/ir-analyzer.test.d.ts +11 -0
  11. package/dist/__tests__/ir-analyzer.test.d.ts.map +1 -0
  12. package/dist/__tests__/ir-jsdoc-constraints.test.d.ts +12 -0
  13. package/dist/__tests__/ir-jsdoc-constraints.test.d.ts.map +1 -0
  14. package/dist/__tests__/ir-json-schema-generator.test.d.ts +11 -0
  15. package/dist/__tests__/ir-json-schema-generator.test.d.ts.map +1 -0
  16. package/dist/__tests__/ir-ui-schema-generator.test.d.ts +2 -0
  17. package/dist/__tests__/ir-ui-schema-generator.test.d.ts.map +1 -0
  18. package/dist/__tests__/jsdoc-constraints.test.d.ts +4 -4
  19. package/dist/__tests__/parity/fixtures/address/chain-dsl.d.ts +9 -0
  20. package/dist/__tests__/parity/fixtures/address/chain-dsl.d.ts.map +1 -0
  21. package/dist/__tests__/parity/fixtures/address/expected-ir.d.ts +9 -0
  22. package/dist/__tests__/parity/fixtures/address/expected-ir.d.ts.map +1 -0
  23. package/dist/__tests__/parity/fixtures/address/tsdoc.d.ts +19 -0
  24. package/dist/__tests__/parity/fixtures/address/tsdoc.d.ts.map +1 -0
  25. package/dist/__tests__/parity/fixtures/product-config/chain-dsl.d.ts +13 -0
  26. package/dist/__tests__/parity/fixtures/product-config/chain-dsl.d.ts.map +1 -0
  27. package/dist/__tests__/parity/fixtures/product-config/expected-ir.d.ts +9 -0
  28. package/dist/__tests__/parity/fixtures/product-config/expected-ir.d.ts.map +1 -0
  29. package/dist/__tests__/parity/fixtures/product-config/tsdoc.d.ts +28 -0
  30. package/dist/__tests__/parity/fixtures/product-config/tsdoc.d.ts.map +1 -0
  31. package/dist/__tests__/parity/fixtures/user-registration/chain-dsl.d.ts +12 -0
  32. package/dist/__tests__/parity/fixtures/user-registration/chain-dsl.d.ts.map +1 -0
  33. package/dist/__tests__/parity/fixtures/user-registration/expected-ir.d.ts +9 -0
  34. package/dist/__tests__/parity/fixtures/user-registration/expected-ir.d.ts.map +1 -0
  35. package/dist/__tests__/parity/fixtures/user-registration/tsdoc.d.ts +19 -0
  36. package/dist/__tests__/parity/fixtures/user-registration/tsdoc.d.ts.map +1 -0
  37. package/dist/__tests__/parity/parity.test.d.ts +14 -0
  38. package/dist/__tests__/parity/parity.test.d.ts.map +1 -0
  39. package/dist/__tests__/parity/utils.d.ts +139 -0
  40. package/dist/__tests__/parity/utils.d.ts.map +1 -0
  41. package/dist/analyzer/class-analyzer.d.ts +54 -99
  42. package/dist/analyzer/class-analyzer.d.ts.map +1 -1
  43. package/dist/analyzer/jsdoc-constraints.d.ts +78 -30
  44. package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -1
  45. package/dist/analyzer/tsdoc-parser.d.ts +61 -0
  46. package/dist/analyzer/tsdoc-parser.d.ts.map +1 -0
  47. package/dist/browser.cjs +1200 -0
  48. package/dist/browser.cjs.map +1 -0
  49. package/dist/browser.d.ts +12 -6
  50. package/dist/browser.d.ts.map +1 -1
  51. package/dist/browser.js +1147 -44
  52. package/dist/browser.js.map +1 -1
  53. package/dist/build.d.ts +385 -160
  54. package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +18 -0
  55. package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -0
  56. package/dist/canonicalize/index.d.ts +8 -0
  57. package/dist/canonicalize/index.d.ts.map +1 -0
  58. package/dist/canonicalize/tsdoc-canonicalizer.d.ts +34 -0
  59. package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -0
  60. package/dist/cli.cjs +2028 -0
  61. package/dist/cli.cjs.map +1 -0
  62. package/dist/cli.js +1978 -101
  63. package/dist/cli.js.map +1 -1
  64. package/dist/extensions/index.d.ts +8 -0
  65. package/dist/extensions/index.d.ts.map +1 -0
  66. package/dist/extensions/registry.d.ts +55 -0
  67. package/dist/extensions/registry.d.ts.map +1 -0
  68. package/dist/generators/class-schema.d.ts +28 -47
  69. package/dist/generators/class-schema.d.ts.map +1 -1
  70. package/dist/generators/method-schema.d.ts +6 -8
  71. package/dist/generators/method-schema.d.ts.map +1 -1
  72. package/dist/index.cjs +1832 -0
  73. package/dist/index.cjs.map +1 -0
  74. package/dist/index.d.ts +8 -8
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1779 -114
  77. package/dist/index.js.map +1 -1
  78. package/dist/internals.cjs +2125 -0
  79. package/dist/internals.cjs.map +1 -0
  80. package/dist/internals.d.ts +12 -2
  81. package/dist/internals.d.ts.map +1 -1
  82. package/dist/internals.js +2084 -21
  83. package/dist/internals.js.map +1 -1
  84. package/dist/json-schema/generator.d.ts +10 -5
  85. package/dist/json-schema/generator.d.ts.map +1 -1
  86. package/dist/json-schema/ir-generator.d.ts +84 -0
  87. package/dist/json-schema/ir-generator.d.ts.map +1 -0
  88. package/dist/json-schema/schema.d.ts +16 -0
  89. package/dist/json-schema/schema.d.ts.map +1 -0
  90. package/dist/json-schema/types.d.ts +5 -6
  91. package/dist/json-schema/types.d.ts.map +1 -1
  92. package/dist/ui-schema/generator.d.ts +5 -0
  93. package/dist/ui-schema/generator.d.ts.map +1 -1
  94. package/dist/ui-schema/ir-generator.d.ts +53 -0
  95. package/dist/ui-schema/ir-generator.d.ts.map +1 -0
  96. package/dist/ui-schema/schema.d.ts +357 -0
  97. package/dist/ui-schema/schema.d.ts.map +1 -0
  98. package/dist/ui-schema/types.d.ts +8 -73
  99. package/dist/ui-schema/types.d.ts.map +1 -1
  100. package/dist/validate/constraint-validator.d.ts +66 -0
  101. package/dist/validate/constraint-validator.d.ts.map +1 -0
  102. package/dist/validate/index.d.ts +9 -0
  103. package/dist/validate/index.d.ts.map +1 -0
  104. package/package.json +15 -9
  105. package/dist/__tests__/analyzer-edge-cases.test.d.ts +0 -13
  106. package/dist/__tests__/analyzer-edge-cases.test.d.ts.map +0 -1
  107. package/dist/__tests__/analyzer-edge-cases.test.js +0 -376
  108. package/dist/__tests__/analyzer-edge-cases.test.js.map +0 -1
  109. package/dist/__tests__/analyzer.test.d.ts +0 -5
  110. package/dist/__tests__/analyzer.test.d.ts.map +0 -1
  111. package/dist/__tests__/analyzer.test.js +0 -190
  112. package/dist/__tests__/analyzer.test.js.map +0 -1
  113. package/dist/__tests__/cli.test.js +0 -178
  114. package/dist/__tests__/cli.test.js.map +0 -1
  115. package/dist/__tests__/codegen.test.d.ts +0 -5
  116. package/dist/__tests__/codegen.test.d.ts.map +0 -1
  117. package/dist/__tests__/codegen.test.js +0 -506
  118. package/dist/__tests__/codegen.test.js.map +0 -1
  119. package/dist/__tests__/decorator-pipeline.test.d.ts +0 -11
  120. package/dist/__tests__/decorator-pipeline.test.d.ts.map +0 -1
  121. package/dist/__tests__/decorator-pipeline.test.js +0 -460
  122. package/dist/__tests__/decorator-pipeline.test.js.map +0 -1
  123. package/dist/__tests__/edge-cases.test.js +0 -215
  124. package/dist/__tests__/edge-cases.test.js.map +0 -1
  125. package/dist/__tests__/fixtures/edge-cases.js +0 -137
  126. package/dist/__tests__/fixtures/edge-cases.js.map +0 -1
  127. package/dist/__tests__/fixtures/example-a-builtins.js +0 -100
  128. package/dist/__tests__/fixtures/example-a-builtins.js.map +0 -1
  129. package/dist/__tests__/fixtures/example-b-decorators.d.ts +0 -5
  130. package/dist/__tests__/fixtures/example-b-decorators.d.ts.map +0 -1
  131. package/dist/__tests__/fixtures/example-b-decorators.js +0 -5
  132. package/dist/__tests__/fixtures/example-b-decorators.js.map +0 -1
  133. package/dist/__tests__/fixtures/example-b-extended.d.ts +0 -5
  134. package/dist/__tests__/fixtures/example-b-extended.d.ts.map +0 -1
  135. package/dist/__tests__/fixtures/example-b-extended.js +0 -60
  136. package/dist/__tests__/fixtures/example-b-extended.js.map +0 -1
  137. package/dist/__tests__/fixtures/example-c-custom.d.ts +0 -5
  138. package/dist/__tests__/fixtures/example-c-custom.d.ts.map +0 -1
  139. package/dist/__tests__/fixtures/example-c-custom.js +0 -61
  140. package/dist/__tests__/fixtures/example-c-custom.js.map +0 -1
  141. package/dist/__tests__/fixtures/example-c-decorators.d.ts +0 -5
  142. package/dist/__tests__/fixtures/example-c-decorators.d.ts.map +0 -1
  143. package/dist/__tests__/fixtures/example-c-decorators.js +0 -4
  144. package/dist/__tests__/fixtures/example-c-decorators.js.map +0 -1
  145. package/dist/__tests__/fixtures/example-d-mixed-decorators.d.ts +0 -6
  146. package/dist/__tests__/fixtures/example-d-mixed-decorators.d.ts.map +0 -1
  147. package/dist/__tests__/fixtures/example-d-mixed-decorators.js +0 -75
  148. package/dist/__tests__/fixtures/example-d-mixed-decorators.js.map +0 -1
  149. package/dist/__tests__/fixtures/example-e-decorators.d.ts +0 -11
  150. package/dist/__tests__/fixtures/example-e-decorators.d.ts.map +0 -1
  151. package/dist/__tests__/fixtures/example-e-decorators.js +0 -10
  152. package/dist/__tests__/fixtures/example-e-decorators.js.map +0 -1
  153. package/dist/__tests__/fixtures/example-e-no-namespace.d.ts +0 -5
  154. package/dist/__tests__/fixtures/example-e-no-namespace.d.ts.map +0 -1
  155. package/dist/__tests__/fixtures/example-e-no-namespace.js +0 -61
  156. package/dist/__tests__/fixtures/example-e-no-namespace.js.map +0 -1
  157. package/dist/__tests__/fixtures/example-interface-types.js +0 -8
  158. package/dist/__tests__/fixtures/example-interface-types.js.map +0 -1
  159. package/dist/__tests__/fixtures/example-jsdoc-constraints.d.ts +0 -16
  160. package/dist/__tests__/fixtures/example-jsdoc-constraints.d.ts.map +0 -1
  161. package/dist/__tests__/fixtures/example-jsdoc-constraints.js +0 -98
  162. package/dist/__tests__/fixtures/example-jsdoc-constraints.js.map +0 -1
  163. package/dist/__tests__/fixtures/example-nested-class.d.ts +0 -45
  164. package/dist/__tests__/fixtures/example-nested-class.d.ts.map +0 -1
  165. package/dist/__tests__/fixtures/example-nested-class.js +0 -248
  166. package/dist/__tests__/fixtures/example-nested-class.js.map +0 -1
  167. package/dist/__tests__/fixtures/sample-forms.js +0 -78
  168. package/dist/__tests__/fixtures/sample-forms.js.map +0 -1
  169. package/dist/__tests__/generator.test.js +0 -234
  170. package/dist/__tests__/generator.test.js.map +0 -1
  171. package/dist/__tests__/integration.test.js +0 -161
  172. package/dist/__tests__/integration.test.js.map +0 -1
  173. package/dist/__tests__/interface-types.test.d.ts +0 -11
  174. package/dist/__tests__/interface-types.test.d.ts.map +0 -1
  175. package/dist/__tests__/interface-types.test.js +0 -404
  176. package/dist/__tests__/interface-types.test.js.map +0 -1
  177. package/dist/__tests__/jsdoc-constraints.test.js +0 -465
  178. package/dist/__tests__/jsdoc-constraints.test.js.map +0 -1
  179. package/dist/__tests__/write-schemas.test.js +0 -198
  180. package/dist/__tests__/write-schemas.test.js.map +0 -1
  181. package/dist/analyzer/class-analyzer.js +0 -377
  182. package/dist/analyzer/class-analyzer.js.map +0 -1
  183. package/dist/analyzer/decorator-extractor.d.ts +0 -78
  184. package/dist/analyzer/decorator-extractor.d.ts.map +0 -1
  185. package/dist/analyzer/decorator-extractor.js +0 -336
  186. package/dist/analyzer/decorator-extractor.js.map +0 -1
  187. package/dist/analyzer/jsdoc-constraints.js +0 -153
  188. package/dist/analyzer/jsdoc-constraints.js.map +0 -1
  189. package/dist/analyzer/program.js +0 -114
  190. package/dist/analyzer/program.js.map +0 -1
  191. package/dist/analyzer/type-converter.d.ts +0 -75
  192. package/dist/analyzer/type-converter.d.ts.map +0 -1
  193. package/dist/analyzer/type-converter.js +0 -474
  194. package/dist/analyzer/type-converter.js.map +0 -1
  195. package/dist/codegen/index.d.ts +0 -75
  196. package/dist/codegen/index.d.ts.map +0 -1
  197. package/dist/codegen/index.js +0 -597
  198. package/dist/codegen/index.js.map +0 -1
  199. package/dist/generators/class-schema.js +0 -140
  200. package/dist/generators/class-schema.js.map +0 -1
  201. package/dist/generators/method-schema.js +0 -108
  202. package/dist/generators/method-schema.js.map +0 -1
  203. package/dist/json-schema/generator.js +0 -166
  204. package/dist/json-schema/generator.js.map +0 -1
  205. package/dist/json-schema/types.js +0 -33
  206. package/dist/json-schema/types.js.map +0 -1
  207. package/dist/ui-schema/generator.js +0 -148
  208. package/dist/ui-schema/generator.js.map +0 -1
  209. package/dist/ui-schema/types.js +0 -8
  210. package/dist/ui-schema/types.js.map +0 -1
@@ -0,0 +1,1200 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/browser.ts
21
+ var browser_exports = {};
22
+ __export(browser_exports, {
23
+ buildFormSchemas: () => buildFormSchemas,
24
+ canonicalizeChainDSL: () => canonicalizeChainDSL,
25
+ categorizationSchema: () => categorizationSchema,
26
+ categorySchema: () => categorySchema,
27
+ controlSchema: () => controlSchema,
28
+ generateJsonSchema: () => generateJsonSchema,
29
+ generateUiSchema: () => generateUiSchema,
30
+ getSchemaExtension: () => getSchemaExtension,
31
+ groupLayoutSchema: () => groupLayoutSchema,
32
+ horizontalLayoutSchema: () => horizontalLayoutSchema,
33
+ jsonSchema7Schema: () => jsonSchema7Schema,
34
+ jsonSchemaTypeSchema: () => jsonSchemaTypeSchema,
35
+ labelElementSchema: () => labelElementSchema,
36
+ ruleConditionSchema: () => ruleConditionSchema,
37
+ ruleEffectSchema: () => ruleEffectSchema,
38
+ ruleSchema: () => ruleSchema,
39
+ schemaBasedConditionSchema: () => schemaBasedConditionSchema,
40
+ setSchemaExtension: () => setSchemaExtension,
41
+ uiSchemaElementSchema: () => uiSchemaElementSchema,
42
+ uiSchemaElementTypeSchema: () => uiSchemaElementTypeSchema,
43
+ uiSchemaSchema: () => uiSchema,
44
+ validateIR: () => validateIR,
45
+ verticalLayoutSchema: () => verticalLayoutSchema
46
+ });
47
+ module.exports = __toCommonJS(browser_exports);
48
+
49
+ // src/canonicalize/chain-dsl-canonicalizer.ts
50
+ var import_core = require("@formspec/core");
51
+ var CHAIN_DSL_PROVENANCE = {
52
+ surface: "chain-dsl",
53
+ file: "",
54
+ line: 0,
55
+ column: 0
56
+ };
57
+ function isGroup(el) {
58
+ return el._type === "group";
59
+ }
60
+ function isConditional(el) {
61
+ return el._type === "conditional";
62
+ }
63
+ function isField(el) {
64
+ return el._type === "field";
65
+ }
66
+ function canonicalizeChainDSL(form) {
67
+ return {
68
+ kind: "form-ir",
69
+ irVersion: import_core.IR_VERSION,
70
+ elements: canonicalizeElements(form.elements),
71
+ typeRegistry: {},
72
+ provenance: CHAIN_DSL_PROVENANCE
73
+ };
74
+ }
75
+ function canonicalizeElements(elements) {
76
+ return elements.map(canonicalizeElement);
77
+ }
78
+ function canonicalizeElement(element) {
79
+ if (isField(element)) {
80
+ return canonicalizeField(element);
81
+ }
82
+ if (isGroup(element)) {
83
+ return canonicalizeGroup(element);
84
+ }
85
+ if (isConditional(element)) {
86
+ return canonicalizeConditional(element);
87
+ }
88
+ const _exhaustive = element;
89
+ throw new Error(`Unknown element type: ${JSON.stringify(_exhaustive)}`);
90
+ }
91
+ function canonicalizeField(field) {
92
+ switch (field._field) {
93
+ case "text":
94
+ return canonicalizeTextField(field);
95
+ case "number":
96
+ return canonicalizeNumberField(field);
97
+ case "boolean":
98
+ return canonicalizeBooleanField(field);
99
+ case "enum":
100
+ return canonicalizeStaticEnumField(field);
101
+ case "dynamic_enum":
102
+ return canonicalizeDynamicEnumField(field);
103
+ case "dynamic_schema":
104
+ return canonicalizeDynamicSchemaField(field);
105
+ case "array":
106
+ return canonicalizeArrayField(field);
107
+ case "object":
108
+ return canonicalizeObjectField(field);
109
+ default: {
110
+ const _exhaustive = field;
111
+ throw new Error(`Unknown field type: ${JSON.stringify(_exhaustive)}`);
112
+ }
113
+ }
114
+ }
115
+ function canonicalizeTextField(field) {
116
+ const type = { kind: "primitive", primitiveKind: "string" };
117
+ return buildFieldNode(
118
+ field.name,
119
+ type,
120
+ field.required,
121
+ buildAnnotations(field.label, field.placeholder)
122
+ );
123
+ }
124
+ function canonicalizeNumberField(field) {
125
+ const type = { kind: "primitive", primitiveKind: "number" };
126
+ const constraints = [];
127
+ if (field.min !== void 0) {
128
+ const c = {
129
+ kind: "constraint",
130
+ constraintKind: "minimum",
131
+ value: field.min,
132
+ provenance: CHAIN_DSL_PROVENANCE
133
+ };
134
+ constraints.push(c);
135
+ }
136
+ if (field.max !== void 0) {
137
+ const c = {
138
+ kind: "constraint",
139
+ constraintKind: "maximum",
140
+ value: field.max,
141
+ provenance: CHAIN_DSL_PROVENANCE
142
+ };
143
+ constraints.push(c);
144
+ }
145
+ return buildFieldNode(
146
+ field.name,
147
+ type,
148
+ field.required,
149
+ buildAnnotations(field.label),
150
+ constraints
151
+ );
152
+ }
153
+ function canonicalizeBooleanField(field) {
154
+ const type = { kind: "primitive", primitiveKind: "boolean" };
155
+ return buildFieldNode(field.name, type, field.required, buildAnnotations(field.label));
156
+ }
157
+ function canonicalizeStaticEnumField(field) {
158
+ const members = field.options.map((opt) => {
159
+ if (typeof opt === "string") {
160
+ return { value: opt };
161
+ }
162
+ return { value: opt.id, displayName: opt.label };
163
+ });
164
+ const type = { kind: "enum", members };
165
+ return buildFieldNode(field.name, type, field.required, buildAnnotations(field.label));
166
+ }
167
+ function canonicalizeDynamicEnumField(field) {
168
+ const type = {
169
+ kind: "dynamic",
170
+ dynamicKind: "enum",
171
+ sourceKey: field.source,
172
+ parameterFields: field.params ? [...field.params] : []
173
+ };
174
+ return buildFieldNode(field.name, type, field.required, buildAnnotations(field.label));
175
+ }
176
+ function canonicalizeDynamicSchemaField(field) {
177
+ const type = {
178
+ kind: "dynamic",
179
+ dynamicKind: "schema",
180
+ sourceKey: field.schemaSource,
181
+ parameterFields: []
182
+ };
183
+ return buildFieldNode(field.name, type, field.required, buildAnnotations(field.label));
184
+ }
185
+ function canonicalizeArrayField(field) {
186
+ const itemProperties = buildObjectProperties(field.items);
187
+ const itemsType = {
188
+ kind: "object",
189
+ properties: itemProperties,
190
+ additionalProperties: false
191
+ };
192
+ const type = { kind: "array", items: itemsType };
193
+ const constraints = [];
194
+ if (field.minItems !== void 0) {
195
+ const c = {
196
+ kind: "constraint",
197
+ constraintKind: "minItems",
198
+ value: field.minItems,
199
+ provenance: CHAIN_DSL_PROVENANCE
200
+ };
201
+ constraints.push(c);
202
+ }
203
+ if (field.maxItems !== void 0) {
204
+ const c = {
205
+ kind: "constraint",
206
+ constraintKind: "maxItems",
207
+ value: field.maxItems,
208
+ provenance: CHAIN_DSL_PROVENANCE
209
+ };
210
+ constraints.push(c);
211
+ }
212
+ return buildFieldNode(
213
+ field.name,
214
+ type,
215
+ field.required,
216
+ buildAnnotations(field.label),
217
+ constraints
218
+ );
219
+ }
220
+ function canonicalizeObjectField(field) {
221
+ const properties = buildObjectProperties(field.properties);
222
+ const type = {
223
+ kind: "object",
224
+ properties,
225
+ additionalProperties: false
226
+ };
227
+ return buildFieldNode(field.name, type, field.required, buildAnnotations(field.label));
228
+ }
229
+ function canonicalizeGroup(g) {
230
+ return {
231
+ kind: "group",
232
+ label: g.label,
233
+ elements: canonicalizeElements(g.elements),
234
+ provenance: CHAIN_DSL_PROVENANCE
235
+ };
236
+ }
237
+ function canonicalizeConditional(c) {
238
+ return {
239
+ kind: "conditional",
240
+ fieldName: c.field,
241
+ // Conditional values from the chain DSL are JSON-serializable primitives
242
+ // (strings, numbers, booleans) produced by the `is()` predicate helper.
243
+ value: assertJsonValue(c.value),
244
+ elements: canonicalizeElements(c.elements),
245
+ provenance: CHAIN_DSL_PROVENANCE
246
+ };
247
+ }
248
+ function assertJsonValue(v) {
249
+ if (v === null || typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
250
+ return v;
251
+ }
252
+ if (Array.isArray(v)) {
253
+ return v.map(assertJsonValue);
254
+ }
255
+ if (typeof v === "object") {
256
+ const result = {};
257
+ for (const [key, val] of Object.entries(v)) {
258
+ result[key] = assertJsonValue(val);
259
+ }
260
+ return result;
261
+ }
262
+ throw new TypeError(`Conditional value is not a valid JsonValue: ${typeof v}`);
263
+ }
264
+ function buildFieldNode(name, type, required, annotations, constraints = []) {
265
+ return {
266
+ kind: "field",
267
+ name,
268
+ type,
269
+ required: required === true,
270
+ constraints,
271
+ annotations,
272
+ provenance: CHAIN_DSL_PROVENANCE
273
+ };
274
+ }
275
+ function buildAnnotations(label, placeholder) {
276
+ const annotations = [];
277
+ if (label !== void 0) {
278
+ const a = {
279
+ kind: "annotation",
280
+ annotationKind: "displayName",
281
+ value: label,
282
+ provenance: CHAIN_DSL_PROVENANCE
283
+ };
284
+ annotations.push(a);
285
+ }
286
+ if (placeholder !== void 0) {
287
+ const a = {
288
+ kind: "annotation",
289
+ annotationKind: "placeholder",
290
+ value: placeholder,
291
+ provenance: CHAIN_DSL_PROVENANCE
292
+ };
293
+ annotations.push(a);
294
+ }
295
+ return annotations;
296
+ }
297
+ function buildObjectProperties(elements, insideConditional = false) {
298
+ const properties = [];
299
+ for (const el of elements) {
300
+ if (isField(el)) {
301
+ const fieldNode = canonicalizeField(el);
302
+ properties.push({
303
+ name: fieldNode.name,
304
+ type: fieldNode.type,
305
+ // Fields inside a conditional branch are always optional in the
306
+ // data schema, regardless of their `required` flag — the condition
307
+ // may not be met, so the field may be absent.
308
+ optional: insideConditional || !fieldNode.required,
309
+ constraints: fieldNode.constraints,
310
+ annotations: fieldNode.annotations,
311
+ provenance: CHAIN_DSL_PROVENANCE
312
+ });
313
+ } else if (isGroup(el)) {
314
+ properties.push(...buildObjectProperties(el.elements, insideConditional));
315
+ } else if (isConditional(el)) {
316
+ properties.push(...buildObjectProperties(el.elements, true));
317
+ }
318
+ }
319
+ return properties;
320
+ }
321
+
322
+ // src/canonicalize/tsdoc-canonicalizer.ts
323
+ var import_core2 = require("@formspec/core");
324
+
325
+ // src/json-schema/ir-generator.ts
326
+ function makeContext() {
327
+ return { defs: {} };
328
+ }
329
+ function generateJsonSchemaFromIR(ir) {
330
+ const ctx = makeContext();
331
+ for (const [name, typeDef] of Object.entries(ir.typeRegistry)) {
332
+ ctx.defs[name] = generateTypeNode(typeDef.type, ctx);
333
+ }
334
+ const properties = {};
335
+ const required = [];
336
+ collectFields(ir.elements, properties, required, ctx);
337
+ const uniqueRequired = [...new Set(required)];
338
+ const result = {
339
+ $schema: "https://json-schema.org/draft/2020-12/schema",
340
+ type: "object",
341
+ properties,
342
+ ...uniqueRequired.length > 0 && { required: uniqueRequired }
343
+ };
344
+ if (Object.keys(ctx.defs).length > 0) {
345
+ result.$defs = ctx.defs;
346
+ }
347
+ return result;
348
+ }
349
+ function collectFields(elements, properties, required, ctx) {
350
+ for (const element of elements) {
351
+ switch (element.kind) {
352
+ case "field":
353
+ properties[element.name] = generateFieldSchema(element, ctx);
354
+ if (element.required) {
355
+ required.push(element.name);
356
+ }
357
+ break;
358
+ case "group":
359
+ collectFields(element.elements, properties, required, ctx);
360
+ break;
361
+ case "conditional":
362
+ collectFields(element.elements, properties, required, ctx);
363
+ break;
364
+ default: {
365
+ const _exhaustive = element;
366
+ void _exhaustive;
367
+ }
368
+ }
369
+ }
370
+ }
371
+ function generateFieldSchema(field, ctx) {
372
+ const schema = generateTypeNode(field.type, ctx);
373
+ applyConstraints(schema, field.constraints);
374
+ applyAnnotations(schema, field.annotations);
375
+ return schema;
376
+ }
377
+ function generateTypeNode(type, ctx) {
378
+ switch (type.kind) {
379
+ case "primitive":
380
+ return generatePrimitiveType(type);
381
+ case "enum":
382
+ return generateEnumType(type);
383
+ case "array":
384
+ return generateArrayType(type, ctx);
385
+ case "object":
386
+ return generateObjectType(type, ctx);
387
+ case "union":
388
+ return generateUnionType(type, ctx);
389
+ case "reference":
390
+ return generateReferenceType(type);
391
+ case "dynamic":
392
+ return generateDynamicType(type);
393
+ case "custom":
394
+ return generateCustomType(type);
395
+ default: {
396
+ const _exhaustive = type;
397
+ return _exhaustive;
398
+ }
399
+ }
400
+ }
401
+ function generatePrimitiveType(type) {
402
+ return { type: type.primitiveKind };
403
+ }
404
+ function generateEnumType(type) {
405
+ const hasDisplayNames = type.members.some((m) => m.displayName !== void 0);
406
+ if (hasDisplayNames) {
407
+ return {
408
+ oneOf: type.members.map((m) => {
409
+ const entry = { const: m.value };
410
+ if (m.displayName !== void 0) {
411
+ entry.title = m.displayName;
412
+ }
413
+ return entry;
414
+ })
415
+ };
416
+ }
417
+ return { enum: type.members.map((m) => m.value) };
418
+ }
419
+ function generateArrayType(type, ctx) {
420
+ return {
421
+ type: "array",
422
+ items: generateTypeNode(type.items, ctx)
423
+ };
424
+ }
425
+ function generateObjectType(type, ctx) {
426
+ const properties = {};
427
+ const required = [];
428
+ for (const prop of type.properties) {
429
+ properties[prop.name] = generatePropertySchema(prop, ctx);
430
+ if (!prop.optional) {
431
+ required.push(prop.name);
432
+ }
433
+ }
434
+ const schema = { type: "object", properties };
435
+ if (required.length > 0) {
436
+ schema.required = required;
437
+ }
438
+ if (!type.additionalProperties) {
439
+ schema.additionalProperties = false;
440
+ }
441
+ return schema;
442
+ }
443
+ function generatePropertySchema(prop, ctx) {
444
+ const schema = generateTypeNode(prop.type, ctx);
445
+ applyConstraints(schema, prop.constraints);
446
+ applyAnnotations(schema, prop.annotations);
447
+ return schema;
448
+ }
449
+ function generateUnionType(type, ctx) {
450
+ if (isBooleanUnion(type)) {
451
+ return { type: "boolean" };
452
+ }
453
+ return {
454
+ anyOf: type.members.map((m) => generateTypeNode(m, ctx))
455
+ };
456
+ }
457
+ function isBooleanUnion(type) {
458
+ if (type.members.length !== 2) return false;
459
+ const kinds = type.members.map((m) => m.kind);
460
+ return kinds.every((k) => k === "primitive") && type.members.every((m) => m.kind === "primitive" && m.primitiveKind === "boolean");
461
+ }
462
+ function generateReferenceType(type) {
463
+ return { $ref: `#/$defs/${type.name}` };
464
+ }
465
+ function generateDynamicType(type) {
466
+ if (type.dynamicKind === "enum") {
467
+ const schema = {
468
+ type: "string",
469
+ "x-formspec-source": type.sourceKey
470
+ };
471
+ if (type.parameterFields.length > 0) {
472
+ schema["x-formspec-params"] = [...type.parameterFields];
473
+ }
474
+ return schema;
475
+ }
476
+ return {
477
+ type: "object",
478
+ additionalProperties: true,
479
+ "x-formspec-schemaSource": type.sourceKey
480
+ };
481
+ }
482
+ function generateCustomType(_type) {
483
+ return { type: "object" };
484
+ }
485
+ function applyConstraints(schema, constraints) {
486
+ for (const constraint of constraints) {
487
+ switch (constraint.constraintKind) {
488
+ case "minimum":
489
+ schema.minimum = constraint.value;
490
+ break;
491
+ case "maximum":
492
+ schema.maximum = constraint.value;
493
+ break;
494
+ case "exclusiveMinimum":
495
+ schema.exclusiveMinimum = constraint.value;
496
+ break;
497
+ case "exclusiveMaximum":
498
+ schema.exclusiveMaximum = constraint.value;
499
+ break;
500
+ case "multipleOf": {
501
+ const { value } = constraint;
502
+ if (value === 1 && schema.type === "number") {
503
+ schema.type = "integer";
504
+ } else {
505
+ schema.multipleOf = value;
506
+ }
507
+ break;
508
+ }
509
+ case "minLength":
510
+ schema.minLength = constraint.value;
511
+ break;
512
+ case "maxLength":
513
+ schema.maxLength = constraint.value;
514
+ break;
515
+ case "minItems":
516
+ schema.minItems = constraint.value;
517
+ break;
518
+ case "maxItems":
519
+ schema.maxItems = constraint.value;
520
+ break;
521
+ case "pattern":
522
+ schema.pattern = constraint.pattern;
523
+ break;
524
+ case "uniqueItems":
525
+ schema.uniqueItems = constraint.value;
526
+ break;
527
+ case "allowedMembers":
528
+ break;
529
+ case "custom":
530
+ break;
531
+ default: {
532
+ const _exhaustive = constraint;
533
+ void _exhaustive;
534
+ }
535
+ }
536
+ }
537
+ }
538
+ function applyAnnotations(schema, annotations) {
539
+ for (const annotation of annotations) {
540
+ switch (annotation.annotationKind) {
541
+ case "displayName":
542
+ schema.title = annotation.value;
543
+ break;
544
+ case "description":
545
+ schema.description = annotation.value;
546
+ break;
547
+ case "defaultValue":
548
+ schema.default = annotation.value;
549
+ break;
550
+ case "deprecated":
551
+ schema.deprecated = true;
552
+ break;
553
+ case "placeholder":
554
+ break;
555
+ case "formatHint":
556
+ break;
557
+ case "custom":
558
+ break;
559
+ default: {
560
+ const _exhaustive = annotation;
561
+ void _exhaustive;
562
+ }
563
+ }
564
+ }
565
+ }
566
+
567
+ // src/json-schema/generator.ts
568
+ function generateJsonSchema(form) {
569
+ const ir = canonicalizeChainDSL(form);
570
+ return generateJsonSchemaFromIR(ir);
571
+ }
572
+
573
+ // src/ui-schema/schema.ts
574
+ var import_zod = require("zod");
575
+ var jsonPointerSchema = import_zod.z.string();
576
+ var ruleEffectSchema = import_zod.z.enum(["SHOW", "HIDE", "ENABLE", "DISABLE"]);
577
+ var uiSchemaElementTypeSchema = import_zod.z.enum([
578
+ "Control",
579
+ "VerticalLayout",
580
+ "HorizontalLayout",
581
+ "Group",
582
+ "Categorization",
583
+ "Category",
584
+ "Label"
585
+ ]);
586
+ var ruleConditionSchema = import_zod.z.lazy(
587
+ () => import_zod.z.object({
588
+ const: import_zod.z.unknown().optional(),
589
+ enum: import_zod.z.array(import_zod.z.unknown()).readonly().optional(),
590
+ type: import_zod.z.string().optional(),
591
+ not: ruleConditionSchema.optional(),
592
+ minimum: import_zod.z.number().optional(),
593
+ maximum: import_zod.z.number().optional(),
594
+ exclusiveMinimum: import_zod.z.number().optional(),
595
+ exclusiveMaximum: import_zod.z.number().optional(),
596
+ minLength: import_zod.z.number().optional(),
597
+ properties: import_zod.z.record(import_zod.z.string(), ruleConditionSchema).optional(),
598
+ required: import_zod.z.array(import_zod.z.string()).optional(),
599
+ allOf: import_zod.z.array(ruleConditionSchema).optional()
600
+ }).strict()
601
+ );
602
+ var schemaBasedConditionSchema = import_zod.z.object({
603
+ scope: jsonPointerSchema,
604
+ schema: ruleConditionSchema
605
+ }).strict();
606
+ var ruleSchema = import_zod.z.object({
607
+ effect: ruleEffectSchema,
608
+ condition: schemaBasedConditionSchema
609
+ }).strict();
610
+ var uiSchemaElementSchema = import_zod.z.lazy(
611
+ () => import_zod.z.union([
612
+ controlSchema,
613
+ verticalLayoutSchema,
614
+ horizontalLayoutSchema,
615
+ groupLayoutSchema,
616
+ categorizationSchema,
617
+ categorySchema,
618
+ labelElementSchema
619
+ ])
620
+ );
621
+ var controlSchema = import_zod.z.object({
622
+ type: import_zod.z.literal("Control"),
623
+ scope: jsonPointerSchema,
624
+ label: import_zod.z.union([import_zod.z.string(), import_zod.z.literal(false)]).optional(),
625
+ rule: ruleSchema.optional(),
626
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
627
+ }).passthrough();
628
+ var verticalLayoutSchema = import_zod.z.lazy(
629
+ () => import_zod.z.object({
630
+ type: import_zod.z.literal("VerticalLayout"),
631
+ elements: import_zod.z.array(uiSchemaElementSchema),
632
+ rule: ruleSchema.optional(),
633
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
634
+ }).passthrough()
635
+ );
636
+ var horizontalLayoutSchema = import_zod.z.lazy(
637
+ () => import_zod.z.object({
638
+ type: import_zod.z.literal("HorizontalLayout"),
639
+ elements: import_zod.z.array(uiSchemaElementSchema),
640
+ rule: ruleSchema.optional(),
641
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
642
+ }).passthrough()
643
+ );
644
+ var groupLayoutSchema = import_zod.z.lazy(
645
+ () => import_zod.z.object({
646
+ type: import_zod.z.literal("Group"),
647
+ label: import_zod.z.string(),
648
+ elements: import_zod.z.array(uiSchemaElementSchema),
649
+ rule: ruleSchema.optional(),
650
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
651
+ }).passthrough()
652
+ );
653
+ var categorySchema = import_zod.z.lazy(
654
+ () => import_zod.z.object({
655
+ type: import_zod.z.literal("Category"),
656
+ label: import_zod.z.string(),
657
+ elements: import_zod.z.array(uiSchemaElementSchema),
658
+ rule: ruleSchema.optional(),
659
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
660
+ }).passthrough()
661
+ );
662
+ var categorizationSchema = import_zod.z.lazy(
663
+ () => import_zod.z.object({
664
+ type: import_zod.z.literal("Categorization"),
665
+ elements: import_zod.z.array(categorySchema),
666
+ label: import_zod.z.string().optional(),
667
+ rule: ruleSchema.optional(),
668
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
669
+ }).passthrough()
670
+ );
671
+ var labelElementSchema = import_zod.z.object({
672
+ type: import_zod.z.literal("Label"),
673
+ text: import_zod.z.string(),
674
+ rule: ruleSchema.optional(),
675
+ options: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
676
+ }).passthrough();
677
+ var uiSchema = import_zod.z.lazy(
678
+ () => import_zod.z.union([verticalLayoutSchema, horizontalLayoutSchema, groupLayoutSchema, categorizationSchema])
679
+ );
680
+
681
+ // src/ui-schema/ir-generator.ts
682
+ var import_zod2 = require("zod");
683
+ function parseOrThrow(schema, value, label) {
684
+ try {
685
+ return schema.parse(value);
686
+ } catch (error) {
687
+ if (error instanceof import_zod2.z.ZodError) {
688
+ throw new Error(
689
+ `Generated ${label} failed validation:
690
+ ${error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`).join("\n")}`
691
+ );
692
+ }
693
+ throw error;
694
+ }
695
+ }
696
+ function fieldToScope(fieldName) {
697
+ return `#/properties/${fieldName}`;
698
+ }
699
+ function createShowRule(fieldName, value) {
700
+ return {
701
+ effect: "SHOW",
702
+ condition: {
703
+ scope: fieldToScope(fieldName),
704
+ schema: { const: value }
705
+ }
706
+ };
707
+ }
708
+ function combineRules(parentRule, childRule) {
709
+ const parentCondition = parentRule.condition;
710
+ const childCondition = childRule.condition;
711
+ return {
712
+ effect: "SHOW",
713
+ condition: {
714
+ scope: "#",
715
+ schema: {
716
+ allOf: [
717
+ {
718
+ properties: {
719
+ [parentCondition.scope.replace("#/properties/", "")]: parentCondition.schema
720
+ }
721
+ },
722
+ {
723
+ properties: {
724
+ [childCondition.scope.replace("#/properties/", "")]: childCondition.schema
725
+ }
726
+ }
727
+ ]
728
+ }
729
+ }
730
+ };
731
+ }
732
+ function fieldNodeToControl(field, parentRule) {
733
+ const displayNameAnnotation = field.annotations.find((a) => a.annotationKind === "displayName");
734
+ const control = {
735
+ type: "Control",
736
+ scope: fieldToScope(field.name),
737
+ ...displayNameAnnotation !== void 0 && { label: displayNameAnnotation.value },
738
+ ...parentRule !== void 0 && { rule: parentRule }
739
+ };
740
+ return control;
741
+ }
742
+ function groupNodeToLayout(group, parentRule) {
743
+ return {
744
+ type: "Group",
745
+ label: group.label,
746
+ elements: irElementsToUiSchema(group.elements, parentRule),
747
+ ...parentRule !== void 0 && { rule: parentRule }
748
+ };
749
+ }
750
+ function irElementsToUiSchema(elements, parentRule) {
751
+ const result = [];
752
+ for (const element of elements) {
753
+ switch (element.kind) {
754
+ case "field": {
755
+ result.push(fieldNodeToControl(element, parentRule));
756
+ break;
757
+ }
758
+ case "group": {
759
+ result.push(groupNodeToLayout(element, parentRule));
760
+ break;
761
+ }
762
+ case "conditional": {
763
+ const newRule = createShowRule(element.fieldName, element.value);
764
+ const combinedRule = parentRule !== void 0 ? combineRules(parentRule, newRule) : newRule;
765
+ const childElements = irElementsToUiSchema(element.elements, combinedRule);
766
+ result.push(...childElements);
767
+ break;
768
+ }
769
+ default: {
770
+ const _exhaustive = element;
771
+ void _exhaustive;
772
+ throw new Error("Unhandled IR element kind");
773
+ }
774
+ }
775
+ }
776
+ return result;
777
+ }
778
+ function generateUiSchemaFromIR(ir) {
779
+ const result = {
780
+ type: "VerticalLayout",
781
+ elements: irElementsToUiSchema(ir.elements)
782
+ };
783
+ return parseOrThrow(uiSchema, result, "UI Schema");
784
+ }
785
+
786
+ // src/ui-schema/generator.ts
787
+ function generateUiSchema(form) {
788
+ const ir = canonicalizeChainDSL(form);
789
+ return generateUiSchemaFromIR(ir);
790
+ }
791
+
792
+ // src/json-schema/types.ts
793
+ function setSchemaExtension(schema, key, value) {
794
+ schema[key] = value;
795
+ }
796
+ function getSchemaExtension(schema, key) {
797
+ return schema[key];
798
+ }
799
+
800
+ // src/json-schema/schema.ts
801
+ var import_zod3 = require("zod");
802
+ var jsonSchemaTypeSchema = import_zod3.z.enum([
803
+ "string",
804
+ "number",
805
+ "integer",
806
+ "boolean",
807
+ "object",
808
+ "array",
809
+ "null"
810
+ ]);
811
+ var jsonSchema7Schema = import_zod3.z.lazy(
812
+ () => import_zod3.z.object({
813
+ $schema: import_zod3.z.string().optional(),
814
+ $id: import_zod3.z.string().optional(),
815
+ $ref: import_zod3.z.string().optional(),
816
+ // Metadata
817
+ title: import_zod3.z.string().optional(),
818
+ description: import_zod3.z.string().optional(),
819
+ deprecated: import_zod3.z.boolean().optional(),
820
+ // Type
821
+ type: import_zod3.z.union([jsonSchemaTypeSchema, import_zod3.z.array(jsonSchemaTypeSchema)]).optional(),
822
+ // String validation
823
+ minLength: import_zod3.z.number().optional(),
824
+ maxLength: import_zod3.z.number().optional(),
825
+ pattern: import_zod3.z.string().optional(),
826
+ // Number validation
827
+ minimum: import_zod3.z.number().optional(),
828
+ maximum: import_zod3.z.number().optional(),
829
+ exclusiveMinimum: import_zod3.z.number().optional(),
830
+ exclusiveMaximum: import_zod3.z.number().optional(),
831
+ // Enum
832
+ enum: import_zod3.z.array(import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean(), import_zod3.z.null()])).readonly().optional(),
833
+ const: import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean(), import_zod3.z.null()]).optional(),
834
+ // Object
835
+ properties: import_zod3.z.record(import_zod3.z.string(), jsonSchema7Schema).optional(),
836
+ required: import_zod3.z.array(import_zod3.z.string()).optional(),
837
+ additionalProperties: import_zod3.z.union([import_zod3.z.boolean(), jsonSchema7Schema]).optional(),
838
+ // Array
839
+ items: import_zod3.z.union([jsonSchema7Schema, import_zod3.z.array(jsonSchema7Schema)]).optional(),
840
+ minItems: import_zod3.z.number().optional(),
841
+ maxItems: import_zod3.z.number().optional(),
842
+ // Composition
843
+ allOf: import_zod3.z.array(jsonSchema7Schema).optional(),
844
+ anyOf: import_zod3.z.array(jsonSchema7Schema).optional(),
845
+ oneOf: import_zod3.z.array(jsonSchema7Schema).optional(),
846
+ not: jsonSchema7Schema.optional(),
847
+ // Conditional
848
+ if: jsonSchema7Schema.optional(),
849
+ then: jsonSchema7Schema.optional(),
850
+ else: jsonSchema7Schema.optional(),
851
+ // Format
852
+ format: import_zod3.z.string().optional(),
853
+ // Default
854
+ default: import_zod3.z.unknown().optional(),
855
+ // FormSpec extensions
856
+ "x-formspec-source": import_zod3.z.string().optional(),
857
+ "x-formspec-params": import_zod3.z.array(import_zod3.z.string()).readonly().optional(),
858
+ "x-formspec-schemaSource": import_zod3.z.string().optional()
859
+ }).passthrough()
860
+ );
861
+
862
+ // src/validate/constraint-validator.ts
863
+ function makeCode(ctx, category, number) {
864
+ return `${ctx.vendorPrefix}-${category}-${String(number).padStart(3, "0")}`;
865
+ }
866
+ function addContradiction(ctx, message, primary, related) {
867
+ ctx.diagnostics.push({
868
+ code: makeCode(ctx, "CONTRADICTION", 1),
869
+ message,
870
+ severity: "error",
871
+ primaryLocation: primary,
872
+ relatedLocations: [related]
873
+ });
874
+ }
875
+ function addTypeMismatch(ctx, message, primary) {
876
+ ctx.diagnostics.push({
877
+ code: makeCode(ctx, "TYPE_MISMATCH", 1),
878
+ message,
879
+ severity: "error",
880
+ primaryLocation: primary,
881
+ relatedLocations: []
882
+ });
883
+ }
884
+ function addUnknownExtension(ctx, message, primary) {
885
+ ctx.diagnostics.push({
886
+ code: makeCode(ctx, "UNKNOWN_EXTENSION", 1),
887
+ message,
888
+ severity: "warning",
889
+ primaryLocation: primary,
890
+ relatedLocations: []
891
+ });
892
+ }
893
+ function findNumeric(constraints, constraintKind) {
894
+ return constraints.find(
895
+ (c) => c.constraintKind === constraintKind
896
+ );
897
+ }
898
+ function findLength(constraints, constraintKind) {
899
+ return constraints.find(
900
+ (c) => c.constraintKind === constraintKind
901
+ );
902
+ }
903
+ function findAllowedMembers(constraints) {
904
+ return constraints.filter(
905
+ (c) => c.constraintKind === "allowedMembers"
906
+ );
907
+ }
908
+ function checkNumericContradictions(ctx, fieldName, constraints) {
909
+ const min = findNumeric(constraints, "minimum");
910
+ const max = findNumeric(constraints, "maximum");
911
+ const exMin = findNumeric(constraints, "exclusiveMinimum");
912
+ const exMax = findNumeric(constraints, "exclusiveMaximum");
913
+ if (min !== void 0 && max !== void 0 && min.value > max.value) {
914
+ addContradiction(
915
+ ctx,
916
+ `Field "${fieldName}": minimum (${String(min.value)}) is greater than maximum (${String(max.value)})`,
917
+ min.provenance,
918
+ max.provenance
919
+ );
920
+ }
921
+ if (exMin !== void 0 && max !== void 0 && exMin.value >= max.value) {
922
+ addContradiction(
923
+ ctx,
924
+ `Field "${fieldName}": exclusiveMinimum (${String(exMin.value)}) is greater than or equal to maximum (${String(max.value)})`,
925
+ exMin.provenance,
926
+ max.provenance
927
+ );
928
+ }
929
+ if (min !== void 0 && exMax !== void 0 && min.value >= exMax.value) {
930
+ addContradiction(
931
+ ctx,
932
+ `Field "${fieldName}": minimum (${String(min.value)}) is greater than or equal to exclusiveMaximum (${String(exMax.value)})`,
933
+ min.provenance,
934
+ exMax.provenance
935
+ );
936
+ }
937
+ if (exMin !== void 0 && exMax !== void 0 && exMin.value >= exMax.value) {
938
+ addContradiction(
939
+ ctx,
940
+ `Field "${fieldName}": exclusiveMinimum (${String(exMin.value)}) is greater than or equal to exclusiveMaximum (${String(exMax.value)})`,
941
+ exMin.provenance,
942
+ exMax.provenance
943
+ );
944
+ }
945
+ }
946
+ function checkLengthContradictions(ctx, fieldName, constraints) {
947
+ const minLen = findLength(constraints, "minLength");
948
+ const maxLen = findLength(constraints, "maxLength");
949
+ if (minLen !== void 0 && maxLen !== void 0 && minLen.value > maxLen.value) {
950
+ addContradiction(
951
+ ctx,
952
+ `Field "${fieldName}": minLength (${String(minLen.value)}) is greater than maxLength (${String(maxLen.value)})`,
953
+ minLen.provenance,
954
+ maxLen.provenance
955
+ );
956
+ }
957
+ const minItems = findLength(constraints, "minItems");
958
+ const maxItems = findLength(constraints, "maxItems");
959
+ if (minItems !== void 0 && maxItems !== void 0 && minItems.value > maxItems.value) {
960
+ addContradiction(
961
+ ctx,
962
+ `Field "${fieldName}": minItems (${String(minItems.value)}) is greater than maxItems (${String(maxItems.value)})`,
963
+ minItems.provenance,
964
+ maxItems.provenance
965
+ );
966
+ }
967
+ }
968
+ function checkAllowedMembersContradiction(ctx, fieldName, constraints) {
969
+ const members = findAllowedMembers(constraints);
970
+ if (members.length < 2) return;
971
+ const firstSet = new Set(members[0]?.members ?? []);
972
+ for (let i = 1; i < members.length; i++) {
973
+ const current = members[i];
974
+ if (current === void 0) continue;
975
+ for (const m of firstSet) {
976
+ if (!current.members.includes(m)) {
977
+ firstSet.delete(m);
978
+ }
979
+ }
980
+ }
981
+ if (firstSet.size === 0) {
982
+ const first = members[0];
983
+ const second = members[1];
984
+ if (first !== void 0 && second !== void 0) {
985
+ addContradiction(
986
+ ctx,
987
+ `Field "${fieldName}": allowedMembers constraints have an empty intersection (no valid values remain)`,
988
+ first.provenance,
989
+ second.provenance
990
+ );
991
+ }
992
+ }
993
+ }
994
+ function typeLabel(type) {
995
+ switch (type.kind) {
996
+ case "primitive":
997
+ return type.primitiveKind;
998
+ case "enum":
999
+ return "enum";
1000
+ case "array":
1001
+ return "array";
1002
+ case "object":
1003
+ return "object";
1004
+ case "union":
1005
+ return "union";
1006
+ case "reference":
1007
+ return `reference(${type.name})`;
1008
+ case "dynamic":
1009
+ return `dynamic(${type.dynamicKind})`;
1010
+ case "custom":
1011
+ return `custom(${type.typeId})`;
1012
+ default: {
1013
+ const _exhaustive = type;
1014
+ return String(_exhaustive);
1015
+ }
1016
+ }
1017
+ }
1018
+ function checkTypeApplicability(ctx, fieldName, type, constraints) {
1019
+ const isNumber = type.kind === "primitive" && type.primitiveKind === "number";
1020
+ const isString = type.kind === "primitive" && type.primitiveKind === "string";
1021
+ const isArray = type.kind === "array";
1022
+ const isEnum = type.kind === "enum";
1023
+ const label = typeLabel(type);
1024
+ for (const constraint of constraints) {
1025
+ const ck = constraint.constraintKind;
1026
+ switch (ck) {
1027
+ case "minimum":
1028
+ case "maximum":
1029
+ case "exclusiveMinimum":
1030
+ case "exclusiveMaximum":
1031
+ case "multipleOf": {
1032
+ if (!isNumber) {
1033
+ addTypeMismatch(
1034
+ ctx,
1035
+ `Field "${fieldName}": constraint "${ck}" is only valid on number fields, but field type is "${label}"`,
1036
+ constraint.provenance
1037
+ );
1038
+ }
1039
+ break;
1040
+ }
1041
+ case "minLength":
1042
+ case "maxLength":
1043
+ case "pattern": {
1044
+ if (!isString) {
1045
+ addTypeMismatch(
1046
+ ctx,
1047
+ `Field "${fieldName}": constraint "${ck}" is only valid on string fields, but field type is "${label}"`,
1048
+ constraint.provenance
1049
+ );
1050
+ }
1051
+ break;
1052
+ }
1053
+ case "minItems":
1054
+ case "maxItems":
1055
+ case "uniqueItems": {
1056
+ if (!isArray) {
1057
+ addTypeMismatch(
1058
+ ctx,
1059
+ `Field "${fieldName}": constraint "${ck}" is only valid on array fields, but field type is "${label}"`,
1060
+ constraint.provenance
1061
+ );
1062
+ }
1063
+ break;
1064
+ }
1065
+ case "allowedMembers": {
1066
+ if (!isEnum) {
1067
+ addTypeMismatch(
1068
+ ctx,
1069
+ `Field "${fieldName}": constraint "allowedMembers" is only valid on enum fields, but field type is "${label}"`,
1070
+ constraint.provenance
1071
+ );
1072
+ }
1073
+ break;
1074
+ }
1075
+ case "custom": {
1076
+ checkCustomConstraint(ctx, fieldName, type, constraint);
1077
+ break;
1078
+ }
1079
+ default: {
1080
+ const _exhaustive = constraint;
1081
+ throw new Error(
1082
+ `Unhandled constraint kind: ${_exhaustive.constraintKind}`
1083
+ );
1084
+ }
1085
+ }
1086
+ }
1087
+ }
1088
+ function checkCustomConstraint(ctx, fieldName, type, constraint) {
1089
+ if (ctx.extensionRegistry === void 0) return;
1090
+ const registration = ctx.extensionRegistry.findConstraint(constraint.constraintId);
1091
+ if (registration === void 0) {
1092
+ addUnknownExtension(
1093
+ ctx,
1094
+ `Field "${fieldName}": custom constraint "${constraint.constraintId}" is not registered in the extension registry`,
1095
+ constraint.provenance
1096
+ );
1097
+ return;
1098
+ }
1099
+ if (registration.applicableTypes === null) return;
1100
+ if (!registration.applicableTypes.includes(type.kind)) {
1101
+ addTypeMismatch(
1102
+ ctx,
1103
+ `Field "${fieldName}": custom constraint "${constraint.constraintId}" is not applicable to type "${typeLabel(type)}"`,
1104
+ constraint.provenance
1105
+ );
1106
+ }
1107
+ }
1108
+ function validateFieldNode(ctx, field) {
1109
+ validateConstraints(ctx, field.name, field.type, field.constraints);
1110
+ if (field.type.kind === "object") {
1111
+ for (const prop of field.type.properties) {
1112
+ validateObjectProperty(ctx, field.name, prop);
1113
+ }
1114
+ }
1115
+ }
1116
+ function validateObjectProperty(ctx, parentName, prop) {
1117
+ const qualifiedName = `${parentName}.${prop.name}`;
1118
+ validateConstraints(ctx, qualifiedName, prop.type, prop.constraints);
1119
+ if (prop.type.kind === "object") {
1120
+ for (const nestedProp of prop.type.properties) {
1121
+ validateObjectProperty(ctx, qualifiedName, nestedProp);
1122
+ }
1123
+ }
1124
+ }
1125
+ function validateConstraints(ctx, name, type, constraints) {
1126
+ checkNumericContradictions(ctx, name, constraints);
1127
+ checkLengthContradictions(ctx, name, constraints);
1128
+ checkAllowedMembersContradiction(ctx, name, constraints);
1129
+ checkTypeApplicability(ctx, name, type, constraints);
1130
+ }
1131
+ function validateElement(ctx, element) {
1132
+ switch (element.kind) {
1133
+ case "field":
1134
+ validateFieldNode(ctx, element);
1135
+ break;
1136
+ case "group":
1137
+ for (const child of element.elements) {
1138
+ validateElement(ctx, child);
1139
+ }
1140
+ break;
1141
+ case "conditional":
1142
+ for (const child of element.elements) {
1143
+ validateElement(ctx, child);
1144
+ }
1145
+ break;
1146
+ default: {
1147
+ const _exhaustive = element;
1148
+ throw new Error(`Unhandled element kind: ${_exhaustive.kind}`);
1149
+ }
1150
+ }
1151
+ }
1152
+ function validateIR(ir, options) {
1153
+ const ctx = {
1154
+ diagnostics: [],
1155
+ vendorPrefix: options?.vendorPrefix ?? "FORMSPEC",
1156
+ extensionRegistry: options?.extensionRegistry
1157
+ };
1158
+ for (const element of ir.elements) {
1159
+ validateElement(ctx, element);
1160
+ }
1161
+ return {
1162
+ diagnostics: ctx.diagnostics,
1163
+ valid: ctx.diagnostics.every((d) => d.severity !== "error")
1164
+ };
1165
+ }
1166
+
1167
+ // src/browser.ts
1168
+ function buildFormSchemas(form) {
1169
+ return {
1170
+ jsonSchema: generateJsonSchema(form),
1171
+ uiSchema: generateUiSchema(form)
1172
+ };
1173
+ }
1174
+ // Annotate the CommonJS export names for ESM import in node:
1175
+ 0 && (module.exports = {
1176
+ buildFormSchemas,
1177
+ canonicalizeChainDSL,
1178
+ categorizationSchema,
1179
+ categorySchema,
1180
+ controlSchema,
1181
+ generateJsonSchema,
1182
+ generateUiSchema,
1183
+ getSchemaExtension,
1184
+ groupLayoutSchema,
1185
+ horizontalLayoutSchema,
1186
+ jsonSchema7Schema,
1187
+ jsonSchemaTypeSchema,
1188
+ labelElementSchema,
1189
+ ruleConditionSchema,
1190
+ ruleEffectSchema,
1191
+ ruleSchema,
1192
+ schemaBasedConditionSchema,
1193
+ setSchemaExtension,
1194
+ uiSchemaElementSchema,
1195
+ uiSchemaElementTypeSchema,
1196
+ uiSchemaSchema,
1197
+ validateIR,
1198
+ verticalLayoutSchema
1199
+ });
1200
+ //# sourceMappingURL=browser.cjs.map