schema-components 1.21.0 → 1.23.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 (91) hide show
  1. package/README.md +3 -1
  2. package/dist/core/adapter.d.mts +115 -4
  3. package/dist/core/adapter.mjs +405 -75
  4. package/dist/core/constraints.d.mts +2 -2
  5. package/dist/core/constraints.mjs +0 -7
  6. package/dist/core/cssClasses.d.mts +52 -0
  7. package/dist/core/cssClasses.mjs +51 -0
  8. package/dist/core/diagnostics.d.mts +1 -1
  9. package/dist/core/errors.d.mts +1 -1
  10. package/dist/core/errors.mjs +5 -13
  11. package/dist/core/fieldOrder.d.mts +1 -1
  12. package/dist/core/formats.d.mts +30 -2
  13. package/dist/core/formats.mjs +33 -1
  14. package/dist/core/idPath.d.mts +54 -0
  15. package/dist/core/idPath.mjs +66 -0
  16. package/dist/core/limits.d.mts +2 -0
  17. package/dist/core/limits.mjs +23 -0
  18. package/dist/core/merge.d.mts +10 -1
  19. package/dist/core/merge.mjs +49 -10
  20. package/dist/core/normalise.d.mts +40 -3
  21. package/dist/core/normalise.mjs +2 -2
  22. package/dist/core/openapi30.d.mts +15 -1
  23. package/dist/core/openapi30.mjs +2 -2
  24. package/dist/core/openapiConstants.d.mts +67 -0
  25. package/dist/core/openapiConstants.mjs +90 -0
  26. package/dist/core/ref.d.mts +2 -2
  27. package/dist/core/ref.mjs +85 -6
  28. package/dist/core/refChain.d.mts +70 -0
  29. package/dist/core/refChain.mjs +44 -0
  30. package/dist/core/renderer.d.mts +1 -1
  31. package/dist/core/renderer.mjs +0 -2
  32. package/dist/core/swagger2.d.mts +1 -1
  33. package/dist/core/swagger2.mjs +1 -1
  34. package/dist/core/typeInference.d.mts +982 -2
  35. package/dist/core/types.d.mts +2 -2
  36. package/dist/core/types.mjs +1 -4
  37. package/dist/core/unionMatch.d.mts +36 -0
  38. package/dist/core/unionMatch.mjs +53 -0
  39. package/dist/core/version.d.mts +1 -1
  40. package/dist/core/version.mjs +29 -17
  41. package/dist/core/walkBuilders.d.mts +23 -4
  42. package/dist/core/walkBuilders.mjs +27 -7
  43. package/dist/core/walker.d.mts +1 -1
  44. package/dist/core/walker.mjs +123 -47
  45. package/dist/{diagnostics-CbBPsxSt.d.mts → diagnostics-BS2kaUyE.d.mts} +1 -1
  46. package/dist/{errors-QEwOtQAA.d.mts → errors-g_MCTQel.d.mts} +10 -16
  47. package/dist/html/a11y.d.mts +9 -4
  48. package/dist/html/a11y.mjs +10 -12
  49. package/dist/html/renderToHtml.d.mts +10 -3
  50. package/dist/html/renderToHtml.mjs +13 -3
  51. package/dist/html/renderToHtmlStream.d.mts +2 -2
  52. package/dist/html/renderToHtmlStream.mjs +12 -1
  53. package/dist/html/renderers.d.mts +43 -8
  54. package/dist/html/renderers.mjs +136 -116
  55. package/dist/html/streamRenderers.d.mts +6 -6
  56. package/dist/html/streamRenderers.mjs +129 -89
  57. package/dist/limits-Cw5QZND8.d.mts +29 -0
  58. package/dist/{normalise-DaSrnr8g.mjs → normalise-DCYp06Sr.mjs} +770 -227
  59. package/dist/openapi/ApiCallbacks.d.mts +1 -1
  60. package/dist/openapi/ApiLinks.d.mts +1 -1
  61. package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
  62. package/dist/openapi/ApiSecurity.d.mts +1 -1
  63. package/dist/openapi/ApiSecurity.mjs +16 -2
  64. package/dist/openapi/components.d.mts +234 -23
  65. package/dist/openapi/components.mjs +183 -52
  66. package/dist/openapi/parser.d.mts +9 -8
  67. package/dist/openapi/parser.mjs +252 -70
  68. package/dist/openapi/resolve.d.mts +31 -15
  69. package/dist/openapi/resolve.mjs +260 -40
  70. package/dist/react/SchemaComponent.d.mts +126 -36
  71. package/dist/react/SchemaComponent.mjs +95 -57
  72. package/dist/react/SchemaView.d.mts +30 -10
  73. package/dist/react/SchemaView.mjs +2 -2
  74. package/dist/react/a11y.d.mts +21 -0
  75. package/dist/react/a11y.mjs +24 -0
  76. package/dist/react/fieldPath.d.mts +1 -1
  77. package/dist/react/headless.d.mts +1 -1
  78. package/dist/react/headless.mjs +1 -2
  79. package/dist/react/headlessRenderers.d.mts +9 -11
  80. package/dist/react/headlessRenderers.mjs +51 -102
  81. package/dist/{ref-si8ViYun.d.mts → ref-DjLEKa_E.d.mts} +38 -3
  82. package/dist/{renderer-DI6ZYf7a.d.mts → renderer-CXJ8y0qw.d.mts} +2 -2
  83. package/dist/themes/mantine.d.mts +1 -1
  84. package/dist/themes/mui.d.mts +1 -1
  85. package/dist/themes/radix.d.mts +1 -1
  86. package/dist/themes/shadcn.d.mts +1 -1
  87. package/dist/themes/shadcn.mjs +2 -1
  88. package/dist/{types-BnxPEElk.d.mts → types-BTB73MB8.d.mts} +35 -14
  89. package/dist/{version-D-u7aMfy.d.mts → version-BFTVLsdb.d.mts} +7 -1
  90. package/package.json +1 -3
  91. package/dist/typeInference-Bxw3NOG1.d.mts +0 -647
@@ -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-BTB73MB8.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 };
@@ -0,0 +1,36 @@
1
+ import { j as WalkedField } from "../types-BTB73MB8.mjs";
2
+
3
+ //#region src/core/unionMatch.d.ts
4
+ /**
5
+ * Pick the union option that structurally matches the supplied value.
6
+ *
7
+ * Heuristic only — picks by JavaScript typeof / array / object class. Returns
8
+ * `undefined` when the value's shape doesn't correspond to any option (for
9
+ * example a `null` value against a non-nullable union). Callers should
10
+ * fall back to the first option or render an empty state in that case.
11
+ */
12
+ declare function matchUnionOption(options: readonly WalkedField[], value: unknown): WalkedField | undefined;
13
+ /**
14
+ * Resolution of a discriminated union against a concrete value. The renderer
15
+ * uses `optionLabels` to title each tab, `activeIndex` to select the open
16
+ * tab, and `activeOption` as the field to render below.
17
+ */
18
+ interface DiscriminatedActive {
19
+ readonly optionLabels: readonly string[];
20
+ readonly activeIndex: number;
21
+ readonly activeOption: WalkedField | undefined;
22
+ }
23
+ /**
24
+ * Derive labels, active index, and active option for a discriminated union.
25
+ *
26
+ * For each option, the label is the discriminator property's `const` value
27
+ * (when the option is an object with a literal discriminator) or, failing
28
+ * that, the option's `meta.title` or its `type`. The active index is chosen
29
+ * from the discriminator's value on `valueObject`; missing or non-matching
30
+ * values fall back to index 0.
31
+ *
32
+ * Pure data transformation — no rendering concerns, no React imports.
33
+ */
34
+ declare function resolveDiscriminatedActive(options: readonly WalkedField[], discriminator: string, valueObject: Record<string, unknown> | undefined): DiscriminatedActive;
35
+ //#endregion
36
+ export { DiscriminatedActive, matchUnionOption, resolveDiscriminatedActive };
@@ -0,0 +1,53 @@
1
+ //#region src/core/unionMatch.ts
2
+ /**
3
+ * Pick the union option that structurally matches the supplied value.
4
+ *
5
+ * Heuristic only — picks by JavaScript typeof / array / object class. Returns
6
+ * `undefined` when the value's shape doesn't correspond to any option (for
7
+ * example a `null` value against a non-nullable union). Callers should
8
+ * fall back to the first option or render an empty state in that case.
9
+ */
10
+ function matchUnionOption(options, value) {
11
+ if (typeof value === "string") return options.find((o) => o.type === "string" || o.type === "enum");
12
+ if (typeof value === "number") return options.find((o) => o.type === "number");
13
+ if (typeof value === "boolean") return options.find((o) => o.type === "boolean");
14
+ if (Array.isArray(value)) return options.find((o) => o.type === "array");
15
+ if (typeof value === "object" && value !== null) return options.find((o) => o.type === "object");
16
+ }
17
+ /**
18
+ * Derive labels, active index, and active option for a discriminated union.
19
+ *
20
+ * For each option, the label is the discriminator property's `const` value
21
+ * (when the option is an object with a literal discriminator) or, failing
22
+ * that, the option's `meta.title` or its `type`. The active index is chosen
23
+ * from the discriminator's value on `valueObject`; missing or non-matching
24
+ * values fall back to index 0.
25
+ *
26
+ * Pure data transformation — no rendering concerns, no React imports.
27
+ */
28
+ function resolveDiscriminatedActive(options, discriminator, valueObject) {
29
+ const currentDiscriminatorValue = valueObject !== void 0 && typeof valueObject[discriminator] === "string" ? valueObject[discriminator] : void 0;
30
+ const optionLabels = options.map((opt) => {
31
+ if (opt.type === "object") {
32
+ const discriminatorField = opt.fields[discriminator];
33
+ if (discriminatorField?.type === "literal") {
34
+ const constVal = discriminatorField.literalValues[0];
35
+ if (typeof constVal === "string") return constVal;
36
+ }
37
+ }
38
+ if (typeof opt.meta.title === "string") return opt.meta.title;
39
+ return opt.type;
40
+ });
41
+ let activeIndex = 0;
42
+ if (currentDiscriminatorValue !== void 0) {
43
+ const found = optionLabels.indexOf(currentDiscriminatorValue);
44
+ if (found !== -1) activeIndex = found;
45
+ }
46
+ return {
47
+ optionLabels,
48
+ activeIndex,
49
+ activeOption: options[activeIndex]
50
+ };
51
+ }
52
+ //#endregion
53
+ export { matchUnionOption, resolveDiscriminatedActive };
@@ -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-BFTVLsdb.mjs";
2
2
  export { InferredDraft, JsonSchemaDialectInfo, JsonSchemaDraft, OpenApiVersionInfo, detectJsonSchemaDraft, detectOpenApiVersion, inferJsonSchemaDraft, inferJsonSchemaDraftWithReason, isOpenApi30, isOpenApi31, isSwagger2, matchJsonSchemaDraftUri, readJsonSchemaDialect };
@@ -116,27 +116,39 @@ function inferJsonSchemaDraftWithReason(schema) {
116
116
  }
117
117
  /**
118
118
  * Detect the OpenAPI/Swagger version from a document.
119
- * Returns `undefined` for documents that are not OpenAPI or Swagger.
119
+ *
120
+ * Returns `undefined` when the document declares neither `swagger` nor
121
+ * `openapi` strings, or when the declared version string is malformed
122
+ * (missing parts or non-numeric segments). `Number("abc")` yields `NaN`,
123
+ * which `parts[i] ?? default` does NOT replace — nullish coalescing only
124
+ * substitutes `null`/`undefined` — so any unparseable segment surfaces
125
+ * as `undefined` rather than a silent fabricated default.
120
126
  */
121
127
  function detectOpenApiVersion(doc) {
122
128
  const swagger = doc.swagger;
123
- if (typeof swagger === "string") {
124
- const parts = swagger.split(".").map(Number);
125
- return {
126
- major: parts[0] ?? 2,
127
- minor: parts[1] ?? 0,
128
- patch: parts[2] ?? 0
129
- };
130
- }
129
+ if (typeof swagger === "string") return parseVersionString(swagger);
131
130
  const openapi = doc.openapi;
132
- if (typeof openapi === "string") {
133
- const parts = openapi.split(".").map(Number);
134
- return {
135
- major: parts[0] ?? 3,
136
- minor: parts[1] ?? 0,
137
- patch: parts[2] ?? 0
138
- };
139
- }
131
+ if (typeof openapi === "string") return parseVersionString(openapi);
132
+ }
133
+ /**
134
+ * Parse a dotted version string into `{ major, minor, patch }`.
135
+ *
136
+ * Returns `undefined` when any required segment is missing or fails to
137
+ * parse as a finite number. A two-segment string ("3.1") fills `patch`
138
+ * with `0` because the spec treats the patch as optional, but a missing
139
+ * `major` or `minor` is a malformed declaration and yields `undefined`.
140
+ */
141
+ function parseVersionString(version) {
142
+ const parts = version.split(".").map(Number);
143
+ const major = parts[0];
144
+ const minor = parts[1];
145
+ const patch = parts[2] ?? 0;
146
+ if (major === void 0 || minor === void 0 || !Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch)) return;
147
+ return {
148
+ major,
149
+ minor,
150
+ patch
151
+ };
140
152
  }
141
153
  /**
142
154
  * Check if an OpenAPI version is 3.0.x (uses modified Draft 04 schemas
@@ -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-BTB73MB8.mjs";
2
+ import { i as DiagnosticsOptions } from "../diagnostics-BS2kaUyE.mjs";
3
+ import { t as ExternalResolver } from "../ref-DjLEKa_E.mjs";
4
4
 
5
5
  //#region src/core/walkBuilders.d.ts
6
6
  declare function getString(obj: Record<string, unknown>, key: string): string | undefined;
@@ -70,5 +70,24 @@ declare function walkDependentRequiredMap(map: Record<string, unknown>): Record<
70
70
  */
71
71
  declare function withoutKeys(schema: Record<string, unknown>, keys: string[]): Record<string, unknown>;
72
72
  declare function isPrimitive(value: unknown): value is string | number | boolean | null;
73
+ /**
74
+ * Convert any JSON-shaped value to a display string suitable for
75
+ * form input attributes or text rendering.
76
+ *
77
+ * Centralises the conversion logic because `EnumField.enumValues` and
78
+ * `LiteralField.literalValues` are typed as `unknown[]` (Draft 2020-12
79
+ * permits any JSON value in `enum` / `const`). Renderers call this
80
+ * helper instead of inlining their own narrowing — the alternative
81
+ * `String(v)` on `unknown` trips `@typescript-eslint/no-base-to-string`.
82
+ *
83
+ * Inputs originate from parsed JSON (or runtime JSON-equivalents) so
84
+ * they are always `null | boolean | number | string | object | array`.
85
+ * Objects and arrays serialise via `JSON.stringify` so a discriminated
86
+ * union with object const values still produces a stable display key.
87
+ *
88
+ * Throws on non-JSON-shaped values (function, symbol, bigint, undefined)
89
+ * — their presence indicates the producer violated the JSON contract.
90
+ */
91
+ declare function displayJsonValue(value: unknown): string;
73
92
  //#endregion
74
- export { WalkContext, WalkOptions, buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, extractChildOverride, extractMetaFromJson, extractSchemaMetaFields, getArray, getObject, getString, isPrimitive, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys };
93
+ export { WalkContext, WalkOptions, buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, displayJsonValue, extractChildOverride, extractMetaFromJson, extractSchemaMetaFields, getArray, getObject, getString, isPrimitive, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys };
@@ -68,13 +68,8 @@ function buildBase(schema, ctx) {
68
68
  const defaultValue = "default" in schema ? schema.default : void 0;
69
69
  const examplesRaw = schema.examples;
70
70
  const examples = Array.isArray(examplesRaw) ? examplesRaw : void 0;
71
- const editability = resolveEditability(mergedMeta, ctx.componentMeta, ctx.rootMeta);
72
- if ((overrideMeta !== void 0 && ("readOnly" in overrideMeta || "writeOnly" in overrideMeta) || Boolean(propertyMeta.readOnly) || Boolean(propertyMeta.writeOnly)) && ctx.componentMeta !== void 0) ctx = {
73
- ...ctx,
74
- componentMeta: void 0
75
- };
76
71
  return {
77
- editability,
72
+ editability: resolveEditability(mergedMeta, ctx.componentMeta, ctx.rootMeta),
78
73
  meta: mergedMeta,
79
74
  isOptional: ctx.isOptional,
80
75
  isNullable: ctx.isNullable,
@@ -156,5 +151,30 @@ function withoutKeys(schema, keys) {
156
151
  function isPrimitive(value) {
157
152
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null;
158
153
  }
154
+ /**
155
+ * Convert any JSON-shaped value to a display string suitable for
156
+ * form input attributes or text rendering.
157
+ *
158
+ * Centralises the conversion logic because `EnumField.enumValues` and
159
+ * `LiteralField.literalValues` are typed as `unknown[]` (Draft 2020-12
160
+ * permits any JSON value in `enum` / `const`). Renderers call this
161
+ * helper instead of inlining their own narrowing — the alternative
162
+ * `String(v)` on `unknown` trips `@typescript-eslint/no-base-to-string`.
163
+ *
164
+ * Inputs originate from parsed JSON (or runtime JSON-equivalents) so
165
+ * they are always `null | boolean | number | string | object | array`.
166
+ * Objects and arrays serialise via `JSON.stringify` so a discriminated
167
+ * union with object const values still produces a stable display key.
168
+ *
169
+ * Throws on non-JSON-shaped values (function, symbol, bigint, undefined)
170
+ * — their presence indicates the producer violated the JSON contract.
171
+ */
172
+ function displayJsonValue(value) {
173
+ if (value === null) return "null";
174
+ if (typeof value === "string") return value;
175
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
176
+ if (typeof value === "object") return JSON.stringify(value);
177
+ throw new TypeError(`displayJsonValue: value of type ${typeof value} is not a JSON-shaped value`);
178
+ }
159
179
  //#endregion
160
- export { buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, extractChildOverride, extractMetaFromJson, extractSchemaMetaFields, getArray, getObject, getString, isPrimitive, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys };
180
+ export { buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, displayJsonValue, extractChildOverride, extractMetaFromJson, extractSchemaMetaFields, getArray, getObject, getString, isPrimitive, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys };
@@ -1,4 +1,4 @@
1
- import { M as WalkedField } from "../types-BnxPEElk.mjs";
1
+ import { j as WalkedField } from "../types-BTB73MB8.mjs";
2
2
  import { WalkOptions } from "./walkBuilders.mjs";
3
3
 
4
4
  //#region src/core/walker.d.ts
@@ -2,9 +2,10 @@ 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
- import { buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, extractChildOverride, extractSchemaMetaFields, getArray, getObject, getString, isPrimitive, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys } from "./walkBuilders.mjs";
8
+ import { buildBase, buildBooleanField, buildFileField, buildNullField, buildNumberField, buildStringField, buildUnknownField, extractChildOverride, extractSchemaMetaFields, getArray, getObject, getString, walkDependentRequiredMap, walkSubSchemaMap, withoutKeys } from "./walkBuilders.mjs";
8
9
  //#region src/core/walker.ts
9
10
  /**
10
11
  * Handle JSON Schema boolean values (Draft 06+).
@@ -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");
@@ -156,15 +208,7 @@ function walkNode(schema, ctx) {
156
208
  }
157
209
  const enumValues = getArray(schema, "enum");
158
210
  if (enumValues !== void 0) return walkEnum(schema, enumValues, ctx);
159
- if ("const" in schema) {
160
- if (!isPrimitive(schema.const)) emitDiagnostic(ctx.diagnostics, {
161
- code: "invalid-const",
162
- message: `const value is not a primitive: ${typeof schema.const}`,
163
- pointer: ctx.pointer,
164
- detail: { constValue: schema.const }
165
- });
166
- return walkLiteral(schema, ctx);
167
- }
211
+ if ("const" in schema) return walkLiteral(schema, ctx);
168
212
  const type = getString(schema, "type");
169
213
  const typeArray = getArray(schema, "type");
170
214
  if (type === void 0 && typeArray !== void 0) {
@@ -227,11 +271,36 @@ function walkNode(schema, ctx) {
227
271
  });
228
272
  return buildUnknownField(schema, ctx);
229
273
  }
274
+ /**
275
+ * Drafts that pre-date the `contentSchema` keyword (added in Draft
276
+ * 2019-09). Used to emit `keyword-out-of-draft` when a document
277
+ * declaring one of these drafts uses `contentSchema` anyway.
278
+ */
279
+ const PRE_CONTENT_SCHEMA_DRAFTS = new Set([
280
+ "draft-04",
281
+ "draft-06",
282
+ "draft-07"
283
+ ]);
230
284
  function walkString(schema, ctx) {
231
285
  if (getString(schema, "format") === "binary") return buildFileField(schema, ctx);
232
286
  const field = buildStringField(schema, ctx);
233
287
  const contentSchema = getObject(schema, "contentSchema");
234
- if (contentSchema !== void 0) field.meta.decodedSchema = walkNode(contentSchema, ctx);
288
+ if (contentSchema !== void 0) {
289
+ const rootSchema = getString(ctx.rootDocument, "$schema");
290
+ if (rootSchema !== void 0) {
291
+ const draft = matchJsonSchemaDraftUri(rootSchema);
292
+ if (draft !== void 0 && PRE_CONTENT_SCHEMA_DRAFTS.has(draft)) emitDiagnostic(ctx.diagnostics, {
293
+ code: "keyword-out-of-draft",
294
+ message: `\`contentSchema\` is a Draft 2019-09+ keyword; the document declares ${draft}`,
295
+ pointer: appendPointer(ctx.pointer, "contentSchema"),
296
+ detail: {
297
+ keyword: "contentSchema",
298
+ declaredDraft: draft
299
+ }
300
+ });
301
+ }
302
+ field.meta.decodedSchema = walkNode(contentSchema, ctx);
303
+ }
235
304
  return field;
236
305
  }
237
306
  function walkNumber(schema, ctx) {
@@ -241,38 +310,19 @@ function walkBoolean(schema, ctx) {
241
310
  return buildBooleanField(schema, ctx);
242
311
  }
243
312
  function walkEnum(schema, enumValues, ctx) {
244
- const accepted = [];
245
- for (let i = 0; i < enumValues.length; i++) {
246
- const v = enumValues[i];
247
- if (isPrimitive(v)) {
248
- accepted.push(v);
249
- continue;
250
- }
251
- emitDiagnostic(ctx.diagnostics, {
252
- code: "enum-value-filtered",
253
- message: `enum value at index ${String(i)} is not a primitive (${v === void 0 ? "undefined" : typeof v}); dropping the entry`,
254
- pointer: appendPointer(ctx.pointer, `enum/${String(i)}`),
255
- detail: {
256
- index: i,
257
- value: v
258
- }
259
- });
260
- }
261
313
  return {
262
314
  ...buildBase(schema, ctx),
263
315
  type: "enum",
264
316
  constraints: {},
265
- enumValues: accepted
317
+ enumValues: [...enumValues]
266
318
  };
267
319
  }
268
320
  function walkLiteral(schema, ctx) {
269
- const constValue = schema.const;
270
- const values = isPrimitive(constValue) ? [constValue] : [];
271
321
  return {
272
322
  ...buildBase(schema, ctx),
273
323
  type: "literal",
274
324
  constraints: {},
275
- literalValues: values
325
+ literalValues: [schema.const]
276
326
  };
277
327
  }
278
328
  function walkObject(schema, properties, ctx) {
@@ -386,36 +436,61 @@ function walkRecord(schema, valueSchema, ctx) {
386
436
  valueType
387
437
  };
388
438
  }
439
+ /**
440
+ * Resolve the `unevaluatedItems` keyword into the structural shape the
441
+ * field consumes. Returns the walked schema (object form), the
442
+ * `unevaluatedItemsClosed` flag (`false` form), or both undefined
443
+ * (absent or `true` — `true` permits everything and so has no
444
+ * structural consequence beyond the absence of a constraint).
445
+ *
446
+ * Mirrors the equivalent dispatch in `walkObject` for
447
+ * `unevaluatedProperties` — the parallel keeps the array/tuple and
448
+ * object branches symmetrical.
449
+ */
450
+ function resolveUnevaluatedItems(schema, ctx) {
451
+ if (!("unevaluatedItems" in schema)) return {};
452
+ const value = schema.unevaluatedItems;
453
+ if (value === false) return { unevaluatedItemsClosed: true };
454
+ if (value === true) return { unevaluatedItems: {
455
+ type: "unknown",
456
+ editability: "editable",
457
+ meta: {},
458
+ constraints: {}
459
+ } };
460
+ if (isObject(value)) return { unevaluatedItems: walkNode(value, ctx) };
461
+ return {};
462
+ }
389
463
  function walkArray(schema, ctx) {
390
464
  const walkedContains = "contains" in schema ? walkSubSchema(schema.contains, ctx) : void 0;
465
+ const unevaluatedInfo = resolveUnevaluatedItems(schema, ctx);
391
466
  const prefixItems = getArray(schema, "prefixItems");
392
467
  if (prefixItems !== void 0) {
393
- const walkedItems = prefixItems.filter(isObject).map((item) => walkNode(item, ctx));
394
- const restSchema = getObject(schema, "items");
395
- const restItems = restSchema !== void 0 ? walkNode(restSchema, ctx) : void 0;
468
+ const walkedItems = prefixItems.map((item) => walkSubSchema(item, ctx));
469
+ const restItems = "items" in schema ? walkSubSchema(schema.items, ctx) : void 0;
396
470
  return {
397
471
  ...buildBase(schema, ctx),
398
472
  type: "tuple",
399
473
  constraints: extractArrayConstraints(schema),
400
474
  prefixItems: walkedItems,
401
475
  ...restItems !== void 0 ? { restItems } : {},
402
- ...walkedContains !== void 0 ? { contains: walkedContains } : {}
476
+ ...walkedContains !== void 0 ? { contains: walkedContains } : {},
477
+ ...unevaluatedInfo.unevaluatedItems !== void 0 ? { unevaluatedItems: unevaluatedInfo.unevaluatedItems } : {},
478
+ ...unevaluatedInfo.unevaluatedItemsClosed === true ? { unevaluatedItemsClosed: true } : {}
403
479
  };
404
480
  }
405
- const unevaluatedItemsSchema = getObject(schema, "unevaluatedItems");
406
- const walkedUnevaluatedItems = unevaluatedItemsSchema !== void 0 ? walkNode(unevaluatedItemsSchema, ctx) : void 0;
407
- const items = getObject(schema, "items");
408
- if (items !== void 0) {
481
+ if ("items" in schema) {
409
482
  const elementOverride = extractChildOverride(ctx.fieldOverrides, "[]");
483
+ const elementCtx = {
484
+ ...ctx,
485
+ fieldOverrides: elementOverride
486
+ };
410
487
  return {
411
488
  ...buildBase(schema, ctx),
412
489
  type: "array",
413
490
  constraints: extractArrayConstraints(schema),
414
- element: walkNode(items, {
415
- ...ctx,
416
- fieldOverrides: elementOverride
417
- }),
418
- ...walkedUnevaluatedItems !== void 0 ? { unevaluatedItems: walkedUnevaluatedItems } : {},
491
+ element: walkSubSchema(schema.items, elementCtx),
492
+ ...unevaluatedInfo.unevaluatedItems !== void 0 ? { unevaluatedItems: unevaluatedInfo.unevaluatedItems } : {},
493
+ ...unevaluatedInfo.unevaluatedItemsClosed === true ? { unevaluatedItemsClosed: true } : {},
419
494
  ...walkedContains !== void 0 ? { contains: walkedContains } : {}
420
495
  };
421
496
  }
@@ -423,7 +498,8 @@ function walkArray(schema, ctx) {
423
498
  ...buildBase(schema, ctx),
424
499
  type: "array",
425
500
  constraints: extractArrayConstraints(schema),
426
- ...walkedUnevaluatedItems !== void 0 ? { unevaluatedItems: walkedUnevaluatedItems } : {},
501
+ ...unevaluatedInfo.unevaluatedItems !== void 0 ? { unevaluatedItems: unevaluatedInfo.unevaluatedItems } : {},
502
+ ...unevaluatedInfo.unevaluatedItemsClosed === true ? { unevaluatedItemsClosed: true } : {},
427
503
  ...walkedContains !== void 0 ? { contains: walkedContains } : {}
428
504
  };
429
505
  }
@@ -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 = "allof-conflict" | "assumed-draft" | "bare-exclusive-bound" | "conditional-fallback" | "cross-schema-relative-ref-unsupported" | "cyclic-path-item-ref" | "dependencies-conflict" | "dependent-required-invalid" | "depth-exceeded" | "discriminator-inconsistent" | "divisible-by-conflict" | "doc-not-object" | "dropped-swagger-feature" | "duplicate-body-parameter" | "duplicate-operation-id" | "dynamic-ref-degraded" | "enum-value-filtered" | "external-ref" | "invalid-const" | "invalid-id-fragment" | "keyword-out-of-draft" | "legacy-dependencies-split" | "legacy-dependencies-split-2019" | "non-json-media-type-fallback" | "parameter-missing-schema" | "path-item-ref-too-deep" | "path-webhook-name-collision" | "pattern-invalid" | "prototype-polluting-property" | "recursive-anchor-collision" | "relative-ref-resolved" | "required-non-string" | "schema-allof-incompatible" | "swagger-collection-format-dropped" | "swagger-cyclic-parameter-ref" | "swagger-invalid-file-parameter" | "swagger-malformed-oauth-flow" | "swagger-missing-consumes" | "swagger-missing-host" | "type-mismatch" | "type-negation-fallback" | "unknown-format" | "unknown-json-schema-dialect" | "unknown-keyword" | "unknown-openapi-version" | "unknown-parameter-location" | "unknown-security-scheme-type" | "unresolved-ref" | "unsupported-type" | "zod-codec-nested-output-only" | "zod-codec-output-only" | "zod-preprocess-output-only" | "zod-promise-nested-unwrap";
20
20
  /**
21
21
  * A single diagnostic emitted during schema processing.
22
22
  */
@@ -1,16 +1,6 @@
1
+ import { T as SchemaType } from "./types-BTB73MB8.mjs";
2
+
1
3
  //#region src/core/errors.d.ts
2
- /**
3
- * Structured error types for schema-components.
4
- *
5
- * Every error produced by the library is one of these three types:
6
- *
7
- * - SchemaNormalisationError — the adapter failed to convert the input
8
- * to JSON Schema (invalid Zod, bad OpenAPI ref, malformed schema)
9
- * - SchemaRenderError — a theme adapter's render function threw
10
- * - SchemaFieldError — a field path couldn't be resolved
11
- *
12
- * All extend `SchemaError` so consumers can catch the base class.
13
- */
14
4
  /**
15
5
  * Base class for all schema-components errors.
16
6
  * Catch this to handle any library error uniformly.
@@ -32,7 +22,7 @@ declare class SchemaError extends Error {
32
22
  * JSON Schema, missing OpenAPI ref, unsupported ref format.
33
23
  */
34
24
  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";
25
+ 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
26
  /**
37
27
  * For `zod-type-unrepresentable`, the offending Zod type name
38
28
  * (e.g. "bigint", "date", "map", "set"). `undefined` for other kinds.
@@ -46,9 +36,13 @@ declare class SchemaNormalisationError extends SchemaError {
46
36
  * The `cause` is the original error from the render function.
47
37
  */
48
38
  declare class SchemaRenderError extends SchemaError {
49
- /** The schema type being rendered when the error occurred. */
50
- readonly schemaType: string;
51
- constructor(message: string, schema: unknown, schemaType: string, cause: unknown);
39
+ /**
40
+ * The schema type being rendered when the error occurred. Drawn from
41
+ * the walker's discriminant union so consumers can switch on it
42
+ * exhaustively without a wider `string` fallback.
43
+ */
44
+ readonly schemaType: SchemaType;
45
+ constructor(message: string, schema: unknown, schemaType: SchemaType, cause: unknown);
52
46
  }
53
47
  /**
54
48
  * A field path couldn't be resolved against the walked schema tree.
@@ -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-BTB73MB8.mjs";
2
+ import { t as AllConstraints } from "../renderer-CXJ8y0qw.mjs";
3
3
  import { HtmlAttributes, HtmlNode } from "./html.mjs";
4
4
 
5
5
  //#region src/html/a11y.d.ts
@@ -15,11 +15,16 @@ import { HtmlAttributes, HtmlNode } from "./html.mjs";
15
15
  */
16
16
  declare function joinPath(parent: string, suffix: string | undefined): string;
17
17
  /**
18
- * Build the input ID for a field at a given path.
18
+ * Build the input ID for a field at a given path. Joins `path` and `key`
19
+ * via `joinPath` then delegates to the canonical `fieldDomId` helper from
20
+ * `core/idPath.ts` so every render pipeline emits identical ids for the
21
+ * same structural position.
19
22
  */
20
23
  declare function buildInputId(path: string, key: string): string;
21
24
  /**
22
- * Derive the hint element ID from the input ID.
25
+ * Derive the hint element ID from the input ID. Thin re-export of the
26
+ * canonical helper so this module remains the one-stop a11y surface for
27
+ * the HTML renderers.
23
28
  */
24
29
  declare function buildHintId(inputId: string): string;
25
30
  /**