schema-components 1.28.2 → 2.0.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 (105) hide show
  1. package/README.md +38 -16
  2. package/dist/core/adapter.d.mts +213 -3
  3. package/dist/core/adapter.mjs +21 -2
  4. package/dist/core/constraintHint.d.mts +15 -0
  5. package/dist/core/constraintHint.mjs +24 -0
  6. package/dist/core/constraints.d.mts +34 -2
  7. package/dist/core/constraints.mjs +33 -1
  8. package/dist/core/cssClasses.d.mts +1 -0
  9. package/dist/core/diagnostics.d.mts +1 -1
  10. package/dist/core/errors.d.mts +1 -1
  11. package/dist/core/errors.mjs +22 -12
  12. package/dist/core/fieldOrder.d.mts +1 -1
  13. package/dist/core/formats.d.mts +7 -1
  14. package/dist/core/formats.mjs +6 -0
  15. package/dist/core/idPath.d.mts +35 -5
  16. package/dist/core/idPath.mjs +79 -7
  17. package/dist/core/inferValue.d.mts +2 -0
  18. package/dist/core/inferValue.mjs +1 -0
  19. package/dist/core/limits.d.mts +1 -1
  20. package/dist/core/limits.mjs +6 -0
  21. package/dist/core/merge.d.mts +22 -1
  22. package/dist/core/merge.mjs +66 -3
  23. package/dist/core/normalise.d.mts +17 -2
  24. package/dist/core/normalise.mjs +1 -1
  25. package/dist/core/openapi30.mjs +1 -1
  26. package/dist/core/openapiConstants.d.mts +1 -0
  27. package/dist/core/ref.d.mts +1 -1
  28. package/dist/core/refChain.d.mts +3 -4
  29. package/dist/core/refChain.mjs +2 -3
  30. package/dist/core/renderer.d.mts +199 -2
  31. package/dist/core/renderer.mjs +5 -0
  32. package/dist/core/swagger2.d.mts +1 -1
  33. package/dist/core/swagger2.mjs +1 -1
  34. package/dist/core/typeInference.d.mts +3 -3
  35. package/dist/core/types.d.mts +1 -1
  36. package/dist/core/types.mjs +17 -0
  37. package/dist/core/unionMatch.d.mts +1 -1
  38. package/dist/core/uri.d.mts +12 -4
  39. package/dist/core/uri.mjs +30 -4
  40. package/dist/core/version.d.mts +1 -1
  41. package/dist/core/walkBuilders.d.mts +63 -6
  42. package/dist/core/walkBuilders.mjs +33 -1
  43. package/dist/core/walker.d.mts +14 -1
  44. package/dist/core/walker.mjs +18 -0
  45. package/dist/{diagnostics-Cbwak-ZX.d.mts → diagnostics-BTrm3O6J.d.mts} +9 -1
  46. package/dist/{errors-DQSIK4n1.d.mts → errors-Dki7tji4.d.mts} +23 -13
  47. package/dist/html/a11y.d.mts +3 -7
  48. package/dist/html/a11y.mjs +1 -16
  49. package/dist/html/html.d.mts +11 -0
  50. package/dist/html/html.mjs +11 -0
  51. package/dist/html/renderToHtml.d.mts +45 -12
  52. package/dist/html/renderToHtml.mjs +20 -4
  53. package/dist/html/renderToHtmlStream.d.mts +63 -18
  54. package/dist/html/renderToHtmlStream.mjs +34 -8
  55. package/dist/html/renderers.d.mts +6 -31
  56. package/dist/html/renderers.mjs +45 -91
  57. package/dist/html/streamRenderers.d.mts +31 -3
  58. package/dist/html/streamRenderers.mjs +41 -8
  59. package/dist/inferValue-PPXWJpbN.d.mts +77 -0
  60. package/dist/{limits-DJhgx5Ay.d.mts → limits-x4OiyJxh.d.mts} +6 -0
  61. package/dist/{normalise-Db1xaxgx.mjs → normalise-DB-Xtjmn.mjs} +43 -2
  62. package/dist/openapi/ApiCallbacks.d.mts +13 -1
  63. package/dist/openapi/ApiCallbacks.mjs +7 -0
  64. package/dist/openapi/ApiLinks.d.mts +13 -1
  65. package/dist/openapi/ApiLinks.mjs +7 -0
  66. package/dist/openapi/ApiResponseHeaders.d.mts +13 -1
  67. package/dist/openapi/ApiResponseHeaders.mjs +7 -0
  68. package/dist/openapi/ApiSecurity.d.mts +14 -1
  69. package/dist/openapi/ApiSecurity.mjs +29 -8
  70. package/dist/openapi/bundle.d.mts +31 -0
  71. package/dist/openapi/components.d.mts +135 -20
  72. package/dist/openapi/components.mjs +90 -15
  73. package/dist/openapi/parser.d.mts +140 -13
  74. package/dist/openapi/parser.mjs +84 -12
  75. package/dist/openapi/resolve.d.mts +42 -47
  76. package/dist/openapi/resolve.mjs +62 -56
  77. package/dist/react/SchemaComponent.d.mts +90 -88
  78. package/dist/react/SchemaComponent.mjs +74 -2
  79. package/dist/react/SchemaErrorBoundary.d.mts +18 -1
  80. package/dist/react/SchemaErrorBoundary.mjs +13 -1
  81. package/dist/react/SchemaView.d.mts +39 -11
  82. package/dist/react/SchemaView.mjs +23 -6
  83. package/dist/react/a11y.d.mts +74 -7
  84. package/dist/react/a11y.mjs +67 -6
  85. package/dist/react/fieldPath.d.mts +16 -1
  86. package/dist/react/fieldPath.mjs +25 -1
  87. package/dist/react/fieldShell.d.mts +49 -0
  88. package/dist/react/fieldShell.mjs +37 -0
  89. package/dist/react/headless.d.mts +1 -1
  90. package/dist/react/headlessRenderers.d.mts +13 -2
  91. package/dist/react/headlessRenderers.mjs +134 -54
  92. package/dist/{ref-TdeMfaV_.d.mts → ref-DdsbekXX.d.mts} +33 -1
  93. package/dist/themes/mantine.d.mts +54 -12
  94. package/dist/themes/mantine.mjs +195 -140
  95. package/dist/themes/mui.d.mts +64 -11
  96. package/dist/themes/mui.mjs +277 -213
  97. package/dist/themes/radix.d.mts +67 -15
  98. package/dist/themes/radix.mjs +235 -170
  99. package/dist/themes/shadcn.d.mts +25 -1
  100. package/dist/themes/shadcn.mjs +112 -91
  101. package/dist/{types-BTB73MB8.d.mts → types-BrYbjC7_.d.mts} +30 -0
  102. package/dist/{version-ZzL5R6cS.d.mts → version-DL8U5RuA.d.mts} +6 -0
  103. package/package.json +8 -1
  104. package/dist/adapter-DqlAnZ_w.d.mts +0 -172
  105. package/dist/renderer-Ul9taFYp.d.mts +0 -169
@@ -1,2 +1,2 @@
1
- import { c as normaliseSwagger2Document } from "../normalise-Db1xaxgx.mjs";
1
+ import { c as normaliseSwagger2Document } from "../normalise-DB-Xtjmn.mjs";
2
2
  export { normaliseSwagger2Document };
@@ -1,5 +1,5 @@
1
- import { d as FieldOverrides, u as FieldOverride } from "../types-BTB73MB8.mjs";
2
- import { i as MaxRefDepth } from "../limits-DJhgx5Ay.mjs";
1
+ import { d as FieldOverrides, u as FieldOverride } from "../types-BrYbjC7_.mjs";
2
+ import { i as MaxRefDepth } from "../limits-x4OiyJxh.mjs";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/core/typeInference.d.ts
@@ -790,7 +790,7 @@ type RequestBodySchemaOf<Op, ContentType extends string = DEFAULT_OPENAPI_CONTEN
790
790
  * Without this fallback, querying a concrete status against a document
791
791
  * that declares only `"2XX"` or `"default"` would silently produce
792
792
  * `unknown`. The runtime resolver applies the same fall-through
793
- * behaviour in `resolveResponseFromParsed`.
793
+ * behaviour in `resolveResponse`.
794
794
  */
795
795
  type ResponseSchemaOf<Op, Status extends string, ContentType extends string = DEFAULT_OPENAPI_CONTENT_TYPE> = Op extends {
796
796
  responses: infer Rs extends Record<string, unknown>;
@@ -1,2 +1,2 @@
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";
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-BrYbjC7_.mjs";
2
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 };
@@ -38,54 +38,71 @@ function resolveEditability(propertyMeta, componentMeta, rootMeta) {
38
38
  function isField(field, t) {
39
39
  return field.type === t;
40
40
  }
41
+ /** Type guard: narrows a `WalkedField` to its `string` variant. */
41
42
  function isStringField(field) {
42
43
  return isField(field, "string");
43
44
  }
45
+ /** Type guard: narrows a `WalkedField` to its `number` variant. */
44
46
  function isNumberField(field) {
45
47
  return isField(field, "number");
46
48
  }
49
+ /** Type guard: narrows a `WalkedField` to its `boolean` variant. */
47
50
  function isBooleanField(field) {
48
51
  return isField(field, "boolean");
49
52
  }
53
+ /** Type guard: narrows a `WalkedField` to its `null` variant. */
50
54
  function isNullField(field) {
51
55
  return isField(field, "null");
52
56
  }
57
+ /** Type guard: narrows a `WalkedField` to its `enum` variant. */
53
58
  function isEnumField(field) {
54
59
  return isField(field, "enum");
55
60
  }
61
+ /** Type guard: narrows a `WalkedField` to its `literal` variant. */
56
62
  function isLiteralField(field) {
57
63
  return isField(field, "literal");
58
64
  }
65
+ /** Type guard: narrows a `WalkedField` to its `object` variant. */
59
66
  function isObjectField(field) {
60
67
  return isField(field, "object");
61
68
  }
69
+ /** Type guard: narrows a `WalkedField` to its `array` variant. */
62
70
  function isArrayField(field) {
63
71
  return isField(field, "array");
64
72
  }
73
+ /** Type guard: narrows a `WalkedField` to its `tuple` variant. */
65
74
  function isTupleField(field) {
66
75
  return isField(field, "tuple");
67
76
  }
77
+ /** Type guard: narrows a `WalkedField` to its `record` variant. */
68
78
  function isRecordField(field) {
69
79
  return isField(field, "record");
70
80
  }
81
+ /** Type guard: narrows a `WalkedField` to its plain `union` variant. */
71
82
  function isUnionField(field) {
72
83
  return isField(field, "union");
73
84
  }
85
+ /** Type guard: narrows a `WalkedField` to its `discriminatedUnion` variant. */
74
86
  function isDiscriminatedUnionField(field) {
75
87
  return isField(field, "discriminatedUnion");
76
88
  }
89
+ /** Type guard: narrows a `WalkedField` to its `conditional` (if/then/else) variant. */
77
90
  function isConditionalField(field) {
78
91
  return isField(field, "conditional");
79
92
  }
93
+ /** Type guard: narrows a `WalkedField` to its `negation` (`not`) variant. */
80
94
  function isNegationField(field) {
81
95
  return isField(field, "negation");
82
96
  }
97
+ /** Type guard: narrows a `WalkedField` to its `file` variant. */
83
98
  function isFileField(field) {
84
99
  return isField(field, "file");
85
100
  }
101
+ /** Type guard: narrows a `WalkedField` to its `never` variant (false schema). */
86
102
  function isNeverField(field) {
87
103
  return isField(field, "never");
88
104
  }
105
+ /** Type guard: narrows a `WalkedField` to its `unknown` variant (permissive). */
89
106
  function isUnknownField(field) {
90
107
  return isField(field, "unknown");
91
108
  }
@@ -1,4 +1,4 @@
1
- import { j as WalkedField } from "../types-BTB73MB8.mjs";
1
+ import { j as WalkedField } from "../types-BrYbjC7_.mjs";
2
2
 
3
3
  //#region src/core/unionMatch.d.ts
4
4
  /**
@@ -17,16 +17,24 @@
17
17
  * Returns `true` when the value is either a relative reference (no scheme
18
18
  * component) or an absolute URI using `http`/`https`. Returns `false`
19
19
  * for any other scheme, including dangerous ones like `javascript:` and
20
- * `data:`.
20
+ * `data:`, and for any value that splices ASCII tab/newline/NUL bytes
21
+ * into its scheme — the WHATWG URL parser strips those before scheme
22
+ * detection, so accepting them would let `"java\tscript:alert(1)"`
23
+ * resolve to `javascript:alert(1)` in a browser.
21
24
  */
22
25
  declare function isSafeHyperlink(value: string): boolean;
23
26
  /**
24
27
  * Decide whether `value` is safe to interpolate into a `mailto:` URI.
25
28
  *
26
29
  * The check rejects values that do not match the standard email format
27
- * pattern. The format pattern excludes whitespace, which means a CRLF
28
- * sequence (or its percent-encoded form embedded by the caller) cannot
29
- * pass eliminating the SMTP/`mailto` header-injection vector.
30
+ * pattern. The format pattern excludes whitespace, but it does permit
31
+ * `%`, and a browser decodes percent-escapes at click time so a value
32
+ * such as `"foo%0Abcc:victim@bar.com"` would inject a `Bcc:` header into
33
+ * the resulting `mailto:` URI. Refuse any value containing `%` to close
34
+ * that header-injection vector. The plain email-format regex stays a
35
+ * pure email-syntax check; the additional `%` filter lives here so other
36
+ * callers of the format pattern (form validators, JSON Schema `format:
37
+ * email` checks) are not affected.
30
38
  */
31
39
  declare function isSafeMailtoAddress(value: string): boolean;
32
40
  /**
package/dist/core/uri.mjs CHANGED
@@ -20,6 +20,22 @@ import { EMAIL_FORMAT_PATTERN } from "./formats.mjs";
20
20
  */
21
21
  const ABSOLUTE_URI_SCHEME = /^\s*([a-z][a-z0-9+\-.]*):/i;
22
22
  /**
23
+ * ASCII control characters that the WHATWG URL parser strips before it
24
+ * detects a scheme. A value such as `"java\tscript:alert(1)"` therefore
25
+ * resolves to `javascript:alert(1)` in a browser, even though the literal
26
+ * scheme regex would not match. Splicing any of these characters into a
27
+ * URI is unambiguously hostile, so the safe-scheme check refuses such
28
+ * values outright.
29
+ *
30
+ * Source: WHATWG URL Living Standard §4.4 "URL parsing" — tab and newline
31
+ * (`\t`, `\n`, `\r`) are removed prior to state-machine entry. NUL bytes
32
+ * (`\0`) are likewise stripped by some user agents and never legitimate
33
+ * inside a URI.
34
+ *
35
+ * https://web.archive.org/web/20251101000000*\/https://url.spec.whatwg.org/#concept-basic-url-parser
36
+ */
37
+ const URL_CONTROL_CHARACTERS = /[\t\n\r\0]/;
38
+ /**
23
39
  * Schemes safe to emit unmodified into an `href` attribute. Anything
24
40
  * outside this set — most importantly `javascript:`, `data:`, `vbscript:`
25
41
  * and `file:` — is rejected and rendered as text.
@@ -31,9 +47,13 @@ const SAFE_HYPERLINK_SCHEMES = new Set(["http", "https"]);
31
47
  * Returns `true` when the value is either a relative reference (no scheme
32
48
  * component) or an absolute URI using `http`/`https`. Returns `false`
33
49
  * for any other scheme, including dangerous ones like `javascript:` and
34
- * `data:`.
50
+ * `data:`, and for any value that splices ASCII tab/newline/NUL bytes
51
+ * into its scheme — the WHATWG URL parser strips those before scheme
52
+ * detection, so accepting them would let `"java\tscript:alert(1)"`
53
+ * resolve to `javascript:alert(1)` in a browser.
35
54
  */
36
55
  function isSafeHyperlink(value) {
56
+ if (URL_CONTROL_CHARACTERS.test(value)) return false;
37
57
  const match = ABSOLUTE_URI_SCHEME.exec(value);
38
58
  if (match === null) return true;
39
59
  const scheme = match[1];
@@ -44,11 +64,17 @@ function isSafeHyperlink(value) {
44
64
  * Decide whether `value` is safe to interpolate into a `mailto:` URI.
45
65
  *
46
66
  * The check rejects values that do not match the standard email format
47
- * pattern. The format pattern excludes whitespace, which means a CRLF
48
- * sequence (or its percent-encoded form embedded by the caller) cannot
49
- * pass eliminating the SMTP/`mailto` header-injection vector.
67
+ * pattern. The format pattern excludes whitespace, but it does permit
68
+ * `%`, and a browser decodes percent-escapes at click time so a value
69
+ * such as `"foo%0Abcc:victim@bar.com"` would inject a `Bcc:` header into
70
+ * the resulting `mailto:` URI. Refuse any value containing `%` to close
71
+ * that header-injection vector. The plain email-format regex stays a
72
+ * pure email-syntax check; the additional `%` filter lives here so other
73
+ * callers of the format pattern (form validators, JSON Schema `format:
74
+ * email` checks) are not affected.
50
75
  */
51
76
  function isSafeMailtoAddress(value) {
77
+ if (value.includes("%")) return false;
52
78
  return EMAIL_FORMAT_PATTERN.test(value);
53
79
  }
54
80
  /**
@@ -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-ZzL5R6cS.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-DL8U5RuA.mjs";
2
2
  export { InferredDraft, JsonSchemaDialectInfo, JsonSchemaDraft, OpenApiVersionInfo, detectJsonSchemaDraft, detectOpenApiVersion, inferJsonSchemaDraft, inferJsonSchemaDraftWithReason, isOpenApi30, isOpenApi31, isSwagger2, matchJsonSchemaDraftUri, readJsonSchemaDialect };
@@ -1,16 +1,38 @@
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-Cbwak-ZX.mjs";
3
- import { t as ExternalResolver } from "../ref-TdeMfaV_.mjs";
1
+ import { A as UnknownField, D as StringField, b as NumberField, c as FieldBase, d as FieldOverrides, j as WalkedField, o as Editability, p as FileField, r as BooleanField, v as NullField, w as SchemaMeta } from "../types-BrYbjC7_.mjs";
2
+ import { i as DiagnosticsOptions } from "../diagnostics-BTrm3O6J.mjs";
3
+ import { t as ExternalResolver } from "../ref-DdsbekXX.mjs";
4
4
 
5
5
  //#region src/core/walkBuilders.d.ts
6
+ /** Read a key from a JSON object, returning the value when it is a string and `undefined` otherwise. */
6
7
  declare function getString(obj: Record<string, unknown>, key: string): string | undefined;
8
+ /** Read a key from a JSON object, returning the value when it is an array and `undefined` otherwise. */
7
9
  declare function getArray(obj: Record<string, unknown>, key: string): unknown[] | undefined;
10
+ /** Read a key from a JSON object, returning the value when it is a plain object and `undefined` otherwise. */
8
11
  declare function getObject(obj: Record<string, unknown>, key: string): Record<string, unknown> | undefined;
9
- interface WalkOptions {
12
+ /**
13
+ * Options accepted by `walk`. Use to inject meta overrides, field-level
14
+ * overrides, the root document for cross-document `$ref` resolution, a
15
+ * diagnostics sink, and an external `$ref` resolver.
16
+ *
17
+ * `WalkOptions` is generic in the schema's value type so callers that
18
+ * walk a typed schema can carry `FieldOverrides<T>` through. The
19
+ * default `T = unknown` preserves the loose runtime record shape for
20
+ * existing non-generic callers — `Record<string, unknown>`.
21
+ *
22
+ * @group Walkers
23
+ */
24
+ interface WalkOptions<T = unknown> {
10
25
  componentMeta?: SchemaMeta | undefined;
11
26
  rootMeta?: SchemaMeta | undefined;
12
- /** Nested field overrides — same shape as the schema. */
13
- fieldOverrides?: Record<string, unknown> | undefined;
27
+ /**
28
+ * Nested field overrides — same shape as the schema.
29
+ *
30
+ * Typed against `FieldOverrides<T>` when a schema value type is
31
+ * supplied; falls back to `Record<string, unknown>` for the
32
+ * default `T = unknown` so the loose runtime shape continues to
33
+ * compile.
34
+ */
35
+ fieldOverrides?: unknown extends T ? Record<string, unknown> | undefined : FieldOverrides<T> | undefined;
14
36
  /** The root document for $ref resolution. */
15
37
  rootDocument?: Record<string, unknown> | undefined;
16
38
  /** Diagnostics channel for surfacing silent fallbacks. */
@@ -18,9 +40,34 @@ interface WalkOptions {
18
40
  /** Sync resolver for external $ref URIs. */
19
41
  externalResolver?: ExternalResolver;
20
42
  }
43
+ /**
44
+ * Extract recognised meta keywords (`readOnly`, `writeOnly`,
45
+ * `description`, `title`, `deprecated`, `default`, `component`,
46
+ * `example`, `examples`) from a JSON Schema node into the `SchemaMeta`
47
+ * shape consumed by the walker.
48
+ */
21
49
  declare function extractMetaFromJson(schema: Record<string, unknown>): SchemaMeta;
50
+ /**
51
+ * Project the meta-style keys (`readOnly`, `writeOnly`, `description`,
52
+ * `title`, `deprecated`, `component`, `visible`, `order`) out of a
53
+ * field override object into a `SchemaMeta`. Returns `undefined` when
54
+ * the override has no meta fields so the walker can short-circuit.
55
+ */
22
56
  declare function extractSchemaMetaFields(overrides: Record<string, unknown> | undefined): SchemaMeta | undefined;
57
+ /**
58
+ * Pluck the nested override at `key` from a parent field override map.
59
+ * Returns `undefined` when no override is present or when the entry is
60
+ * not a non-array object.
61
+ */
23
62
  declare function extractChildOverride(overrides: Record<string, unknown> | undefined, key: string): Record<string, unknown> | undefined;
63
+ /**
64
+ * Mutable context threaded through every recursive walk step. Carries
65
+ * the merged metadata, field overrides, document root, nullability /
66
+ * optionality flags, `$ref` cache, diagnostics sink, and per-document
67
+ * `$ref` depth bound that `walkBuilders` and the walker itself share.
68
+ *
69
+ * @group Walkers
70
+ */
24
71
  interface WalkContext {
25
72
  componentMeta: SchemaMeta | undefined;
26
73
  rootMeta: SchemaMeta | undefined;
@@ -46,11 +93,17 @@ interface WalkContext {
46
93
  declare function buildBase(schema: Record<string, unknown>, ctx: WalkContext): FieldBase & {
47
94
  editability: Editability;
48
95
  };
96
+ /** Build a walked `StringField` from a JSON Schema node. */
49
97
  declare function buildStringField(schema: Record<string, unknown>, ctx: WalkContext): StringField;
98
+ /** Build a walked `NumberField` from a JSON Schema node. */
50
99
  declare function buildNumberField(schema: Record<string, unknown>, ctx: WalkContext): NumberField;
100
+ /** Build a walked `BooleanField` from a JSON Schema node. */
51
101
  declare function buildBooleanField(schema: Record<string, unknown>, ctx: WalkContext): BooleanField;
102
+ /** Build a walked `NullField` from a JSON Schema node. */
52
103
  declare function buildNullField(schema: Record<string, unknown>, ctx: WalkContext): NullField;
104
+ /** Build a walked `UnknownField` (permissive open-shape) from a JSON Schema node. */
53
105
  declare function buildUnknownField(schema: Record<string, unknown>, ctx: WalkContext): UnknownField;
106
+ /** Build a walked `FileField` from a JSON Schema node carrying `contentMediaType`. */
54
107
  declare function buildFileField(schema: Record<string, unknown>, ctx: WalkContext): FileField;
55
108
  /**
56
109
  * Walk a map of sub-schemas (patternProperties, dependentSchemas, $defs).
@@ -69,6 +122,10 @@ declare function walkDependentRequiredMap(map: Record<string, unknown>): Record<
69
122
  * Used to strip composition keywords before walking the base schema.
70
123
  */
71
124
  declare function withoutKeys(schema: Record<string, unknown>, keys: string[]): Record<string, unknown>;
125
+ /**
126
+ * Type guard for a JSON primitive: string, number, boolean, or null.
127
+ * Used to short-circuit walk-time decisions about leaf values.
128
+ */
72
129
  declare function isPrimitive(value: unknown): value is string | number | boolean | null;
73
130
  /**
74
131
  * Convert any JSON-shaped value to a display string suitable for
@@ -2,14 +2,17 @@ import { isObject } from "./guards.mjs";
2
2
  import { extractFileConstraints, extractNumberConstraints, extractStringConstraints } from "./constraints.mjs";
3
3
  import { resolveEditability } from "./types.mjs";
4
4
  //#region src/core/walkBuilders.ts
5
+ /** Read a key from a JSON object, returning the value when it is a string and `undefined` otherwise. */
5
6
  function getString(obj, key) {
6
7
  const value = obj[key];
7
8
  return typeof value === "string" ? value : void 0;
8
9
  }
10
+ /** Read a key from a JSON object, returning the value when it is an array and `undefined` otherwise. */
9
11
  function getArray(obj, key) {
10
12
  const value = obj[key];
11
13
  return Array.isArray(value) ? value : void 0;
12
14
  }
15
+ /** Read a key from a JSON object, returning the value when it is a plain object and `undefined` otherwise. */
13
16
  function getObject(obj, key) {
14
17
  const value = obj[key];
15
18
  return isObject(value) ? value : void 0;
@@ -25,6 +28,12 @@ const META_KEYWORDS = new Set([
25
28
  "example",
26
29
  "examples"
27
30
  ]);
31
+ /**
32
+ * Extract recognised meta keywords (`readOnly`, `writeOnly`,
33
+ * `description`, `title`, `deprecated`, `default`, `component`,
34
+ * `example`, `examples`) from a JSON Schema node into the `SchemaMeta`
35
+ * shape consumed by the walker.
36
+ */
28
37
  function extractMetaFromJson(schema) {
29
38
  const meta = {};
30
39
  for (const [key, value] of Object.entries(schema)) if (META_KEYWORDS.has(key)) meta[key] = value;
@@ -40,12 +49,23 @@ const OVERRIDE_META_KEYS = new Set([
40
49
  "visible",
41
50
  "order"
42
51
  ]);
52
+ /**
53
+ * Project the meta-style keys (`readOnly`, `writeOnly`, `description`,
54
+ * `title`, `deprecated`, `component`, `visible`, `order`) out of a
55
+ * field override object into a `SchemaMeta`. Returns `undefined` when
56
+ * the override has no meta fields so the walker can short-circuit.
57
+ */
43
58
  function extractSchemaMetaFields(overrides) {
44
59
  if (overrides === void 0) return void 0;
45
60
  const meta = {};
46
61
  for (const key of Object.keys(overrides)) if (OVERRIDE_META_KEYS.has(key)) meta[key] = overrides[key];
47
62
  return Object.keys(meta).length > 0 ? meta : void 0;
48
63
  }
64
+ /**
65
+ * Pluck the nested override at `key` from a parent field override map.
66
+ * Returns `undefined` when no override is present or when the entry is
67
+ * not a non-array object.
68
+ */
49
69
  function extractChildOverride(overrides, key) {
50
70
  if (overrides === void 0) return void 0;
51
71
  const child = overrides[key];
@@ -77,6 +97,7 @@ function buildBase(schema, ctx) {
77
97
  ...examples !== void 0 ? { examples } : {}
78
98
  };
79
99
  }
100
+ /** Build a walked `StringField` from a JSON Schema node. */
80
101
  function buildStringField(schema, ctx) {
81
102
  return {
82
103
  ...buildBase(schema, ctx),
@@ -84,13 +105,17 @@ function buildStringField(schema, ctx) {
84
105
  constraints: extractStringConstraints(schema, ctx.diagnostics, ctx.pointer)
85
106
  };
86
107
  }
108
+ /** Build a walked `NumberField` from a JSON Schema node. */
87
109
  function buildNumberField(schema, ctx) {
110
+ const isInteger = schema.type === "integer";
88
111
  return {
89
112
  ...buildBase(schema, ctx),
90
113
  type: "number",
91
- constraints: extractNumberConstraints(schema)
114
+ constraints: extractNumberConstraints(schema),
115
+ isInteger
92
116
  };
93
117
  }
118
+ /** Build a walked `BooleanField` from a JSON Schema node. */
94
119
  function buildBooleanField(schema, ctx) {
95
120
  return {
96
121
  ...buildBase(schema, ctx),
@@ -98,6 +123,7 @@ function buildBooleanField(schema, ctx) {
98
123
  constraints: {}
99
124
  };
100
125
  }
126
+ /** Build a walked `NullField` from a JSON Schema node. */
101
127
  function buildNullField(schema, ctx) {
102
128
  return {
103
129
  ...buildBase(schema, ctx),
@@ -105,6 +131,7 @@ function buildNullField(schema, ctx) {
105
131
  constraints: {}
106
132
  };
107
133
  }
134
+ /** Build a walked `UnknownField` (permissive open-shape) from a JSON Schema node. */
108
135
  function buildUnknownField(schema, ctx) {
109
136
  return {
110
137
  ...buildBase(schema, ctx),
@@ -112,6 +139,7 @@ function buildUnknownField(schema, ctx) {
112
139
  constraints: {}
113
140
  };
114
141
  }
142
+ /** Build a walked `FileField` from a JSON Schema node carrying `contentMediaType`. */
115
143
  function buildFileField(schema, ctx) {
116
144
  return {
117
145
  ...buildBase(schema, ctx),
@@ -148,6 +176,10 @@ function withoutKeys(schema, keys) {
148
176
  for (const [key, value] of Object.entries(schema)) if (!keys.includes(key)) result[key] = value;
149
177
  return result;
150
178
  }
179
+ /**
180
+ * Type guard for a JSON primitive: string, number, boolean, or null.
181
+ * Used to short-circuit walk-time decisions about leaf values.
182
+ */
151
183
  function isPrimitive(value) {
152
184
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null;
153
185
  }
@@ -1,7 +1,20 @@
1
- import { j as WalkedField } from "../types-BTB73MB8.mjs";
1
+ import { j as WalkedField } from "../types-BrYbjC7_.mjs";
2
2
  import { WalkOptions } from "./walkBuilders.mjs";
3
3
 
4
4
  //#region src/core/walker.d.ts
5
+ /**
6
+ * Walk a normalised JSON Schema and produce a {@link WalkedField} tree
7
+ * that drives every rendering pipeline in schema-components (React,
8
+ * HTML, streaming HTML).
9
+ *
10
+ * Reads standard Draft 2020-12 keywords only — no Zod internals. Handles
11
+ * `$ref` resolution, `allOf` merging, `nullable` detection from
12
+ * `anyOf`, and discriminated-union detection from `oneOf` + `const`.
13
+ * Pass `rootDocument` so cross-document refs resolve correctly and
14
+ * `diagnostics` to receive per-keyword warnings.
15
+ *
16
+ * @group Walkers
17
+ */
5
18
  declare function walk(schema: unknown, options?: WalkOptions): WalkedField;
6
19
  //#endregion
7
20
  export { walk };
@@ -90,6 +90,19 @@ function applyStrictestUnevaluated(merged, branches) {
90
90
  if (strictestProps !== void 0) merged.unevaluatedProperties = strictestProps;
91
91
  if (strictestItems !== void 0) merged.unevaluatedItems = strictestItems;
92
92
  }
93
+ /**
94
+ * Walk a normalised JSON Schema and produce a {@link WalkedField} tree
95
+ * that drives every rendering pipeline in schema-components (React,
96
+ * HTML, streaming HTML).
97
+ *
98
+ * Reads standard Draft 2020-12 keywords only — no Zod internals. Handles
99
+ * `$ref` resolution, `allOf` merging, `nullable` detection from
100
+ * `anyOf`, and discriminated-union detection from `oneOf` + `const`.
101
+ * Pass `rootDocument` so cross-document refs resolve correctly and
102
+ * `diagnostics` to receive per-keyword warnings.
103
+ *
104
+ * @group Walkers
105
+ */
93
106
  function walk(schema, options = {}) {
94
107
  const { componentMeta, rootMeta, fieldOverrides, rootDocument, diagnostics, externalResolver } = options;
95
108
  if (typeof schema === "boolean") return walkBooleanSchema(schema);
@@ -310,6 +323,11 @@ function walkBoolean(schema, ctx) {
310
323
  return buildBooleanField(schema, ctx);
311
324
  }
312
325
  function walkEnum(schema, enumValues, ctx) {
326
+ if (enumValues.length === 0) emitDiagnostic(ctx.diagnostics, {
327
+ code: "enum-empty",
328
+ message: "`enum` array is empty; per Draft 2020-12 §6.1.2 it must be non-empty. The schema describes an unsatisfiable value set.",
329
+ pointer: ctx.pointer
330
+ });
313
331
  return {
314
332
  ...buildBase(schema, ctx),
315
333
  type: "enum",
@@ -15,10 +15,14 @@
15
15
  /**
16
16
  * Machine-readable codes identifying each class of diagnostic.
17
17
  * Stable across releases — consumers can pattern-match on these.
18
+ *
19
+ * @group Diagnostics
18
20
  */
19
- type DiagnosticCode = "allof-conflict" | "assumed-draft" | "bare-exclusive-bound" | "conditional-fallback" | "cross-schema-relative-ref-unsupported" | "cyclic-header-ref" | "cyclic-link-ref" | "cyclic-parameter-ref" | "cyclic-path-item-ref" | "dependencies-conflict" | "dependent-required-invalid" | "depth-exceeded" | "discriminator-inconsistent" | "divisible-by-conflict" | "doc-not-object" | "dropped-swagger-feature" | "header-ref-too-deep" | "duplicate-body-parameter" | "duplicate-operation-id" | "dynamic-ref-degraded" | "enum-value-filtered" | "external-ref" | "invalid-const" | "invalid-id-fragment" | "keyword-out-of-draft" | "link-ref-too-deep" | "legacy-dependencies-split" | "legacy-dependencies-split-2019" | "non-json-media-type-fallback" | "parameter-missing-schema" | "parameter-ref-too-deep" | "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";
21
+ type DiagnosticCode = "allof-conflict" | "assumed-draft" | "bare-exclusive-bound" | "conditional-fallback" | "cross-schema-relative-ref-unsupported" | "cyclic-header-ref" | "cyclic-link-ref" | "cyclic-parameter-ref" | "cyclic-path-item-ref" | "dependencies-conflict" | "dependent-required-invalid" | "depth-exceeded" | "discriminator-duplicate" | "discriminator-inconsistent" | "divisible-by-conflict" | "doc-not-object" | "dropped-swagger-feature" | "header-ref-too-deep" | "duplicate-body-parameter" | "duplicate-operation-id" | "dynamic-ref-degraded" | "enum-empty" | "enum-value-filtered" | "external-ref" | "invalid-const" | "invalid-id-fragment" | "keyword-out-of-draft" | "link-ref-too-deep" | "legacy-dependencies-split" | "legacy-dependencies-split-2019" | "non-json-media-type-fallback" | "parameter-missing-schema" | "parameter-ref-too-deep" | "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
22
  /**
21
23
  * A single diagnostic emitted during schema processing.
24
+ *
25
+ * @group Diagnostics
22
26
  */
23
27
  interface Diagnostic {
24
28
  /** Machine-readable code for programmatic handling. */
@@ -32,10 +36,14 @@ interface Diagnostic {
32
36
  }
33
37
  /**
34
38
  * Callback that receives each diagnostic as it is emitted.
39
+ *
40
+ * @group Diagnostics
35
41
  */
36
42
  type DiagnosticSink = (d: Diagnostic) => void;
37
43
  /**
38
44
  * Diagnostics configuration threaded through the processing pipeline.
45
+ *
46
+ * @group Diagnostics
39
47
  */
40
48
  interface DiagnosticsOptions {
41
49
  /**
@@ -1,14 +1,17 @@
1
- import { T as SchemaType } from "./types-BTB73MB8.mjs";
1
+ import { T as SchemaType } from "./types-BrYbjC7_.mjs";
2
2
 
3
3
  //#region src/core/errors.d.ts
4
4
  /**
5
- * Base class for all schema-components errors.
6
- * Catch this to handle any library error uniformly.
5
+ * Base class for every schema-components error. Catch this to handle
6
+ * any library error uniformly.
7
7
  *
8
- * Forwards the optional `cause` to the native ES2022 `Error` constructor so
9
- * `error.cause` is wired up by the runtime and rendered correctly by
10
- * `util.inspect` ("Caused by: ..."). Subclasses that need a typed `cause`
11
- * field still get it via the platform's own `Error.cause` getter.
8
+ * Forwards the optional `cause` to the native ES2022 `Error` constructor
9
+ * so `error.cause` is wired up by the runtime and rendered correctly by
10
+ * `util.inspect` ("Caused by: ..."). Subclasses that need a typed
11
+ * `cause` field still get it via the platform's own `Error.cause`
12
+ * getter.
13
+ *
14
+ * @group Errors
12
15
  */
13
16
  declare class SchemaError extends Error {
14
17
  /** The schema input that caused the error. */
@@ -19,7 +22,12 @@ declare class SchemaError extends Error {
19
22
  * The adapter failed to convert the input schema to JSON Schema.
20
23
  *
21
24
  * Causes: invalid Zod schema, Zod 3 schema (unsupported), malformed
22
- * JSON Schema, missing OpenAPI ref, unsupported ref format.
25
+ * JSON Schema, missing OpenAPI ref, unsupported ref format,
26
+ * unrepresentable Zod types, conversion bugs, cycles, and duplicate
27
+ * ids. The `kind` field carries the precise classification — see the
28
+ * union declaration below.
29
+ *
30
+ * @group Errors
23
31
  */
24
32
  declare class SchemaNormalisationError extends SchemaError {
25
33
  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";
@@ -31,9 +39,10 @@ declare class SchemaNormalisationError extends SchemaError {
31
39
  constructor(message: string, schema: unknown, kind: SchemaNormalisationError["kind"], zodType?: string, cause?: unknown);
32
40
  }
33
41
  /**
34
- * A theme adapter's render function threw during rendering.
42
+ * A theme adapter's render function threw during rendering. The
43
+ * original error is preserved on `cause`.
35
44
  *
36
- * The `cause` is the original error from the render function.
45
+ * @group Errors
37
46
  */
38
47
  declare class SchemaRenderError extends SchemaError {
39
48
  /**
@@ -45,10 +54,11 @@ declare class SchemaRenderError extends SchemaError {
45
54
  constructor(message: string, schema: unknown, schemaType: SchemaType, cause: unknown);
46
55
  }
47
56
  /**
48
- * A field path couldn't be resolved against the walked schema tree.
57
+ * A field path could not be resolved against the walked schema tree.
58
+ * Produced by `<SchemaField>` when the `path` prop does not match any
59
+ * field in the schema.
49
60
  *
50
- * This is produced by `<SchemaField>` when the `path` prop doesn't
51
- * match any field in the schema.
61
+ * @group Errors
52
62
  */
53
63
  declare class SchemaFieldError extends SchemaError {
54
64
  /** The unresolvable dot-separated path. */
@@ -1,5 +1,6 @@
1
- import { j as WalkedField } from "../types-BTB73MB8.mjs";
2
- import { t as AllConstraints } from "../renderer-Ul9taFYp.mjs";
1
+ import { j as WalkedField } from "../types-BrYbjC7_.mjs";
2
+ import { AllConstraints } from "../core/renderer.mjs";
3
+ import { constraintHint } from "../core/constraintHint.mjs";
3
4
  import { HtmlAttributes, HtmlNode } from "./html.mjs";
4
5
 
5
6
  //#region src/html/a11y.d.ts
@@ -27,11 +28,6 @@ declare function buildInputId(path: string, key: string): string;
27
28
  * the HTML renderers.
28
29
  */
29
30
  declare function buildHintId(inputId: string): string;
30
- /**
31
- * Build a human-readable constraint description string.
32
- * Returns undefined if no constraints are present.
33
- */
34
- declare function constraintHint(c: AllConstraints): string | undefined;
35
31
  /**
36
32
  * Build `aria-required` attribute for required fields.
37
33
  * Returns an object to spread into `h()` attributes, or empty object.
@@ -1,3 +1,4 @@
1
+ import { constraintHint } from "../core/constraintHint.mjs";
1
2
  import { fieldDomId, hintIdFor } from "../core/idPath.mjs";
2
3
  import { h } from "./html.mjs";
3
4
  //#region src/html/a11y.ts
@@ -35,22 +36,6 @@ function buildHintId(inputId) {
35
36
  return hintIdFor(inputId);
36
37
  }
37
38
  /**
38
- * Build a human-readable constraint description string.
39
- * Returns undefined if no constraints are present.
40
- */
41
- function constraintHint(c) {
42
- const parts = [];
43
- if (c.minLength !== void 0) parts.push(`Minimum ${String(c.minLength)} characters`);
44
- if (c.maxLength !== void 0) parts.push(`Maximum ${String(c.maxLength)} characters`);
45
- if (c.minimum !== void 0) parts.push(`Minimum ${String(c.minimum)}`);
46
- if (c.maximum !== void 0) parts.push(`Maximum ${String(c.maximum)}`);
47
- if (c.pattern !== void 0 && c.format === void 0) parts.push("Must match pattern");
48
- if (c.minItems !== void 0) parts.push(`Minimum ${String(c.minItems)} items`);
49
- if (c.maxItems !== void 0) parts.push(`Maximum ${String(c.maxItems)} items`);
50
- if (parts.length === 0) return void 0;
51
- return parts.join(". ");
52
- }
53
- /**
54
39
  * Build `aria-required` attribute for required fields.
55
40
  * Returns an object to spread into `h()` attributes, or empty object.
56
41
  */