schema-components 1.22.0 → 1.24.0
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 +3 -1
- package/dist/core/adapter.d.mts +97 -3
- package/dist/core/adapter.mjs +260 -111
- package/dist/core/constraints.d.mts +2 -2
- package/dist/core/constraints.mjs +0 -7
- package/dist/core/cssClasses.d.mts +52 -0
- package/dist/core/cssClasses.mjs +51 -0
- package/dist/core/diagnostics.d.mts +1 -1
- package/dist/core/errors.d.mts +1 -1
- package/dist/core/errors.mjs +5 -13
- package/dist/core/fieldOrder.d.mts +1 -1
- package/dist/core/formats.d.mts +9 -2
- package/dist/core/formats.mjs +12 -1
- package/dist/core/idPath.d.mts +54 -0
- package/dist/core/idPath.mjs +66 -0
- package/dist/core/merge.d.mts +10 -1
- package/dist/core/merge.mjs +49 -10
- package/dist/core/normalise.d.mts +14 -3
- package/dist/core/normalise.mjs +2 -2
- package/dist/core/openapi30.d.mts +15 -1
- package/dist/core/openapi30.mjs +2 -2
- package/dist/core/openapiConstants.d.mts +67 -0
- package/dist/core/openapiConstants.mjs +90 -0
- package/dist/core/ref.d.mts +2 -2
- package/dist/core/ref.mjs +83 -6
- package/dist/core/refChain.d.mts +70 -0
- package/dist/core/refChain.mjs +44 -0
- package/dist/core/renderer.d.mts +1 -1
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/swagger2.mjs +1 -1
- package/dist/core/typeInference.d.mts +982 -2
- package/dist/core/types.d.mts +1 -1
- package/dist/core/unionMatch.d.mts +36 -0
- package/dist/core/unionMatch.mjs +53 -0
- package/dist/core/version.d.mts +1 -1
- package/dist/core/version.mjs +29 -17
- package/dist/core/walkBuilders.d.mts +23 -4
- package/dist/core/walkBuilders.mjs +27 -7
- package/dist/core/walker.d.mts +1 -1
- package/dist/core/walker.mjs +44 -45
- package/dist/{diagnostics-D0QCYGv0.d.mts → diagnostics-Cbwak-ZX.d.mts} +1 -1
- package/dist/{errors-DpFwqs5C.d.mts → errors-g_MCTQel.d.mts} +9 -15
- package/dist/html/a11y.d.mts +9 -4
- package/dist/html/a11y.mjs +10 -19
- package/dist/html/renderToHtml.d.mts +2 -2
- package/dist/html/renderToHtmlStream.d.mts +2 -2
- package/dist/html/renderToHtmlStream.mjs +12 -1
- package/dist/html/renderers.d.mts +32 -8
- package/dist/html/renderers.mjs +125 -111
- package/dist/html/streamRenderers.d.mts +4 -5
- package/dist/html/streamRenderers.mjs +40 -61
- package/dist/{normalise-DVEJQmF7.mjs → normalise-DCYp06Sr.mjs} +352 -162
- package/dist/openapi/ApiCallbacks.d.mts +1 -1
- package/dist/openapi/ApiLinks.d.mts +1 -1
- package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
- package/dist/openapi/ApiSecurity.d.mts +1 -1
- package/dist/openapi/components.d.mts +116 -37
- package/dist/openapi/components.mjs +54 -37
- package/dist/openapi/parser.d.mts +19 -9
- package/dist/openapi/parser.mjs +262 -86
- package/dist/openapi/resolve.d.mts +20 -11
- package/dist/openapi/resolve.mjs +135 -75
- package/dist/react/SchemaComponent.d.mts +32 -7
- package/dist/react/SchemaComponent.mjs +45 -21
- package/dist/react/SchemaView.d.mts +30 -10
- package/dist/react/a11y.d.mts +21 -0
- package/dist/react/a11y.mjs +24 -0
- package/dist/react/fieldPath.d.mts +1 -1
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +8 -9
- package/dist/react/headlessRenderers.mjs +41 -72
- package/dist/{ref-D-_JBZkF.d.mts → ref-DCDuswPe.d.mts} +38 -3
- package/dist/{renderer-BaRlQIuN.d.mts → renderer-CXJ8y0qw.d.mts} +1 -1
- package/dist/themes/mantine.d.mts +1 -1
- package/dist/themes/mui.d.mts +1 -1
- package/dist/themes/radix.d.mts +1 -1
- package/dist/themes/shadcn.d.mts +1 -1
- package/dist/themes/shadcn.mjs +2 -1
- package/dist/{types-BrRMV0en.d.mts → types-BTB73MB8.d.mts} +32 -4
- package/dist/{version-D2jfdX6E.d.mts → version-BFTVLsdb.d.mts} +7 -1
- package/package.json +1 -1
- package/dist/typeInference-DkcUHfaM.d.mts +0 -982
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { isObject } from "../core/guards.mjs";
|
|
2
2
|
import "../core/limits.mjs";
|
|
3
3
|
import { emitDiagnostic } from "../core/diagnostics.mjs";
|
|
4
|
+
import { SC_CLASSES } from "../core/cssClasses.mjs";
|
|
4
5
|
import { getHtmlRenderFn } from "../core/renderer.mjs";
|
|
6
|
+
import { matchUnionOption, resolveDiscriminatedActive } from "../core/unionMatch.mjs";
|
|
5
7
|
import { VOID_ELEMENTS, h, raw, serialize, serializeAttributes } from "./html.mjs";
|
|
6
8
|
import { ariaLabelAttrs, buildHintElement, buildInputId, joinPath, requiredIndicator } from "./a11y.mjs";
|
|
9
|
+
import { panelId, tabId } from "./renderers.mjs";
|
|
7
10
|
import { recursionSentinelHtml } from "./renderToHtml.mjs";
|
|
8
11
|
//#region src/html/streamRenderers.ts
|
|
9
12
|
function yieldOpen(el) {
|
|
10
13
|
const attrStr = serializeAttributes(el.attributes);
|
|
11
|
-
if (
|
|
14
|
+
if (VOID_ELEMENTS.has(el.tag)) return `<${el.tag}${attrStr} />`;
|
|
12
15
|
return `<${el.tag}${attrStr}>`;
|
|
13
16
|
}
|
|
14
17
|
function yieldClose(el) {
|
|
@@ -27,19 +30,12 @@ function renderLeaf(tree, value, mergedResolver, path) {
|
|
|
27
30
|
tree,
|
|
28
31
|
renderChild: () => ""
|
|
29
32
|
});
|
|
30
|
-
if (value === void 0 || value === null) return serialize(h("span", { class:
|
|
31
|
-
return serialize(h("span", { class:
|
|
33
|
+
if (value === void 0 || value === null) return serialize(h("span", { class: SC_CLASSES.valueEmpty }, "—"));
|
|
34
|
+
return serialize(h("span", { class: SC_CLASSES.value }, typeof value === "string" ? value : JSON.stringify(value)));
|
|
32
35
|
}
|
|
33
36
|
function renderFieldSync(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
|
|
34
37
|
return [...streamField(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics)].join("");
|
|
35
38
|
}
|
|
36
|
-
function matchUnionOption(options, value) {
|
|
37
|
-
if (typeof value === "string") return options.find((o) => o.type === "string" || o.type === "enum");
|
|
38
|
-
if (typeof value === "number") return options.find((o) => o.type === "number");
|
|
39
|
-
if (typeof value === "boolean") return options.find((o) => o.type === "boolean");
|
|
40
|
-
if (Array.isArray(value)) return options.find((o) => o.type === "array");
|
|
41
|
-
if (typeof value === "object" && value !== null) return options.find((o) => o.type === "object");
|
|
42
|
-
}
|
|
43
39
|
/**
|
|
44
40
|
* Build a visible placeholder element used when a value does not match
|
|
45
41
|
* the shape implied by its field type. The expected-shape label is
|
|
@@ -110,7 +106,7 @@ function* streamObject(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
110
106
|
const descriptionText = typeof tree.meta.description === "string" ? tree.meta.description : void 0;
|
|
111
107
|
const labelAttrs = ariaLabelAttrs(descriptionText);
|
|
112
108
|
if (readOnly) {
|
|
113
|
-
const dlAttrs = { class:
|
|
109
|
+
const dlAttrs = { class: SC_CLASSES.object };
|
|
114
110
|
Object.assign(dlAttrs, labelAttrs);
|
|
115
111
|
const dl = h("dl", dlAttrs);
|
|
116
112
|
const legend = descriptionText !== void 0 ? serialize(h("legend", {}, descriptionText)) : "";
|
|
@@ -119,11 +115,11 @@ function* streamObject(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
119
115
|
const label = typeof field.meta.description === "string" ? field.meta.description : key;
|
|
120
116
|
const childValue = obj[key];
|
|
121
117
|
const childHtml = renderFieldSync(field, childValue, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics);
|
|
122
|
-
yield `${serialize(h("dt", { class:
|
|
118
|
+
yield `${serialize(h("dt", { class: SC_CLASSES.label }, label))}${serialize(h("dd", { class: SC_CLASSES.value }, raw(childHtml)))}`;
|
|
123
119
|
}
|
|
124
120
|
yield yieldClose(dl);
|
|
125
121
|
} else {
|
|
126
|
-
const fieldsetAttrs = { class:
|
|
122
|
+
const fieldsetAttrs = { class: SC_CLASSES.object };
|
|
127
123
|
Object.assign(fieldsetAttrs, labelAttrs);
|
|
128
124
|
const fieldset = h("fieldset", fieldsetAttrs);
|
|
129
125
|
const legend = descriptionText !== void 0 ? serialize(h("legend", {}, descriptionText)) : "";
|
|
@@ -137,12 +133,12 @@ function* streamObject(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
137
133
|
const labelContent = [label];
|
|
138
134
|
if (required !== void 0) labelContent.push(required);
|
|
139
135
|
const fieldChildren = [h("label", {
|
|
140
|
-
class:
|
|
136
|
+
class: SC_CLASSES.label,
|
|
141
137
|
for: fieldId
|
|
142
138
|
}, ...labelContent), raw(childChunks)];
|
|
143
139
|
const hint = buildHintElement(key, field.constraints);
|
|
144
140
|
if (hint !== void 0) fieldChildren.push(hint);
|
|
145
|
-
yield serialize(h("div", { class:
|
|
141
|
+
yield serialize(h("div", { class: SC_CLASSES.field }, ...fieldChildren));
|
|
146
142
|
}
|
|
147
143
|
yield yieldClose(fieldset);
|
|
148
144
|
}
|
|
@@ -167,12 +163,12 @@ function* streamArray(tree, value, mergedResolver, path, rawResolver, currentDep
|
|
|
167
163
|
}
|
|
168
164
|
const arr = Array.isArray(value) ? value : [];
|
|
169
165
|
if (tree.editability === "presentation") {
|
|
170
|
-
const ul = h("ul", { class:
|
|
166
|
+
const ul = h("ul", { class: SC_CLASSES.array });
|
|
171
167
|
yield yieldOpen(ul);
|
|
172
168
|
for (const [i, item] of arr.entries()) yield serialize(h("li", { class: "sc-item" }, raw(renderFieldSync(element, item, mergedResolver, joinPath(path, `[${String(i)}]`), rawResolver, currentDepth + 1, diagnostics))));
|
|
173
169
|
yield yieldClose(ul);
|
|
174
170
|
} else {
|
|
175
|
-
const div = h("div", { class:
|
|
171
|
+
const div = h("div", { class: SC_CLASSES.array });
|
|
176
172
|
yield yieldOpen(div);
|
|
177
173
|
for (const [i, item] of arr.entries()) yield serialize(h("div", {}, raw(renderFieldSync(element, item, mergedResolver, joinPath(path, `[${String(i)}]`), rawResolver, currentDepth + 1, diagnostics))));
|
|
178
174
|
yield yieldClose(div);
|
|
@@ -198,7 +194,7 @@ function* streamRecord(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
198
194
|
const obj = isObject(value) ? value : {};
|
|
199
195
|
const readOnly = tree.editability === "presentation";
|
|
200
196
|
const attrs = {
|
|
201
|
-
class:
|
|
197
|
+
class: SC_CLASSES.record,
|
|
202
198
|
role: "group"
|
|
203
199
|
};
|
|
204
200
|
if (readOnly) {
|
|
@@ -206,7 +202,7 @@ function* streamRecord(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
206
202
|
yield yieldOpen(dl);
|
|
207
203
|
for (const [key, val] of Object.entries(obj)) {
|
|
208
204
|
const childHtml = renderFieldSync(valueType, val, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics);
|
|
209
|
-
yield `${serialize(h("dt", { class:
|
|
205
|
+
yield `${serialize(h("dt", { class: SC_CLASSES.label }, key))}${serialize(h("dd", { class: SC_CLASSES.value }, raw(childHtml)))}`;
|
|
210
206
|
}
|
|
211
207
|
yield yieldClose(dl);
|
|
212
208
|
} else {
|
|
@@ -214,7 +210,7 @@ function* streamRecord(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
214
210
|
yield yieldOpen(container);
|
|
215
211
|
for (const [key, val] of Object.entries(obj)) {
|
|
216
212
|
const childHtml = renderFieldSync(valueType, val, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics);
|
|
217
|
-
yield serialize(h("div", { class:
|
|
213
|
+
yield serialize(h("div", { class: SC_CLASSES.field }, h("label", { class: SC_CLASSES.label }, key), raw(childHtml)));
|
|
218
214
|
}
|
|
219
215
|
yield yieldClose(container);
|
|
220
216
|
}
|
|
@@ -222,67 +218,50 @@ function* streamRecord(tree, value, mergedResolver, path, rawResolver, currentDe
|
|
|
222
218
|
function* streamUnion(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
|
|
223
219
|
const options = tree.type === "union" ? tree.options : void 0;
|
|
224
220
|
if (options === void 0 || options.length === 0) {
|
|
225
|
-
if (value === void 0 || value === null) yield serialize(h("span", { class:
|
|
226
|
-
else yield serialize(h("span", { class:
|
|
221
|
+
if (value === void 0 || value === null) yield serialize(h("span", { class: SC_CLASSES.valueEmpty }, "—"));
|
|
222
|
+
else yield serialize(h("span", { class: SC_CLASSES.value }, JSON.stringify(value)));
|
|
227
223
|
return;
|
|
228
224
|
}
|
|
229
225
|
const target = matchUnionOption(options, value) ?? options[0];
|
|
230
226
|
if (target !== void 0) yield* streamField(target, value, mergedResolver, path, rawResolver, currentDepth + 1, diagnostics);
|
|
231
|
-
else yield serialize(h("span", { class:
|
|
227
|
+
else yield serialize(h("span", { class: SC_CLASSES.valueEmpty }, "—"));
|
|
232
228
|
}
|
|
233
229
|
function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
if (options
|
|
237
|
-
if (value === void 0 || value === null) yield serialize(h("span", { class:
|
|
238
|
-
else yield serialize(h("span", { class:
|
|
230
|
+
if (tree.type !== "discriminatedUnion") return;
|
|
231
|
+
const { options, discriminator } = tree;
|
|
232
|
+
if (options.length === 0) {
|
|
233
|
+
if (value === void 0 || value === null) yield serialize(h("span", { class: SC_CLASSES.valueEmpty }, "—"));
|
|
234
|
+
else yield serialize(h("span", { class: SC_CLASSES.value }, JSON.stringify(value)));
|
|
239
235
|
return;
|
|
240
236
|
}
|
|
241
|
-
const
|
|
242
|
-
const discKey = discriminator ?? "";
|
|
243
|
-
const currentDiscriminatorValue = typeof obj[discKey] === "string" ? obj[discKey] : void 0;
|
|
244
|
-
const optionLabels = options.map((opt) => {
|
|
245
|
-
if (opt.type === "object") {
|
|
246
|
-
const discriminatorField = opt.fields[discKey];
|
|
247
|
-
if (discriminatorField?.type === "literal") {
|
|
248
|
-
const constVal = discriminatorField.literalValues[0];
|
|
249
|
-
if (typeof constVal === "string") return constVal;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return typeof opt.meta.title === "string" ? opt.meta.title : opt.type;
|
|
253
|
-
});
|
|
254
|
-
let activeIndex = 0;
|
|
255
|
-
if (currentDiscriminatorValue !== void 0) {
|
|
256
|
-
const found = optionLabels.indexOf(currentDiscriminatorValue);
|
|
257
|
-
if (found !== -1) activeIndex = found;
|
|
258
|
-
}
|
|
259
|
-
const activeOption = options[activeIndex];
|
|
237
|
+
const { optionLabels, activeIndex, activeOption } = resolveDiscriminatedActive(options, discriminator, isObject(value) ? value : void 0);
|
|
260
238
|
if (tree.editability === "presentation") {
|
|
261
239
|
if (activeOption !== void 0) yield* streamField(activeOption, value, mergedResolver, path, rawResolver, currentDepth + 1, diagnostics);
|
|
262
240
|
return;
|
|
263
241
|
}
|
|
264
|
-
const
|
|
265
|
-
const wrapper = h("div", { class:
|
|
242
|
+
const tabPanelId = panelId(path);
|
|
243
|
+
const wrapper = h("div", { class: SC_CLASSES.discriminatedUnion });
|
|
266
244
|
yield yieldOpen(wrapper);
|
|
267
|
-
|
|
268
|
-
role: "tablist",
|
|
269
|
-
class: "sc-tabs",
|
|
270
|
-
"aria-label": "Select variant"
|
|
271
|
-
}, ...options.map((_opt, i) => {
|
|
245
|
+
const tabButtons = options.map((_opt, i) => {
|
|
272
246
|
return h("button", {
|
|
273
247
|
type: "button",
|
|
274
248
|
role: "tab",
|
|
275
|
-
class: i === activeIndex ?
|
|
276
|
-
id:
|
|
249
|
+
class: i === activeIndex ? SC_CLASSES.tabActive : SC_CLASSES.tab,
|
|
250
|
+
id: tabId(path, i),
|
|
277
251
|
"aria-selected": i === activeIndex ? "true" : void 0,
|
|
278
|
-
"aria-controls":
|
|
252
|
+
"aria-controls": tabPanelId,
|
|
279
253
|
tabindex: i === activeIndex ? "0" : "-1"
|
|
280
254
|
}, optionLabels[i]);
|
|
281
|
-
})
|
|
255
|
+
});
|
|
256
|
+
yield serialize(h("div", {
|
|
257
|
+
role: "tablist",
|
|
258
|
+
class: SC_CLASSES.tabs,
|
|
259
|
+
"aria-label": "Select variant"
|
|
260
|
+
}, ...tabButtons));
|
|
282
261
|
const panelOpen = h("div", {
|
|
283
262
|
role: "tabpanel",
|
|
284
|
-
id:
|
|
285
|
-
"aria-labelledby":
|
|
263
|
+
id: tabPanelId,
|
|
264
|
+
"aria-labelledby": tabId(path, activeIndex)
|
|
286
265
|
});
|
|
287
266
|
yield yieldOpen(panelOpen);
|
|
288
267
|
if (activeOption !== void 0) yield* streamField(activeOption, value, mergedResolver, path, rawResolver, currentDepth + 1, diagnostics);
|
|
@@ -290,4 +269,4 @@ function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolve
|
|
|
290
269
|
yield yieldClose(wrapper);
|
|
291
270
|
}
|
|
292
271
|
//#endregion
|
|
293
|
-
export {
|
|
272
|
+
export { renderFieldSync, renderLeaf, streamField, yieldClose, yieldOpen };
|