cf-json-schema-viz 0.1.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/LICENSE +190 -0
- package/README.md +105 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.js +1195 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +480 -0
- package/package.json +70 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1195 @@
|
|
|
1
|
+
import { isRootNode, isRegularNode, SchemaCombinerName, isMirroredNode, isReferenceNode, isBooleanishNode, SchemaNodeKind, SchemaTree } from '@stoplight/json-schema-tree';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { atom, useSetAtom, useAtomValue, Provider } from 'jotai';
|
|
4
|
+
import * as React2 from 'react';
|
|
5
|
+
import { isPlainObject, extractPointerFromRef, pointerToPath, getLastPathSegment } from '@stoplight/json';
|
|
6
|
+
import { atomFamily } from 'jotai/utils';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
import { CaretRight, CaretDown, Check, Warning } from '@phosphor-icons/react';
|
|
9
|
+
import { Select as Select$1 } from '@base-ui/react/select';
|
|
10
|
+
import { Menu } from '@base-ui/react/menu';
|
|
11
|
+
|
|
12
|
+
// src/components/JsonSchemaViewer.tsx
|
|
13
|
+
var JSVOptionsContext = React2.createContext({
|
|
14
|
+
defaultExpandedDepth: 0,
|
|
15
|
+
viewMode: "standalone",
|
|
16
|
+
hideExamples: false
|
|
17
|
+
});
|
|
18
|
+
var useJSVOptionsContext = () => React2.useContext(JSVOptionsContext);
|
|
19
|
+
var JSVOptionsContextProvider = JSVOptionsContext.Provider;
|
|
20
|
+
|
|
21
|
+
// src/guards/isNonNullable.ts
|
|
22
|
+
function isNonNullable(maybeNullable) {
|
|
23
|
+
return maybeNullable !== void 0 && maybeNullable !== null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/tree/utils.ts
|
|
27
|
+
var isNonEmptyParentNode = (node) => isRegularNode(node) && !!node.children && node.children.length > 0;
|
|
28
|
+
function isFlattenableNode(node) {
|
|
29
|
+
if (!isRegularNode(node)) return false;
|
|
30
|
+
if (!isArrayNode(node) && !isDictionaryNode(node) || !isNonNullable(node.children) || node.children.length === 0) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return node.children.length === 1 && (isRegularNode(node.children[0]) && (!isArrayNode(node) || !isDictionaryNode(node.children[0])) || isReferenceNode(node.children[0]) && node.children[0].error !== null);
|
|
34
|
+
}
|
|
35
|
+
function isPrimitiveArray(node) {
|
|
36
|
+
return isFlattenableNode(node) && isArrayNode(node) && isRegularNode(node.children[0]) && node.children[0].simple;
|
|
37
|
+
}
|
|
38
|
+
function isPrimitiveDictionary(node) {
|
|
39
|
+
return isFlattenableNode(node) && isDictionaryNode(node) && isRegularNode(node.children[0]) && node.children[0].simple;
|
|
40
|
+
}
|
|
41
|
+
function isComplexArray(node) {
|
|
42
|
+
return isFlattenableNode(node) && isArrayNode(node) && isRegularNode(node.children[0]) && !node.children[0].simple;
|
|
43
|
+
}
|
|
44
|
+
function isComplexDictionary(node) {
|
|
45
|
+
return isFlattenableNode(node) && isDictionaryNode(node) && isRegularNode(node.children[0]) && !node.children[0].simple;
|
|
46
|
+
}
|
|
47
|
+
function isDictionaryNode(node) {
|
|
48
|
+
return isRegularNode(node) && node.primaryType === SchemaNodeKind.Object && isPlainObject(node.fragment.additionalProperties);
|
|
49
|
+
}
|
|
50
|
+
function isArrayNode(node) {
|
|
51
|
+
return isRegularNode(node) && node.primaryType === SchemaNodeKind.Array;
|
|
52
|
+
}
|
|
53
|
+
function visibleChildren(node) {
|
|
54
|
+
if (!isRegularNode(node) || isPrimitiveArray(node) || isPrimitiveDictionary(node)) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
if (isComplexArray(node) || isComplexDictionary(node)) {
|
|
58
|
+
return node.children[0].children ?? [];
|
|
59
|
+
}
|
|
60
|
+
return node.children ?? [];
|
|
61
|
+
}
|
|
62
|
+
function isPropertyRequired(schemaNode) {
|
|
63
|
+
const { parent } = schemaNode;
|
|
64
|
+
if (parent === null || !isRegularNode(parent) || schemaNode.subpath.length === 0) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return !!parent.required?.includes(schemaNode.subpath[schemaNode.subpath.length - 1]);
|
|
68
|
+
}
|
|
69
|
+
function isValidViewMode(node, viewMode) {
|
|
70
|
+
const { validations } = node;
|
|
71
|
+
if (!!validations.writeOnly === !!validations.readOnly) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return !(viewMode === "read" && !!validations.writeOnly || viewMode === "write" && !!validations.readOnly);
|
|
75
|
+
}
|
|
76
|
+
function isRenderableNode(node) {
|
|
77
|
+
if (node.parent === null) return true;
|
|
78
|
+
if (isDictionaryNode(node.parent)) {
|
|
79
|
+
return node.subpath.length !== 2 || node.subpath[0] !== "properties";
|
|
80
|
+
}
|
|
81
|
+
if (isArrayNode(node.parent)) {
|
|
82
|
+
return node.subpath[0] !== "additionalItems";
|
|
83
|
+
}
|
|
84
|
+
if (isRegularNode(node.parent) && node.parent.primaryType === SchemaNodeKind.Object && isBooleanishNode(node)) {
|
|
85
|
+
return !(node.subpath.length === 1 || node.subpath[0] === "additionalProperties");
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
function shouldNodeBeIncluded(node, viewMode = "standalone") {
|
|
90
|
+
return (isReferenceNode(node) || isRootNode(node) || isRenderableNode(node)) && (!isRegularNode(node) || isValidViewMode(node, viewMode));
|
|
91
|
+
}
|
|
92
|
+
var hoveredNodeAtom = atom(null);
|
|
93
|
+
var isNodeHoveredAtom = atomFamily(
|
|
94
|
+
(node) => atom((get) => node === get(hoveredNodeAtom))
|
|
95
|
+
);
|
|
96
|
+
atomFamily(
|
|
97
|
+
(parent) => atom((get) => {
|
|
98
|
+
const hoveredNode = get(hoveredNodeAtom);
|
|
99
|
+
if (!hoveredNode || hoveredNode === parent) return false;
|
|
100
|
+
return hoveredNode.parent === parent;
|
|
101
|
+
})
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// src/components/PathCrumbs/state.ts
|
|
105
|
+
var pathCrumbsAtom = atom((get) => {
|
|
106
|
+
const node = get(hoveredNodeAtom);
|
|
107
|
+
if (!node) return [];
|
|
108
|
+
return propertyPathToObjectPath(node);
|
|
109
|
+
});
|
|
110
|
+
function propertyPathToObjectPath(node) {
|
|
111
|
+
const objectPath = [];
|
|
112
|
+
let currentNode = node;
|
|
113
|
+
while (currentNode && !isRootNode(currentNode)) {
|
|
114
|
+
if (isRegularNode(currentNode)) {
|
|
115
|
+
const pathPart = currentNode.subpath[currentNode.subpath.length - 1];
|
|
116
|
+
if (currentNode.primaryType === "array") {
|
|
117
|
+
const key = `${pathPart || ""}[]`;
|
|
118
|
+
if (objectPath[objectPath.length - 1]) {
|
|
119
|
+
objectPath[objectPath.length - 1] = key;
|
|
120
|
+
} else {
|
|
121
|
+
objectPath.push(key);
|
|
122
|
+
}
|
|
123
|
+
} else if (pathPart && (currentNode.subpath.length !== 2 || !["allOf", "oneOf", "anyOf"].includes(currentNode.subpath[0]))) {
|
|
124
|
+
objectPath.push(currentNode.subpath[currentNode.subpath.length - 1]);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
currentNode = currentNode.parent;
|
|
128
|
+
}
|
|
129
|
+
return objectPath.reverse();
|
|
130
|
+
}
|
|
131
|
+
var SCROLL_THRESHOLD = 20;
|
|
132
|
+
var PathCrumbs = ({ parentCrumbs = [] }) => {
|
|
133
|
+
const pathCrumbs = useAtomValue(pathCrumbsAtom);
|
|
134
|
+
const { disableCrumbs } = useJSVOptionsContext();
|
|
135
|
+
const crumbsRef = React2.useRef(null);
|
|
136
|
+
const [style, setStyle] = React2.useState({
|
|
137
|
+
position: "fixed",
|
|
138
|
+
top: -100,
|
|
139
|
+
// Start off-screen
|
|
140
|
+
left: 0,
|
|
141
|
+
width: 0
|
|
142
|
+
});
|
|
143
|
+
const [hasScrolled, setHasScrolled] = React2.useState(false);
|
|
144
|
+
React2.useEffect(() => {
|
|
145
|
+
const crumbsEl = crumbsRef.current;
|
|
146
|
+
if (!crumbsEl) return;
|
|
147
|
+
const scrollContainer = crumbsEl.closest(".jsv-root");
|
|
148
|
+
if (!scrollContainer) return;
|
|
149
|
+
const updatePosition = () => {
|
|
150
|
+
const containerRect = scrollContainer.getBoundingClientRect();
|
|
151
|
+
const scrolled = scrollContainer.scrollTop > SCROLL_THRESHOLD;
|
|
152
|
+
setHasScrolled(scrolled);
|
|
153
|
+
setStyle({
|
|
154
|
+
position: "fixed",
|
|
155
|
+
top: Math.max(0, containerRect.top),
|
|
156
|
+
left: containerRect.left,
|
|
157
|
+
width: containerRect.width
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
updatePosition();
|
|
161
|
+
scrollContainer.addEventListener("scroll", updatePosition);
|
|
162
|
+
window.addEventListener("scroll", updatePosition);
|
|
163
|
+
window.addEventListener("resize", updatePosition);
|
|
164
|
+
return () => {
|
|
165
|
+
scrollContainer.removeEventListener("scroll", updatePosition);
|
|
166
|
+
window.removeEventListener("scroll", updatePosition);
|
|
167
|
+
window.removeEventListener("resize", updatePosition);
|
|
168
|
+
};
|
|
169
|
+
}, []);
|
|
170
|
+
if (disableCrumbs) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const parentCrumbElems = [];
|
|
174
|
+
parentCrumbs.forEach((crumb, i) => {
|
|
175
|
+
parentCrumbElems.push(/* @__PURE__ */ jsx("span", { children: crumb }, i));
|
|
176
|
+
});
|
|
177
|
+
const pathCrumbElems = [];
|
|
178
|
+
pathCrumbs.forEach((crumb, i) => {
|
|
179
|
+
if (pathCrumbs[i + 1]) {
|
|
180
|
+
pathCrumbElems.push(/* @__PURE__ */ jsx("span", { children: crumb }, i));
|
|
181
|
+
} else {
|
|
182
|
+
pathCrumbElems.push(
|
|
183
|
+
/* @__PURE__ */ jsx("span", { className: "jsv-crumb-current", children: crumb }, i)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
const hasCrumbs = parentCrumbElems.length > 0 || pathCrumbElems.length > 0;
|
|
188
|
+
const isVisible = hasCrumbs && hasScrolled;
|
|
189
|
+
return /* @__PURE__ */ jsxs("div", { ref: crumbsRef, className: "jsv-crumbs", style, "data-visible": isVisible, children: [
|
|
190
|
+
parentCrumbElems.map((elem, i) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
|
|
191
|
+
elem,
|
|
192
|
+
i < parentCrumbElems.length - 1 && /* @__PURE__ */ jsx("span", { children: "/" })
|
|
193
|
+
] }, `parent-${i}`)),
|
|
194
|
+
parentCrumbElems.length > 0 && pathCrumbElems.length > 0 && /* @__PURE__ */ jsx("span", { children: "/" }),
|
|
195
|
+
pathCrumbElems.map((elem, i) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
|
|
196
|
+
elem,
|
|
197
|
+
i < pathCrumbElems.length - 1 && /* @__PURE__ */ jsx("span", { style: { fontWeight: 700 }, children: "." })
|
|
198
|
+
] }, `path-${i}`))
|
|
199
|
+
] });
|
|
200
|
+
};
|
|
201
|
+
({
|
|
202
|
+
[SchemaCombinerName.AllOf]: "and",
|
|
203
|
+
[SchemaCombinerName.AnyOf]: "and/or",
|
|
204
|
+
[SchemaCombinerName.OneOf]: "or"
|
|
205
|
+
});
|
|
206
|
+
var COMMON_JSON_SCHEMA_AND_OAS_FORMATS = {
|
|
207
|
+
// strings are omitted because they are the default type to apply format to
|
|
208
|
+
number: ["byte", "int32", "int64", "float", "double"],
|
|
209
|
+
get integer() {
|
|
210
|
+
return this.number;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
var COMBINER_NAME_MAP = {
|
|
214
|
+
allOf: "all of",
|
|
215
|
+
anyOf: "any of",
|
|
216
|
+
oneOf: "one of"
|
|
217
|
+
};
|
|
218
|
+
var SKIP_HASHING = false;
|
|
219
|
+
function fnv1a52(str) {
|
|
220
|
+
const FNV_PRIME = 16777619;
|
|
221
|
+
const FNV_OFFSET = 2166136261;
|
|
222
|
+
let hash2 = FNV_OFFSET;
|
|
223
|
+
for (let i = 0; i < str.length; i++) {
|
|
224
|
+
hash2 ^= str.charCodeAt(i);
|
|
225
|
+
hash2 = Math.imul(hash2, FNV_PRIME);
|
|
226
|
+
}
|
|
227
|
+
const hash32 = hash2 >>> 0;
|
|
228
|
+
return hash32.toString(16).padStart(8, "0");
|
|
229
|
+
}
|
|
230
|
+
var hash = (value, skipHashing = SKIP_HASHING) => {
|
|
231
|
+
return skipHashing ? value : fnv1a52(value);
|
|
232
|
+
};
|
|
233
|
+
function getStoplightId(fragment) {
|
|
234
|
+
if (typeof fragment === "boolean") return void 0;
|
|
235
|
+
const xStoplight = fragment["x-stoplight"];
|
|
236
|
+
if (isPlainObject(xStoplight)) {
|
|
237
|
+
const id = xStoplight.id;
|
|
238
|
+
return typeof id === "string" ? id : void 0;
|
|
239
|
+
}
|
|
240
|
+
return void 0;
|
|
241
|
+
}
|
|
242
|
+
var getNodeId = (node, parentId) => {
|
|
243
|
+
const nodeId = getStoplightId(node.fragment);
|
|
244
|
+
if (nodeId) return nodeId;
|
|
245
|
+
const key = node.path[node.path.length - 1];
|
|
246
|
+
return hash(["schema_property", parentId, String(key)].join("-"));
|
|
247
|
+
};
|
|
248
|
+
var getOriginalNodeId = (node, parentId) => {
|
|
249
|
+
const nodeId = getStoplightId(node.originalFragment);
|
|
250
|
+
if (nodeId) return nodeId;
|
|
251
|
+
const key = node.path[node.path.length - 1];
|
|
252
|
+
return hash(["schema_property", parentId, String(key)].join("-"));
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// src/utils/extractVendorExtensions.ts
|
|
256
|
+
function extractVendorExtensions(fragment) {
|
|
257
|
+
if (typeof fragment === "boolean") {
|
|
258
|
+
return [0, {}];
|
|
259
|
+
}
|
|
260
|
+
const extensionKeys = Object.entries(fragment).filter(([key]) => key.startsWith("x-"));
|
|
261
|
+
let vendorExtensions = {};
|
|
262
|
+
for (const [key, value] of extensionKeys) {
|
|
263
|
+
vendorExtensions[key] = value;
|
|
264
|
+
}
|
|
265
|
+
return [extensionKeys.length, vendorExtensions];
|
|
266
|
+
}
|
|
267
|
+
var Caret = ({ isExpanded }) => /* @__PURE__ */ jsx(
|
|
268
|
+
"span",
|
|
269
|
+
{
|
|
270
|
+
className: clsx("jsv-caret", isExpanded && "jsv-caret-expanded"),
|
|
271
|
+
role: "button",
|
|
272
|
+
"aria-expanded": isExpanded,
|
|
273
|
+
children: /* @__PURE__ */ jsx(CaretRight, { size: 12, weight: "bold" })
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
var ChildStack = React2.memo(
|
|
277
|
+
({
|
|
278
|
+
childNodes,
|
|
279
|
+
currentNestingLevel,
|
|
280
|
+
className,
|
|
281
|
+
RowComponent = SchemaRow,
|
|
282
|
+
parentNodeId,
|
|
283
|
+
parentChangeType
|
|
284
|
+
}) => {
|
|
285
|
+
const { renderRootTreeLines } = useJSVOptionsContext();
|
|
286
|
+
const rootLevel = renderRootTreeLines ? 0 : 1;
|
|
287
|
+
const isRootLevel = currentNestingLevel < rootLevel;
|
|
288
|
+
return /* @__PURE__ */ jsx(
|
|
289
|
+
"div",
|
|
290
|
+
{
|
|
291
|
+
className: clsx(
|
|
292
|
+
"jsv-child-stack",
|
|
293
|
+
!isRootLevel && "jsv-child-stack-nested",
|
|
294
|
+
className
|
|
295
|
+
),
|
|
296
|
+
"data-level": currentNestingLevel,
|
|
297
|
+
children: childNodes.map((childNode) => /* @__PURE__ */ jsx(
|
|
298
|
+
RowComponent,
|
|
299
|
+
{
|
|
300
|
+
schemaNode: childNode,
|
|
301
|
+
nestingLevel: currentNestingLevel + 1,
|
|
302
|
+
parentNodeId,
|
|
303
|
+
parentChangeType
|
|
304
|
+
},
|
|
305
|
+
childNode.id
|
|
306
|
+
))
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
ChildStack.displayName = "ChildStack";
|
|
312
|
+
var Description = ({ value }) => {
|
|
313
|
+
const [showAll, setShowAll] = React2.useState(false);
|
|
314
|
+
if (typeof value !== "string" || value.trim().length === 0) return null;
|
|
315
|
+
const paragraphs = value.split("\n\n");
|
|
316
|
+
if (paragraphs.length <= 1 || showAll) {
|
|
317
|
+
return /* @__PURE__ */ jsx("div", { className: "jsv-description", "data-test": "property-description", children: value });
|
|
318
|
+
}
|
|
319
|
+
const firstParagraph = paragraphs[0];
|
|
320
|
+
return /* @__PURE__ */ jsx("div", { className: "jsv-description", "data-test": "property-description", children: /* @__PURE__ */ jsxs("p", { children: [
|
|
321
|
+
/* @__PURE__ */ jsx("span", { className: "mr-1", children: firstParagraph }),
|
|
322
|
+
/* @__PURE__ */ jsx(
|
|
323
|
+
"button",
|
|
324
|
+
{
|
|
325
|
+
type: "button",
|
|
326
|
+
className: "text-jsv-primary cursor-pointer hover:underline",
|
|
327
|
+
onClick: () => setShowAll(true),
|
|
328
|
+
children: "Show all..."
|
|
329
|
+
}
|
|
330
|
+
)
|
|
331
|
+
] }) });
|
|
332
|
+
};
|
|
333
|
+
var Divider = ({ hoveredAtom }) => {
|
|
334
|
+
const isHovered = useAtomValue(hoveredAtom);
|
|
335
|
+
return /* @__PURE__ */ jsx("span", { className: clsx("jsv-divider", isHovered && "jsv-divider-visible") });
|
|
336
|
+
};
|
|
337
|
+
function getInternalSchemaError(schemaNode) {
|
|
338
|
+
let errorMessage;
|
|
339
|
+
const fragment = schemaNode.fragment;
|
|
340
|
+
if (!isPlainObject(fragment)) return;
|
|
341
|
+
const xStoplight = fragment["x-stoplight"];
|
|
342
|
+
if (isPlainObject(xStoplight) && typeof xStoplight["error-message"] === "string") {
|
|
343
|
+
errorMessage = xStoplight["error-message"];
|
|
344
|
+
} else {
|
|
345
|
+
const fragmentErrorMessage = fragment["x-sl-error-message"];
|
|
346
|
+
if (typeof fragmentErrorMessage === "string") {
|
|
347
|
+
errorMessage = fragmentErrorMessage;
|
|
348
|
+
} else {
|
|
349
|
+
const items = fragment["items"];
|
|
350
|
+
if (isPlainObject(items)) {
|
|
351
|
+
const itemsErrorMessage = items["x-sl-error-message"];
|
|
352
|
+
if (typeof itemsErrorMessage === "string") {
|
|
353
|
+
errorMessage = itemsErrorMessage;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return errorMessage;
|
|
359
|
+
}
|
|
360
|
+
function useRefNode(schemaNode) {
|
|
361
|
+
return React2.useMemo(() => {
|
|
362
|
+
if (isReferenceNode(schemaNode)) {
|
|
363
|
+
return schemaNode;
|
|
364
|
+
}
|
|
365
|
+
if (isRegularNode(schemaNode) && (isFlattenableNode(schemaNode) || schemaNode.primaryType === SchemaNodeKind.Array && schemaNode.children?.length === 1)) {
|
|
366
|
+
return schemaNode.children?.find(isReferenceNode) ?? null;
|
|
367
|
+
}
|
|
368
|
+
return null;
|
|
369
|
+
}, [schemaNode]);
|
|
370
|
+
}
|
|
371
|
+
var Error = ({ schemaNode }) => {
|
|
372
|
+
const refNode = useRefNode(schemaNode);
|
|
373
|
+
const error = getInternalSchemaError(schemaNode) ?? refNode?.error;
|
|
374
|
+
if (typeof error !== "string") return null;
|
|
375
|
+
return /* @__PURE__ */ jsx("span", { className: "inline-block ml-1.5", title: error, children: /* @__PURE__ */ jsx(Warning, { className: "jsv-error", size: 16, "aria-label": error }) });
|
|
376
|
+
};
|
|
377
|
+
var NodeAnnotation = ({ change, style }) => {
|
|
378
|
+
if (!change) return null;
|
|
379
|
+
return /* @__PURE__ */ jsx(
|
|
380
|
+
"span",
|
|
381
|
+
{
|
|
382
|
+
className: clsx(
|
|
383
|
+
"jsv-annotation",
|
|
384
|
+
change.type === "added" && "jsv-annotation-added",
|
|
385
|
+
change.type === "removed" && "jsv-annotation-removed",
|
|
386
|
+
change.type === "modified" && "jsv-annotation-modified"
|
|
387
|
+
),
|
|
388
|
+
style,
|
|
389
|
+
"aria-label": `${change.type} property`
|
|
390
|
+
}
|
|
391
|
+
);
|
|
392
|
+
};
|
|
393
|
+
var useHasProperties = ({ required, deprecated, validations: { readOnly, writeOnly } }) => {
|
|
394
|
+
const { viewMode } = useJSVOptionsContext();
|
|
395
|
+
const showVisibilityValidations = viewMode === "standalone" && !!readOnly !== !!writeOnly;
|
|
396
|
+
return deprecated || showVisibilityValidations || required;
|
|
397
|
+
};
|
|
398
|
+
var Properties = ({
|
|
399
|
+
required,
|
|
400
|
+
deprecated,
|
|
401
|
+
validations: { readOnly, writeOnly }
|
|
402
|
+
}) => {
|
|
403
|
+
const { viewMode } = useJSVOptionsContext();
|
|
404
|
+
const showVisibilityValidations = viewMode === "standalone" && !!readOnly !== !!writeOnly;
|
|
405
|
+
const visibility = showVisibilityValidations ? readOnly ? /* @__PURE__ */ jsx("span", { className: "jsv-badge jsv-badge-readonly", "data-test": "property-read-only", children: "read-only" }) : /* @__PURE__ */ jsx("span", { className: "jsv-badge jsv-badge-readonly", "data-test": "property-write-only", children: "write-only" }) : null;
|
|
406
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
407
|
+
deprecated ? /* @__PURE__ */ jsx("span", { className: "jsv-badge jsv-badge-deprecated", "data-test": "property-deprecated", children: "deprecated" }) : null,
|
|
408
|
+
visibility,
|
|
409
|
+
required && /* @__PURE__ */ jsx("span", { className: "jsv-badge jsv-badge-required", "data-test": "property-required", children: "required" })
|
|
410
|
+
] });
|
|
411
|
+
};
|
|
412
|
+
var Select = ({
|
|
413
|
+
"aria-label": ariaLabel,
|
|
414
|
+
options,
|
|
415
|
+
value,
|
|
416
|
+
onChange,
|
|
417
|
+
prefix
|
|
418
|
+
}) => {
|
|
419
|
+
return /* @__PURE__ */ jsxs(
|
|
420
|
+
Select$1.Root,
|
|
421
|
+
{
|
|
422
|
+
value,
|
|
423
|
+
onValueChange: (newValue) => {
|
|
424
|
+
if (newValue !== null) {
|
|
425
|
+
onChange(newValue);
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
children: [
|
|
429
|
+
/* @__PURE__ */ jsxs(
|
|
430
|
+
Select$1.Trigger,
|
|
431
|
+
{
|
|
432
|
+
"aria-label": ariaLabel,
|
|
433
|
+
className: "jsv-select-trigger",
|
|
434
|
+
children: [
|
|
435
|
+
/* @__PURE__ */ jsx(Select$1.Value, { placeholder: "", children: (val) => {
|
|
436
|
+
const selectedOption = options.find((opt) => opt.value === val);
|
|
437
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
438
|
+
prefix,
|
|
439
|
+
selectedOption?.label ?? val
|
|
440
|
+
] });
|
|
441
|
+
} }),
|
|
442
|
+
/* @__PURE__ */ jsx(Select$1.Icon, { children: /* @__PURE__ */ jsx(CaretDown, { size: 12 }) })
|
|
443
|
+
]
|
|
444
|
+
}
|
|
445
|
+
),
|
|
446
|
+
/* @__PURE__ */ jsx(Select$1.Portal, { children: /* @__PURE__ */ jsx(Select$1.Positioner, { className: "jsv-select-positioner", sideOffset: 4, children: /* @__PURE__ */ jsx(Select$1.Popup, { className: "jsv-select-popup", children: options.map((option) => /* @__PURE__ */ jsxs(
|
|
447
|
+
Select$1.Item,
|
|
448
|
+
{
|
|
449
|
+
value: option.value,
|
|
450
|
+
className: "jsv-select-item",
|
|
451
|
+
children: [
|
|
452
|
+
/* @__PURE__ */ jsx(Select$1.ItemIndicator, { className: "jsv-select-item-indicator", children: /* @__PURE__ */ jsx(Check, { size: 12, weight: "bold" }) }),
|
|
453
|
+
/* @__PURE__ */ jsx(Select$1.ItemText, { children: option.label })
|
|
454
|
+
]
|
|
455
|
+
},
|
|
456
|
+
option.value
|
|
457
|
+
)) }) }) })
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
};
|
|
462
|
+
function getApplicableFormats(schemaNode) {
|
|
463
|
+
const fragment = schemaNode.fragment;
|
|
464
|
+
if (isPlainObject(fragment) && fragment["contentMediaType"] === "application/octet-stream" && schemaNode.types && schemaNode.types.length > 0) {
|
|
465
|
+
return [schemaNode.types[0], "binary"];
|
|
466
|
+
}
|
|
467
|
+
if (schemaNode.format === null) {
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
if (schemaNode.types !== null) {
|
|
471
|
+
for (const type of schemaNode.types) {
|
|
472
|
+
if (!(type in COMMON_JSON_SCHEMA_AND_OAS_FORMATS)) continue;
|
|
473
|
+
if (COMMON_JSON_SCHEMA_AND_OAS_FORMATS[type].includes(schemaNode.format)) {
|
|
474
|
+
return [type, schemaNode.format];
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return [SchemaNodeKind.String, schemaNode.format];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// src/utils/printName.ts
|
|
482
|
+
function upperFirst(str) {
|
|
483
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
484
|
+
}
|
|
485
|
+
function printName(schemaNode, { shouldUseRefNameFallback = false } = {}) {
|
|
486
|
+
if (!isFlattenableNode(schemaNode)) {
|
|
487
|
+
return schemaNode.title ?? (shouldUseRefNameFallback ? getNodeNameFromOriginalRef(schemaNode) : void 0);
|
|
488
|
+
}
|
|
489
|
+
return printFlattenedName(schemaNode, { shouldUseRefNameFallback });
|
|
490
|
+
}
|
|
491
|
+
function printFlattenedName(schemaNode, { shouldUseRefNameFallback = false }) {
|
|
492
|
+
if (!isNonNullable(schemaNode.children) || schemaNode.children.length === 0) {
|
|
493
|
+
return schemaNode.title ?? (shouldUseRefNameFallback ? getNodeNameFromOriginalRef(schemaNode) : void 0);
|
|
494
|
+
}
|
|
495
|
+
if (schemaNode.children.length === 1 && isReferenceNode(schemaNode.children[0])) {
|
|
496
|
+
const value = `$ref(${schemaNode.children[0].value})`;
|
|
497
|
+
return isDictionaryNode(schemaNode) ? `dictionary[string, ${value}]` : `${value}[]`;
|
|
498
|
+
}
|
|
499
|
+
const format = isDictionaryNode(schemaNode) ? "dictionary[string, %s]" : "array[%s]";
|
|
500
|
+
if (isPrimitiveArray(schemaNode) || isPrimitiveDictionary(schemaNode)) {
|
|
501
|
+
const val = schemaNode.children?.reduce((mergedTypes, child) => {
|
|
502
|
+
if (mergedTypes === null) return null;
|
|
503
|
+
if (!isRegularNode(child)) return null;
|
|
504
|
+
if (child.types !== null && child.types.length > 0) {
|
|
505
|
+
const formats = getApplicableFormats(child);
|
|
506
|
+
for (const type of child.types) {
|
|
507
|
+
if (mergedTypes.includes(type)) continue;
|
|
508
|
+
if (formats !== null && formats[0] === type) {
|
|
509
|
+
mergedTypes.push(`${type}<${formats[1]}>`);
|
|
510
|
+
} else {
|
|
511
|
+
mergedTypes.push(type);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return mergedTypes;
|
|
516
|
+
}, []) ?? null;
|
|
517
|
+
if (val !== null && val.length > 0) {
|
|
518
|
+
return format.replace("%s", val.join(" or "));
|
|
519
|
+
}
|
|
520
|
+
return isDictionaryNode(schemaNode) ? "dictionary[string, any]" : "array";
|
|
521
|
+
}
|
|
522
|
+
if (isComplexArray(schemaNode) || isComplexDictionary(schemaNode)) {
|
|
523
|
+
const firstChild = schemaNode.children[0];
|
|
524
|
+
if (firstChild.title) {
|
|
525
|
+
return format.replace("%s", firstChild.title);
|
|
526
|
+
} else if (shouldUseRefNameFallback && getNodeNameFromOriginalRef(schemaNode)) {
|
|
527
|
+
return format.replace("%s", getNodeNameFromOriginalRef(schemaNode) ?? "any");
|
|
528
|
+
} else if (firstChild.primaryType) {
|
|
529
|
+
return format.replace("%s", firstChild.primaryType);
|
|
530
|
+
} else if (firstChild.combiners?.length) {
|
|
531
|
+
return format.replace("%s", firstChild.combiners.join(" "));
|
|
532
|
+
}
|
|
533
|
+
return isComplexArray(schemaNode) ? "array" : format.replace("%s", "any");
|
|
534
|
+
}
|
|
535
|
+
return void 0;
|
|
536
|
+
}
|
|
537
|
+
function getNodeNameFromOriginalRef(node) {
|
|
538
|
+
if (typeof node.originalFragment.$ref === "string") {
|
|
539
|
+
return upperFirst(getLastPathSegment(node.originalFragment.$ref));
|
|
540
|
+
}
|
|
541
|
+
return void 0;
|
|
542
|
+
}
|
|
543
|
+
function shouldRenderName(type) {
|
|
544
|
+
return type === SchemaNodeKind.Array || type === SchemaNodeKind.Object || type === "$ref";
|
|
545
|
+
}
|
|
546
|
+
function getTypes(schemaNode) {
|
|
547
|
+
return [schemaNode.types, schemaNode.combiners].reduce(
|
|
548
|
+
(values, value) => {
|
|
549
|
+
if (value === null) {
|
|
550
|
+
return values;
|
|
551
|
+
}
|
|
552
|
+
values.push(...value);
|
|
553
|
+
return values;
|
|
554
|
+
},
|
|
555
|
+
[]
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
var Types = ({ schemaNode }) => {
|
|
559
|
+
if (isReferenceNode(schemaNode)) {
|
|
560
|
+
return /* @__PURE__ */ jsx("span", { className: "jsv-type", "data-test": "property-type-ref", children: schemaNode.value ?? "$ref" });
|
|
561
|
+
}
|
|
562
|
+
if (isBooleanishNode(schemaNode)) {
|
|
563
|
+
return /* @__PURE__ */ jsx("span", { className: "jsv-type", "data-test": "property-type", children: schemaNode.fragment ? "any" : "never" });
|
|
564
|
+
}
|
|
565
|
+
if (!isRegularNode(schemaNode)) {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
const formats = getApplicableFormats(schemaNode);
|
|
569
|
+
const types = getTypes(schemaNode);
|
|
570
|
+
if (types.length === 0) {
|
|
571
|
+
return /* @__PURE__ */ jsx("span", { className: "jsv-type", "data-test": "property-type", children: formats === null ? "any" : `<${formats[1]}>` });
|
|
572
|
+
}
|
|
573
|
+
const rendered = types.map((type, i, { length }) => {
|
|
574
|
+
let printedName;
|
|
575
|
+
if (shouldRenderName(type)) {
|
|
576
|
+
printedName = printName(schemaNode);
|
|
577
|
+
}
|
|
578
|
+
printedName ?? (printedName = type + (formats === null || formats[0] !== type ? "" : `<${formats[1]}>`));
|
|
579
|
+
return /* @__PURE__ */ jsxs(React2.Fragment, { children: [
|
|
580
|
+
/* @__PURE__ */ jsx("span", { className: "jsv-type", "data-test": "property-type", children: printedName }),
|
|
581
|
+
i < length - 1 && /* @__PURE__ */ jsx("span", { className: "jsv-type", children: " or " }, `${i}-sep`)
|
|
582
|
+
] }, type);
|
|
583
|
+
});
|
|
584
|
+
return rendered.length > 1 ? /* @__PURE__ */ jsx("span", { className: "truncate", children: rendered }) : /* @__PURE__ */ jsx(Fragment, { children: rendered });
|
|
585
|
+
};
|
|
586
|
+
Types.displayName = "JsonSchemaViewer.Types";
|
|
587
|
+
var numberValidationNames = [
|
|
588
|
+
"minimum",
|
|
589
|
+
"maximum",
|
|
590
|
+
"minLength",
|
|
591
|
+
"maxLength",
|
|
592
|
+
"minItems",
|
|
593
|
+
"maxItems",
|
|
594
|
+
"exclusiveMinimum",
|
|
595
|
+
"exclusiveMaximum"
|
|
596
|
+
];
|
|
597
|
+
var exampleValidationNames = ["examples"];
|
|
598
|
+
var excludedValidations = ["exclusiveMinimum", "exclusiveMaximum", "readOnly", "writeOnly"];
|
|
599
|
+
var numberValidationFormatters = {
|
|
600
|
+
minimum: (value) => `>= ${value}`,
|
|
601
|
+
exclusiveMinimum: (value) => `> ${value}`,
|
|
602
|
+
minItems: (value) => `>= ${value} items`,
|
|
603
|
+
minLength: (value) => `>= ${value} characters`,
|
|
604
|
+
maximum: (value) => `<= ${value}`,
|
|
605
|
+
exclusiveMaximum: (value) => `< ${value}`,
|
|
606
|
+
maxItems: (value) => `<= ${value} items`,
|
|
607
|
+
maxLength: (value) => `<= ${value} characters`
|
|
608
|
+
};
|
|
609
|
+
var createStringFormatter = (nowrap) => (value) => {
|
|
610
|
+
return nowrap && typeof value === "string" ? value : JSON.stringify(value);
|
|
611
|
+
};
|
|
612
|
+
var createValidationsFormatter = (name, options) => (value) => {
|
|
613
|
+
const values = Array.isArray(value) ? value : [value];
|
|
614
|
+
if (values.length) {
|
|
615
|
+
return {
|
|
616
|
+
name: options?.exact ? name : values.length > 1 ? `${name}s` : `${name}`,
|
|
617
|
+
values: values.map(createStringFormatter(options?.nowrap))
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
return null;
|
|
621
|
+
};
|
|
622
|
+
var validationFormatters = {
|
|
623
|
+
enum: createValidationsFormatter("Allowed value", { nowrap: true }),
|
|
624
|
+
examples: createValidationsFormatter("Example", { nowrap: true }),
|
|
625
|
+
multipleOf: createValidationsFormatter("Multiple of", { exact: true }),
|
|
626
|
+
pattern: createValidationsFormatter("Match pattern", { exact: true, nowrap: true }),
|
|
627
|
+
default: createValidationsFormatter("Default", { exact: true, nowrap: true }),
|
|
628
|
+
style: createValidationsFormatter("Style", { exact: true, nowrap: true })
|
|
629
|
+
};
|
|
630
|
+
var oasFormats = {
|
|
631
|
+
int32: {
|
|
632
|
+
minimum: 0 - 2 ** 31,
|
|
633
|
+
maximum: 2 ** 31 - 1
|
|
634
|
+
},
|
|
635
|
+
int64: {
|
|
636
|
+
minimum: Number.MIN_SAFE_INTEGER,
|
|
637
|
+
maximum: Number.MAX_SAFE_INTEGER
|
|
638
|
+
},
|
|
639
|
+
float: {
|
|
640
|
+
minimum: 0 - 2 ** 128,
|
|
641
|
+
maximum: 2 ** 128 - 1
|
|
642
|
+
},
|
|
643
|
+
double: {
|
|
644
|
+
minimum: 0 - Number.MAX_VALUE,
|
|
645
|
+
maximum: Number.MAX_VALUE
|
|
646
|
+
},
|
|
647
|
+
byte: {
|
|
648
|
+
pattern: "^[\\w\\d+\\/=]*$"
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
function isOasFormat(format) {
|
|
652
|
+
return format in oasFormats;
|
|
653
|
+
}
|
|
654
|
+
function filterOutOasFormatValidations(format, values) {
|
|
655
|
+
if (!isOasFormat(format)) {
|
|
656
|
+
return values;
|
|
657
|
+
}
|
|
658
|
+
const newValues = { ...values };
|
|
659
|
+
for (const [key, value] of Object.entries(oasFormats[format])) {
|
|
660
|
+
if (value === newValues[key]) {
|
|
661
|
+
delete newValues[key];
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return newValues;
|
|
665
|
+
}
|
|
666
|
+
function pick(obj, keys) {
|
|
667
|
+
const result = {};
|
|
668
|
+
for (const key of keys) {
|
|
669
|
+
if (key in obj) {
|
|
670
|
+
result[key] = obj[key];
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return result;
|
|
674
|
+
}
|
|
675
|
+
function omit(obj, keys) {
|
|
676
|
+
const result = { ...obj };
|
|
677
|
+
for (const key of keys) {
|
|
678
|
+
delete result[key];
|
|
679
|
+
}
|
|
680
|
+
return result;
|
|
681
|
+
}
|
|
682
|
+
function capitalize(str) {
|
|
683
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
684
|
+
}
|
|
685
|
+
function uniq(arr) {
|
|
686
|
+
return [...new Set(arr)];
|
|
687
|
+
}
|
|
688
|
+
var Validations = ({ validations, hideExamples }) => {
|
|
689
|
+
const numberValidations = pick(validations, numberValidationNames);
|
|
690
|
+
const keyValueValidations = omit(validations, [
|
|
691
|
+
...Object.keys(numberValidations),
|
|
692
|
+
...excludedValidations,
|
|
693
|
+
...hideExamples ? exampleValidationNames : []
|
|
694
|
+
]);
|
|
695
|
+
return /* @__PURE__ */ jsxs("div", { className: "jsv-validations", children: [
|
|
696
|
+
/* @__PURE__ */ jsx(NumberValidations, { validations: numberValidations }),
|
|
697
|
+
/* @__PURE__ */ jsx(KeyValueValidations, { validations: keyValueValidations })
|
|
698
|
+
] });
|
|
699
|
+
};
|
|
700
|
+
var NumberValidations = ({ validations }) => {
|
|
701
|
+
const entries = Object.entries(validations);
|
|
702
|
+
if (!entries.length) {
|
|
703
|
+
return null;
|
|
704
|
+
}
|
|
705
|
+
return /* @__PURE__ */ jsx("div", { className: "jsv-validations-row", "data-test": "property-validation", children: entries.map(([key, value]) => numberValidationFormatters[key](value)).map((value, i) => /* @__PURE__ */ jsx(Value, { name: value }, i)) });
|
|
706
|
+
};
|
|
707
|
+
var KeyValueValidations = ({ validations }) => /* @__PURE__ */ jsx(Fragment, { children: Object.keys(validations).filter((key) => Object.keys(validationFormatters).includes(key) && validations[key] !== void 0).map((key) => {
|
|
708
|
+
const validation = validationFormatters[key](validations[key]);
|
|
709
|
+
if (validation) {
|
|
710
|
+
return /* @__PURE__ */ jsx(KeyValueValidation, { name: validation.name, values: validation.values }, key);
|
|
711
|
+
} else {
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
}) });
|
|
715
|
+
var KeyValueValidation = ({ name, values }) => {
|
|
716
|
+
return /* @__PURE__ */ jsxs("div", { className: "jsv-validation", "data-test": "property-validation", children: [
|
|
717
|
+
/* @__PURE__ */ jsxs("span", { className: "jsv-validation-label", children: [
|
|
718
|
+
capitalize(name),
|
|
719
|
+
":"
|
|
720
|
+
] }),
|
|
721
|
+
/* @__PURE__ */ jsx("div", { className: "jsv-validation-values", children: uniq(values).map((value) => /* @__PURE__ */ jsx(Value, { name: value }, value)) })
|
|
722
|
+
] });
|
|
723
|
+
};
|
|
724
|
+
var Value = ({ name }) => /* @__PURE__ */ jsx("span", { className: "jsv-validation-value", children: name });
|
|
725
|
+
var getArrayValidations = (schemaNode) => {
|
|
726
|
+
if (schemaNode.children?.length === 1 && isRegularNode(schemaNode.children[0])) {
|
|
727
|
+
if (schemaNode.children[0].enum !== null) {
|
|
728
|
+
return { enum: schemaNode.children[0].enum };
|
|
729
|
+
} else if (schemaNode.children[0].fragment.pattern !== void 0) {
|
|
730
|
+
return { pattern: schemaNode.children[0].fragment.pattern };
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return null;
|
|
734
|
+
};
|
|
735
|
+
function getValidationsFromSchema(schemaNode) {
|
|
736
|
+
return {
|
|
737
|
+
...schemaNode.enum !== null ? { enum: schemaNode.enum } : schemaNode.primaryType === "array" ? (
|
|
738
|
+
// in case schemaNode is type: "array", check if its child has an additional validation
|
|
739
|
+
getArrayValidations(schemaNode)
|
|
740
|
+
) : null,
|
|
741
|
+
..."annotations" in schemaNode ? {
|
|
742
|
+
...schemaNode.annotations.default !== void 0 ? { default: schemaNode.annotations.default } : null,
|
|
743
|
+
...schemaNode.annotations.examples ? { examples: schemaNode.annotations.examples } : null
|
|
744
|
+
} : null,
|
|
745
|
+
...getFilteredValidations(schemaNode)
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
function getFilteredValidations(schemaNode) {
|
|
749
|
+
if (schemaNode.format !== null) {
|
|
750
|
+
return filterOutOasFormatValidations(schemaNode.format, schemaNode.validations);
|
|
751
|
+
}
|
|
752
|
+
return schemaNode.validations;
|
|
753
|
+
}
|
|
754
|
+
function last(arr) {
|
|
755
|
+
return arr[arr.length - 1];
|
|
756
|
+
}
|
|
757
|
+
function calculateChoiceTitle(node, isPlural) {
|
|
758
|
+
const primitiveSuffix = isPlural ? "s" : "";
|
|
759
|
+
if (isRegularNode(node)) {
|
|
760
|
+
const realName = printName(node, { shouldUseRefNameFallback: true });
|
|
761
|
+
if (realName) {
|
|
762
|
+
return realName;
|
|
763
|
+
}
|
|
764
|
+
return node.primaryType !== null ? node.primaryType + primitiveSuffix : String(node.originalFragment.title || "any");
|
|
765
|
+
}
|
|
766
|
+
if (isReferenceNode(node)) {
|
|
767
|
+
if (node.value) {
|
|
768
|
+
const value = extractPointerFromRef(node.value);
|
|
769
|
+
const lastPiece = !node.error && value ? last(pointerToPath(value)) : null;
|
|
770
|
+
if (typeof lastPiece === "string") {
|
|
771
|
+
return lastPiece.split(".")[0];
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return "$ref" + primitiveSuffix;
|
|
775
|
+
}
|
|
776
|
+
return "any";
|
|
777
|
+
}
|
|
778
|
+
function makeChoice(node) {
|
|
779
|
+
return {
|
|
780
|
+
type: node,
|
|
781
|
+
title: calculateChoiceTitle(node, false)
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
function makeArrayChoice(node, combiner) {
|
|
785
|
+
const itemTitle = calculateChoiceTitle(node, true);
|
|
786
|
+
const title = itemTitle !== "any" ? `array ${combiner ? `(${combiner})` : null} [${itemTitle}]` : "array";
|
|
787
|
+
return {
|
|
788
|
+
type: node,
|
|
789
|
+
title
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
var useChoices = (schemaNode) => {
|
|
793
|
+
const choices = React2.useMemo(() => {
|
|
794
|
+
if (isComplexArray(schemaNode) && isNonEmptyParentNode(schemaNode.children[0]) && shouldShowChildSelector(schemaNode.children[0])) {
|
|
795
|
+
return schemaNode.children[0].children.map(
|
|
796
|
+
(child) => makeArrayChoice(child, schemaNode.children[0].combiners?.[0])
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
if (isNonEmptyParentNode(schemaNode) && shouldShowChildSelector(schemaNode)) {
|
|
800
|
+
return schemaNode.children.map(makeChoice);
|
|
801
|
+
}
|
|
802
|
+
return [makeChoice(schemaNode)];
|
|
803
|
+
}, [schemaNode]);
|
|
804
|
+
const defaultChoice = choices[0];
|
|
805
|
+
const [selectedChoice, setSelectedChoice] = React2.useState(defaultChoice);
|
|
806
|
+
React2.useEffect(() => {
|
|
807
|
+
setSelectedChoice(defaultChoice);
|
|
808
|
+
}, [defaultChoice]);
|
|
809
|
+
const actualSelectedChoice = selectedChoice && choices.includes(selectedChoice) ? selectedChoice : defaultChoice;
|
|
810
|
+
return { selectedChoice: actualSelectedChoice, setSelectedChoice, choices };
|
|
811
|
+
};
|
|
812
|
+
var shouldShowChildSelector = (schemaNode) => isNonEmptyParentNode(schemaNode) && ["anyOf", "oneOf"].includes(schemaNode.combiners?.[0] ?? "");
|
|
813
|
+
var SchemaRow = React2.memo(
|
|
814
|
+
({ schemaNode, nestingLevel, pl, parentNodeId, parentChangeType }) => {
|
|
815
|
+
const {
|
|
816
|
+
defaultExpandedDepth,
|
|
817
|
+
renderRowAddon,
|
|
818
|
+
renderExtensionAddon,
|
|
819
|
+
onGoToRef,
|
|
820
|
+
hideExamples,
|
|
821
|
+
renderRootTreeLines,
|
|
822
|
+
nodeHasChanged,
|
|
823
|
+
viewMode
|
|
824
|
+
} = useJSVOptionsContext();
|
|
825
|
+
const setHoveredNode = useSetAtom(hoveredNodeAtom);
|
|
826
|
+
const nodeId = getNodeId(schemaNode, parentNodeId);
|
|
827
|
+
const originalNodeId = schemaNode.originalFragment?.$ref ? getOriginalNodeId(schemaNode, parentNodeId) : nodeId;
|
|
828
|
+
const mode = viewMode === "standalone" ? void 0 : viewMode;
|
|
829
|
+
const hasChanged = nodeHasChanged?.({ nodeId: originalNodeId, mode });
|
|
830
|
+
const [isExpanded, setExpanded] = React2.useState(
|
|
831
|
+
!isMirroredNode(schemaNode) && nestingLevel <= defaultExpandedDepth
|
|
832
|
+
);
|
|
833
|
+
const { selectedChoice, setSelectedChoice, choices } = useChoices(schemaNode);
|
|
834
|
+
const typeToShow = selectedChoice.type;
|
|
835
|
+
const description = isRegularNode(typeToShow) ? typeToShow.annotations.description : null;
|
|
836
|
+
const rootLevel = renderRootTreeLines ? 1 : 2;
|
|
837
|
+
const childNodes = React2.useMemo(() => visibleChildren(typeToShow), [typeToShow]);
|
|
838
|
+
const combiner = isRegularNode(schemaNode) && schemaNode.combiners?.length ? schemaNode.combiners[0] : null;
|
|
839
|
+
const isCollapsible = childNodes.length > 0;
|
|
840
|
+
const isRootLevel = nestingLevel < rootLevel;
|
|
841
|
+
const required = isPropertyRequired(schemaNode);
|
|
842
|
+
const deprecated = isRegularNode(schemaNode) && schemaNode.deprecated;
|
|
843
|
+
const validations = isRegularNode(schemaNode) ? schemaNode.validations : {};
|
|
844
|
+
const hasProperties = useHasProperties({ required, deprecated, validations });
|
|
845
|
+
const [totalVendorExtensions, vendorExtensions] = React2.useMemo(
|
|
846
|
+
() => extractVendorExtensions(schemaNode.fragment),
|
|
847
|
+
[schemaNode.fragment]
|
|
848
|
+
);
|
|
849
|
+
const hasVendorProperties = totalVendorExtensions > 0;
|
|
850
|
+
const annotationRootOffset = renderRootTreeLines ? 0 : 8;
|
|
851
|
+
let annotationLeftOffset = -20 - annotationRootOffset;
|
|
852
|
+
if (nestingLevel > 1) {
|
|
853
|
+
annotationLeftOffset = -1 * 29 * Math.max(nestingLevel - 1, 1) - Math.min(nestingLevel, 2) * 2 - 16 - annotationRootOffset;
|
|
854
|
+
if (!renderRootTreeLines) {
|
|
855
|
+
annotationLeftOffset += 27;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
if (parentChangeType === "added" && hasChanged && hasChanged.type === "removed") {
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
if (parentChangeType === "removed" && hasChanged && hasChanged.type === "added") {
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
const lastSubpath = schemaNode.subpath.length > 0 ? schemaNode.subpath[schemaNode.subpath.length - 1] : null;
|
|
865
|
+
const isHoveredAtom = isNodeHoveredAtom(schemaNode);
|
|
866
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
867
|
+
/* @__PURE__ */ jsxs(
|
|
868
|
+
"div",
|
|
869
|
+
{
|
|
870
|
+
className: "jsv-row",
|
|
871
|
+
style: { paddingLeft: pl ? `${pl * 0.25}rem` : void 0 },
|
|
872
|
+
"data-id": originalNodeId,
|
|
873
|
+
"data-test": "schema-row",
|
|
874
|
+
onMouseEnter: (e) => {
|
|
875
|
+
e.stopPropagation();
|
|
876
|
+
setHoveredNode(selectedChoice.type);
|
|
877
|
+
},
|
|
878
|
+
children: [
|
|
879
|
+
!isRootLevel && /* @__PURE__ */ jsx("span", { className: clsx("jsv-nubbin", isCollapsible && "jsv-nubbin-short") }),
|
|
880
|
+
parentChangeType !== "added" && parentChangeType !== "removed" ? /* @__PURE__ */ jsx(NodeAnnotation, { change: hasChanged, style: { left: annotationLeftOffset } }) : null,
|
|
881
|
+
/* @__PURE__ */ jsxs("div", { className: clsx("jsv-row-content", isCollapsible && !isRootLevel && "jsv-ml-2"), children: [
|
|
882
|
+
/* @__PURE__ */ jsxs(
|
|
883
|
+
"div",
|
|
884
|
+
{
|
|
885
|
+
className: clsx("jsv-row-header", isCollapsible && "jsv-cursor-pointer"),
|
|
886
|
+
onClick: isCollapsible ? () => setExpanded(!isExpanded) : void 0,
|
|
887
|
+
children: [
|
|
888
|
+
isCollapsible ? /* @__PURE__ */ jsx(Caret, { isExpanded }) : null,
|
|
889
|
+
/* @__PURE__ */ jsxs("div", { className: "jsv-types-container", children: [
|
|
890
|
+
schemaNode.subpath.length > 0 && shouldShowPropertyName(schemaNode) && /* @__PURE__ */ jsx(
|
|
891
|
+
"span",
|
|
892
|
+
{
|
|
893
|
+
className: "jsv-property-name",
|
|
894
|
+
"data-test": `property-name-${lastSubpath}`,
|
|
895
|
+
children: lastSubpath
|
|
896
|
+
}
|
|
897
|
+
),
|
|
898
|
+
choices.length === 1 && /* @__PURE__ */ jsx(Types, { schemaNode: typeToShow }),
|
|
899
|
+
onGoToRef && isReferenceNode(schemaNode) && schemaNode.external ? /* @__PURE__ */ jsx(
|
|
900
|
+
"a",
|
|
901
|
+
{
|
|
902
|
+
href: "#",
|
|
903
|
+
className: "jsv-link",
|
|
904
|
+
onClick: (e) => {
|
|
905
|
+
e.preventDefault();
|
|
906
|
+
e.stopPropagation();
|
|
907
|
+
onGoToRef(schemaNode);
|
|
908
|
+
},
|
|
909
|
+
children: "(go to ref)"
|
|
910
|
+
}
|
|
911
|
+
) : null,
|
|
912
|
+
schemaNode.subpath.length > 1 && schemaNode.subpath[0] === "patternProperties" ? /* @__PURE__ */ jsx("span", { className: "jsv-type jsv-ml-2", children: "(pattern property)" }) : null,
|
|
913
|
+
choices.length > 1 && /* @__PURE__ */ jsx(
|
|
914
|
+
Select,
|
|
915
|
+
{
|
|
916
|
+
"aria-label": "Pick a type",
|
|
917
|
+
prefix: combiner ? `${COMBINER_NAME_MAP[combiner]}: ` : void 0,
|
|
918
|
+
options: choices.map((choice, index) => ({
|
|
919
|
+
value: String(index),
|
|
920
|
+
label: choice.title
|
|
921
|
+
})),
|
|
922
|
+
value: String(choices.indexOf(selectedChoice)),
|
|
923
|
+
onChange: (selectedIndex) => setSelectedChoice(choices[Number(selectedIndex)])
|
|
924
|
+
}
|
|
925
|
+
)
|
|
926
|
+
] }),
|
|
927
|
+
hasProperties && /* @__PURE__ */ jsx(Divider, { hoveredAtom: isHoveredAtom }),
|
|
928
|
+
/* @__PURE__ */ jsx(Properties, { required, deprecated, validations })
|
|
929
|
+
]
|
|
930
|
+
}
|
|
931
|
+
),
|
|
932
|
+
typeof description === "string" && (!combiner || schemaNode.parent?.fragment.description !== description) && description.length > 0 && /* @__PURE__ */ jsx(Description, { value: description }),
|
|
933
|
+
/* @__PURE__ */ jsx(
|
|
934
|
+
Validations,
|
|
935
|
+
{
|
|
936
|
+
validations: isRegularNode(schemaNode) ? getValidationsFromSchema(schemaNode) : {},
|
|
937
|
+
hideExamples
|
|
938
|
+
}
|
|
939
|
+
),
|
|
940
|
+
hasVendorProperties && renderExtensionAddon ? /* @__PURE__ */ jsx("div", { children: renderExtensionAddon({ schemaNode, nestingLevel, vendorExtensions }) }) : null
|
|
941
|
+
] }),
|
|
942
|
+
/* @__PURE__ */ jsx(Error, { schemaNode }),
|
|
943
|
+
renderRowAddon ? /* @__PURE__ */ jsx("div", { children: renderRowAddon({ schemaNode, nestingLevel }) }) : null
|
|
944
|
+
]
|
|
945
|
+
}
|
|
946
|
+
),
|
|
947
|
+
isCollapsible && isExpanded ? /* @__PURE__ */ jsx(
|
|
948
|
+
ChildStack,
|
|
949
|
+
{
|
|
950
|
+
schemaNode,
|
|
951
|
+
childNodes,
|
|
952
|
+
currentNestingLevel: nestingLevel,
|
|
953
|
+
parentNodeId: nodeId,
|
|
954
|
+
parentChangeType: parentChangeType ? parentChangeType : hasChanged ? hasChanged?.type : void 0
|
|
955
|
+
}
|
|
956
|
+
) : null
|
|
957
|
+
] });
|
|
958
|
+
}
|
|
959
|
+
);
|
|
960
|
+
SchemaRow.displayName = "SchemaRow";
|
|
961
|
+
function shouldShowPropertyName(schemaNode) {
|
|
962
|
+
return schemaNode.subpath.length === 2 && (schemaNode.subpath[0] === "properties" || schemaNode.subpath[0] === "patternProperties");
|
|
963
|
+
}
|
|
964
|
+
function isEmpty(obj) {
|
|
965
|
+
return Object.keys(obj).length === 0;
|
|
966
|
+
}
|
|
967
|
+
function getStoplightId2(fragment) {
|
|
968
|
+
if (typeof fragment === "boolean") return void 0;
|
|
969
|
+
const xStoplight = fragment["x-stoplight"];
|
|
970
|
+
if (isPlainObject(xStoplight)) {
|
|
971
|
+
const id = xStoplight.id;
|
|
972
|
+
return typeof id === "string" ? id : void 0;
|
|
973
|
+
}
|
|
974
|
+
return void 0;
|
|
975
|
+
}
|
|
976
|
+
var TopLevelSchemaRow = ({
|
|
977
|
+
schemaNode,
|
|
978
|
+
skipDescription
|
|
979
|
+
}) => {
|
|
980
|
+
const { renderExtensionAddon } = useJSVOptionsContext();
|
|
981
|
+
const { selectedChoice, setSelectedChoice, choices } = useChoices(schemaNode);
|
|
982
|
+
const childNodes = React2.useMemo(() => visibleChildren(selectedChoice.type), [selectedChoice.type]);
|
|
983
|
+
const nestingLevel = 0;
|
|
984
|
+
const nodeId = getStoplightId2(schemaNode.fragment);
|
|
985
|
+
const [totalVendorExtensions, vendorExtensions] = React2.useMemo(
|
|
986
|
+
() => extractVendorExtensions(schemaNode.fragment),
|
|
987
|
+
[schemaNode.fragment]
|
|
988
|
+
);
|
|
989
|
+
const hasVendorProperties = totalVendorExtensions > 0;
|
|
990
|
+
if (isRegularNode(schemaNode) && isPureObjectNode(schemaNode)) {
|
|
991
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
992
|
+
!skipDescription ? /* @__PURE__ */ jsx(Description, { value: schemaNode.annotations.description }) : null,
|
|
993
|
+
hasVendorProperties && renderExtensionAddon ? renderExtensionAddon({ schemaNode, nestingLevel, vendorExtensions }) : null,
|
|
994
|
+
/* @__PURE__ */ jsx(
|
|
995
|
+
ChildStack,
|
|
996
|
+
{
|
|
997
|
+
schemaNode,
|
|
998
|
+
childNodes,
|
|
999
|
+
currentNestingLevel: nestingLevel,
|
|
1000
|
+
parentNodeId: nodeId
|
|
1001
|
+
}
|
|
1002
|
+
),
|
|
1003
|
+
/* @__PURE__ */ jsx(Error, { schemaNode })
|
|
1004
|
+
] });
|
|
1005
|
+
}
|
|
1006
|
+
if (isRegularNode(schemaNode) && choices.length > 1) {
|
|
1007
|
+
const combiner = isRegularNode(schemaNode) && schemaNode.combiners?.length ? schemaNode.combiners[0] : null;
|
|
1008
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1009
|
+
schemaNode.annotations.description !== schemaNode.parent?.fragment.description && /* @__PURE__ */ jsx(Description, { value: schemaNode.annotations.description }),
|
|
1010
|
+
/* @__PURE__ */ jsxs("div", { className: "jsv-top-section", children: [
|
|
1011
|
+
/* @__PURE__ */ jsxs(Menu.Root, { children: [
|
|
1012
|
+
/* @__PURE__ */ jsxs(Menu.Trigger, { className: "jsv-select-trigger", children: [
|
|
1013
|
+
selectedChoice.title,
|
|
1014
|
+
/* @__PURE__ */ jsx(CaretDown, { size: 12 })
|
|
1015
|
+
] }),
|
|
1016
|
+
/* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { className: "jsv-select-positioner", children: /* @__PURE__ */ jsx(Menu.Popup, { className: "jsv-select-popup", children: choices.map((choice, index) => /* @__PURE__ */ jsx(
|
|
1017
|
+
Menu.Item,
|
|
1018
|
+
{
|
|
1019
|
+
className: "jsv-select-item",
|
|
1020
|
+
onClick: () => setSelectedChoice(choice),
|
|
1021
|
+
children: choice.title
|
|
1022
|
+
},
|
|
1023
|
+
index
|
|
1024
|
+
)) }) }) })
|
|
1025
|
+
] }),
|
|
1026
|
+
combiner !== null ? /* @__PURE__ */ jsx("span", { className: "jsv-combiner-label", children: `(${COMBINER_NAME_MAP[combiner]})` }) : null
|
|
1027
|
+
] }),
|
|
1028
|
+
childNodes.length > 0 ? /* @__PURE__ */ jsx(
|
|
1029
|
+
ChildStack,
|
|
1030
|
+
{
|
|
1031
|
+
schemaNode,
|
|
1032
|
+
childNodes,
|
|
1033
|
+
currentNestingLevel: nestingLevel,
|
|
1034
|
+
parentNodeId: nodeId
|
|
1035
|
+
}
|
|
1036
|
+
) : combiner ? /* @__PURE__ */ jsx(SchemaRow, { schemaNode: selectedChoice.type, nestingLevel }) : null
|
|
1037
|
+
] });
|
|
1038
|
+
}
|
|
1039
|
+
if (isComplexArray(schemaNode) && isPureObjectNode(schemaNode.children[0])) {
|
|
1040
|
+
const validations = isRegularNode(schemaNode) ? getValidationsFromSchema(schemaNode) : {};
|
|
1041
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1042
|
+
/* @__PURE__ */ jsx(Description, { value: schemaNode.annotations.description }),
|
|
1043
|
+
/* @__PURE__ */ jsx("div", { className: "jsv-top-label", children: "array of:" }),
|
|
1044
|
+
!isEmpty(validations) && /* @__PURE__ */ jsx("div", { className: "jsv-validations", style: { marginBottom: "0.25rem" }, children: /* @__PURE__ */ jsx(Validations, { validations }) }),
|
|
1045
|
+
childNodes.length > 0 ? /* @__PURE__ */ jsx(
|
|
1046
|
+
ChildStack,
|
|
1047
|
+
{
|
|
1048
|
+
schemaNode,
|
|
1049
|
+
childNodes,
|
|
1050
|
+
currentNestingLevel: nestingLevel,
|
|
1051
|
+
parentNodeId: nodeId
|
|
1052
|
+
}
|
|
1053
|
+
) : null
|
|
1054
|
+
] });
|
|
1055
|
+
}
|
|
1056
|
+
return /* @__PURE__ */ jsx(SchemaRow, { schemaNode, nestingLevel });
|
|
1057
|
+
};
|
|
1058
|
+
function isPureObjectNode(schemaNode) {
|
|
1059
|
+
return schemaNode.primaryType === "object" && schemaNode.types?.length === 1 && !isDictionaryNode(schemaNode);
|
|
1060
|
+
}
|
|
1061
|
+
var JsonSchemaViewer = ({
|
|
1062
|
+
viewMode = "standalone",
|
|
1063
|
+
defaultExpandedDepth = 1,
|
|
1064
|
+
onGoToRef,
|
|
1065
|
+
renderRowAddon,
|
|
1066
|
+
renderExtensionAddon,
|
|
1067
|
+
hideExamples,
|
|
1068
|
+
renderRootTreeLines,
|
|
1069
|
+
disableCrumbs,
|
|
1070
|
+
nodeHasChanged,
|
|
1071
|
+
skipTopLevelDescription,
|
|
1072
|
+
...rest
|
|
1073
|
+
}) => {
|
|
1074
|
+
const options = React2.useMemo(
|
|
1075
|
+
() => ({
|
|
1076
|
+
defaultExpandedDepth,
|
|
1077
|
+
viewMode,
|
|
1078
|
+
onGoToRef,
|
|
1079
|
+
renderRowAddon,
|
|
1080
|
+
renderExtensionAddon,
|
|
1081
|
+
hideExamples,
|
|
1082
|
+
renderRootTreeLines,
|
|
1083
|
+
disableCrumbs,
|
|
1084
|
+
nodeHasChanged
|
|
1085
|
+
}),
|
|
1086
|
+
[
|
|
1087
|
+
defaultExpandedDepth,
|
|
1088
|
+
viewMode,
|
|
1089
|
+
onGoToRef,
|
|
1090
|
+
renderRowAddon,
|
|
1091
|
+
renderExtensionAddon,
|
|
1092
|
+
hideExamples,
|
|
1093
|
+
renderRootTreeLines,
|
|
1094
|
+
disableCrumbs,
|
|
1095
|
+
nodeHasChanged
|
|
1096
|
+
]
|
|
1097
|
+
);
|
|
1098
|
+
return /* @__PURE__ */ jsx(JSVOptionsContextProvider, { value: options, children: /* @__PURE__ */ jsx(Provider, { children: /* @__PURE__ */ jsx(
|
|
1099
|
+
JsonSchemaViewerInner,
|
|
1100
|
+
{
|
|
1101
|
+
viewMode,
|
|
1102
|
+
skipTopLevelDescription,
|
|
1103
|
+
...rest
|
|
1104
|
+
}
|
|
1105
|
+
) }) });
|
|
1106
|
+
};
|
|
1107
|
+
var JsonSchemaViewerInner = ({
|
|
1108
|
+
schema,
|
|
1109
|
+
viewMode,
|
|
1110
|
+
className,
|
|
1111
|
+
resolveRef,
|
|
1112
|
+
maxRefDepth,
|
|
1113
|
+
emptyText = "No schema defined",
|
|
1114
|
+
onTreePopulated,
|
|
1115
|
+
maxHeight,
|
|
1116
|
+
parentCrumbs,
|
|
1117
|
+
skipTopLevelDescription,
|
|
1118
|
+
"data-theme": dataTheme
|
|
1119
|
+
}) => {
|
|
1120
|
+
const setHoveredNode = useSetAtom(hoveredNodeAtom);
|
|
1121
|
+
const onMouseLeave = React2.useCallback(() => {
|
|
1122
|
+
setHoveredNode(null);
|
|
1123
|
+
}, [setHoveredNode]);
|
|
1124
|
+
const { jsonSchemaTreeRoot, nodeCount } = React2.useMemo(() => {
|
|
1125
|
+
const jsonSchemaTree = new SchemaTree(schema, {
|
|
1126
|
+
mergeAllOf: true,
|
|
1127
|
+
refResolver: resolveRef,
|
|
1128
|
+
maxRefDepth
|
|
1129
|
+
});
|
|
1130
|
+
let nodeCount2 = 0;
|
|
1131
|
+
jsonSchemaTree.walker.hookInto("filter", (node) => {
|
|
1132
|
+
if (shouldNodeBeIncluded(node, viewMode)) {
|
|
1133
|
+
nodeCount2++;
|
|
1134
|
+
return true;
|
|
1135
|
+
}
|
|
1136
|
+
return false;
|
|
1137
|
+
});
|
|
1138
|
+
jsonSchemaTree.populate();
|
|
1139
|
+
return {
|
|
1140
|
+
jsonSchemaTreeRoot: jsonSchemaTree.root,
|
|
1141
|
+
nodeCount: nodeCount2
|
|
1142
|
+
};
|
|
1143
|
+
}, [schema, resolveRef, maxRefDepth, viewMode]);
|
|
1144
|
+
React2.useEffect(() => {
|
|
1145
|
+
onTreePopulated?.({
|
|
1146
|
+
rootNode: jsonSchemaTreeRoot,
|
|
1147
|
+
nodeCount
|
|
1148
|
+
});
|
|
1149
|
+
}, [jsonSchemaTreeRoot, onTreePopulated, nodeCount]);
|
|
1150
|
+
const isEmpty2 = React2.useMemo(
|
|
1151
|
+
() => jsonSchemaTreeRoot.children.every((node) => !isRegularNode(node) || node.unknown),
|
|
1152
|
+
[jsonSchemaTreeRoot]
|
|
1153
|
+
);
|
|
1154
|
+
if (isEmpty2) {
|
|
1155
|
+
return /* @__PURE__ */ jsx("div", { className: clsx("jsv-root", className), "data-test": "empty-text", "data-theme": dataTheme, children: emptyText });
|
|
1156
|
+
}
|
|
1157
|
+
return /* @__PURE__ */ jsxs(
|
|
1158
|
+
"div",
|
|
1159
|
+
{
|
|
1160
|
+
className: clsx("jsv-root", className),
|
|
1161
|
+
onMouseLeave,
|
|
1162
|
+
style: { maxHeight, ...maxHeight ? { overflowY: "auto" } : {} },
|
|
1163
|
+
"data-theme": dataTheme,
|
|
1164
|
+
children: [
|
|
1165
|
+
/* @__PURE__ */ jsx(PathCrumbs, { parentCrumbs }),
|
|
1166
|
+
/* @__PURE__ */ jsx("div", { className: "jsv-content", children: /* @__PURE__ */ jsx(TopLevelSchemaRow, { schemaNode: jsonSchemaTreeRoot.children[0], skipDescription: skipTopLevelDescription }) })
|
|
1167
|
+
]
|
|
1168
|
+
}
|
|
1169
|
+
);
|
|
1170
|
+
};
|
|
1171
|
+
var JsonSchemaViewerErrorBoundary = class extends React2.Component {
|
|
1172
|
+
constructor(props) {
|
|
1173
|
+
super(props);
|
|
1174
|
+
this.state = { hasError: false, error: null };
|
|
1175
|
+
}
|
|
1176
|
+
static getDerivedStateFromError(error) {
|
|
1177
|
+
return { hasError: true, error };
|
|
1178
|
+
}
|
|
1179
|
+
render() {
|
|
1180
|
+
if (this.state.hasError) {
|
|
1181
|
+
if (this.props.fallback) {
|
|
1182
|
+
return this.props.fallback;
|
|
1183
|
+
}
|
|
1184
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "1rem" }, children: [
|
|
1185
|
+
/* @__PURE__ */ jsx("strong", { style: { color: "var(--jsv-color-danger, #ef4444)" }, children: "Error" }),
|
|
1186
|
+
this.state.error !== null ? `: ${this.state.error.message}` : null
|
|
1187
|
+
] });
|
|
1188
|
+
}
|
|
1189
|
+
return this.props.children;
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
export { JsonSchemaViewer, JsonSchemaViewerErrorBoundary, Validations, getValidationsFromSchema, useChoices, visibleChildren };
|
|
1194
|
+
//# sourceMappingURL=index.js.map
|
|
1195
|
+
//# sourceMappingURL=index.js.map
|