@open-resource-discovery/metadata-renderer 0.0.0 → 1.0.1

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 (74) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +94 -1
  3. package/dist/a2a/index.d.ts +9 -0
  4. package/dist/a2a.js +2 -0
  5. package/dist/asyncApi/asyncapi-browser.d.ts +3 -0
  6. package/dist/asyncApi/customAttributes/attributeLink.d.ts +3 -0
  7. package/dist/asyncApi/customAttributes/autoDiscover.d.ts +4 -0
  8. package/dist/asyncApi/customAttributes/buildExtensionsConfig.d.ts +5 -0
  9. package/dist/asyncApi/customAttributes/context.d.ts +7 -0
  10. package/dist/asyncApi/customAttributes/genericRenderer.d.ts +4 -0
  11. package/dist/asyncApi/customAttributes/sapPreset.d.ts +2 -0
  12. package/dist/asyncApi/customAttributes/stateInfo.d.ts +3 -0
  13. package/dist/asyncApi/customAttributes/styles.d.ts +2 -0
  14. package/dist/asyncApi/customAttributes/types.d.ts +32 -0
  15. package/dist/asyncApi/index.d.ts +11 -0
  16. package/dist/asyncapi.js +2 -0
  17. package/dist/chunks/a2a-B5lkgqLU.js +29 -0
  18. package/dist/chunks/asyncApi-DtAXW7IY.js +502 -0
  19. package/dist/chunks/csn-3ek2O4d6.js +385 -0
  20. package/dist/chunks/mcp-qA5sYRAN.js +29 -0
  21. package/dist/chunks/openApi-BTb5yzun.js +783 -0
  22. package/dist/chunks/utils-BC3WF3-9.js +77 -0
  23. package/dist/core/ShadowRoot.d.ts +6 -0
  24. package/dist/core/dispatch.d.ts +3 -0
  25. package/dist/core/dispatch.test.d.ts +1 -0
  26. package/dist/core/index.d.ts +11 -0
  27. package/dist/core/utils.d.ts +7 -0
  28. package/dist/core/utils.test.d.ts +1 -0
  29. package/dist/csn/customAttributes/genericRenderer.d.ts +2 -0
  30. package/dist/csn/customAttributes/postProcess.d.ts +5 -0
  31. package/dist/csn/customAttributes/sapPreset.d.ts +2 -0
  32. package/dist/csn/customAttributes/types.d.ts +28 -0
  33. package/dist/csn/index.d.ts +11 -0
  34. package/dist/csn/styles.d.ts +2 -0
  35. package/dist/csn.js +2 -0
  36. package/dist/entries/a2a.d.ts +2 -0
  37. package/dist/entries/asyncapi.d.ts +2 -0
  38. package/dist/entries/csn.d.ts +2 -0
  39. package/dist/entries/mcp.d.ts +2 -0
  40. package/dist/entries/openapi.d.ts +2 -0
  41. package/dist/favicon.ico +0 -0
  42. package/dist/favicon.svg +29 -0
  43. package/dist/index.css +210782 -0
  44. package/dist/index.d.ts +23 -0
  45. package/dist/index.js +783 -0
  46. package/dist/mcp/index.d.ts +8 -0
  47. package/dist/mcp.js +2 -0
  48. package/dist/openApi/customAttributes/attributeLink.d.ts +3 -0
  49. package/dist/openApi/customAttributes/autoDiscover.d.ts +15 -0
  50. package/dist/openApi/customAttributes/genericRenderer.d.ts +3 -0
  51. package/dist/openApi/customAttributes/sapAttributes/operation/deprecatedOperation.d.ts +10 -0
  52. package/dist/openApi/customAttributes/sapAttributes/root/extOverview.d.ts +2 -0
  53. package/dist/openApi/customAttributes/sapAttributes/root/extensible.d.ts +10 -0
  54. package/dist/openApi/customAttributes/sapAttributes/root/ordId.d.ts +6 -0
  55. package/dist/openApi/customAttributes/sapAttributes/root/stateInfo.d.ts +11 -0
  56. package/dist/openApi/customAttributes/sapAttributes/root/typeCheckXxtOverview.d.ts +10 -0
  57. package/dist/openApi/customAttributes/sapAttributes/root/typeCheckXxtOverview.spec.d.ts +1 -0
  58. package/dist/openApi/customAttributes/sapAttributes/sapPreset.d.ts +2 -0
  59. package/dist/openApi/customAttributes/sapAttributes/schema/odmEntityName.d.ts +6 -0
  60. package/dist/openApi/customAttributes/sapAttributes/schema/odmSemanticKey.d.ts +10 -0
  61. package/dist/openApi/customAttributes/types.d.ts +31 -0
  62. package/dist/openApi/index.d.ts +9 -0
  63. package/dist/openApi/styles.d.ts +2 -0
  64. package/dist/openApi/utils/context.d.ts +7 -0
  65. package/dist/openApi/utils/context.test.d.ts +1 -0
  66. package/dist/openApi/utils/plugins.d.ts +3 -0
  67. package/dist/openApi/utils/scalarTheme.d.ts +11 -0
  68. package/dist/openapi.js +2 -0
  69. package/dist/styles.d.ts +0 -0
  70. package/dist/styles.js +4 -0
  71. package/dist/theme-builder.d.ts +28 -0
  72. package/dist/types.d.ts +46 -0
  73. package/dist/vendor.d.ts +2 -0
  74. package/package.json +135 -3
@@ -0,0 +1,783 @@
1
+ import { i as loadObject } from "./utils-BC3WF3-9.js";
2
+ /* empty css */
3
+ import { createElement, useEffect, useId, useMemo, useRef } from "react";
4
+ import { ApiReferenceReact } from "@scalar/api-reference-react";
5
+ import Markdown from "react-markdown";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { ReactRenderer } from "@scalar/react-renderer";
8
+ //#region src/lib/openApi/utils/context.ts
9
+ var openApiContext = {
10
+ version: "",
11
+ configs: [],
12
+ getDocumentationUrl(attributeName) {
13
+ return (this.configs.find((c) => c.extensions?.[attributeName]) ?? this.configs.find((c) => c.prefixStartsWith && attributeName.startsWith(c.prefixStartsWith)))?.documentationUrl?.(attributeName, { version: this.version });
14
+ }
15
+ };
16
+ var getVersion = (content) => {
17
+ const parsedContent = loadObject(content);
18
+ if (!parsedContent) return "";
19
+ if ("openapi" in parsedContent && parsedContent.openapi && typeof parsedContent.openapi === "string") return parsedContent.openapi.substring(0, 3);
20
+ if ("swagger" in parsedContent && parsedContent.swagger && typeof parsedContent.swagger === "string") return "2.0";
21
+ return "";
22
+ };
23
+ //#endregion
24
+ //#region src/lib/openApi/customAttributes/autoDiscover.ts
25
+ var HTTP_METHODS = [
26
+ "get",
27
+ "put",
28
+ "post",
29
+ "delete",
30
+ "options",
31
+ "head",
32
+ "patch",
33
+ "trace"
34
+ ];
35
+ function discoverAttributeNames(doc, prefix) {
36
+ const names = /* @__PURE__ */ new Set();
37
+ for (const key of Object.keys(doc)) if (key.startsWith(prefix)) names.add(key);
38
+ const paths = doc.paths;
39
+ if (paths) for (const pathItem of Object.values(paths)) {
40
+ if (!pathItem || typeof pathItem !== "object") continue;
41
+ for (const method of HTTP_METHODS) {
42
+ const op = pathItem[method];
43
+ if (!op || typeof op !== "object") continue;
44
+ for (const key of Object.keys(op)) if (key.startsWith(prefix)) names.add(key);
45
+ }
46
+ }
47
+ const schemas = doc.components?.schemas;
48
+ if (schemas) for (const schema of Object.values(schemas)) {
49
+ if (!schema || typeof schema !== "object") continue;
50
+ const s = schema;
51
+ for (const key of Object.keys(s)) if (key.startsWith(prefix)) names.add(key);
52
+ const properties = s.properties;
53
+ if (properties) for (const prop of Object.values(properties)) {
54
+ if (!prop || typeof prop !== "object") continue;
55
+ for (const key of Object.keys(prop)) if (key.startsWith(prefix)) names.add(key);
56
+ }
57
+ }
58
+ return [...names];
59
+ }
60
+ /**
61
+ * Synthetic property key injected into schema.properties so Scalar calls SpecificationExtension on it.
62
+ * The value is the full schema object; our extension component reads any x-* fields from it.
63
+ */
64
+ var SCHEMA_ATTRS_KEY = "x-sap-schema-attrs";
65
+ /**
66
+ * Clone doc and inject a synthetic property into every schema object that carries
67
+ * at least one key matching the given prefix. Scalar only calls SpecificationExtension
68
+ * on property-level schemas, so this is the only way to render schema-level x-* fields.
69
+ */
70
+ function injectSchemaExtensions(doc, prefixes) {
71
+ const schemas = doc.components?.schemas;
72
+ if (!schemas) return doc;
73
+ const patchedSchemas = {};
74
+ let anyPatched = false;
75
+ for (const [name, schema] of Object.entries(schemas)) {
76
+ if (!schema || typeof schema !== "object") {
77
+ patchedSchemas[name] = schema;
78
+ continue;
79
+ }
80
+ const s = schema;
81
+ const xFields = {};
82
+ for (const [k, v] of Object.entries(s)) if (prefixes.some((p) => k.startsWith(p))) xFields[k] = v;
83
+ if (Object.keys(xFields).length === 0) {
84
+ patchedSchemas[name] = schema;
85
+ continue;
86
+ }
87
+ anyPatched = true;
88
+ patchedSchemas[name] = {
89
+ ...s,
90
+ properties: {
91
+ [SCHEMA_ATTRS_KEY]: { [SCHEMA_ATTRS_KEY]: xFields },
92
+ ...s.properties
93
+ }
94
+ };
95
+ }
96
+ if (!anyPatched) return doc;
97
+ return {
98
+ ...doc,
99
+ components: {
100
+ ...doc.components,
101
+ schemas: patchedSchemas
102
+ }
103
+ };
104
+ }
105
+ function extractCustomAttributeValues(doc, prefix) {
106
+ const result = [];
107
+ for (const [k, v] of Object.entries(doc)) if (k.startsWith(prefix)) result.push([k, v]);
108
+ const paths = doc.paths;
109
+ if (paths) for (const [path, pathItem] of Object.entries(paths)) {
110
+ if (!pathItem || typeof pathItem !== "object") continue;
111
+ for (const method of HTTP_METHODS) {
112
+ const op = pathItem[method];
113
+ if (!op || typeof op !== "object") continue;
114
+ for (const [k, v] of Object.entries(op)) if (k.startsWith(prefix)) result.push([`paths.${path}.${method}.${k}`, v]);
115
+ }
116
+ }
117
+ const schemas = doc.components?.schemas;
118
+ if (schemas) for (const [schemaName, schema] of Object.entries(schemas)) {
119
+ if (!schema || typeof schema !== "object") continue;
120
+ const s = schema;
121
+ for (const [k, v] of Object.entries(s)) if (k.startsWith(prefix)) result.push([`components.schemas.${schemaName}.${k}`, v]);
122
+ const properties = s.properties;
123
+ if (properties) for (const [propName, prop] of Object.entries(properties)) {
124
+ if (!prop || typeof prop !== "object") continue;
125
+ for (const [k, v] of Object.entries(prop)) if (k.startsWith(prefix)) result.push([`components.schemas.${schemaName}.properties.${propName}.${k}`, v]);
126
+ }
127
+ }
128
+ return result;
129
+ }
130
+ //#endregion
131
+ //#region src/lib/openApi/customAttributes/attributeLink.tsx
132
+ function attributeLink({ attributeName }) {
133
+ const href = openApiContext.getDocumentationUrl(attributeName);
134
+ if (!href) return null;
135
+ return /* @__PURE__ */ jsx("a", {
136
+ href,
137
+ style: { marginLeft: 4 },
138
+ target: "_blank",
139
+ rel: "noreferrer",
140
+ title: "View in OpenAPI Specification",
141
+ children: /* @__PURE__ */ jsx("svg", {
142
+ width: "16",
143
+ height: "16",
144
+ viewBox: "0 0 16 16",
145
+ fill: "currentColor",
146
+ children: /* @__PURE__ */ jsx("path", { d: "M10.604 1h4.146a.25.25 0 01.25.25v4.146a.25.25 0 01-.427.177L13.03 4.03 9.28 7.78a.75.75 0 01-1.06-1.06l3.75-3.75-1.543-1.543A.25.25 0 0110.604 1zM3.75 2A1.75 1.75 0 002 3.75v8.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 12.25v-3.5a.75.75 0 00-1.5 0v3.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-8.5a.25.25 0 01.25-.25h3.5a.75.75 0 000-1.5h-3.5z" })
147
+ })
148
+ });
149
+ }
150
+ //#endregion
151
+ //#region src/lib/openApi/customAttributes/genericRenderer.tsx
152
+ function autoLabel(fieldName, prefix) {
153
+ let name = fieldName;
154
+ if (prefix && name.startsWith(prefix)) name = name.slice(prefix.length);
155
+ return name.split("-").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
156
+ }
157
+ function kebabToCamel(str) {
158
+ return str.replace(/-./g, (x) => x[1].toUpperCase());
159
+ }
160
+ function getValueKey(fieldName) {
161
+ return kebabToCamel(fieldName);
162
+ }
163
+ function extractValue(data, fieldName) {
164
+ if (!data || typeof data !== "object") return void 0;
165
+ return data[getValueKey(fieldName)];
166
+ }
167
+ function Label({ name, label }) {
168
+ return /* @__PURE__ */ jsxs("div", {
169
+ className: "sap-api-label",
170
+ children: [
171
+ label,
172
+ " ",
173
+ /* @__PURE__ */ jsx(attributeLink, { attributeName: name })
174
+ ]
175
+ });
176
+ }
177
+ function StringRenderer(props) {
178
+ const link = props.valueLinks?.[props.value];
179
+ return /* @__PURE__ */ jsxs("div", {
180
+ className: "sap-api-container",
181
+ children: [/* @__PURE__ */ jsx(Label, {
182
+ name: props.name,
183
+ label: props.label
184
+ }), /* @__PURE__ */ jsx("p", {
185
+ className: "sap-api-value",
186
+ children: link ? /* @__PURE__ */ jsx("a", {
187
+ href: link,
188
+ rel: "noreferrer noopener",
189
+ target: "_blank",
190
+ className: "sap-api-link",
191
+ children: props.value
192
+ }) : props.value
193
+ })]
194
+ });
195
+ }
196
+ function BooleanRenderer(props) {
197
+ return /* @__PURE__ */ jsxs("div", {
198
+ className: "sap-api-container",
199
+ children: [/* @__PURE__ */ jsx(Label, {
200
+ name: props.name,
201
+ label: props.label
202
+ }), /* @__PURE__ */ jsx("p", {
203
+ className: "sap-api-value",
204
+ children: props.value ? "Yes" : "No"
205
+ })]
206
+ });
207
+ }
208
+ function NumberRenderer(props) {
209
+ return /* @__PURE__ */ jsxs("div", {
210
+ className: "sap-api-container",
211
+ children: [/* @__PURE__ */ jsx(Label, {
212
+ name: props.name,
213
+ label: props.label
214
+ }), /* @__PURE__ */ jsx("p", {
215
+ className: "sap-api-value",
216
+ children: props.value
217
+ })]
218
+ });
219
+ }
220
+ function ArrayRenderer(props) {
221
+ return /* @__PURE__ */ jsxs("div", {
222
+ className: "sap-api-container",
223
+ children: [/* @__PURE__ */ jsx(Label, {
224
+ name: props.name,
225
+ label: props.label
226
+ }), /* @__PURE__ */ jsx("div", {
227
+ className: "sap-api-value",
228
+ children: /* @__PURE__ */ jsx("ul", {
229
+ className: "sap-api-list",
230
+ children: props.value.map((item, i) => /* @__PURE__ */ jsx("li", { children: renderObjectValue(item) }, i))
231
+ })
232
+ })]
233
+ });
234
+ }
235
+ function renderObjectValue(val) {
236
+ if (val === null || val === void 0) return /* @__PURE__ */ jsx("span", {
237
+ className: "sap-api-placeholder",
238
+ children: "—"
239
+ });
240
+ if (typeof val === "boolean") return /* @__PURE__ */ jsx("span", { children: val ? "Yes" : "No" });
241
+ if (typeof val === "number") return /* @__PURE__ */ jsx("span", { children: val });
242
+ if (Array.isArray(val)) return /* @__PURE__ */ jsx("ul", {
243
+ className: "sap-api-list",
244
+ children: val.map((item, i) => /* @__PURE__ */ jsx("li", { children: renderObjectValue(item) }, i))
245
+ });
246
+ if (typeof val === "object") return /* @__PURE__ */ jsx("dl", {
247
+ className: "sap-api-obj",
248
+ children: Object.entries(val).map(([k, v]) => /* @__PURE__ */ jsxs("div", {
249
+ className: "sap-api-obj-row",
250
+ children: [
251
+ /* @__PURE__ */ jsxs("dt", {
252
+ className: "sap-api-obj-key",
253
+ children: [k, ":"]
254
+ }),
255
+ " ",
256
+ /* @__PURE__ */ jsx("dd", {
257
+ className: "sap-api-obj-val",
258
+ children: renderObjectValue(v)
259
+ })
260
+ ]
261
+ }, k))
262
+ });
263
+ const str = String(val);
264
+ return /[*_`[\]#]/.test(str) ? /* @__PURE__ */ jsx(Markdown, { children: str }) : /* @__PURE__ */ jsx("span", { children: str });
265
+ }
266
+ function ObjectRenderer(props) {
267
+ return /* @__PURE__ */ jsxs("div", {
268
+ className: "sap-api-container",
269
+ children: [/* @__PURE__ */ jsx(Label, {
270
+ name: props.name,
271
+ label: props.label
272
+ }), /* @__PURE__ */ jsx("div", {
273
+ className: "sap-api-value",
274
+ children: renderObjectValue(props.value)
275
+ })]
276
+ });
277
+ }
278
+ function LinkRenderer(props) {
279
+ const href = props.callback(props.value);
280
+ return /* @__PURE__ */ jsxs("div", {
281
+ className: "sap-api-container",
282
+ children: [/* @__PURE__ */ jsx(Label, {
283
+ name: props.name,
284
+ label: props.label
285
+ }), /* @__PURE__ */ jsx("p", {
286
+ className: "sap-api-value",
287
+ children: href ? /* @__PURE__ */ jsx("a", {
288
+ href,
289
+ rel: "noreferrer noopener",
290
+ target: "_blank",
291
+ className: "sap-api-link",
292
+ children: String(props.value)
293
+ }) : String(props.value)
294
+ })]
295
+ });
296
+ }
297
+ function buildGenericRenderer(fieldName, def, config) {
298
+ if (def && "component" in def) return def.component;
299
+ return (data) => {
300
+ const value = extractValue(data, fieldName);
301
+ if (value === void 0 || value === null) return null;
302
+ const label = def && "label" in def && def.label ? def.label : autoLabel(fieldName, config.prefixStartsWith);
303
+ if (def?.type === "link" && "callback" in def) return /* @__PURE__ */ jsx(LinkRenderer, {
304
+ name: fieldName,
305
+ label,
306
+ value,
307
+ callback: def.callback
308
+ });
309
+ if (def?.type === "boolean" || typeof value === "boolean") return /* @__PURE__ */ jsx(BooleanRenderer, {
310
+ name: fieldName,
311
+ label,
312
+ value: Boolean(value)
313
+ });
314
+ if (def?.type === "number" || typeof value === "number") return /* @__PURE__ */ jsx(NumberRenderer, {
315
+ name: fieldName,
316
+ label,
317
+ value
318
+ });
319
+ if (def?.type === "array" || Array.isArray(value)) {
320
+ if (!Array.isArray(value)) return null;
321
+ return /* @__PURE__ */ jsx(ArrayRenderer, {
322
+ name: fieldName,
323
+ label,
324
+ value
325
+ });
326
+ }
327
+ if (def?.type === "object" || typeof value === "object") return /* @__PURE__ */ jsx(ObjectRenderer, {
328
+ name: fieldName,
329
+ label,
330
+ value
331
+ });
332
+ const valueLinks = def && "valueLinks" in def ? def.valueLinks : void 0;
333
+ return /* @__PURE__ */ jsx(StringRenderer, {
334
+ name: fieldName,
335
+ label,
336
+ value: String(value),
337
+ valueLinks
338
+ });
339
+ };
340
+ }
341
+ //#endregion
342
+ //#region src/lib/openApi/utils/plugins.ts
343
+ function camelCaseKeys(obj) {
344
+ const result = {};
345
+ for (const [k, v] of Object.entries(obj)) {
346
+ const camelKey = k.replace(/-./g, (x) => x[1].toUpperCase());
347
+ result[camelKey] = v;
348
+ }
349
+ return result;
350
+ }
351
+ function buildSchemaAttrsRenderer(configs) {
352
+ return (data) => {
353
+ if (!data || typeof data !== "object") return null;
354
+ const outer = data;
355
+ const xFields = outer["xSapSchemaAttrs"] ?? outer["x-sap-schema-attrs"];
356
+ if (!xFields || typeof xFields !== "object") return null;
357
+ const camelData = camelCaseKeys(xFields);
358
+ const renderers = [];
359
+ for (const key of Object.keys(xFields)) {
360
+ if (!key.startsWith("x-")) continue;
361
+ const matchingConfig = configs.find((c) => c.extensions?.[key]) ?? configs.find((c) => c.prefixStartsWith && key.startsWith(c.prefixStartsWith));
362
+ if (!matchingConfig) continue;
363
+ const def = matchingConfig.extensions?.[key];
364
+ const el = buildGenericRenderer(key, def, matchingConfig)(camelData);
365
+ if (el) renderers.push(el);
366
+ }
367
+ if (renderers.length === 0) return null;
368
+ return createElement("div", { className: "sap-schema-attrs-block" }, ...renderers);
369
+ };
370
+ }
371
+ function buildCustomAttributesPlugin(doc, configs) {
372
+ const allNames = /* @__PURE__ */ new Set();
373
+ for (const config of configs) {
374
+ if (config.extensions) for (const name of Object.keys(config.extensions)) allNames.add(name);
375
+ if (config.prefixStartsWith && doc) for (const name of discoverAttributeNames(doc, config.prefixStartsWith)) allNames.add(name);
376
+ }
377
+ const extensions = [...allNames].map((name) => {
378
+ const matchingConfig = configs.find((c) => c.extensions?.[name]) ?? configs.find((c) => c.prefixStartsWith && name.startsWith(c.prefixStartsWith)) ?? configs[0];
379
+ const def = matchingConfig?.extensions?.[name];
380
+ return {
381
+ name,
382
+ component: buildGenericRenderer(name, def, matchingConfig ?? {}),
383
+ renderer: ReactRenderer
384
+ };
385
+ });
386
+ extensions.push({
387
+ name: SCHEMA_ATTRS_KEY,
388
+ component: buildSchemaAttrsRenderer(configs),
389
+ renderer: ReactRenderer
390
+ });
391
+ return () => ({
392
+ name: "custom-attributes-plugin",
393
+ extensions
394
+ });
395
+ }
396
+ //#endregion
397
+ //#region src/lib/openApi/utils/scalarTheme.ts
398
+ var SCALAR_MAP = {
399
+ "--ord-background": ["--scalar-background-1"],
400
+ "--ord-foreground": ["--scalar-color-1"],
401
+ "--ord-secondary": ["--scalar-background-2"],
402
+ "--ord-secondary-foreground": ["--scalar-color-2"],
403
+ "--ord-muted": ["--scalar-background-3"],
404
+ "--ord-muted-foreground": ["--scalar-color-3"],
405
+ "--ord-primary": [
406
+ "--scalar-color-accent",
407
+ "--scalar-button-1",
408
+ "--scalar-link-color",
409
+ "--scalar-button-1-hover",
410
+ "--scalar-link-color-hover"
411
+ ],
412
+ "--ord-primary-foreground": ["--scalar-button-1-color"],
413
+ "--ord-border": ["--scalar-border-color"],
414
+ "--ord-destructive": ["--scalar-color-red", "--scalar-color-danger"],
415
+ "--ord-success": ["--scalar-color-green"],
416
+ "--ord-warning": ["--scalar-color-orange"],
417
+ "--ord-radius": ["--scalar-radius", "--scalar-radius-lg"]
418
+ };
419
+ var SCALAR_SIDEBAR_MAP = {
420
+ "--ord-sidebar": ["--scalar-sidebar-background-1"],
421
+ "--ord-sidebar-foreground": ["--scalar-sidebar-color-1"],
422
+ "--ord-sidebar-primary": ["--scalar-sidebar-background-2"],
423
+ "--ord-sidebar-primary-foreground": ["--scalar-sidebar-color-2", "--scalar-sidebar-search-color"],
424
+ "--ord-sidebar-accent": [
425
+ "--scalar-sidebar-item-active-background",
426
+ "--scalar-sidebar-item-hover-background",
427
+ "--scalar-sidebar-search-background"
428
+ ],
429
+ "--ord-sidebar-accent-foreground": ["--scalar-sidebar-color-active", "--scalar-sidebar-item-hover-color"],
430
+ "--ord-sidebar-border": ["--scalar-sidebar-border-color", "--scalar-sidebar-search-border-color"]
431
+ };
432
+ function formatValue(name, value) {
433
+ if (name === "--ord-radius") return `${value}px`;
434
+ return value;
435
+ }
436
+ var scalarAdapter = {
437
+ selector: ".scalar-app",
438
+ map(canonical) {
439
+ const out = {};
440
+ for (const [name, value] of Object.entries(canonical)) {
441
+ const targets = SCALAR_MAP[name];
442
+ if (!targets) continue;
443
+ const formatted = formatValue(name, value);
444
+ for (const target of targets) out[target] = formatted;
445
+ }
446
+ return out;
447
+ }
448
+ };
449
+ var scalarSidebarAdapter = {
450
+ selector: ".scalar-app .t-doc__sidebar",
451
+ map(canonical) {
452
+ const out = {};
453
+ for (const [name, value] of Object.entries(canonical)) {
454
+ const targets = SCALAR_SIDEBAR_MAP[name];
455
+ if (!targets) continue;
456
+ for (const target of targets) out[target] = value;
457
+ }
458
+ return out;
459
+ }
460
+ };
461
+ var scalarModeAdapter = {
462
+ selector: ".scalar-app .dark-mode, .scalar-app.dark-mode, .scalar-app .light-mode, .scalar-app.light-mode",
463
+ map(canonical) {
464
+ const out = {};
465
+ for (const [name, value] of Object.entries(canonical)) {
466
+ const targets = SCALAR_MAP[name];
467
+ if (!targets) continue;
468
+ const formatted = formatValue(name, value);
469
+ for (const target of targets) out[target] = formatted;
470
+ }
471
+ return out;
472
+ }
473
+ };
474
+ var SCALAR_HLJS_VARS = [
475
+ "--ord-hljs-attr",
476
+ "--ord-hljs-string",
477
+ "--ord-hljs-number",
478
+ "--ord-hljs-function",
479
+ "--ord-hljs-literal",
480
+ "--ord-hljs-punctuation",
481
+ "--ord-hljs-keyword",
482
+ "--ord-hljs-comment"
483
+ ];
484
+ var scalarHljsAdapter = {
485
+ selector: ".scalar-app",
486
+ map(canonical) {
487
+ const out = {};
488
+ for (const name of SCALAR_HLJS_VARS) if (name in canonical) out[name] = canonical[name];
489
+ return out;
490
+ }
491
+ };
492
+ var scalarTeleportAdapter = {
493
+ selector: ".scalar-app, #headlessui-portal-root",
494
+ map(canonical) {
495
+ const out = {};
496
+ for (const [name, value] of Object.entries(canonical)) {
497
+ const targets = SCALAR_MAP[name];
498
+ if (!targets) continue;
499
+ const formatted = formatValue(name, value);
500
+ for (const target of targets) out[target] = formatted;
501
+ }
502
+ return out;
503
+ }
504
+ };
505
+ function buildScalarThemeStyles(id, theme) {
506
+ const scope = `[data-renderer-id="${id}"]`;
507
+ return [[
508
+ scalarAdapter,
509
+ scalarSidebarAdapter,
510
+ scalarModeAdapter,
511
+ scalarHljsAdapter
512
+ ].map((adapter) => {
513
+ const mapped = adapter.map(theme);
514
+ const decls = Object.entries(mapped).map(([k, v]) => ` ${k}: ${v};`).join("\n");
515
+ if (!decls) return "";
516
+ return `${scope} ${adapter.selector} {\n${decls}\n}`;
517
+ }).filter(Boolean).join("\n\n"), (() => {
518
+ const mapped = scalarTeleportAdapter.map(theme);
519
+ const decls = Object.entries(mapped).map(([k, v]) => ` ${k}: ${v};`).join("\n");
520
+ if (!decls) return "";
521
+ return `${scalarTeleportAdapter.selector} {\n${decls}\n}`;
522
+ })()].filter(Boolean).join("\n\n");
523
+ }
524
+ //#endregion
525
+ //#region src/lib/openApi/styles.ts
526
+ var styles_default = `
527
+ .sap-api-container {
528
+ display: flex;
529
+ flex-wrap: wrap;
530
+ container-type: inline-size;
531
+ border: var(--scalar-border-width) solid var(--scalar-border-color);
532
+ border-radius: var(--scalar-radius-lg);
533
+ margin-top: 8px;
534
+ font-size: var(--scalar-small);
535
+ line-height: var(--scalar-line-height-3);
536
+ overflow: hidden;
537
+ }
538
+
539
+ .sap-api-label {
540
+ color: var(--scalar-color-1);
541
+ width: 30%;
542
+ min-width: 20ch;
543
+ flex-shrink: 0;
544
+ background: var(--scalar-background-2);
545
+ padding: 6px 9px 6px 12px;
546
+ border-right: var(--scalar-border-width) solid var(--scalar-border-color);
547
+ display: flex;
548
+ align-items: flex-start;
549
+ justify-content: space-between;
550
+ font-weight: 500;
551
+ }
552
+
553
+ .sap-api-label--root {
554
+ min-width: 20ch;
555
+ }
556
+
557
+ .sap-api-value {
558
+ color: var(--scalar-color-2);
559
+ padding: 8px;
560
+ flex: 1 1 0;
561
+ min-width: 0;
562
+ }
563
+
564
+ .sap-api-value--root {
565
+ flex: 1 1 0;
566
+ min-width: 0;
567
+ }
568
+
569
+ .sap-api-list {
570
+ margin: 0 2ch;
571
+ list-style: disc;
572
+ }
573
+
574
+ .sap-api-link {
575
+ text-decoration: none;
576
+ color: var(--scalar-link-color);
577
+ transition: color 0.1s ease-in-out;
578
+ cursor: pointer;
579
+ }
580
+
581
+ .sap-api-ord-id {
582
+ display: flex;
583
+ align-items: flex-start;
584
+ gap: 8px;
585
+ }
586
+
587
+ .sap-api-ord-id-text {
588
+ flex: 1 1 auto;
589
+ min-width: 0;
590
+ word-break: break-all;
591
+ }
592
+
593
+ .sap-api-copy-btn {
594
+ flex-shrink: 0;
595
+ cursor: pointer;
596
+ display: inline-flex;
597
+ align-items: center;
598
+ justify-content: center;
599
+ font-size: 1em;
600
+ line-height: 1;
601
+ padding: 4px;
602
+ color: var(--scalar-color-2);
603
+ background: var(--scalar-background-2);
604
+ border: var(--scalar-border-width) solid var(--scalar-border-color);
605
+ border-radius: var(--scalar-radius);
606
+ transition: background 0.1s ease-in-out, color 0.1s ease-in-out;
607
+ }
608
+
609
+ .sap-api-copy-btn:hover {
610
+ background: var(--scalar-background-3);
611
+ color: var(--scalar-color-1);
612
+ }
613
+
614
+ .sap-api-placeholder {
615
+ color: #999;
616
+ }
617
+
618
+ .sap-api-obj {
619
+ margin: 0;
620
+ padding-left: 12px;
621
+ }
622
+
623
+ .sap-api-obj-row {
624
+ margin-bottom: 4px;
625
+ }
626
+
627
+ .sap-api-obj-key {
628
+ font-weight: 600;
629
+ display: inline;
630
+ }
631
+
632
+ .sap-api-obj-val {
633
+ display: inline;
634
+ margin: 0;
635
+ }
636
+
637
+ /* Width-adaptive rows: react to the row's own available width (container-type above).
638
+ When the row is narrow, label and value wrap onto separate lines (label above value). */
639
+ @container (max-width: 420px) {
640
+ .sap-api-label,
641
+ .sap-api-label--root {
642
+ flex-basis: 100%;
643
+ width: 100%;
644
+ min-width: 0;
645
+ border-right: none;
646
+ border-bottom: var(--scalar-border-width) solid var(--scalar-border-color);
647
+ }
648
+ .sap-api-value,
649
+ .sap-api-value--root {
650
+ flex-basis: 100%;
651
+ width: 100%;
652
+ }
653
+ }
654
+
655
+ a {
656
+ text-decoration: none;
657
+ color: var(--sapLinkColor);
658
+ transition: color 0.1s ease-in-out;
659
+ cursor: pointer;
660
+ }
661
+ a:hover {
662
+ text-decoration: underline;
663
+ }
664
+
665
+ /* Keyboard key: use Scalar background instead of Infima colors */
666
+ .scalar-app kbd {
667
+ background: var(--scalar-background-1);
668
+ color: var(--scalar-color-1);
669
+ border: 1px solid var(--scalar-border-color);
670
+ }
671
+
672
+ /* Syntax highlighting — override --scalar-color-* with ThemeEditor --ord-hljs-* tokens */
673
+ .scalar-app .hljs-attr,
674
+ .scalar-app .hljs-attribute { color: var(--ord-hljs-attr); }
675
+
676
+ .scalar-app .hljs-string,
677
+ .scalar-app .hljs-regexp,
678
+ .scalar-app .hljs-subst,
679
+ .scalar-app .hljs-doctag,
680
+ .scalar-app .hljs-bullet,
681
+ .scalar-app .hljs-link,
682
+ .scalar-app .hljs-meta,
683
+ .scalar-app .hljs-symbol { color: var(--ord-hljs-string); }
684
+
685
+ .scalar-app .hljs-number,
686
+ .scalar-app .hljs-selector-attr,
687
+ .scalar-app .hljs-selector-pseudo,
688
+ .scalar-app .hljs-built_in { color: var(--ord-hljs-number); }
689
+
690
+ .scalar-app .hljs-title.function_ { color: var(--ord-hljs-function); }
691
+
692
+ .scalar-app .hljs-addition,
693
+ .scalar-app .hljs-literal,
694
+ .scalar-app .hljs-selector-tag,
695
+ .scalar-app .hljs-type { color: var(--ord-hljs-literal); }
696
+
697
+ .scalar-app .hljs-keyword { color: var(--ord-hljs-keyword); }
698
+
699
+ .scalar-app .hljs-comment,
700
+ .scalar-app .hljs-quote { color: var(--ord-hljs-comment); }
701
+
702
+ .scalar-app .hljs-punctuation { color: var(--ord-hljs-punctuation); }
703
+
704
+ /* Hide the "x-sap-schema-attrs" property heading row — the row exists only to
705
+ carry schema-level extension components; the key name should not be visible. */
706
+ .scalar-app .property:has(.sap-schema-attrs-block) {
707
+ padding-top: 2px;
708
+ }
709
+ .scalar-app .property:has(.sap-schema-attrs-block) .property-heading {
710
+ display: none;
711
+ }
712
+
713
+ /* Override Scalar's sidebar height variable so the <aside> uses our measured container height
714
+ instead of Scalar's default 100dvh (which breaks when embedded in Docusaurus/non-fullscreen). */
715
+ .scalar-app {
716
+ --refs-sidebar-height: calc(var(--scalar-container-height, 100dvh) - var(--refs-header-height, 0px));
717
+ }
718
+ `;
719
+ //#endregion
720
+ //#region src/lib/openApi/index.tsx
721
+ function OpenApiRenderer({ content, customAttributes, className, theme }) {
722
+ const id = useId();
723
+ const containerRef = useRef(null);
724
+ const isDark = className?.split(/\s+/).includes("dark") ?? false;
725
+ const activeConfigs = useMemo(() => customAttributes ?? [], [customAttributes]);
726
+ const isEnabled = customAttributes !== void 0;
727
+ useEffect(() => {
728
+ const el = containerRef.current;
729
+ if (!el) return;
730
+ const ro = new ResizeObserver(([entry]) => {
731
+ el.style.setProperty("--scalar-container-height", `${entry.contentRect.height}px`);
732
+ });
733
+ ro.observe(el);
734
+ return () => {
735
+ ro.disconnect();
736
+ if (window.location.hash) history.replaceState(null, "", window.location.pathname + window.location.search);
737
+ };
738
+ }, []);
739
+ const customAttributesKey = useMemo(() => {
740
+ if (!isEnabled) return "";
741
+ const parsed = loadObject(content);
742
+ if (!parsed) return "";
743
+ return activeConfigs.flatMap((config) => extractCustomAttributeValues(parsed, config.prefixStartsWith ?? "").map(([k, v]) => `${k}=${JSON.stringify(v)}`)).join("|");
744
+ }, [
745
+ content,
746
+ isEnabled,
747
+ activeConfigs
748
+ ]);
749
+ const configuration = useMemo(() => {
750
+ openApiContext.version = getVersion(content);
751
+ openApiContext.configs = isEnabled ? activeConfigs : [];
752
+ const parsed = loadObject(content);
753
+ const prefixes = activeConfigs.map((c) => c.prefixStartsWith).filter(Boolean);
754
+ return {
755
+ content: isEnabled && parsed && prefixes.length ? injectSchemaExtensions(parsed, prefixes) : parsed ?? content,
756
+ plugins: isEnabled ? [buildCustomAttributesPlugin(parsed, activeConfigs)] : [],
757
+ forceDarkModeState: isDark ? "dark" : "light",
758
+ hideDarkModeToggle: true,
759
+ hideClientButton: true,
760
+ showDeveloperTools: "never"
761
+ };
762
+ }, [
763
+ content,
764
+ isDark,
765
+ isEnabled,
766
+ activeConfigs
767
+ ]);
768
+ return /* @__PURE__ */ jsxs("div", {
769
+ ref: containerRef,
770
+ "data-renderer-id": id,
771
+ style: {
772
+ height: "100%",
773
+ ...theme
774
+ },
775
+ children: [
776
+ /* @__PURE__ */ jsx("style", { children: styles_default }),
777
+ theme && /* @__PURE__ */ jsx("style", { children: buildScalarThemeStyles(id, theme) }),
778
+ /* @__PURE__ */ jsx(ApiReferenceReact, { configuration }, `${isDark ? "dark" : "light"}-${isEnabled}-${customAttributesKey}`)
779
+ ]
780
+ });
781
+ }
782
+ //#endregion
783
+ export { attributeLink as n, OpenApiRenderer as t };