schema-components 1.21.0 → 1.22.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 (72) hide show
  1. package/README.md +1 -1
  2. package/dist/core/adapter.d.mts +20 -3
  3. package/dist/core/adapter.mjs +209 -28
  4. package/dist/core/constraints.d.mts +2 -2
  5. package/dist/core/diagnostics.d.mts +1 -1
  6. package/dist/core/errors.d.mts +1 -1
  7. package/dist/core/fieldOrder.d.mts +1 -1
  8. package/dist/core/formats.d.mts +22 -1
  9. package/dist/core/formats.mjs +21 -0
  10. package/dist/core/limits.d.mts +2 -0
  11. package/dist/core/limits.mjs +23 -0
  12. package/dist/core/merge.d.mts +1 -1
  13. package/dist/core/normalise.d.mts +29 -3
  14. package/dist/core/normalise.mjs +2 -2
  15. package/dist/core/openapi30.mjs +1 -1
  16. package/dist/core/ref.d.mts +1 -1
  17. package/dist/core/ref.mjs +1 -0
  18. package/dist/core/renderer.d.mts +1 -1
  19. package/dist/core/renderer.mjs +0 -2
  20. package/dist/core/swagger2.d.mts +1 -1
  21. package/dist/core/swagger2.mjs +1 -1
  22. package/dist/core/typeInference.d.mts +2 -2
  23. package/dist/core/types.d.mts +2 -2
  24. package/dist/core/types.mjs +1 -4
  25. package/dist/core/version.d.mts +1 -1
  26. package/dist/core/walkBuilders.d.mts +3 -3
  27. package/dist/core/walker.d.mts +1 -1
  28. package/dist/core/walker.mjs +79 -2
  29. package/dist/{diagnostics-CbBPsxSt.d.mts → diagnostics-D0QCYGv0.d.mts} +1 -1
  30. package/dist/{errors-QEwOtQAA.d.mts → errors-DpFwqs5C.d.mts} +1 -1
  31. package/dist/html/a11y.d.mts +2 -2
  32. package/dist/html/a11y.mjs +10 -3
  33. package/dist/html/renderToHtml.d.mts +10 -3
  34. package/dist/html/renderToHtml.mjs +13 -3
  35. package/dist/html/renderToHtmlStream.d.mts +2 -2
  36. package/dist/html/renderers.d.mts +2 -2
  37. package/dist/html/renderers.mjs +0 -5
  38. package/dist/html/streamRenderers.d.mts +5 -4
  39. package/dist/html/streamRenderers.mjs +91 -30
  40. package/dist/limits-Cw5QZND8.d.mts +29 -0
  41. package/dist/{normalise-DaSrnr8g.mjs → normalise-DVEJQmF7.mjs} +468 -115
  42. package/dist/openapi/ApiCallbacks.d.mts +1 -1
  43. package/dist/openapi/ApiLinks.d.mts +1 -1
  44. package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
  45. package/dist/openapi/ApiSecurity.d.mts +1 -1
  46. package/dist/openapi/ApiSecurity.mjs +16 -2
  47. package/dist/openapi/components.d.mts +150 -18
  48. package/dist/openapi/components.mjs +129 -15
  49. package/dist/openapi/parser.d.mts +1 -1
  50. package/dist/openapi/parser.mjs +35 -3
  51. package/dist/openapi/resolve.d.mts +12 -5
  52. package/dist/openapi/resolve.mjs +183 -23
  53. package/dist/react/SchemaComponent.d.mts +100 -35
  54. package/dist/react/SchemaComponent.mjs +59 -45
  55. package/dist/react/SchemaView.d.mts +3 -3
  56. package/dist/react/SchemaView.mjs +2 -2
  57. package/dist/react/fieldPath.d.mts +1 -1
  58. package/dist/react/headless.d.mts +1 -1
  59. package/dist/react/headless.mjs +1 -2
  60. package/dist/react/headlessRenderers.d.mts +3 -4
  61. package/dist/react/headlessRenderers.mjs +10 -30
  62. package/dist/{ref-si8ViYun.d.mts → ref-D-_JBZkF.d.mts} +1 -1
  63. package/dist/{renderer-DI6ZYf7a.d.mts → renderer-BaRlQIuN.d.mts} +2 -2
  64. package/dist/themes/mantine.d.mts +1 -1
  65. package/dist/themes/mui.d.mts +1 -1
  66. package/dist/themes/radix.d.mts +1 -1
  67. package/dist/themes/shadcn.d.mts +1 -1
  68. package/dist/typeInference-DkcUHfaM.d.mts +982 -0
  69. package/dist/{types-BnxPEElk.d.mts → types-BrRMV0en.d.mts} +3 -10
  70. package/package.json +1 -3
  71. package/dist/typeInference-Bxw3NOG1.d.mts +0 -647
  72. /package/dist/{version-D-u7aMfy.d.mts → version-D2jfdX6E.d.mts} +0 -0
@@ -1,2 +1,2 @@
1
- import { o as normaliseSwagger2Document } from "../normalise-DaSrnr8g.mjs";
1
+ import { s as normaliseSwagger2Document } from "../normalise-DVEJQmF7.mjs";
2
2
  export { normaliseSwagger2Document };
@@ -1,2 +1,2 @@
1
- import { a as InferResponseFields, c as PathOfType, d as TypeAtPath, f as UnrepresentableZodSchemaError, h as __SchemaInferenceFellBack, i as InferRequestBodyFields, l as RejectUnrepresentableZod, m as UnsafeFields, n as FromJSONSchema, o as OpenAPIRequestBodyType, p as UnrepresentableZodType, r as InferParameterOverrides, s as OpenAPIResponseType, t as DEFAULT_MAX_DEPTH, u as ResolveOpenAPIRef } from "../typeInference-Bxw3NOG1.mjs";
2
- export { DEFAULT_MAX_DEPTH, FromJSONSchema, InferParameterOverrides, InferRequestBodyFields, InferResponseFields, OpenAPIRequestBodyType, OpenAPIResponseType, PathOfType, RejectUnrepresentableZod, ResolveOpenAPIRef, TypeAtPath, UnrepresentableZodSchemaError, UnrepresentableZodType, UnsafeFields, __SchemaInferenceFellBack };
1
+ import { _ as __SchemaInferenceFellBack, a as InferParameterOverrides, c as OpenAPIRequestBodyType, d as RejectUnrepresentableZod, f as ResolveOpenAPIRef, g as UnsafeFields, h as UnrepresentableZodType, i as FromJSONSchemaMode, l as OpenAPIResponseType, m as UnrepresentableZodSchemaError, n as DEFAULT_OPENAPI_CONTENT_TYPE, o as InferRequestBodyFields, p as TypeAtPath, r as FromJSONSchema, s as InferResponseFields, t as DEFAULT_MAX_DEPTH, u as PathOfType } from "../typeInference-DkcUHfaM.mjs";
2
+ export { DEFAULT_MAX_DEPTH, DEFAULT_OPENAPI_CONTENT_TYPE, FromJSONSchema, FromJSONSchemaMode, InferParameterOverrides, InferRequestBodyFields, InferResponseFields, OpenAPIRequestBodyType, OpenAPIResponseType, PathOfType, RejectUnrepresentableZod, ResolveOpenAPIRef, TypeAtPath, UnrepresentableZodSchemaError, UnrepresentableZodType, UnsafeFields, __SchemaInferenceFellBack };
@@ -1,2 +1,2 @@
1
- import { A as UnionField, B as isNegationField, C as RecordField, D as StringConstraints, E as SchemaType, F as isConditionalField, G as isRecordField, H as isNullField, I as isDiscriminatedUnionField, J as isTupleField, K as isRecursiveField, L as isEnumField, M as WalkedField, N as isArrayField, O as StringField, P as isBooleanField, R as isFileField, S as ObjectField, T as SchemaMeta, U as isNumberField, V as isNeverField, W as isObjectField, X as isUnknownField, Y as isUnionField, Z as resolveEditability, _ as NeverField, a as DiscriminatedUnionField, b as NumberField, c as FieldBase, d as FieldOverrides, f as FileConstraints, g as NegationField, h as LiteralField, i as ConditionalField, j as UnknownField, k as TupleField, l as FieldConstraints, m as JsonObject, n as ArrayField, o as Editability, p as FileField, q as isStringField, r as BooleanField, s as EnumField, t as ArrayConstraints, u as FieldOverride, v as NullField, w as RecursiveField, x as ObjectConstraints, y as NumberConstraints, z as isLiteralField } from "../types-BnxPEElk.mjs";
2
- export { ArrayConstraints, ArrayField, BooleanField, ConditionalField, DiscriminatedUnionField, Editability, EnumField, FieldBase, FieldConstraints, FieldOverride, FieldOverrides, FileConstraints, FileField, JsonObject, LiteralField, NegationField, NeverField, NullField, NumberConstraints, NumberField, ObjectConstraints, ObjectField, RecordField, RecursiveField, SchemaMeta, SchemaType, StringConstraints, StringField, TupleField, UnionField, UnknownField, WalkedField, isArrayField, isBooleanField, isConditionalField, isDiscriminatedUnionField, isEnumField, isFileField, isLiteralField, isNegationField, isNeverField, isNullField, isNumberField, isObjectField, isRecordField, isRecursiveField, isStringField, isTupleField, isUnionField, isUnknownField, resolveEditability };
1
+ import { A as UnknownField, B as isNeverField, C as RecordField, D as StringField, E as StringConstraints, F as isDiscriminatedUnionField, G as isStringField, H as isNumberField, I as isEnumField, J as isUnknownField, K as isTupleField, L as isFileField, M as isArrayField, N as isBooleanField, O as TupleField, P as isConditionalField, R as isLiteralField, S as ObjectField, T as SchemaType, U as isObjectField, V as isNullField, W as isRecordField, Y as resolveEditability, _ as NeverField, a as DiscriminatedUnionField, b as NumberField, c as FieldBase, d as FieldOverrides, f as FileConstraints, g as NegationField, h as LiteralField, i as ConditionalField, j as WalkedField, k as UnionField, l as FieldConstraints, m as JsonObject, n as ArrayField, o as Editability, p as FileField, q as isUnionField, r as BooleanField, s as EnumField, t as ArrayConstraints, u as FieldOverride, v as NullField, w as SchemaMeta, x as ObjectConstraints, y as NumberConstraints, z as isNegationField } from "../types-BrRMV0en.mjs";
2
+ export { ArrayConstraints, ArrayField, BooleanField, ConditionalField, DiscriminatedUnionField, Editability, EnumField, FieldBase, FieldConstraints, FieldOverride, FieldOverrides, FileConstraints, FileField, JsonObject, LiteralField, NegationField, NeverField, NullField, NumberConstraints, NumberField, ObjectConstraints, ObjectField, RecordField, SchemaMeta, SchemaType, StringConstraints, StringField, TupleField, UnionField, UnknownField, WalkedField, isArrayField, isBooleanField, isConditionalField, isDiscriminatedUnionField, isEnumField, isFileField, isLiteralField, isNegationField, isNeverField, isNullField, isNumberField, isObjectField, isRecordField, isStringField, isTupleField, isUnionField, isUnknownField, resolveEditability };
@@ -83,9 +83,6 @@ function isNegationField(field) {
83
83
  function isFileField(field) {
84
84
  return isField(field, "file");
85
85
  }
86
- function isRecursiveField(field) {
87
- return isField(field, "recursive");
88
- }
89
86
  function isNeverField(field) {
90
87
  return isField(field, "never");
91
88
  }
@@ -93,4 +90,4 @@ function isUnknownField(field) {
93
90
  return isField(field, "unknown");
94
91
  }
95
92
  //#endregion
96
- export { isArrayField, isBooleanField, isConditionalField, isDiscriminatedUnionField, isEnumField, isFileField, isLiteralField, isNegationField, isNeverField, isNullField, isNumberField, isObjectField, isRecordField, isRecursiveField, isStringField, isTupleField, isUnionField, isUnknownField, resolveEditability };
93
+ export { isArrayField, isBooleanField, isConditionalField, isDiscriminatedUnionField, isEnumField, isFileField, isLiteralField, isNegationField, isNeverField, isNullField, isNumberField, isObjectField, isRecordField, isStringField, isTupleField, isUnionField, isUnknownField, resolveEditability };
@@ -1,2 +1,2 @@
1
- import { a as detectJsonSchemaDraft, c as inferJsonSchemaDraftWithReason, d as isSwagger2, f as matchJsonSchemaDraftUri, i as OpenApiVersionInfo, l as isOpenApi30, n as JsonSchemaDialectInfo, o as detectOpenApiVersion, p as readJsonSchemaDialect, r as JsonSchemaDraft, s as inferJsonSchemaDraft, t as InferredDraft, u as isOpenApi31 } from "../version-D-u7aMfy.mjs";
1
+ import { a as detectJsonSchemaDraft, c as inferJsonSchemaDraftWithReason, d as isSwagger2, f as matchJsonSchemaDraftUri, i as OpenApiVersionInfo, l as isOpenApi30, n as JsonSchemaDialectInfo, o as detectOpenApiVersion, p as readJsonSchemaDialect, r as JsonSchemaDraft, s as inferJsonSchemaDraft, t as InferredDraft, u as isOpenApi31 } from "../version-D2jfdX6E.mjs";
2
2
  export { InferredDraft, JsonSchemaDialectInfo, JsonSchemaDraft, OpenApiVersionInfo, detectJsonSchemaDraft, detectOpenApiVersion, inferJsonSchemaDraft, inferJsonSchemaDraftWithReason, isOpenApi30, isOpenApi31, isSwagger2, matchJsonSchemaDraftUri, readJsonSchemaDialect };
@@ -1,6 +1,6 @@
1
- import { M as WalkedField, O as StringField, T as SchemaMeta, b as NumberField, c as FieldBase, j as UnknownField, o as Editability, p as FileField, r as BooleanField, v as NullField } from "../types-BnxPEElk.mjs";
2
- import { i as DiagnosticsOptions } from "../diagnostics-CbBPsxSt.mjs";
3
- import { t as ExternalResolver } from "../ref-si8ViYun.mjs";
1
+ import { A as UnknownField, D as StringField, b as NumberField, c as FieldBase, j as WalkedField, o as Editability, p as FileField, r as BooleanField, v as NullField, w as SchemaMeta } from "../types-BrRMV0en.mjs";
2
+ import { i as DiagnosticsOptions } from "../diagnostics-D0QCYGv0.mjs";
3
+ import { t as ExternalResolver } from "../ref-D-_JBZkF.mjs";
4
4
 
5
5
  //#region src/core/walkBuilders.d.ts
6
6
  declare function getString(obj: Record<string, unknown>, key: string): string | undefined;
@@ -1,4 +1,4 @@
1
- import { M as WalkedField } from "../types-BnxPEElk.mjs";
1
+ import { j as WalkedField } from "../types-BrRMV0en.mjs";
2
2
  import { WalkOptions } from "./walkBuilders.mjs";
3
3
 
4
4
  //#region src/core/walker.d.ts
@@ -2,6 +2,7 @@ import { isObject } from "./guards.mjs";
2
2
  import { appendPointer, emitDiagnostic } from "./diagnostics.mjs";
3
3
  import { isPrototypePollutingKey } from "./uri.mjs";
4
4
  import { countDistinctRefs, resolveRef } from "./ref.mjs";
5
+ import { matchJsonSchemaDraftUri } from "./version.mjs";
5
6
  import { extractArrayConstraints, extractObjectConstraints, stripInapplicableConstraints } from "./constraints.mjs";
6
7
  import { ANNOTATION_SIBLINGS, detectDiscriminated, mergeAllOf, mergeRefSiblings, normaliseAnyOf } from "./merge.mjs";
7
8
  import { buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, extractChildOverride, extractSchemaMetaFields, getArray, getObject, getString, isPrimitive, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys } from "./walkBuilders.mjs";
@@ -40,6 +41,55 @@ function walkSubSchema(value, ctx) {
40
41
  constraints: {}
41
42
  };
42
43
  }
44
+ /**
45
+ * Rank an `unevaluatedProperties`/`unevaluatedItems` value by how
46
+ * restrictive it is. Higher is stricter. The ordering reflects
47
+ * JSON Schema 2020-12 §11.2/§11.3 semantics:
48
+ *
49
+ * false (forbid all extras)
50
+ * > schema-object (extras must match the schema)
51
+ * > true (extras explicitly permitted)
52
+ * > absent (extras implicitly permitted)
53
+ *
54
+ * Unknown shapes (numbers, arrays, strings) sort below absent — we
55
+ * cannot reason about them, so do not let them override anything.
56
+ */
57
+ function unevaluatedRank(value) {
58
+ if (value === false) return 3;
59
+ if (isObject(value)) return 2;
60
+ if (value === true) return 1;
61
+ if (value === void 0) return 0;
62
+ return -1;
63
+ }
64
+ /**
65
+ * Pick the strictest `unevaluatedProperties` / `unevaluatedItems` across
66
+ * a set of `allOf` branches (including the parent prepended as a
67
+ * branch) and apply it to the merged node. `mergeAllOf` already collects
68
+ * properties from every branch into the merged result; surfacing the
69
+ * strictest unevaluated keyword closes the loop so the walker's object
70
+ * builder sees the spec-correct value.
71
+ *
72
+ * The merged node is mutated in place — that is consistent with the
73
+ * surrounding walker code, which treats the merge output as a fresh
74
+ * working node.
75
+ */
76
+ function applyStrictestUnevaluated(merged, branches) {
77
+ let strictestProps = merged.unevaluatedProperties;
78
+ let strictestItems = merged.unevaluatedItems;
79
+ for (const branch of branches) {
80
+ if (!isObject(branch)) continue;
81
+ if ("unevaluatedProperties" in branch) {
82
+ const candidate = branch.unevaluatedProperties;
83
+ if (unevaluatedRank(candidate) > unevaluatedRank(strictestProps)) strictestProps = candidate;
84
+ }
85
+ if ("unevaluatedItems" in branch) {
86
+ const candidate = branch.unevaluatedItems;
87
+ if (unevaluatedRank(candidate) > unevaluatedRank(strictestItems)) strictestItems = candidate;
88
+ }
89
+ }
90
+ if (strictestProps !== void 0) merged.unevaluatedProperties = strictestProps;
91
+ if (strictestItems !== void 0) merged.unevaluatedItems = strictestItems;
92
+ }
43
93
  function walk(schema, options = {}) {
44
94
  const { componentMeta, rootMeta, fieldOverrides, rootDocument, diagnostics, externalResolver } = options;
45
95
  if (typeof schema === "boolean") return walkBooleanSchema(schema);
@@ -76,8 +126,10 @@ function walk(schema, options = {}) {
76
126
  function walkNode(schema, ctx) {
77
127
  const allOf = getArray(schema, "allOf");
78
128
  if (allOf !== void 0 && allOf.length > 0) {
79
- const merged = mergeAllOf(allOf, ctx.diagnostics, ctx.pointer);
129
+ const branches = [withoutKeys(schema, ["allOf"]), ...allOf];
130
+ const merged = mergeAllOf(branches, ctx.diagnostics, ctx.pointer);
80
131
  if (merged === false) return walkBooleanSchema(false);
132
+ applyStrictestUnevaluated(merged, branches);
81
133
  return walkNode(merged, ctx);
82
134
  }
83
135
  const anyOf = getArray(schema, "anyOf");
@@ -227,11 +279,36 @@ function walkNode(schema, ctx) {
227
279
  });
228
280
  return buildUnknownField(schema, ctx);
229
281
  }
282
+ /**
283
+ * Drafts that pre-date the `contentSchema` keyword (added in Draft
284
+ * 2019-09). Used to emit `keyword-out-of-draft` when a document
285
+ * declaring one of these drafts uses `contentSchema` anyway.
286
+ */
287
+ const PRE_CONTENT_SCHEMA_DRAFTS = new Set([
288
+ "draft-04",
289
+ "draft-06",
290
+ "draft-07"
291
+ ]);
230
292
  function walkString(schema, ctx) {
231
293
  if (getString(schema, "format") === "binary") return buildFileField(schema, ctx);
232
294
  const field = buildStringField(schema, ctx);
233
295
  const contentSchema = getObject(schema, "contentSchema");
234
- if (contentSchema !== void 0) field.meta.decodedSchema = walkNode(contentSchema, ctx);
296
+ if (contentSchema !== void 0) {
297
+ const rootSchema = getString(ctx.rootDocument, "$schema");
298
+ if (rootSchema !== void 0) {
299
+ const draft = matchJsonSchemaDraftUri(rootSchema);
300
+ if (draft !== void 0 && PRE_CONTENT_SCHEMA_DRAFTS.has(draft)) emitDiagnostic(ctx.diagnostics, {
301
+ code: "keyword-out-of-draft",
302
+ message: `\`contentSchema\` is a Draft 2019-09+ keyword; the document declares ${draft}`,
303
+ pointer: appendPointer(ctx.pointer, "contentSchema"),
304
+ detail: {
305
+ keyword: "contentSchema",
306
+ declaredDraft: draft
307
+ }
308
+ });
309
+ }
310
+ field.meta.decodedSchema = walkNode(contentSchema, ctx);
311
+ }
235
312
  return field;
236
313
  }
237
314
  function walkNumber(schema, ctx) {
@@ -16,7 +16,7 @@
16
16
  * Machine-readable codes identifying each class of diagnostic.
17
17
  * Stable across releases — consumers can pattern-match on these.
18
18
  */
19
- type DiagnosticCode = "unresolved-ref" | "unknown-keyword" | "unknown-format" | "invalid-const" | "unsupported-type" | "dropped-swagger-feature" | "external-ref" | "type-negation-fallback" | "conditional-fallback" | "assumed-draft" | "depth-exceeded" | "allof-conflict" | "discriminator-inconsistent" | "divisible-by-conflict" | "legacy-dependencies-split" | "dependent-required-invalid" | "unknown-json-schema-dialect" | "relative-ref-resolved" | "bare-exclusive-bound" | "enum-value-filtered" | "required-non-string" | "pattern-invalid" | "duplicate-body-parameter" | "prototype-polluting-property";
19
+ type DiagnosticCode = "unresolved-ref" | "unknown-keyword" | "unknown-format" | "invalid-const" | "invalid-id-fragment" | "unsupported-type" | "dropped-swagger-feature" | "dynamic-ref-degraded" | "external-ref" | "type-negation-fallback" | "conditional-fallback" | "assumed-draft" | "depth-exceeded" | "allof-conflict" | "discriminator-inconsistent" | "divisible-by-conflict" | "keyword-out-of-draft" | "legacy-dependencies-split" | "dependent-required-invalid" | "unknown-json-schema-dialect" | "unknown-openapi-version" | "relative-ref-resolved" | "bare-exclusive-bound" | "enum-value-filtered" | "required-non-string" | "pattern-invalid" | "duplicate-body-parameter" | "prototype-polluting-property" | "cross-schema-relative-ref-unsupported" | "cyclic-path-item-ref" | "doc-not-object" | "path-item-ref-too-deep" | "swagger-cyclic-parameter-ref" | "swagger-invalid-file-parameter" | "swagger-missing-consumes" | "swagger-missing-host" | "type-mismatch" | "unknown-security-scheme-type" | "zod-codec-output-only";
20
20
  /**
21
21
  * A single diagnostic emitted during schema processing.
22
22
  */
@@ -32,7 +32,7 @@ declare class SchemaError extends Error {
32
32
  * JSON Schema, missing OpenAPI ref, unsupported ref format.
33
33
  */
34
34
  declare class SchemaNormalisationError extends SchemaError {
35
- readonly kind: "invalid-zod" | "zod3-unsupported" | "zod-transform-unsupported" | "zod-type-unrepresentable" | "zod-conversion-failed" | "zod-conversion-bug" | "zod-cycle-detected" | "zod-duplicate-id" | "invalid-json-schema" | "openapi-missing-ref" | "openapi-invalid" | "unknown";
35
+ readonly kind: "invalid-zod" | "unsupported-schema" | "zod3-unsupported" | "zod-transform-unsupported" | "zod-type-unrepresentable" | "zod-conversion-failed" | "zod-conversion-bug" | "zod-cycle-detected" | "zod-duplicate-id" | "invalid-json-schema" | "openapi-missing-ref" | "openapi-invalid" | "unknown";
36
36
  /**
37
37
  * For `zod-type-unrepresentable`, the offending Zod type name
38
38
  * (e.g. "bigint", "date", "map", "set"). `undefined` for other kinds.
@@ -1,5 +1,5 @@
1
- import { M as WalkedField } from "../types-BnxPEElk.mjs";
2
- import { t as AllConstraints } from "../renderer-DI6ZYf7a.mjs";
1
+ import { j as WalkedField } from "../types-BrRMV0en.mjs";
2
+ import { t as AllConstraints } from "../renderer-BaRlQIuN.mjs";
3
3
  import { HtmlAttributes, HtmlNode } from "./html.mjs";
4
4
 
5
5
  //#region src/html/a11y.d.ts
@@ -18,11 +18,18 @@ function joinPath(parent, suffix) {
18
18
  }
19
19
  /**
20
20
  * Normalise a path into the id segment used after the `sc-` prefix.
21
- * Dots (object nesting) and brackets (array indices) become hyphens so
22
- * the id remains a valid CSS selector and matches test query semantics.
21
+ *
22
+ * Whitelist-based: every character outside `[A-Za-z0-9_-]` collapses to
23
+ * a single hyphen. A blacklist that only stripped `.[]` would still leak
24
+ * spaces, slashes, and other punctuation through into ids when a path
25
+ * is sourced from a free-text field like `meta.description` — producing
26
+ * structurally invalid CSS selectors and `aria-labelledby` references.
27
+ *
28
+ * Trailing hyphens are trimmed so e.g. `tags[0]` → `tags-0` (not
29
+ * `tags-0-`).
23
30
  */
24
31
  function normaliseIdSegment(value) {
25
- return value.replace(/[.[\]]+/g, "-").replace(/-+$/g, "");
32
+ return value.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/-+$/g, "");
26
33
  }
27
34
  /**
28
35
  * Build the input ID for a field at a given path.
@@ -1,7 +1,14 @@
1
- import { T as SchemaMeta } from "../types-BnxPEElk.mjs";
2
- import { o as HtmlResolver } from "../renderer-DI6ZYf7a.mjs";
1
+ import { w as SchemaMeta } from "../types-BrRMV0en.mjs";
2
+ import { o as HtmlResolver } from "../renderer-BaRlQIuN.mjs";
3
3
 
4
4
  //#region src/html/renderToHtml.d.ts
5
+ /**
6
+ * Build the recursion-cap sentinel element. The label is interpolated
7
+ * via `h()` + `serialize` so any HTML in `meta.description` (which is
8
+ * schema-author content but can equally be sourced from user-supplied
9
+ * JSON Schema input) is escaped — never interpolated into raw markup.
10
+ */
11
+ declare function recursionSentinelHtml(label: string): string;
5
12
  interface RenderToHtmlOptions {
6
13
  /** The data value to render. */
7
14
  value?: unknown;
@@ -29,4 +36,4 @@ interface RenderToHtmlOptions {
29
36
  */
30
37
  declare function renderToHtml(schema: unknown, options?: RenderToHtmlOptions): string;
31
38
  //#endregion
32
- export { RenderToHtmlOptions, renderToHtml };
39
+ export { RenderToHtmlOptions, recursionSentinelHtml, renderToHtml };
@@ -1,6 +1,8 @@
1
+ import "../core/limits.mjs";
1
2
  import { normaliseSchema } from "../core/adapter.mjs";
2
3
  import { getHtmlRenderFn, mergeHtmlResolvers } from "../core/renderer.mjs";
3
4
  import { walk } from "../core/walker.mjs";
5
+ import { h, serialize } from "./html.mjs";
4
6
  import { joinPath } from "./a11y.mjs";
5
7
  import { defaultHtmlResolver } from "./renderers.mjs";
6
8
  //#region src/html/renderToHtml.ts
@@ -25,6 +27,15 @@ import { defaultHtmlResolver } from "./renderers.mjs";
25
27
  * });
26
28
  */
27
29
  /**
30
+ * Build the recursion-cap sentinel element. The label is interpolated
31
+ * via `h()` + `serialize` so any HTML in `meta.description` (which is
32
+ * schema-author content but can equally be sourced from user-supplied
33
+ * JSON Schema input) is escaped — never interpolated into raw markup.
34
+ */
35
+ function recursionSentinelHtml(label) {
36
+ return serialize(h("fieldset", { class: "sc-recursive" }, h("em", {}, `↻ ${label} (recursive)`)));
37
+ }
38
+ /**
28
39
  * Render a schema to an HTML string.
29
40
  *
30
41
  * @param schema - Zod schema, JSON Schema, or OpenAPI document
@@ -44,9 +55,8 @@ function renderToHtml(schema, options = {}) {
44
55
  rootDocument
45
56
  });
46
57
  const resolver = options.resolver ?? defaultHtmlResolver;
47
- const MAX_HTML_DEPTH = 10;
48
58
  const makeRenderChild = (currentDepth, parentPath) => (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>`;
59
+ if (currentDepth >= 10) return recursionSentinelHtml(typeof childTree.meta.description === "string" ? childTree.meta.description : "schema");
50
60
  const childPath = joinPath(parentPath, pathSuffix);
51
61
  return renderFieldHtml(childTree, childValue, resolver, childPath, makeRenderChild(currentDepth + 1, childPath));
52
62
  };
@@ -73,4 +83,4 @@ function renderFieldHtml(tree, value, resolver, path, renderChild) {
73
83
  return renderFn(props);
74
84
  }
75
85
  //#endregion
76
- export { renderToHtml };
86
+ export { recursionSentinelHtml, renderToHtml };
@@ -1,5 +1,5 @@
1
- import { T as SchemaMeta } from "../types-BnxPEElk.mjs";
2
- import { o as HtmlResolver } from "../renderer-DI6ZYf7a.mjs";
1
+ import { w as SchemaMeta } from "../types-BrRMV0en.mjs";
2
+ import { o as HtmlResolver } from "../renderer-BaRlQIuN.mjs";
3
3
 
4
4
  //#region src/html/renderToHtmlStream.d.ts
5
5
  interface StreamRenderOptions {
@@ -1,5 +1,5 @@
1
- import { M as WalkedField } from "../types-BnxPEElk.mjs";
2
- import { o as HtmlResolver } from "../renderer-DI6ZYf7a.mjs";
1
+ import { j as WalkedField } from "../types-BrRMV0en.mjs";
2
+ import { o as HtmlResolver } from "../renderer-BaRlQIuN.mjs";
3
3
 
4
4
  //#region src/html/renderers.d.ts
5
5
  declare function dateInputType(format: string | undefined): string | undefined;
@@ -334,10 +334,6 @@ function renderFileHtml(props) {
334
334
  if (typeof props.meta.description === "string") Object.assign(attrs, ariaLabelAttrs(props.meta.description));
335
335
  return serialize(h("input", attrs));
336
336
  }
337
- function renderRecursiveHtml(props) {
338
- const refTarget = props.tree.type === "recursive" ? props.tree.refTarget : "";
339
- return serialize(h("fieldset", { class: "sc-recursive" }, `↻ ${typeof props.meta.description === "string" ? props.meta.description : refTarget} (recursive)`));
340
- }
341
337
  function renderUnknownHtml(props) {
342
338
  if (props.readOnly) {
343
339
  if (props.value === void 0 || props.value === null) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
@@ -433,7 +429,6 @@ const defaultHtmlResolver = {
433
429
  discriminatedUnion: renderDiscriminatedUnionHtml,
434
430
  conditional: renderConditionalHtml,
435
431
  negation: renderNegationHtml,
436
- recursive: renderRecursiveHtml,
437
432
  file: renderFileHtml,
438
433
  never: renderNeverHtml,
439
434
  unknown: renderUnknownHtml
@@ -1,13 +1,14 @@
1
- import { M as WalkedField } from "../types-BnxPEElk.mjs";
2
- import { o as HtmlResolver } from "../renderer-DI6ZYf7a.mjs";
1
+ import { j as WalkedField } from "../types-BrRMV0en.mjs";
2
+ import { i as DiagnosticsOptions } from "../diagnostics-D0QCYGv0.mjs";
3
+ import { o as HtmlResolver } from "../renderer-BaRlQIuN.mjs";
3
4
  import { HtmlElement } from "./html.mjs";
4
5
 
5
6
  //#region src/html/streamRenderers.d.ts
6
7
  declare function yieldOpen(el: HtmlElement): string;
7
8
  declare function yieldClose(el: HtmlElement): string;
8
9
  declare function renderLeaf(tree: WalkedField, value: unknown, mergedResolver: HtmlResolver, path: string): string;
9
- declare function renderFieldSync(tree: WalkedField, value: unknown, mergedResolver: HtmlResolver, path: string, rawResolver: HtmlResolver): string;
10
+ declare function renderFieldSync(tree: WalkedField, value: unknown, mergedResolver: HtmlResolver, path: string, rawResolver: HtmlResolver, currentDepth: number, diagnostics: DiagnosticsOptions | undefined): string;
10
11
  declare function matchUnionOption(options: WalkedField[], value: unknown): WalkedField | undefined;
11
- declare function streamField(tree: WalkedField, value: unknown, mergedResolver: HtmlResolver, path: string, rawResolver: HtmlResolver): Iterable<string, void, undefined>;
12
+ declare function streamField(tree: WalkedField, value: unknown, mergedResolver: HtmlResolver, path: string, rawResolver: HtmlResolver, currentDepth?: number, diagnostics?: DiagnosticsOptions): Iterable<string, void, undefined>;
12
13
  //#endregion
13
14
  export { matchUnionOption, renderFieldSync, renderLeaf, streamField, yieldClose, yieldOpen };
@@ -1,7 +1,10 @@
1
1
  import { isObject } from "../core/guards.mjs";
2
+ import "../core/limits.mjs";
3
+ import { emitDiagnostic } from "../core/diagnostics.mjs";
2
4
  import { getHtmlRenderFn } from "../core/renderer.mjs";
3
5
  import { VOID_ELEMENTS, h, raw, serialize, serializeAttributes } from "./html.mjs";
4
- import { ariaLabelAttrs, buildHintElement, buildInputId, requiredIndicator } from "./a11y.mjs";
6
+ import { ariaLabelAttrs, buildHintElement, buildInputId, joinPath, requiredIndicator } from "./a11y.mjs";
7
+ import { recursionSentinelHtml } from "./renderToHtml.mjs";
5
8
  //#region src/html/streamRenderers.ts
6
9
  function yieldOpen(el) {
7
10
  const attrStr = serializeAttributes(el.attributes);
@@ -27,8 +30,8 @@ function renderLeaf(tree, value, mergedResolver, path) {
27
30
  if (value === void 0 || value === null) return serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
28
31
  return serialize(h("span", { class: "sc-value" }, typeof value === "string" ? value : JSON.stringify(value)));
29
32
  }
30
- function renderFieldSync(tree, value, mergedResolver, path, rawResolver) {
31
- return [...streamField(tree, value, mergedResolver, path, rawResolver)].join("");
33
+ function renderFieldSync(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
34
+ return [...streamField(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics)].join("");
32
35
  }
33
36
  function matchUnionOption(options, value) {
34
37
  if (typeof value === "string") return options.find((o) => o.type === "string" || o.type === "enum");
@@ -37,7 +40,26 @@ function matchUnionOption(options, value) {
37
40
  if (Array.isArray(value)) return options.find((o) => o.type === "array");
38
41
  if (typeof value === "object" && value !== null) return options.find((o) => o.type === "object");
39
42
  }
40
- function* streamField(tree, value, mergedResolver, path, rawResolver) {
43
+ /**
44
+ * Build a visible placeholder element used when a value does not match
45
+ * the shape implied by its field type. The expected-shape label is
46
+ * passed verbatim into `h()` so the serialiser escapes it.
47
+ *
48
+ * Streaming must keep producing output, so we never throw here — the
49
+ * diagnostic surfaces the problem to the caller (when a sink is wired)
50
+ * while the rendered output remains structurally valid.
51
+ */
52
+ function typeMismatchPlaceholder(expectedShape) {
53
+ return serialize(h("span", {
54
+ class: "sc-value sc-value--invalid",
55
+ role: "alert"
56
+ }, `invalid value (expected ${expectedShape})`));
57
+ }
58
+ function* streamField(tree, value, mergedResolver, path, rawResolver, currentDepth = 0, diagnostics) {
59
+ if (currentDepth >= 10) {
60
+ yield recursionSentinelHtml(typeof tree.meta.description === "string" ? tree.meta.description : "schema");
61
+ return;
62
+ }
41
63
  const effectiveValue = value ?? tree.defaultValue;
42
64
  const type = tree.type;
43
65
  if (type === "string" || type === "number" || type === "boolean" || type === "enum" || type === "literal" || type === "file" || type === "unknown") {
@@ -45,30 +67,44 @@ function* streamField(tree, value, mergedResolver, path, rawResolver) {
45
67
  return;
46
68
  }
47
69
  if (type === "union") {
48
- yield* streamUnion(tree, effectiveValue, mergedResolver, path, rawResolver);
70
+ yield* streamUnion(tree, effectiveValue, mergedResolver, path, rawResolver, currentDepth, diagnostics);
49
71
  return;
50
72
  }
51
73
  if (type === "discriminatedUnion") {
52
- yield* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolver);
74
+ yield* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics);
53
75
  return;
54
76
  }
55
77
  if (type === "object") {
56
- yield* streamObject(tree, value, mergedResolver, path, rawResolver);
78
+ yield* streamObject(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics);
57
79
  return;
58
80
  }
59
81
  if (type === "array") {
60
- yield* streamArray(tree, value, mergedResolver, path, rawResolver);
82
+ yield* streamArray(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics);
61
83
  return;
62
84
  }
63
85
  if (type === "record") {
64
- yield* streamRecord(tree, value, mergedResolver, path, rawResolver);
86
+ yield* streamRecord(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics);
65
87
  return;
66
88
  }
67
89
  yield renderLeaf(tree, value, mergedResolver, path);
68
90
  }
69
- function* streamObject(tree, value, mergedResolver, path, rawResolver) {
91
+ function* streamObject(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
70
92
  if (tree.type !== "object") return;
71
93
  const fields = tree.fields;
94
+ if (value !== void 0 && value !== null && !isObject(value)) {
95
+ emitDiagnostic(diagnostics, {
96
+ code: "type-mismatch",
97
+ message: "Object schema received non-object value during streaming render",
98
+ pointer: path === "" ? "/" : `/${path}`,
99
+ detail: {
100
+ expected: "object",
101
+ actualType: typeof value,
102
+ path
103
+ }
104
+ });
105
+ yield typeMismatchPlaceholder("object");
106
+ return;
107
+ }
72
108
  const obj = isObject(value) ? value : {};
73
109
  const readOnly = tree.editability === "presentation";
74
110
  const descriptionText = typeof tree.meta.description === "string" ? tree.meta.description : void 0;
@@ -82,7 +118,7 @@ function* streamObject(tree, value, mergedResolver, path, rawResolver) {
82
118
  for (const [key, field] of Object.entries(fields)) {
83
119
  const label = typeof field.meta.description === "string" ? field.meta.description : key;
84
120
  const childValue = obj[key];
85
- const childHtml = renderFieldSync(field, childValue, mergedResolver, key, rawResolver);
121
+ const childHtml = renderFieldSync(field, childValue, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics);
86
122
  yield `${serialize(h("dt", { class: "sc-label" }, label))}${serialize(h("dd", { class: "sc-value" }, raw(childHtml)))}`;
87
123
  }
88
124
  yield yieldClose(dl);
@@ -96,7 +132,7 @@ function* streamObject(tree, value, mergedResolver, path, rawResolver) {
96
132
  const label = typeof field.meta.description === "string" ? field.meta.description : key;
97
133
  const fieldId = buildInputId(path, key);
98
134
  const childValue = obj[key];
99
- const childChunks = [...streamField(field, childValue, mergedResolver, key, rawResolver)].join("");
135
+ const childChunks = [...streamField(field, childValue, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics)].join("");
100
136
  const required = requiredIndicator(field);
101
137
  const labelContent = [label];
102
138
  if (required !== void 0) labelContent.push(required);
@@ -111,29 +147,55 @@ function* streamObject(tree, value, mergedResolver, path, rawResolver) {
111
147
  yield yieldClose(fieldset);
112
148
  }
113
149
  }
114
- function* streamArray(tree, value, mergedResolver, path, rawResolver) {
115
- const arr = Array.isArray(value) ? value : [];
150
+ function* streamArray(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
116
151
  if (tree.type !== "array") return;
117
152
  const element = tree.element;
118
153
  if (element === void 0) return;
119
- const readOnly = tree.editability === "presentation";
120
- const elementPath = typeof element.meta.description === "string" ? element.meta.description : "";
121
- if (readOnly) {
154
+ if (value !== void 0 && value !== null && !Array.isArray(value)) {
155
+ emitDiagnostic(diagnostics, {
156
+ code: "type-mismatch",
157
+ message: "Array schema received non-array value during streaming render",
158
+ pointer: path === "" ? "/" : `/${path}`,
159
+ detail: {
160
+ expected: "array",
161
+ actualType: typeof value,
162
+ path
163
+ }
164
+ });
165
+ yield typeMismatchPlaceholder("array");
166
+ return;
167
+ }
168
+ const arr = Array.isArray(value) ? value : [];
169
+ if (tree.editability === "presentation") {
122
170
  const ul = h("ul", { class: "sc-array" });
123
171
  yield yieldOpen(ul);
124
- for (const item of arr) yield serialize(h("li", { class: "sc-item" }, raw(renderFieldSync(element, item, mergedResolver, elementPath, rawResolver))));
172
+ 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))));
125
173
  yield yieldClose(ul);
126
174
  } else {
127
175
  const div = h("div", { class: "sc-array" });
128
176
  yield yieldOpen(div);
129
- for (const item of arr) yield serialize(h("div", {}, raw(renderFieldSync(element, item, mergedResolver, elementPath, rawResolver))));
177
+ for (const [i, item] of arr.entries()) yield serialize(h("div", {}, raw(renderFieldSync(element, item, mergedResolver, joinPath(path, `[${String(i)}]`), rawResolver, currentDepth + 1, diagnostics))));
130
178
  yield yieldClose(div);
131
179
  }
132
180
  }
133
- function* streamRecord(tree, value, mergedResolver, path, rawResolver) {
134
- const obj = isObject(value) ? value : {};
181
+ function* streamRecord(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
135
182
  if (tree.type !== "record") return;
136
183
  const valueType = tree.valueType;
184
+ if (value !== void 0 && value !== null && !isObject(value)) {
185
+ emitDiagnostic(diagnostics, {
186
+ code: "type-mismatch",
187
+ message: "Record schema received non-object value during streaming render",
188
+ pointer: path === "" ? "/" : `/${path}`,
189
+ detail: {
190
+ expected: "object",
191
+ actualType: typeof value,
192
+ path
193
+ }
194
+ });
195
+ yield typeMismatchPlaceholder("object");
196
+ return;
197
+ }
198
+ const obj = isObject(value) ? value : {};
137
199
  const readOnly = tree.editability === "presentation";
138
200
  const attrs = {
139
201
  class: "sc-record",
@@ -143,7 +205,7 @@ function* streamRecord(tree, value, mergedResolver, path, rawResolver) {
143
205
  const dl = h("dl", attrs);
144
206
  yield yieldOpen(dl);
145
207
  for (const [key, val] of Object.entries(obj)) {
146
- const childHtml = renderFieldSync(valueType, val, mergedResolver, key, rawResolver);
208
+ const childHtml = renderFieldSync(valueType, val, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics);
147
209
  yield `${serialize(h("dt", { class: "sc-label" }, key))}${serialize(h("dd", { class: "sc-value" }, raw(childHtml)))}`;
148
210
  }
149
211
  yield yieldClose(dl);
@@ -151,13 +213,13 @@ function* streamRecord(tree, value, mergedResolver, path, rawResolver) {
151
213
  const container = h("div", attrs);
152
214
  yield yieldOpen(container);
153
215
  for (const [key, val] of Object.entries(obj)) {
154
- const childHtml = renderFieldSync(valueType, val, mergedResolver, key, rawResolver);
216
+ const childHtml = renderFieldSync(valueType, val, mergedResolver, joinPath(path, key), rawResolver, currentDepth + 1, diagnostics);
155
217
  yield serialize(h("div", { class: "sc-field" }, h("label", { class: "sc-label" }, key), raw(childHtml)));
156
218
  }
157
219
  yield yieldClose(container);
158
220
  }
159
221
  }
160
- function* streamUnion(tree, value, mergedResolver, path, rawResolver) {
222
+ function* streamUnion(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
161
223
  const options = tree.type === "union" ? tree.options : void 0;
162
224
  if (options === void 0 || options.length === 0) {
163
225
  if (value === void 0 || value === null) yield serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
@@ -165,10 +227,10 @@ function* streamUnion(tree, value, mergedResolver, path, rawResolver) {
165
227
  return;
166
228
  }
167
229
  const target = matchUnionOption(options, value) ?? options[0];
168
- if (target !== void 0) yield* streamField(target, value, mergedResolver, typeof target.meta.description === "string" ? target.meta.description : "", rawResolver);
230
+ if (target !== void 0) yield* streamField(target, value, mergedResolver, path, rawResolver, currentDepth + 1, diagnostics);
169
231
  else yield serialize(h("span", { class: "sc-value sc-value--empty" }, "—"));
170
232
  }
171
- function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolver) {
233
+ function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolver, currentDepth, diagnostics) {
172
234
  const options = tree.type === "discriminatedUnion" ? tree.options : void 0;
173
235
  const discriminator = tree.type === "discriminatedUnion" ? tree.discriminator : void 0;
174
236
  if (options === void 0 || options.length === 0) {
@@ -176,8 +238,7 @@ function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolve
176
238
  else yield serialize(h("span", { class: "sc-value" }, JSON.stringify(value)));
177
239
  return;
178
240
  }
179
- const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
180
- const obj = isRecord(value) ? value : {};
241
+ const obj = isObject(value) ? value : {};
181
242
  const discKey = discriminator ?? "";
182
243
  const currentDiscriminatorValue = typeof obj[discKey] === "string" ? obj[discKey] : void 0;
183
244
  const optionLabels = options.map((opt) => {
@@ -197,7 +258,7 @@ function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolve
197
258
  }
198
259
  const activeOption = options[activeIndex];
199
260
  if (tree.editability === "presentation") {
200
- if (activeOption !== void 0) yield* streamField(activeOption, value, mergedResolver, typeof activeOption.meta.description === "string" ? activeOption.meta.description : "", rawResolver);
261
+ if (activeOption !== void 0) yield* streamField(activeOption, value, mergedResolver, path, rawResolver, currentDepth + 1, diagnostics);
201
262
  return;
202
263
  }
203
264
  const panelId = `sc-${path}-panel`;
@@ -224,7 +285,7 @@ function* streamDiscriminatedUnion(tree, value, mergedResolver, path, rawResolve
224
285
  "aria-labelledby": `sc-${path}-tab-${String(activeIndex)}`
225
286
  });
226
287
  yield yieldOpen(panelOpen);
227
- if (activeOption !== void 0) yield* streamField(activeOption, value, mergedResolver, typeof activeOption.meta.description === "string" ? activeOption.meta.description : "", rawResolver);
288
+ if (activeOption !== void 0) yield* streamField(activeOption, value, mergedResolver, path, rawResolver, currentDepth + 1, diagnostics);
228
289
  yield yieldClose(panelOpen);
229
290
  yield yieldClose(wrapper);
230
291
  }