schema-components 1.12.10 → 1.13.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.
Files changed (63) hide show
  1. package/README.md +31 -0
  2. package/dist/core/adapter.d.mts +1 -1
  3. package/dist/core/adapter.mjs +37 -8
  4. package/dist/core/constraints.d.mts +16 -0
  5. package/dist/core/constraints.mjs +138 -0
  6. package/dist/core/merge.d.mts +32 -0
  7. package/dist/core/merge.mjs +96 -0
  8. package/dist/core/normalise.d.mts +40 -0
  9. package/dist/core/normalise.mjs +171 -0
  10. package/dist/core/openapi30.d.mts +38 -0
  11. package/dist/core/openapi30.mjs +223 -0
  12. package/dist/core/ref.d.mts +25 -0
  13. package/dist/core/ref.mjs +86 -0
  14. package/dist/core/renderer.d.mts +2 -2
  15. package/dist/core/renderer.mjs +8 -0
  16. package/dist/core/swagger2.d.mts +10 -0
  17. package/dist/core/swagger2.mjs +294 -0
  18. package/dist/core/typeInference.d.mts +2 -0
  19. package/dist/core/typeInference.mjs +1 -0
  20. package/dist/core/types.d.mts +2 -3
  21. package/dist/core/types.mjs +55 -2
  22. package/dist/core/version.d.mts +2 -0
  23. package/dist/core/version.mjs +79 -0
  24. package/dist/core/walkBuilders.d.mts +52 -0
  25. package/dist/core/walkBuilders.mjs +152 -0
  26. package/dist/core/walker.d.mts +3 -10
  27. package/dist/core/walker.mjs +143 -231
  28. package/dist/html/a11y.d.mts +5 -4
  29. package/dist/html/renderToHtml.d.mts +3 -3
  30. package/dist/html/renderToHtml.mjs +23 -379
  31. package/dist/html/renderToHtmlStream.d.mts +29 -47
  32. package/dist/html/renderToHtmlStream.mjs +33 -305
  33. package/dist/html/renderers.d.mts +14 -0
  34. package/dist/html/renderers.mjs +406 -0
  35. package/dist/html/streamRenderers.d.mts +13 -0
  36. package/dist/html/streamRenderers.mjs +243 -0
  37. package/dist/openapi/components.d.mts +2 -1
  38. package/dist/openapi/parser.d.mts +59 -2
  39. package/dist/openapi/parser.mjs +189 -8
  40. package/dist/react/SchemaComponent.d.mts +4 -2
  41. package/dist/react/SchemaComponent.mjs +39 -85
  42. package/dist/react/SchemaView.d.mts +2 -1
  43. package/dist/react/SchemaView.mjs +21 -9
  44. package/dist/react/fieldPath.d.mts +20 -0
  45. package/dist/react/fieldPath.mjs +81 -0
  46. package/dist/react/headless.d.mts +2 -4
  47. package/dist/react/headless.mjs +3 -492
  48. package/dist/react/headlessRenderers.d.mts +23 -0
  49. package/dist/react/headlessRenderers.mjs +507 -0
  50. package/dist/renderer-DseHeliw.d.mts +160 -0
  51. package/dist/themes/mantine.d.mts +1 -1
  52. package/dist/themes/mantine.mjs +2 -1
  53. package/dist/themes/mui.d.mts +1 -1
  54. package/dist/themes/mui.mjs +2 -1
  55. package/dist/themes/radix.d.mts +1 -1
  56. package/dist/themes/radix.mjs +2 -1
  57. package/dist/themes/shadcn.d.mts +1 -1
  58. package/dist/themes/shadcn.mjs +10 -6
  59. package/dist/typeInference-CRPqVwKu.d.mts +299 -0
  60. package/dist/types-ag2jYLqQ.d.mts +261 -0
  61. package/dist/version-CLchheaH.d.mts +40 -0
  62. package/package.json +1 -1
  63. package/dist/types-BJzEgJdX.d.mts +0 -335
@@ -1,11 +1,11 @@
1
1
  import { normaliseSchema } from "../core/adapter.mjs";
2
2
  import { getHtmlRenderFn, mergeHtmlResolvers } from "../core/renderer.mjs";
3
3
  import { walk } from "../core/walker.mjs";
4
- import { h, raw, serialize } from "./html.mjs";
5
- import { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAttrs, buildHintElement, buildInputId, requiredIndicator } from "./a11y.mjs";
4
+ import { h, serialize } from "./html.mjs";
5
+ import { defaultHtmlResolver } from "./renderers.mjs";
6
6
  //#region src/html/renderToHtml.ts
7
7
  /**
8
- * HTML renderer — produces semantic HTML from schemas using the typed `h()` builder.
8
+ * HTML renderer entry point — produces semantic HTML from schemas.
9
9
  *
10
10
  * Framework-agnostic alternative to the React rendering pipeline.
11
11
  * Uses the same walker and adapter (normalise → walk → render) but
@@ -24,372 +24,6 @@ import { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAt
24
24
  * resolver: { string: (props) => h("b", {}, String(props.value)) },
25
25
  * });
26
26
  */
27
- function dateInputType(format) {
28
- if (format === "date") return "date";
29
- if (format === "time") return "time";
30
- if (format === "date-time" || format === "datetime") return "datetime-local";
31
- }
32
- /**
33
- * Normalise a dot-separated path into a valid, `sc-` prefixed HTML ID.
34
- * Dots in paths (from nested objects) become hyphens.
35
- */
36
- function fieldId(path) {
37
- return `sc-${path.replace(/\./g, "-")}`;
38
- }
39
- function renderStringHtml(props) {
40
- if (props.readOnly) return serialize(renderStringReadOnly(props));
41
- return serialize(renderStringEditable(props));
42
- }
43
- function renderStringReadOnly(props) {
44
- const strValue = typeof props.value === "string" ? props.value : void 0;
45
- if (strValue === void 0 || strValue.length === 0) return h("span", {
46
- class: "sc-value sc-value--empty",
47
- ...ariaReadonlyAttrs()
48
- }, "—");
49
- const format = props.constraints.format;
50
- if (format === "email") return h("a", {
51
- class: "sc-value",
52
- href: `mailto:${strValue}`,
53
- ...ariaReadonlyAttrs()
54
- }, strValue);
55
- if (format === "uri" || format === "url") return h("a", {
56
- class: "sc-value",
57
- href: strValue,
58
- ...ariaReadonlyAttrs()
59
- }, strValue);
60
- return h("span", {
61
- class: "sc-value",
62
- ...ariaReadonlyAttrs()
63
- }, strValue);
64
- }
65
- function renderStringEditable(props) {
66
- const strValue = typeof props.value === "string" ? props.value : "";
67
- const format = props.constraints.format;
68
- const inputType = dateInputType(format) ?? (format === "email" ? "email" : format === "uri" ? "url" : "text");
69
- const id = fieldId(props.path);
70
- const attrs = {
71
- class: "sc-input",
72
- id,
73
- type: inputType,
74
- name: id
75
- };
76
- if (!props.writeOnly) attrs.value = strValue;
77
- if (typeof props.meta.description === "string") attrs.placeholder = props.meta.description;
78
- if (props.constraints.minLength !== void 0) attrs.minlength = String(props.constraints.minLength);
79
- if (props.constraints.maxLength !== void 0) attrs.maxlength = String(props.constraints.maxLength);
80
- Object.assign(attrs, ariaRequiredAttrs(props.tree));
81
- Object.assign(attrs, ariaDescribedByAttrs(id, props.constraints));
82
- return h("input", attrs);
83
- }
84
- function renderNumberHtml(props) {
85
- if (props.readOnly) return serialize(renderNumberReadOnly(props));
86
- return serialize(renderNumberEditable(props));
87
- }
88
- function renderNumberReadOnly(props) {
89
- if (typeof props.value !== "number") return h("span", {
90
- class: "sc-value sc-value--empty",
91
- ...ariaReadonlyAttrs()
92
- }, "—");
93
- return h("span", {
94
- class: "sc-value",
95
- ...ariaReadonlyAttrs()
96
- }, props.value.toLocaleString());
97
- }
98
- function renderNumberEditable(props) {
99
- const numValue = typeof props.value === "number" ? String(props.value) : "";
100
- const id = fieldId(props.path);
101
- const attrs = {
102
- class: "sc-input",
103
- id,
104
- type: "number",
105
- name: id
106
- };
107
- if (!props.writeOnly) attrs.value = numValue;
108
- if (props.constraints.minimum !== void 0) attrs.min = String(props.constraints.minimum);
109
- if (props.constraints.maximum !== void 0) attrs.max = String(props.constraints.maximum);
110
- Object.assign(attrs, ariaRequiredAttrs(props.tree));
111
- Object.assign(attrs, ariaDescribedByAttrs(id, props.constraints));
112
- return h("input", attrs);
113
- }
114
- function renderBooleanHtml(props) {
115
- if (props.readOnly) return serialize(renderBooleanReadOnly(props));
116
- return serialize(renderBooleanEditable(props));
117
- }
118
- function renderBooleanReadOnly(props) {
119
- if (typeof props.value !== "boolean") return h("span", {
120
- class: "sc-value sc-value--empty",
121
- ...ariaReadonlyAttrs()
122
- }, "—");
123
- return h("span", {
124
- class: "sc-value sc-value--boolean",
125
- ...ariaReadonlyAttrs()
126
- }, props.value ? "Yes" : "No");
127
- }
128
- function renderBooleanEditable(props) {
129
- const id = fieldId(props.path);
130
- const attrs = {
131
- class: "sc-input",
132
- id,
133
- type: "checkbox",
134
- name: id
135
- };
136
- if (!props.writeOnly && props.value === true) attrs.checked = true;
137
- Object.assign(attrs, ariaRequiredAttrs(props.tree));
138
- Object.assign(attrs, ariaLabelAttrs(props.meta.description));
139
- return h("input", attrs);
140
- }
141
- function renderEnumHtml(props) {
142
- if (props.readOnly) return serialize(renderEnumReadOnly(props));
143
- return serialize(renderEnumEditable(props));
144
- }
145
- function renderEnumReadOnly(props) {
146
- const enumValue = typeof props.value === "string" ? props.value : "";
147
- if (enumValue.length === 0) return h("span", {
148
- class: "sc-value sc-value--empty",
149
- ...ariaReadonlyAttrs()
150
- }, "—");
151
- return h("span", {
152
- class: "sc-value",
153
- ...ariaReadonlyAttrs()
154
- }, enumValue);
155
- }
156
- function renderEnumEditable(props) {
157
- const enumValue = typeof props.value === "string" ? props.value : "";
158
- const id = fieldId(props.path);
159
- const selectedValue = props.writeOnly ? "" : enumValue;
160
- const optionNodes = [h("option", { value: "" }, "Select…"), ...(props.enumValues ?? []).map((v) => {
161
- const attrs = { value: v };
162
- if (v === selectedValue) attrs.selected = true;
163
- return h("option", attrs, v);
164
- })];
165
- const selectAttrs = {
166
- class: "sc-input",
167
- id,
168
- name: id
169
- };
170
- Object.assign(selectAttrs, ariaRequiredAttrs(props.tree));
171
- return h("select", selectAttrs, ...optionNodes);
172
- }
173
- function renderObjectHtml(props) {
174
- return serialize(renderObjectNode(props));
175
- }
176
- function renderObjectNode(props) {
177
- const fields = props.fields;
178
- if (fields === void 0) return "";
179
- const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
180
- const obj = isRecord(props.value) ? props.value : {};
181
- const descriptionText = typeof props.meta.description === "string" ? props.meta.description : void 0;
182
- const legend = descriptionText !== void 0 ? h("legend", {}, descriptionText) : void 0;
183
- const sortedEntries = Object.entries(fields).sort((a, b) => {
184
- return (typeof a[1].meta.order === "number" ? a[1].meta.order : Infinity) - (typeof b[1].meta.order === "number" ? b[1].meta.order : Infinity);
185
- }).filter(([, field]) => field.meta.visible !== false);
186
- if (props.readOnly) {
187
- const children = [];
188
- if (legend !== void 0) children.push(legend);
189
- for (const [key, field] of sortedEntries) {
190
- const label = typeof field.meta.description === "string" ? field.meta.description : key;
191
- const childValue = obj[key];
192
- const childHtml = props.renderChild(field, childValue, props.path ? `${props.path}.${key}` : key);
193
- children.push(h("dt", { class: "sc-label" }, label));
194
- children.push(h("dd", { class: "sc-value" }, raw(childHtml)));
195
- }
196
- const dlAttrs = { class: "sc-object" };
197
- Object.assign(dlAttrs, ariaLabelAttrs(descriptionText));
198
- return h("dl", dlAttrs, ...children);
199
- }
200
- const children = [];
201
- if (legend !== void 0) children.push(legend);
202
- for (const [key, field] of sortedEntries) {
203
- const label = typeof field.meta.description === "string" ? field.meta.description : key;
204
- const fieldId = buildInputId(props.path, key);
205
- const childPath = props.path ? `${props.path}.${key}` : key;
206
- const childValue = obj[key];
207
- const childHtml = props.renderChild(field, childValue, childPath);
208
- const required = requiredIndicator(field);
209
- const labelContent = [label];
210
- if (required !== void 0) labelContent.push(required);
211
- const fieldChildren = [h("label", {
212
- class: "sc-label",
213
- for: fieldId
214
- }, ...labelContent), raw(childHtml)];
215
- const hint = buildHintElement(fieldId, field.constraints);
216
- if (hint !== void 0) fieldChildren.push(hint);
217
- children.push(h("div", { class: "sc-field" }, ...fieldChildren));
218
- }
219
- const fieldsetAttrs = { class: "sc-object" };
220
- Object.assign(fieldsetAttrs, ariaLabelAttrs(descriptionText));
221
- return h("fieldset", fieldsetAttrs, ...children);
222
- }
223
- function renderArrayHtml(props) {
224
- return serialize(renderArrayNode(props));
225
- }
226
- function renderArrayNode(props) {
227
- const arr = Array.isArray(props.value) ? props.value : [];
228
- const element = props.element;
229
- if (element === void 0) return "";
230
- const items = arr.map((item) => {
231
- return h("li", { class: "sc-item" }, raw(props.renderChild(element, item)));
232
- });
233
- if (props.readOnly) return h("ul", { class: "sc-array" }, ...items);
234
- return h("div", { class: "sc-array" }, ...arr.map((item) => {
235
- return h("div", {}, raw(props.renderChild(element, item)));
236
- }));
237
- }
238
- function renderRecordHtml(props) {
239
- return serialize(renderRecordNode(props));
240
- }
241
- function renderRecordNode(props) {
242
- const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
243
- const obj = isRecord(props.value) ? props.value : {};
244
- const valueType = props.valueType;
245
- if (valueType === void 0) return "";
246
- const attrs = {
247
- class: "sc-record",
248
- role: "group"
249
- };
250
- if (props.readOnly) {
251
- const children = [];
252
- for (const [key, val] of Object.entries(obj)) {
253
- const childHtml = props.renderChild(valueType, val, key);
254
- children.push(h("dt", { class: "sc-label" }, key));
255
- children.push(h("dd", { class: "sc-value" }, raw(childHtml)));
256
- }
257
- return h("dl", attrs, ...children);
258
- }
259
- const children = [];
260
- for (const [key, val] of Object.entries(obj)) {
261
- const childHtml = props.renderChild(valueType, val, key);
262
- children.push(h("div", { class: "sc-field" }, h("label", { class: "sc-label" }, key), raw(childHtml)));
263
- }
264
- return h("div", attrs, ...children);
265
- }
266
- function renderLiteralHtml(props) {
267
- const values = props.tree.literalValues;
268
- if (values === void 0 || values.length === 0) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
269
- return serialize(h("span", { class: "sc-value" }, values.map((v) => v === null ? "null" : String(v)).join(", ")));
270
- }
271
- function renderUnionHtml(props) {
272
- const options = props.options;
273
- if (options === void 0 || options.length === 0) {
274
- if (props.value === void 0 || props.value === null) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
275
- return serialize(h("span", { class: "sc-value" }, JSON.stringify(props.value)));
276
- }
277
- const matched = matchUnionOption(options, props.value);
278
- if (matched !== void 0) return props.renderChild(matched, props.value);
279
- const firstOption = options[0];
280
- if (firstOption !== void 0) return props.renderChild(firstOption, props.value);
281
- return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
282
- }
283
- function renderDiscriminatedUnionHtml(props) {
284
- const options = props.options;
285
- const discriminator = props.discriminator;
286
- if (options === void 0 || options.length === 0) {
287
- if (props.value === void 0 || props.value === null) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
288
- return serialize(h("span", { class: "sc-value" }, JSON.stringify(props.value)));
289
- }
290
- const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
291
- const obj = isRecord(props.value) ? props.value : {};
292
- const discKey = discriminator ?? "";
293
- const currentDiscriminatorValue = typeof obj[discKey] === "string" ? obj[discKey] : void 0;
294
- const optionLabels = options.map((opt) => {
295
- const discriminatorField = opt.fields?.[discKey];
296
- if (discriminatorField !== void 0) {
297
- const constVal = discriminatorField.literalValues?.[0];
298
- if (typeof constVal === "string") return constVal;
299
- }
300
- return typeof opt.meta.title === "string" ? opt.meta.title : opt.type;
301
- });
302
- let activeIndex = 0;
303
- if (currentDiscriminatorValue !== void 0) {
304
- const found = optionLabels.indexOf(currentDiscriminatorValue);
305
- if (found !== -1) activeIndex = found;
306
- }
307
- const activeOption = options[activeIndex];
308
- if (props.readOnly) {
309
- if (activeOption !== void 0) return props.renderChild(activeOption, props.value);
310
- return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
311
- }
312
- const panelId = `sc-${props.path}-panel`;
313
- const children = [h("div", {
314
- role: "tablist",
315
- class: "sc-tabs",
316
- "aria-label": "Select variant"
317
- }, ...options.map((_opt, i) => {
318
- return h("button", {
319
- type: "button",
320
- role: "tab",
321
- class: i === activeIndex ? "sc-tab sc-tab--active" : "sc-tab",
322
- id: `sc-${props.path}-tab-${String(i)}`,
323
- "aria-selected": i === activeIndex ? "true" : void 0,
324
- "aria-controls": panelId,
325
- tabindex: i === activeIndex ? "0" : "-1"
326
- }, optionLabels[i]);
327
- }))];
328
- if (activeOption !== void 0) {
329
- const childHtml = props.renderChild(activeOption, props.value);
330
- children.push(h("div", {
331
- role: "tabpanel",
332
- id: panelId,
333
- "aria-labelledby": `sc-${props.path}-tab-${String(activeIndex)}`
334
- }, raw(childHtml)));
335
- }
336
- return serialize(h("div", { class: "sc-discriminated-union" }, ...children));
337
- }
338
- function renderFileHtml(props) {
339
- const id = fieldId(props.path);
340
- const accept = props.constraints.mimeTypes?.join(",");
341
- if (props.readOnly) return serialize(h("span", {
342
- class: "sc-value",
343
- id,
344
- ...ariaReadonlyAttrs()
345
- }, "File field"));
346
- const attrs = {
347
- class: "sc-input",
348
- id,
349
- type: "file",
350
- name: id
351
- };
352
- if (accept !== void 0) attrs.accept = accept;
353
- Object.assign(attrs, ariaRequiredAttrs(props.tree));
354
- if (typeof props.meta.description === "string") Object.assign(attrs, ariaLabelAttrs(props.meta.description));
355
- return serialize(h("input", attrs));
356
- }
357
- function renderUnknownHtml(props) {
358
- if (props.readOnly) {
359
- if (props.value === void 0 || props.value === null) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
360
- if (typeof props.value === "string") return serialize(h("span", { class: "sc-value" }, props.value));
361
- return serialize(h("span", { class: "sc-value" }, JSON.stringify(props.value)));
362
- }
363
- const strValue = typeof props.value === "string" ? props.value : "";
364
- const attrs = {
365
- class: "sc-input",
366
- type: "text",
367
- name: props.path
368
- };
369
- if (!props.writeOnly) attrs.value = strValue;
370
- return serialize(h("input", attrs));
371
- }
372
- function matchUnionOption(options, value) {
373
- if (typeof value === "string") return options.find((o) => o.type === "string" || o.type === "enum");
374
- if (typeof value === "number") return options.find((o) => o.type === "number");
375
- if (typeof value === "boolean") return options.find((o) => o.type === "boolean");
376
- if (Array.isArray(value)) return options.find((o) => o.type === "array");
377
- if (typeof value === "object" && value !== null) return options.find((o) => o.type === "object");
378
- }
379
- const defaultHtmlResolver = {
380
- string: renderStringHtml,
381
- number: renderNumberHtml,
382
- boolean: renderBooleanHtml,
383
- enum: renderEnumHtml,
384
- object: renderObjectHtml,
385
- array: renderArrayHtml,
386
- record: renderRecordHtml,
387
- literal: renderLiteralHtml,
388
- union: renderUnionHtml,
389
- discriminatedUnion: renderDiscriminatedUnionHtml,
390
- file: renderFileHtml,
391
- unknown: renderUnknownHtml
392
- };
393
27
  /**
394
28
  * Render a schema to an HTML string.
395
29
  *
@@ -410,9 +44,12 @@ function renderToHtml(schema, options = {}) {
410
44
  rootDocument
411
45
  });
412
46
  const resolver = options.resolver ?? defaultHtmlResolver;
413
- const renderChild = (childTree, childValue, pathSuffix) => {
414
- return renderFieldHtml(childTree, childValue, resolver, pathSuffix ?? childTree.meta.description ?? "", renderChild);
47
+ const MAX_HTML_DEPTH = 10;
48
+ const makeRenderChild = (currentDepth) => (childTree, childValue, pathSuffix) => {
49
+ if (currentDepth >= MAX_HTML_DEPTH) return `<fieldset class="sc-recursive"><em>\u21bb ${typeof childTree.meta.description === "string" ? childTree.meta.description : "schema"} (recursive)</em></fieldset>`;
50
+ return renderFieldHtml(childTree, childValue, resolver, pathSuffix ?? childTree.meta.description ?? "", makeRenderChild(currentDepth + 1));
415
51
  };
52
+ const renderChild = makeRenderChild(0);
416
53
  return renderFieldHtml(tree, options.value ?? tree.defaultValue, resolver, "", renderChild);
417
54
  }
418
55
  function renderFieldHtml(tree, value, resolver, path, renderChild) {
@@ -431,17 +68,24 @@ function renderFieldHtml(tree, value, resolver, path, renderChild) {
431
68
  tree,
432
69
  renderChild
433
70
  };
434
- if (tree.enumValues !== void 0) props.enumValues = tree.enumValues;
435
- if (tree.element !== void 0) props.element = tree.element;
436
- if (tree.fields !== void 0) props.fields = tree.fields;
437
- if (tree.options !== void 0) props.options = tree.options;
438
- if (tree.discriminator !== void 0) props.discriminator = tree.discriminator;
439
- if (tree.keyType !== void 0) props.keyType = tree.keyType;
440
- if (tree.valueType !== void 0) props.valueType = tree.valueType;
71
+ if (tree.type === "enum") props.enumValues = tree.enumValues;
72
+ if (tree.type === "array" && tree.element !== void 0) props.element = tree.element;
73
+ if (tree.type === "object") props.fields = tree.fields;
74
+ if (tree.type === "union" || tree.type === "discriminatedUnion") props.options = tree.options;
75
+ if (tree.type === "discriminatedUnion") props.discriminator = tree.discriminator;
76
+ if (tree.type === "record") props.keyType = tree.keyType;
77
+ if (tree.type === "record") props.valueType = tree.valueType;
78
+ if (tree.type === "tuple") props.prefixItems = tree.prefixItems;
79
+ if (tree.type === "conditional") props.ifClause = tree.ifClause;
80
+ if (tree.type === "conditional" && tree.thenClause !== void 0) props.thenClause = tree.thenClause;
81
+ if (tree.type === "conditional" && tree.elseClause !== void 0) props.elseClause = tree.elseClause;
82
+ if (tree.type === "negation") props.negated = tree.negated;
83
+ if (tree.type === "literal") props.literalValues = tree.literalValues;
84
+ if (tree.examples !== void 0) props.examples = tree.examples;
441
85
  return renderFn(props);
442
86
  }
443
87
  if (effectiveValue === void 0 || effectiveValue === null) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
444
88
  return serialize(h("span", { class: "sc-value" }, typeof effectiveValue === "string" ? effectiveValue : JSON.stringify(effectiveValue)));
445
89
  }
446
90
  //#endregion
447
- export { defaultHtmlResolver, renderToHtml };
91
+ export { renderToHtml };
@@ -1,57 +1,39 @@
1
- import { RenderToHtmlOptions } from "./renderToHtml.mjs";
1
+ import { w as SchemaMeta } from "../types-ag2jYLqQ.mjs";
2
+ import { o as HtmlResolver } from "../renderer-DseHeliw.mjs";
2
3
 
3
4
  //#region src/html/renderToHtmlStream.d.ts
5
+ interface StreamRenderOptions {
6
+ /** The data value to render. */
7
+ value?: unknown;
8
+ /** For OpenAPI: a ref string like "#/components/schemas/User". */
9
+ ref?: string;
10
+ /** Per-field meta overrides. */
11
+ fields?: Record<string, unknown>;
12
+ /** Meta overrides applied to the root schema. */
13
+ meta?: SchemaMeta;
14
+ /** Force all fields read-only. */
15
+ readOnly?: boolean;
16
+ /** Force all fields as inputs. */
17
+ writeOnly?: boolean;
18
+ /** Root description. */
19
+ description?: string;
20
+ /** Custom HTML resolver. Falls back to defaultHtmlResolver. */
21
+ resolver?: HtmlResolver;
22
+ }
4
23
  /**
5
- * Streaming HTML renderer yields HTML chunks incrementally.
6
- *
7
- * Same rendering pipeline as `renderToHtml` but yields string fragments
8
- * as each field/element is produced instead of building the entire string
9
- * in memory. Use for server-side rendering where you want to start
10
- * flushing the response before the full schema is rendered.
11
- *
12
- * Three output formats:
13
- *
14
- * - `renderToHtmlChunks(schema, options)` → sync `Iterable<string>`
15
- * - `renderToHtmlStream(schema, options)` → async `AsyncIterable<string>`
16
- * - `renderToHtmlReadable(schema, options)` → web `ReadableStream<string>`
17
- *
18
- * Chunk boundaries:
19
- * - Object: opening tag, one chunk per field, closing tag
20
- * - Array: opening tag, one chunk per item, closing tag
21
- * - Record: opening tag, one chunk per entry, closing tag
22
- * - Leaf types (string, number, boolean, enum, literal, unknown):
23
- * rendered entirely as one chunk
24
- *
25
- * All HTML construction uses `h()` from `html.ts` — the streaming module
26
- * manually yields the opening tag, then children, then the closing tag.
24
+ * Render a schema as an iterable of HTML string chunks.
25
+ * Each chunk is a self-contained HTML fragment.
27
26
  */
28
- type StreamRenderOptions = RenderToHtmlOptions;
27
+ declare function renderToHtmlChunks(schema: unknown, options?: StreamRenderOptions): Iterable<string>;
29
28
  /**
30
- * Render a schema to HTML string chunks, yielded incrementally.
31
- *
32
- * Each yielded chunk is a self-contained HTML fragment. Concatenating
33
- * all chunks produces the same output as `renderToHtml`.
34
- *
35
- * @returns Sync iterable of HTML string chunks
29
+ * Render a schema as an async iterable of HTML string chunks.
30
+ * Yields `undefined` between chunks to allow the event loop to process
31
+ * other tasks (cooperative scheduling).
36
32
  */
37
- declare function renderToHtmlChunks(schema: unknown, options?: StreamRenderOptions): Iterable<string, void, undefined>;
33
+ declare function renderToHtmlStream(schema: unknown, options?: StreamRenderOptions): AsyncIterable<string>;
38
34
  /**
39
- * Render a schema to HTML string chunks asynchronously.
40
- *
41
- * Identical chunk boundaries to `renderToHtmlChunks` but yields via
42
- * an async generator. Use with `for await...of` or pipe to a response.
43
- *
44
- * @returns Async iterable of HTML string chunks
45
- */
46
- declare function renderToHtmlStream(schema: unknown, options?: StreamRenderOptions): AsyncIterable<string, void, undefined>;
47
- /**
48
- * Render a schema to a web `ReadableStream<string>`.
49
- *
50
- * ```ts
51
- * return new Response(renderToHtmlReadable(schema, { value }), {
52
- * headers: { "Content-Type": "text/html" },
53
- * });
54
- * ```
35
+ * Render a schema as a web `ReadableStream<string>`.
36
+ * Uses the async rendering pipeline internally.
55
37
  */
56
38
  declare function renderToHtmlReadable(schema: unknown, options?: StreamRenderOptions): ReadableStream<string>;
57
39
  //#endregion