schema-components 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/adapter.d.mts +1 -1
- package/dist/core/constraints.d.mts +1 -1
- package/dist/core/diagnostics.d.mts +1 -1
- package/dist/core/merge.d.mts +14 -8
- package/dist/core/merge.mjs +81 -12
- package/dist/core/normalise.d.mts +1 -1
- package/dist/core/ref.d.mts +1 -1
- package/dist/core/renderer.d.mts +2 -2
- package/dist/core/renderer.mjs +50 -1
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/typeInference.d.mts +2 -2
- package/dist/core/walkBuilders.d.mts +2 -2
- package/dist/core/walker.mjs +2 -2
- package/dist/{diagnostics-DzbZmcLI.d.mts → diagnostics-BYk63jsC.d.mts} +1 -1
- package/dist/html/a11y.d.mts +13 -2
- package/dist/html/a11y.mjs +26 -2
- package/dist/html/renderToHtml.d.mts +1 -1
- package/dist/html/renderToHtml.mjs +5 -3
- package/dist/html/renderToHtmlStream.d.mts +1 -1
- package/dist/html/renderers.d.mts +4 -3
- package/dist/html/renderers.mjs +9 -13
- package/dist/html/streamRenderers.d.mts +1 -1
- package/dist/openapi/bundle.d.mts +9 -4
- package/dist/openapi/bundle.mjs +73 -15
- package/dist/openapi/components.d.mts +1 -1
- package/dist/openapi/components.mjs +22 -17
- package/dist/openapi/parser.mjs +8 -8
- package/dist/openapi/resolve.d.mts +13 -2
- package/dist/openapi/resolve.mjs +19 -3
- package/dist/react/SchemaComponent.d.mts +4 -4
- package/dist/react/SchemaComponent.mjs +2 -31
- package/dist/react/SchemaView.d.mts +4 -3
- package/dist/react/SchemaView.mjs +13 -44
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +1 -1
- package/dist/react/headlessRenderers.mjs +3 -2
- package/dist/{ref-DvWoULcy.d.mts → ref-Ckt5liZs.d.mts} +1 -1
- package/dist/{renderer-B3s8o2B8.d.mts → renderer-DXo-rXHJ.d.mts} +18 -1
- package/dist/themes/mantine.d.mts +1 -1
- package/dist/themes/mantine.mjs +4 -3
- package/dist/themes/mui.d.mts +1 -1
- package/dist/themes/mui.mjs +6 -5
- package/dist/themes/radix.d.mts +1 -1
- package/dist/themes/radix.mjs +3 -3
- package/dist/themes/shadcn.d.mts +1 -1
- package/dist/themes/shadcn.mjs +6 -5
- package/dist/{typeInference-k7FXfTVO.d.mts → typeInference-5JiqIZ8t.d.mts} +57 -4
- package/package.json +1 -1
package/dist/core/adapter.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { T as SchemaMeta, m as JsonObject } from "../types-D_5ST7SS.mjs";
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-BYk63jsC.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/adapter.d.ts
|
|
5
5
|
type SchemaInput = Record<string, unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { D as StringConstraints, f as FileConstraints, t as ArrayConstraints, x as ObjectConstraints, y as NumberConstraints } from "../types-D_5ST7SS.mjs";
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-BYk63jsC.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/constraints.d.ts
|
|
5
5
|
declare function extractStringConstraints(schema: Record<string, unknown>, diagnostics?: DiagnosticsOptions, pointer?: string): StringConstraints;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as appendPointer, i as DiagnosticsOptions, n as DiagnosticCode, o as emitDiagnostic, r as DiagnosticSink, t as Diagnostic } from "../diagnostics-
|
|
1
|
+
import { a as appendPointer, i as DiagnosticsOptions, n as DiagnosticCode, o as emitDiagnostic, r as DiagnosticSink, t as Diagnostic } from "../diagnostics-BYk63jsC.mjs";
|
|
2
2
|
export { Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticsOptions, appendPointer, emitDiagnostic };
|
package/dist/core/merge.d.mts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
+
import { i as DiagnosticsOptions } from "../diagnostics-BYk63jsC.mjs";
|
|
2
|
+
|
|
1
3
|
//#region src/core/merge.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Schema merging, nullable detection, and discriminated union detection.
|
|
4
|
-
*
|
|
5
|
-
* Used by the walker to handle `allOf`, `anyOf [T, null]`, and
|
|
6
|
-
* `oneOf` with discriminator properties.
|
|
7
|
-
*/
|
|
8
4
|
/**
|
|
9
5
|
* Annotation keywords that can appear as siblings of `$ref` per
|
|
10
6
|
* Draft 2020-12 / OpenAPI 3.1. Structural keywords (type, properties,
|
|
@@ -24,8 +20,13 @@ declare function mergeRefSiblings(referencer: Record<string, unknown>, resolvedM
|
|
|
24
20
|
/**
|
|
25
21
|
* Merge multiple JSON Schema objects from allOf into one.
|
|
26
22
|
* Merges: properties, required, meta fields, and constraints.
|
|
23
|
+
*
|
|
24
|
+
* Semantics are first-write-wins for meta and constraint keywords.
|
|
25
|
+
* When a later branch redefines a keyword with a non-equal value the
|
|
26
|
+
* later value is silently dropped — an `allof-conflict` diagnostic is
|
|
27
|
+
* emitted so the loss is visible to consumers.
|
|
27
28
|
*/
|
|
28
|
-
declare function mergeAllOf(schemas: unknown[]): Record<string, unknown>;
|
|
29
|
+
declare function mergeAllOf(schemas: unknown[], diagnostics?: DiagnosticsOptions, pointer?: string): Record<string, unknown>;
|
|
29
30
|
interface NormalisedAnyOf {
|
|
30
31
|
inner: Record<string, unknown>;
|
|
31
32
|
isNullable: boolean;
|
|
@@ -42,7 +43,12 @@ interface Discriminated {
|
|
|
42
43
|
/**
|
|
43
44
|
* Detect oneOf where every option is an object with a property
|
|
44
45
|
* that has a `const` value → discriminated union.
|
|
46
|
+
*
|
|
47
|
+
* When options carry inconsistent discriminator candidates (e.g. one
|
|
48
|
+
* uses `kind` while another uses `type`) detection fails and a
|
|
49
|
+
* `discriminator-inconsistent` diagnostic is emitted so callers can
|
|
50
|
+
* see why the union falls back to a generic oneOf.
|
|
45
51
|
*/
|
|
46
|
-
declare function detectDiscriminated(options: unknown[]): Discriminated | undefined;
|
|
52
|
+
declare function detectDiscriminated(options: unknown[], diagnostics?: DiagnosticsOptions, pointer?: string): Discriminated | undefined;
|
|
47
53
|
//#endregion
|
|
48
54
|
export { ANNOTATION_SIBLINGS, Discriminated, NormalisedAnyOf, detectDiscriminated, mergeAllOf, mergeRefSiblings, normaliseAnyOf };
|
package/dist/core/merge.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isObject } from "./guards.mjs";
|
|
2
|
+
import { emitDiagnostic } from "./diagnostics.mjs";
|
|
2
3
|
//#region src/core/merge.ts
|
|
3
4
|
/**
|
|
4
5
|
* Schema merging, nullable detection, and discriminated union detection.
|
|
@@ -19,6 +20,31 @@ function getObject(obj, key) {
|
|
|
19
20
|
return isObject(value) ? value : void 0;
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
23
|
+
* Structural equality for arbitrary JSON-like values. Used to decide
|
|
24
|
+
* whether a duplicated keyword across `allOf` branches genuinely
|
|
25
|
+
* conflicts (different values) or is benign (identical values).
|
|
26
|
+
*/
|
|
27
|
+
function deepEqual(a, b) {
|
|
28
|
+
if (a === b) return true;
|
|
29
|
+
if (typeof a !== typeof b) return false;
|
|
30
|
+
if (Array.isArray(a)) {
|
|
31
|
+
if (!Array.isArray(b) || a.length !== b.length) return false;
|
|
32
|
+
for (let i = 0; i < a.length; i++) if (!deepEqual(a[i], b[i])) return false;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if (isObject(a) && isObject(b)) {
|
|
36
|
+
const keysA = Object.keys(a);
|
|
37
|
+
const keysB = Object.keys(b);
|
|
38
|
+
if (keysA.length !== keysB.length) return false;
|
|
39
|
+
for (const key of keysA) {
|
|
40
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
41
|
+
if (!deepEqual(a[key], b[key])) return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
22
48
|
* Annotation keywords that can appear as siblings of `$ref` per
|
|
23
49
|
* Draft 2020-12 / OpenAPI 3.1. Structural keywords (type, properties,
|
|
24
50
|
* etc.) are NOT annotation siblings and should not be merged.
|
|
@@ -50,8 +76,13 @@ function mergeRefSiblings(referencer, resolvedMeta) {
|
|
|
50
76
|
/**
|
|
51
77
|
* Merge multiple JSON Schema objects from allOf into one.
|
|
52
78
|
* Merges: properties, required, meta fields, and constraints.
|
|
79
|
+
*
|
|
80
|
+
* Semantics are first-write-wins for meta and constraint keywords.
|
|
81
|
+
* When a later branch redefines a keyword with a non-equal value the
|
|
82
|
+
* later value is silently dropped — an `allof-conflict` diagnostic is
|
|
83
|
+
* emitted so the loss is visible to consumers.
|
|
53
84
|
*/
|
|
54
|
-
function mergeAllOf(schemas) {
|
|
85
|
+
function mergeAllOf(schemas, diagnostics, pointer = "") {
|
|
55
86
|
const merged = {};
|
|
56
87
|
const properties = {};
|
|
57
88
|
const required = [];
|
|
@@ -66,10 +97,30 @@ function mergeAllOf(schemas) {
|
|
|
66
97
|
for (const [key, value] of Object.entries(entry)) {
|
|
67
98
|
if (key === "properties" || key === "required" || key === "allOf" || key === "type") continue;
|
|
68
99
|
if (!(key in merged)) merged[key] = value;
|
|
100
|
+
else if (!deepEqual(merged[key], value)) emitDiagnostic(diagnostics, {
|
|
101
|
+
code: "allof-conflict",
|
|
102
|
+
message: `allOf branches define conflicting values for "${key}"; keeping the first occurrence and discarding subsequent values`,
|
|
103
|
+
pointer,
|
|
104
|
+
detail: {
|
|
105
|
+
key,
|
|
106
|
+
kept: merged[key],
|
|
107
|
+
discarded: value
|
|
108
|
+
}
|
|
109
|
+
});
|
|
69
110
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (type
|
|
111
|
+
const entryType = getString(entry, "type");
|
|
112
|
+
if (entryType !== void 0) {
|
|
113
|
+
if (!("type" in merged)) merged.type = entryType;
|
|
114
|
+
else if (!deepEqual(merged.type, entryType)) emitDiagnostic(diagnostics, {
|
|
115
|
+
code: "allof-conflict",
|
|
116
|
+
message: `allOf branches define conflicting values for "type"; keeping the first occurrence and discarding subsequent values`,
|
|
117
|
+
pointer,
|
|
118
|
+
detail: {
|
|
119
|
+
key: "type",
|
|
120
|
+
kept: merged.type,
|
|
121
|
+
discarded: entryType
|
|
122
|
+
}
|
|
123
|
+
});
|
|
73
124
|
}
|
|
74
125
|
}
|
|
75
126
|
if (Object.keys(properties).length > 0) merged.properties = properties;
|
|
@@ -98,22 +149,40 @@ function normaliseAnyOf(options) {
|
|
|
98
149
|
/**
|
|
99
150
|
* Detect oneOf where every option is an object with a property
|
|
100
151
|
* that has a `const` value → discriminated union.
|
|
152
|
+
*
|
|
153
|
+
* When options carry inconsistent discriminator candidates (e.g. one
|
|
154
|
+
* uses `kind` while another uses `type`) detection fails and a
|
|
155
|
+
* `discriminator-inconsistent` diagnostic is emitted so callers can
|
|
156
|
+
* see why the union falls back to a generic oneOf.
|
|
101
157
|
*/
|
|
102
|
-
function detectDiscriminated(options) {
|
|
158
|
+
function detectDiscriminated(options, diagnostics, pointer = "") {
|
|
103
159
|
if (options.length === 0) return void 0;
|
|
104
160
|
let discriminator;
|
|
161
|
+
const perOptionKeys = [];
|
|
105
162
|
for (const opt of options) {
|
|
106
163
|
if (!isObject(opt)) return void 0;
|
|
107
164
|
const props = getObject(opt, "properties");
|
|
108
165
|
if (props === void 0) return void 0;
|
|
109
|
-
|
|
110
|
-
for (const [key, value] of Object.entries(props)) if (isObject(value) && "const" in value)
|
|
111
|
-
|
|
112
|
-
|
|
166
|
+
const constKeys = [];
|
|
167
|
+
for (const [key, value] of Object.entries(props)) if (isObject(value) && "const" in value) constKeys.push(key);
|
|
168
|
+
if (constKeys.length === 0) {
|
|
169
|
+
perOptionKeys.push(void 0);
|
|
170
|
+
continue;
|
|
113
171
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
172
|
+
const foundKey = constKeys[0];
|
|
173
|
+
perOptionKeys.push(foundKey);
|
|
174
|
+
discriminator ??= foundKey;
|
|
175
|
+
}
|
|
176
|
+
if (perOptionKeys.some((k) => k === void 0)) return void 0;
|
|
177
|
+
const uniqueKeys = new Set(perOptionKeys);
|
|
178
|
+
if (uniqueKeys.size > 1) {
|
|
179
|
+
emitDiagnostic(diagnostics, {
|
|
180
|
+
code: "discriminator-inconsistent",
|
|
181
|
+
message: `oneOf options use inconsistent discriminator keys (${[...uniqueKeys].map((k) => `"${k ?? ""}"`).join(", ")}); rendering as a generic union`,
|
|
182
|
+
pointer,
|
|
183
|
+
detail: { candidates: perOptionKeys }
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
117
186
|
}
|
|
118
187
|
if (discriminator === void 0) return void 0;
|
|
119
188
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
1
|
+
import { i as DiagnosticsOptions } from "../diagnostics-BYk63jsC.mjs";
|
|
2
2
|
import { n as JsonSchemaDraft, r as OpenApiVersionInfo } from "../version-B5NV-35j.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/normalise.d.ts
|
package/dist/core/ref.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as findAnchor, i as dereference, n as RefOptions, o as resolveRef, r as countDistinctRefs, t as ExternalResolver } from "../ref-
|
|
1
|
+
import { a as findAnchor, i as dereference, n as RefOptions, o as resolveRef, r as countDistinctRefs, t as ExternalResolver } from "../ref-Ckt5liZs.mjs";
|
|
2
2
|
export { ExternalResolver, RefOptions, countDistinctRefs, dereference, findAnchor, resolveRef };
|
package/dist/core/renderer.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as HtmlRenderProps, c as RenderFunction, d as
|
|
2
|
-
export { AllConstraints, BaseFieldProps, ComponentResolver, HtmlRenderFunction, HtmlRenderProps, HtmlResolver, RESOLVER_KEYS, RenderFunction, RenderProps, getHtmlRenderFn, getRenderFunction, mergeHtmlResolvers, mergeResolvers, typeToKey };
|
|
1
|
+
import { a as HtmlRenderProps, c as RenderFunction, d as getHtmlRenderFn, f as getRenderFunction, h as typeToKey, i as HtmlRenderFunction, l as RenderProps, m as mergeResolvers, n as BaseFieldProps, o as HtmlResolver, p as mergeHtmlResolvers, r as ComponentResolver, s as RESOLVER_KEYS, t as AllConstraints, u as buildRenderProps } from "../renderer-DXo-rXHJ.mjs";
|
|
2
|
+
export { AllConstraints, BaseFieldProps, ComponentResolver, HtmlRenderFunction, HtmlRenderProps, HtmlResolver, RESOLVER_KEYS, RenderFunction, RenderProps, buildRenderProps, getHtmlRenderFn, getRenderFunction, mergeHtmlResolvers, mergeResolvers, typeToKey };
|
package/dist/core/renderer.mjs
CHANGED
|
@@ -1,4 +1,53 @@
|
|
|
1
1
|
//#region src/core/renderer.ts
|
|
2
|
+
/** No-op onChange used when callers render in read-only mode. */
|
|
3
|
+
function noopOnChange() {}
|
|
4
|
+
/**
|
|
5
|
+
* Build the `RenderProps` object handed to a resolver render function or a
|
|
6
|
+
* widget. Used by both the server-side `<SchemaView>` (which has no
|
|
7
|
+
* `onChange`) and the client-side `<SchemaComponent>` (which threads an
|
|
8
|
+
* `onChange` callback).
|
|
9
|
+
*
|
|
10
|
+
* When `onChange` is `undefined` the caller is rendering in read-only mode:
|
|
11
|
+
* a noop `onChange` is wired up, `readOnly` is forced to `true`, and
|
|
12
|
+
* `writeOnly` is forced to `false`. Otherwise the editability is taken
|
|
13
|
+
* from `tree.editability`.
|
|
14
|
+
*
|
|
15
|
+
* The duplicate sibling fields (`enumValues`, `element`, `fields`, etc.)
|
|
16
|
+
* are populated for backwards compatibility with renderers that have not
|
|
17
|
+
* yet migrated to reading from `tree` directly. New renderers should
|
|
18
|
+
* narrow on `tree.type` and read from `tree`.
|
|
19
|
+
*/
|
|
20
|
+
function buildRenderProps(tree, value, onChange, renderChild, path) {
|
|
21
|
+
const isReadOnly = onChange === void 0 || tree.editability === "presentation";
|
|
22
|
+
const isWriteOnly = onChange !== void 0 && tree.editability === "input";
|
|
23
|
+
const props = {
|
|
24
|
+
value,
|
|
25
|
+
onChange: onChange ?? noopOnChange,
|
|
26
|
+
readOnly: isReadOnly,
|
|
27
|
+
writeOnly: isWriteOnly,
|
|
28
|
+
meta: tree.meta,
|
|
29
|
+
constraints: tree.constraints,
|
|
30
|
+
path,
|
|
31
|
+
tree,
|
|
32
|
+
renderChild
|
|
33
|
+
};
|
|
34
|
+
if (tree.type === "enum") props.enumValues = tree.enumValues;
|
|
35
|
+
if (tree.type === "array" && tree.element !== void 0) props.element = tree.element;
|
|
36
|
+
if (tree.type === "object") props.fields = tree.fields;
|
|
37
|
+
if (tree.type === "union" || tree.type === "discriminatedUnion") props.options = tree.options;
|
|
38
|
+
if (tree.type === "discriminatedUnion") props.discriminator = tree.discriminator;
|
|
39
|
+
if (tree.type === "record") props.keyType = tree.keyType;
|
|
40
|
+
if (tree.type === "record") props.valueType = tree.valueType;
|
|
41
|
+
if (tree.type === "tuple") props.prefixItems = tree.prefixItems;
|
|
42
|
+
if (tree.type === "conditional") props.ifClause = tree.ifClause;
|
|
43
|
+
if (tree.type === "conditional" && tree.thenClause !== void 0) props.thenClause = tree.thenClause;
|
|
44
|
+
if (tree.type === "conditional" && tree.elseClause !== void 0) props.elseClause = tree.elseClause;
|
|
45
|
+
if (tree.type === "negation") props.negated = tree.negated;
|
|
46
|
+
if (tree.type === "recursive") props.refTarget = tree.refTarget;
|
|
47
|
+
if (tree.type === "literal") props.literalValues = tree.literalValues;
|
|
48
|
+
if (tree.examples !== void 0) props.examples = tree.examples;
|
|
49
|
+
return props;
|
|
50
|
+
}
|
|
2
51
|
const RESOLVER_KEYS = [
|
|
3
52
|
"string",
|
|
4
53
|
"number",
|
|
@@ -77,4 +126,4 @@ function mergeHtmlResolvers(user, fallback) {
|
|
|
77
126
|
return merged;
|
|
78
127
|
}
|
|
79
128
|
//#endregion
|
|
80
|
-
export { RESOLVER_KEYS, getHtmlRenderFn, getRenderFunction, mergeHtmlResolvers, mergeResolvers, typeToKey };
|
|
129
|
+
export { RESOLVER_KEYS, buildRenderProps, getHtmlRenderFn, getRenderFunction, mergeHtmlResolvers, mergeResolvers, typeToKey };
|
package/dist/core/swagger2.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { FromJSONSchema, InferParameterOverrides, InferRequestBodyFields, InferResponseFields, OpenAPIRequestBodyType, OpenAPIResponseType, PathOfType, ResolveOpenAPIRef, TypeAtPath, UnsafeFields, __SchemaInferenceFellBack };
|
|
1
|
+
import { a as InferResponseFields, c as PathOfType, d as UnsafeFields, f as __SchemaInferenceFellBack, i as InferRequestBodyFields, l as ResolveOpenAPIRef, n as FromJSONSchema, o as OpenAPIRequestBodyType, r as InferParameterOverrides, s as OpenAPIResponseType, t as DEFAULT_MAX_DEPTH, u as TypeAtPath } from "../typeInference-5JiqIZ8t.mjs";
|
|
2
|
+
export { DEFAULT_MAX_DEPTH, FromJSONSchema, InferParameterOverrides, InferRequestBodyFields, InferResponseFields, OpenAPIRequestBodyType, OpenAPIResponseType, PathOfType, ResolveOpenAPIRef, TypeAtPath, UnsafeFields, __SchemaInferenceFellBack };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
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-D_5ST7SS.mjs";
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
3
|
-
import { t as ExternalResolver } from "../ref-
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-BYk63jsC.mjs";
|
|
3
|
+
import { t as ExternalResolver } from "../ref-Ckt5liZs.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/core/walkBuilders.d.ts
|
|
6
6
|
declare function getString(obj: Record<string, unknown>, key: string): string | undefined;
|
package/dist/core/walker.mjs
CHANGED
|
@@ -74,7 +74,7 @@ function walk(schema, options = {}) {
|
|
|
74
74
|
}
|
|
75
75
|
function walkNode(schema, ctx) {
|
|
76
76
|
const allOf = getArray(schema, "allOf");
|
|
77
|
-
if (allOf !== void 0 && allOf.length > 0) return walkNode(mergeAllOf(allOf), ctx);
|
|
77
|
+
if (allOf !== void 0 && allOf.length > 0) return walkNode(mergeAllOf(allOf, ctx.diagnostics, ctx.pointer), ctx);
|
|
78
78
|
const anyOf = getArray(schema, "anyOf");
|
|
79
79
|
if (anyOf !== void 0) {
|
|
80
80
|
const nullable = normaliseAnyOf(anyOf);
|
|
@@ -86,7 +86,7 @@ function walkNode(schema, ctx) {
|
|
|
86
86
|
}
|
|
87
87
|
const oneOf = getArray(schema, "oneOf");
|
|
88
88
|
if (oneOf !== void 0) {
|
|
89
|
-
const discriminated = detectDiscriminated(oneOf);
|
|
89
|
+
const discriminated = detectDiscriminated(oneOf, ctx.diagnostics, ctx.pointer);
|
|
90
90
|
if (discriminated !== void 0) return walkDiscriminatedUnion(discriminated, ctx);
|
|
91
91
|
return walkUnion(oneOf, ctx);
|
|
92
92
|
}
|
|
@@ -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";
|
|
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";
|
|
20
20
|
/**
|
|
21
21
|
* A single diagnostic emitted during schema processing.
|
|
22
22
|
*/
|
package/dist/html/a11y.d.mts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { M as WalkedField } from "../types-D_5ST7SS.mjs";
|
|
2
|
-
import { t as AllConstraints } from "../renderer-
|
|
2
|
+
import { t as AllConstraints } from "../renderer-DXo-rXHJ.mjs";
|
|
3
3
|
import { HtmlAttributes, HtmlNode } from "./html.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/html/a11y.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Append a structural suffix to a parent path. Mirrors the canonical
|
|
8
|
+
* `joinPath` used by the React renderers: when the suffix is omitted
|
|
9
|
+
* (e.g. transparent wrappers like union options) the parent path is
|
|
10
|
+
* returned unchanged so the child inherits the parent's id.
|
|
11
|
+
*
|
|
12
|
+
* Suffixes are dot-joined except for bracketed array indices like `[0]`
|
|
13
|
+
* which append directly so `tags` + `[0]` becomes `tags[0]` rather than
|
|
14
|
+
* `tags.[0]`.
|
|
15
|
+
*/
|
|
16
|
+
declare function joinPath(parent: string, suffix: string | undefined): string;
|
|
6
17
|
/**
|
|
7
18
|
* Build the input ID for a field at a given path.
|
|
8
19
|
*/
|
|
@@ -45,4 +56,4 @@ declare function buildHintElement(inputId: string, constraints: AllConstraints):
|
|
|
45
56
|
*/
|
|
46
57
|
declare function requiredIndicator(field: WalkedField): HtmlNode;
|
|
47
58
|
//#endregion
|
|
48
|
-
export { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAttrs, buildHintElement, buildHintId, buildInputId, constraintHint, requiredIndicator };
|
|
59
|
+
export { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAttrs, buildHintElement, buildHintId, buildInputId, constraintHint, joinPath, requiredIndicator };
|
package/dist/html/a11y.mjs
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
import { h } from "./html.mjs";
|
|
2
2
|
//#region src/html/a11y.ts
|
|
3
3
|
/**
|
|
4
|
+
* Append a structural suffix to a parent path. Mirrors the canonical
|
|
5
|
+
* `joinPath` used by the React renderers: when the suffix is omitted
|
|
6
|
+
* (e.g. transparent wrappers like union options) the parent path is
|
|
7
|
+
* returned unchanged so the child inherits the parent's id.
|
|
8
|
+
*
|
|
9
|
+
* Suffixes are dot-joined except for bracketed array indices like `[0]`
|
|
10
|
+
* which append directly so `tags` + `[0]` becomes `tags[0]` rather than
|
|
11
|
+
* `tags.[0]`.
|
|
12
|
+
*/
|
|
13
|
+
function joinPath(parent, suffix) {
|
|
14
|
+
if (suffix === void 0 || suffix.length === 0) return parent;
|
|
15
|
+
if (parent.length === 0) return suffix;
|
|
16
|
+
if (suffix.startsWith("[")) return `${parent}${suffix}`;
|
|
17
|
+
return `${parent}.${suffix}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
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.
|
|
23
|
+
*/
|
|
24
|
+
function normaliseIdSegment(value) {
|
|
25
|
+
return value.replace(/[.[\]]+/g, "-").replace(/-+$/g, "");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
4
28
|
* Build the input ID for a field at a given path.
|
|
5
29
|
*/
|
|
6
30
|
function buildInputId(path, key) {
|
|
7
|
-
return `sc-${path
|
|
31
|
+
return `sc-${normaliseIdSegment(joinPath(path, key))}`;
|
|
8
32
|
}
|
|
9
33
|
/**
|
|
10
34
|
* Derive the hint element ID from the input ID.
|
|
@@ -78,4 +102,4 @@ function requiredIndicator(field) {
|
|
|
78
102
|
}, " *");
|
|
79
103
|
}
|
|
80
104
|
//#endregion
|
|
81
|
-
export { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAttrs, buildHintElement, buildHintId, buildInputId, constraintHint, requiredIndicator };
|
|
105
|
+
export { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAttrs, buildHintElement, buildHintId, buildInputId, constraintHint, joinPath, requiredIndicator };
|
|
@@ -2,6 +2,7 @@ import { normaliseSchema } from "../core/adapter.mjs";
|
|
|
2
2
|
import { getHtmlRenderFn, mergeHtmlResolvers } from "../core/renderer.mjs";
|
|
3
3
|
import { walk } from "../core/walker.mjs";
|
|
4
4
|
import { h, serialize } from "./html.mjs";
|
|
5
|
+
import { joinPath } from "./a11y.mjs";
|
|
5
6
|
import { defaultHtmlResolver } from "./renderers.mjs";
|
|
6
7
|
//#region src/html/renderToHtml.ts
|
|
7
8
|
/**
|
|
@@ -45,11 +46,12 @@ function renderToHtml(schema, options = {}) {
|
|
|
45
46
|
});
|
|
46
47
|
const resolver = options.resolver ?? defaultHtmlResolver;
|
|
47
48
|
const MAX_HTML_DEPTH = 10;
|
|
48
|
-
const makeRenderChild = (currentDepth) => (childTree, childValue, pathSuffix) => {
|
|
49
|
+
const makeRenderChild = (currentDepth, parentPath) => (childTree, childValue, pathSuffix) => {
|
|
49
50
|
if (currentDepth >= MAX_HTML_DEPTH) return `<fieldset class="sc-recursive"><em>\u21bb ${typeof childTree.meta.description === "string" ? childTree.meta.description : "schema"} (recursive)</em></fieldset>`;
|
|
50
|
-
|
|
51
|
+
const childPath = joinPath(parentPath, pathSuffix);
|
|
52
|
+
return renderFieldHtml(childTree, childValue, resolver, childPath, makeRenderChild(currentDepth + 1, childPath));
|
|
51
53
|
};
|
|
52
|
-
const renderChild = makeRenderChild(0);
|
|
54
|
+
const renderChild = makeRenderChild(0, "");
|
|
53
55
|
return renderFieldHtml(tree, options.value ?? tree.defaultValue, resolver, "", renderChild);
|
|
54
56
|
}
|
|
55
57
|
function renderFieldHtml(tree, value, resolver, path, renderChild) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { M as WalkedField } from "../types-D_5ST7SS.mjs";
|
|
2
|
-
import { o as HtmlResolver } from "../renderer-
|
|
2
|
+
import { o as HtmlResolver } from "../renderer-DXo-rXHJ.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/html/renderers.d.ts
|
|
5
5
|
declare function dateInputType(format: string | undefined): string | undefined;
|
|
6
6
|
/**
|
|
7
|
-
* Normalise a
|
|
8
|
-
* Dots
|
|
7
|
+
* Normalise a structural path into a valid, `sc-` prefixed HTML ID.
|
|
8
|
+
* Dots (object nesting) and brackets (array indices) become hyphens so
|
|
9
|
+
* the id remains a valid CSS selector and predictable in test queries.
|
|
9
10
|
*/
|
|
10
11
|
declare function fieldId(path: string): string;
|
|
11
12
|
declare function matchUnionOption(options: WalkedField[], value: unknown): WalkedField | undefined;
|
package/dist/html/renderers.mjs
CHANGED
|
@@ -7,11 +7,12 @@ function dateInputType(format) {
|
|
|
7
7
|
if (format === "date-time" || format === "datetime") return "datetime-local";
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Normalise a
|
|
11
|
-
* Dots
|
|
10
|
+
* Normalise a structural path into a valid, `sc-` prefixed HTML ID.
|
|
11
|
+
* Dots (object nesting) and brackets (array indices) become hyphens so
|
|
12
|
+
* the id remains a valid CSS selector and predictable in test queries.
|
|
12
13
|
*/
|
|
13
14
|
function fieldId(path) {
|
|
14
|
-
return `sc-${path.replace(
|
|
15
|
+
return `sc-${path.replace(/[.[\]]+/g, "-").replace(/-+$/g, "")}`;
|
|
15
16
|
}
|
|
16
17
|
function renderStringHtml(props) {
|
|
17
18
|
if (props.readOnly) return serialize(renderStringReadOnly(props));
|
|
@@ -167,7 +168,7 @@ function renderObjectNode(props) {
|
|
|
167
168
|
for (const [key, field] of sortedEntries) {
|
|
168
169
|
const label = typeof field.meta.description === "string" ? field.meta.description : key;
|
|
169
170
|
const childValue = obj[key];
|
|
170
|
-
const childHtml = props.renderChild(field, childValue,
|
|
171
|
+
const childHtml = props.renderChild(field, childValue, key);
|
|
171
172
|
children.push(h("dt", { class: "sc-label" }, label));
|
|
172
173
|
children.push(h("dd", { class: "sc-value" }, raw(childHtml)));
|
|
173
174
|
}
|
|
@@ -180,9 +181,8 @@ function renderObjectNode(props) {
|
|
|
180
181
|
for (const [key, field] of sortedEntries) {
|
|
181
182
|
const label = typeof field.meta.description === "string" ? field.meta.description : key;
|
|
182
183
|
const fieldId = buildInputId(props.path, key);
|
|
183
|
-
const childPath = props.path ? `${props.path}.${key}` : key;
|
|
184
184
|
const childValue = obj[key];
|
|
185
|
-
const childHtml = props.renderChild(field, childValue,
|
|
185
|
+
const childHtml = props.renderChild(field, childValue, key);
|
|
186
186
|
const required = requiredIndicator(field);
|
|
187
187
|
const labelContent = [label];
|
|
188
188
|
if (required !== void 0) labelContent.push(required);
|
|
@@ -205,13 +205,9 @@ function renderArrayNode(props) {
|
|
|
205
205
|
const arr = Array.isArray(props.value) ? props.value : [];
|
|
206
206
|
const element = props.element;
|
|
207
207
|
if (element === void 0) return "";
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
});
|
|
211
|
-
if (props.readOnly) return h("ul", { class: "sc-array" }, ...items);
|
|
212
|
-
return h("div", { class: "sc-array" }, ...arr.map((item) => {
|
|
213
|
-
return h("div", {}, raw(props.renderChild(element, item)));
|
|
214
|
-
}));
|
|
208
|
+
const childHtmls = arr.map((item, i) => props.renderChild(element, item, `[${String(i)}]`));
|
|
209
|
+
if (props.readOnly) return h("ul", { class: "sc-array" }, ...childHtmls.map((childHtml) => h("li", { class: "sc-item" }, raw(childHtml))));
|
|
210
|
+
return h("div", { class: "sc-array" }, ...childHtmls.map((childHtml) => h("div", {}, raw(childHtml))));
|
|
215
211
|
}
|
|
216
212
|
function renderRecordHtml(props) {
|
|
217
213
|
return serialize(renderRecordNode(props));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { M as WalkedField } from "../types-D_5ST7SS.mjs";
|
|
2
|
-
import { o as HtmlResolver } from "../renderer-
|
|
2
|
+
import { o as HtmlResolver } from "../renderer-DXo-rXHJ.mjs";
|
|
3
3
|
import { HtmlElement } from "./html.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/html/streamRenderers.d.ts
|
|
@@ -34,13 +34,18 @@ type BundleResolver = (uri: string) => unknown;
|
|
|
34
34
|
*
|
|
35
35
|
* Walks every $ref in the document. For external refs (not starting with `#`),
|
|
36
36
|
* calls the resolver to fetch the external document, extracts the referenced
|
|
37
|
-
* schema, inlines it into `components.schemas`
|
|
38
|
-
* rewrites the $ref to point
|
|
37
|
+
* schema, inlines it into `components.schemas` under a synthesised name, and
|
|
38
|
+
* rewrites the original $ref to point at the new internal location
|
|
39
|
+
* (`#/components/schemas/<name>`).
|
|
40
|
+
*
|
|
41
|
+
* Identical external refs share a single entry — the second occurrence of
|
|
42
|
+
* the same `(uri, fragment)` pair reuses the name produced for the first.
|
|
43
|
+
* Name collisions between different refs are resolved by suffixing a counter.
|
|
39
44
|
*
|
|
40
45
|
* The resolver is called once per unique URI and the result is cached.
|
|
41
46
|
*
|
|
42
|
-
* Returns a deep-cloned document with all external refs
|
|
43
|
-
* The original document is never mutated.
|
|
47
|
+
* Returns a deep-cloned document with all external refs replaced by internal
|
|
48
|
+
* refs. The original document is never mutated.
|
|
44
49
|
*/
|
|
45
50
|
declare function bundleOpenApiDoc(doc: Record<string, unknown>, resolver: BundleResolver): Promise<Record<string, unknown>>;
|
|
46
51
|
//#endregion
|