@scalar/blocks 0.5.1 → 0.5.3

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 (139) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/code-example/components/CodeExample.vue.d.ts +2 -0
  3. package/dist/code-example/components/CodeExample.vue.d.ts.map +1 -1
  4. package/dist/code-example/components/CodeExample.vue.js +1 -1
  5. package/dist/code-example/components/CodeExample.vue.js.map +1 -1
  6. package/dist/code-example/components/CodeExample.vue.script.js +71 -68
  7. package/dist/code-example/components/CodeExample.vue.script.js.map +1 -1
  8. package/dist/code-example/helpers/generate-client-options.d.ts.map +1 -1
  9. package/dist/code-example/helpers/generate-client-options.js.map +1 -1
  10. package/dist/code-example/helpers/get-clients.d.ts.map +1 -1
  11. package/dist/code-example/helpers/get-clients.js.map +1 -1
  12. package/dist/code-example/helpers/operation-to-har/process-body.d.ts.map +1 -1
  13. package/dist/code-example/helpers/operation-to-har/process-body.js +42 -42
  14. package/dist/code-example/helpers/operation-to-har/process-body.js.map +1 -1
  15. package/dist/code-example/helpers/operation-to-har/process-parameters.d.ts.map +1 -1
  16. package/dist/code-example/helpers/operation-to-har/process-parameters.js +63 -62
  17. package/dist/code-example/helpers/operation-to-har/process-parameters.js.map +1 -1
  18. package/dist/code-example/mount.d.ts.map +1 -1
  19. package/dist/code-example/mount.js +1 -1
  20. package/dist/code-example/mount.js.map +1 -1
  21. package/dist/constants.js +1 -1
  22. package/dist/schema/Schema.vue.d.ts.map +1 -1
  23. package/dist/schema/Schema.vue.js +1 -1
  24. package/dist/schema/Schema.vue.js.map +1 -1
  25. package/dist/schema/Schema.vue.script.js +122 -116
  26. package/dist/schema/Schema.vue.script.js.map +1 -1
  27. package/dist/schema/SchemaComposition.vue.d.ts.map +1 -1
  28. package/dist/schema/SchemaComposition.vue.js +1 -1
  29. package/dist/schema/SchemaComposition.vue.js.map +1 -1
  30. package/dist/schema/SchemaComposition.vue.script.js +110 -106
  31. package/dist/schema/SchemaComposition.vue.script.js.map +1 -1
  32. package/dist/schema/SchemaEnumPropertyItem.vue.js.map +1 -1
  33. package/dist/schema/SchemaEnumPropertyItem.vue.script.js +2 -2
  34. package/dist/schema/SchemaEnumPropertyItem.vue.script.js.map +1 -1
  35. package/dist/schema/SchemaObjectProperties.vue.js.map +1 -1
  36. package/dist/schema/SchemaObjectProperties.vue.script.js +1 -1
  37. package/dist/schema/SchemaObjectProperties.vue.script.js.map +1 -1
  38. package/dist/schema/SchemaProperty.vue.d.ts +1 -1
  39. package/dist/schema/SchemaProperty.vue.d.ts.map +1 -1
  40. package/dist/schema/SchemaProperty.vue.js +1 -1
  41. package/dist/schema/SchemaProperty.vue.js.map +1 -1
  42. package/dist/schema/SchemaProperty.vue.script.js +179 -164
  43. package/dist/schema/SchemaProperty.vue.script.js.map +1 -1
  44. package/dist/schema/SchemaPropertyHeading.vue.d.ts +5 -3
  45. package/dist/schema/SchemaPropertyHeading.vue.d.ts.map +1 -1
  46. package/dist/schema/SchemaPropertyHeading.vue.js +1 -1
  47. package/dist/schema/SchemaPropertyHeading.vue.js.map +1 -1
  48. package/dist/schema/SchemaPropertyHeading.vue.script.js +122 -117
  49. package/dist/schema/SchemaPropertyHeading.vue.script.js.map +1 -1
  50. package/dist/schema/SchemaPropertyPattern.vue.js +1 -1
  51. package/dist/schema/SchemaPropertyPattern.vue.js.map +1 -1
  52. package/dist/schema/SchemaPropertyPattern.vue.script.js +1 -1
  53. package/dist/schema/SchemaPropertyPattern.vue.script.js.map +1 -1
  54. package/dist/schema/discriminator-metadata.d.ts +13 -0
  55. package/dist/schema/discriminator-metadata.d.ts.map +1 -0
  56. package/dist/schema/discriminator-metadata.js +6 -0
  57. package/dist/schema/discriminator-metadata.js.map +1 -0
  58. package/dist/schema/helpers/get-compositions-to-render.d.ts +3 -1
  59. package/dist/schema/helpers/get-compositions-to-render.d.ts.map +1 -1
  60. package/dist/schema/helpers/get-compositions-to-render.js +25 -24
  61. package/dist/schema/helpers/get-compositions-to-render.js.map +1 -1
  62. package/dist/schema/helpers/get-property-description.d.ts +6 -3
  63. package/dist/schema/helpers/get-property-description.d.ts.map +1 -1
  64. package/dist/schema/helpers/get-property-description.js +10 -10
  65. package/dist/schema/helpers/get-property-description.js.map +1 -1
  66. package/dist/schema/helpers/has-complex-array-items.d.ts.map +1 -1
  67. package/dist/schema/helpers/has-complex-array-items.js +6 -2
  68. package/dist/schema/helpers/has-complex-array-items.js.map +1 -1
  69. package/dist/schema/helpers/merge-all-of-schemas.d.ts.map +1 -1
  70. package/dist/schema/helpers/merge-all-of-schemas.js +2 -2
  71. package/dist/schema/helpers/merge-all-of-schemas.js.map +1 -1
  72. package/dist/schema/helpers/optimize-value-for-display.d.ts.map +1 -1
  73. package/dist/schema/helpers/optimize-value-for-display.js +34 -33
  74. package/dist/schema/helpers/optimize-value-for-display.js.map +1 -1
  75. package/dist/schema/helpers/partition-all-of-compositions.d.ts.map +1 -1
  76. package/dist/schema/helpers/partition-all-of-compositions.js +39 -27
  77. package/dist/schema/helpers/partition-all-of-compositions.js.map +1 -1
  78. package/dist/schema/helpers/schema-name.js +1 -1
  79. package/dist/schema/helpers/schema-name.js.map +1 -1
  80. package/dist/schema/index.d.ts +2 -0
  81. package/dist/schema/index.d.ts.map +1 -1
  82. package/dist/schema/index.js +13 -11
  83. package/dist/schema/localization/index.d.ts +11 -1
  84. package/dist/schema/localization/index.d.ts.map +1 -1
  85. package/dist/schema/localization/locales/ar.d.ts +10 -0
  86. package/dist/schema/localization/locales/ar.d.ts.map +1 -1
  87. package/dist/schema/localization/locales/ar.js +11 -1
  88. package/dist/schema/localization/locales/ar.js.map +1 -1
  89. package/dist/schema/localization/locales/de.d.ts +10 -0
  90. package/dist/schema/localization/locales/de.d.ts.map +1 -1
  91. package/dist/schema/localization/locales/de.js +11 -1
  92. package/dist/schema/localization/locales/de.js.map +1 -1
  93. package/dist/schema/localization/locales/en.d.ts +10 -0
  94. package/dist/schema/localization/locales/en.d.ts.map +1 -1
  95. package/dist/schema/localization/locales/en.js +11 -1
  96. package/dist/schema/localization/locales/en.js.map +1 -1
  97. package/dist/schema/localization/locales/es.d.ts +10 -0
  98. package/dist/schema/localization/locales/es.d.ts.map +1 -1
  99. package/dist/schema/localization/locales/es.js +11 -1
  100. package/dist/schema/localization/locales/es.js.map +1 -1
  101. package/dist/schema/localization/locales/fr.d.ts +10 -0
  102. package/dist/schema/localization/locales/fr.d.ts.map +1 -1
  103. package/dist/schema/localization/locales/fr.js +11 -1
  104. package/dist/schema/localization/locales/fr.js.map +1 -1
  105. package/dist/schema/localization/locales/pt.d.ts +10 -0
  106. package/dist/schema/localization/locales/pt.d.ts.map +1 -1
  107. package/dist/schema/localization/locales/pt.js +11 -1
  108. package/dist/schema/localization/locales/pt.js.map +1 -1
  109. package/dist/schema/localization/locales/ru.d.ts +10 -0
  110. package/dist/schema/localization/locales/ru.d.ts.map +1 -1
  111. package/dist/schema/localization/locales/ru.js +11 -1
  112. package/dist/schema/localization/locales/ru.js.map +1 -1
  113. package/dist/schema/localization/locales/zh-cn.d.ts +10 -0
  114. package/dist/schema/localization/locales/zh-cn.d.ts.map +1 -1
  115. package/dist/schema/localization/locales/zh-cn.js +11 -1
  116. package/dist/schema/localization/locales/zh-cn.js.map +1 -1
  117. package/dist/schema/localization/locales/zh-tw.d.ts +69 -0
  118. package/dist/schema/localization/locales/zh-tw.d.ts.map +1 -0
  119. package/dist/schema/localization/locales/zh-tw.js +70 -0
  120. package/dist/schema/localization/locales/zh-tw.js.map +1 -0
  121. package/dist/schema/localization/translations.d.ts +147 -0
  122. package/dist/schema/localization/translations.d.ts.map +1 -1
  123. package/dist/schema/localization/translations.js +5 -3
  124. package/dist/schema/localization/translations.js.map +1 -1
  125. package/dist/schema/types.d.ts +2 -0
  126. package/dist/schema/types.d.ts.map +1 -1
  127. package/dist/shared/ExternalDocs.vue.d.ts +9 -0
  128. package/dist/shared/ExternalDocs.vue.d.ts.map +1 -0
  129. package/dist/shared/ExternalDocs.vue.js +7 -0
  130. package/dist/shared/ExternalDocs.vue.js.map +1 -0
  131. package/dist/shared/ExternalDocs.vue.script.js +46 -0
  132. package/dist/shared/ExternalDocs.vue.script.js.map +1 -0
  133. package/dist/shared/index.d.ts +1 -0
  134. package/dist/shared/index.d.ts.map +1 -1
  135. package/dist/shared/index.js +4 -3
  136. package/dist/style.css +63 -19
  137. package/dist/styles/schema-tree.css +3 -1
  138. package/dist/vue-styles.css +1 -1
  139. package/package.json +10 -10
@@ -0,0 +1,13 @@
1
+ import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
2
+ /** Display-only discriminator information; symbols never enter exported API descriptions. */
3
+ export declare const schemaDiscriminator: unique symbol;
4
+ /** A schema view can explain inferred values without adding validation constraints. */
5
+ export type DiscriminatorMetadata = {
6
+ [schemaDiscriminator]?: {
7
+ value?: string;
8
+ inheritedVariants?: boolean;
9
+ };
10
+ };
11
+ /** Schema carrying renderer-only discriminator metadata. */
12
+ export type DiscriminatorSchema = SchemaObject & DiscriminatorMetadata;
13
+ //# sourceMappingURL=discriminator-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discriminator-metadata.d.ts","sourceRoot":"","sources":["../../src/schema/discriminator-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAEhG,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,eAAiC,CAAA;AAEjE,uFAAuF;AACvF,MAAM,MAAM,qBAAqB,GAAG;IAClC,CAAC,mBAAmB,CAAC,CAAC,EAAE;QACtB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAC5B,CAAA;CACF,CAAA;AAED,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,qBAAqB,CAAA"}
@@ -0,0 +1,6 @@
1
+ //#region src/schema/discriminator-metadata.ts
2
+ var e = Symbol("schema-discriminator");
3
+ //#endregion
4
+ export { e as schemaDiscriminator };
5
+
6
+ //# sourceMappingURL=discriminator-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discriminator-metadata.js","names":[],"sources":["../../src/schema/discriminator-metadata.ts"],"sourcesContent":["import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\n\n/** Display-only discriminator information; symbols never enter exported API descriptions. */\nexport const schemaDiscriminator = Symbol('schema-discriminator')\n\n/** A schema view can explain inferred values without adding validation constraints. */\nexport type DiscriminatorMetadata = {\n [schemaDiscriminator]?: {\n value?: string\n inheritedVariants?: boolean\n }\n}\n\n/** Schema carrying renderer-only discriminator metadata. */\nexport type DiscriminatorSchema = SchemaObject & DiscriminatorMetadata\n"],"mappings":";AAGA,IAAa,IAAsB,OAAO,sBAAsB"}
@@ -14,7 +14,9 @@ type DocumentSchemaLookup = Pick<OpenApiDocument, 'components'>;
14
14
  * Returns `null` when there is nothing to infer (an explicit composition is
15
15
  * already present, no document to resolve refs against, or no resolvable refs).
16
16
  */
17
- export declare const inferDiscriminatorMappingComposition: (value: SchemaObject, documentProp?: DocumentSchemaLookup) => SchemaObject | null;
17
+ export declare const inferDiscriminatorMappingComposition: (value: SchemaObject, documentProp?: DocumentSchemaLookup,
18
+ /** Inheritance can supply ordered variants, including schemas that share a mapped value. */
19
+ variantRefs?: readonly string[]) => SchemaObject | null;
18
20
  /**
19
21
  * Computes which compositions should be rendered and with which values
20
22
  *
@@ -1 +1 @@
1
- {"version":3,"file":"get-compositions-to-render.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/get-compositions-to-render.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAIjH,OAAO,EAAE,KAAK,kBAAkB,EAAgB,MAAM,sBAAsB,CAAA;AAI5E,KAAK,mBAAmB,GAAG;IACzB,WAAW,EAAE,kBAAkB,CAAA;IAC/B,KAAK,EAAE,YAAY,CAAA;CACpB,CAAA;AAED,KAAK,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;AAK/D;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,GAC/C,OAAO,YAAY,EACnB,eAAe,oBAAoB,KAClC,YAAY,GAAG,IA+CjB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,YAAY,GAAG,SAAS,EAC/B,WAAW,oBAAoB;AAC/B;;;;;GAKG;AACH,mCAAkC,YAAY,GAAG,IAEzC,KACP,mBAAmB,EAuCrB,CAAA"}
1
+ {"version":3,"file":"get-compositions-to-render.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/get-compositions-to-render.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAIjH,OAAO,EAAE,KAAK,kBAAkB,EAAgB,MAAM,sBAAsB,CAAA;AAI5E,KAAK,mBAAmB,GAAG;IACzB,WAAW,EAAE,kBAAkB,CAAA;IAC/B,KAAK,EAAE,YAAY,CAAA;CACpB,CAAA;AAED,KAAK,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;AAK/D;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,GAC/C,OAAO,YAAY,EACnB,eAAe,oBAAoB;AACnC,4FAA4F;AAC5F,cAAc,SAAS,MAAM,EAAE,KAC9B,YAAY,GAAG,IAiDjB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,YAAY,GAAG,SAAS,EAC/B,WAAW,oBAAoB;AAC/B;;;;;GAKG;AACH,mCAAkC,YAAY,GAAG,IAEzC,KACP,mBAAmB,EAuCrB,CAAA"}
@@ -2,38 +2,39 @@ import { getRefName as e } from "./get-ref-name.js";
2
2
  import { compositions as t } from "./schema-composition.js";
3
3
  import { shouldRenderArrayItemComposition as n } from "./should-render-array-item-composition.js";
4
4
  import { unwrapForRead as r } from "./unwrap-for-read.js";
5
- import { resolve as i } from "@scalar/workspace-store/resolve";
6
- import { isDefined as a } from "@scalar/helpers/array/is-defined";
7
- import { isArraySchema as o } from "@scalar/workspace-store/schemas/v3.2/strict/type-guards";
5
+ import { isDefined as i } from "@scalar/helpers/array/is-defined";
6
+ import { unescapeJsonPointerSegment as a } from "@scalar/helpers/json/unescape-json-pointer-segment";
7
+ import { resolve as o } from "@scalar/workspace-store/resolve";
8
+ import { isArraySchema as s } from "@scalar/workspace-store/schemas/v3.2/strict/type-guards";
8
9
  //#region src/schema/helpers/get-compositions-to-render.ts
9
- var s = (e) => e.startsWith("#/") || e.includes("/") ? e : `#/components/schemas/${e}`, c = (t, n) => {
10
+ var c = (e) => e.startsWith("#/") || e.includes("/") ? e : `#/components/schemas/${e}`, l = (t, n, s) => {
10
11
  if (t.oneOf || t.anyOf) return null;
11
- let o = t.discriminator?.mapping;
12
- if (!o) return null;
13
- let c = r(n);
14
- if (!c?.components?.schemas) return null;
15
- let l = Object.values(o).filter((e) => typeof e == "string").map((t) => {
16
- let n = s(t), r = e(n), a = r ? i.schema(c.components?.schemas?.[r]) : void 0;
17
- if (a) return {
12
+ let l = t.discriminator?.mapping;
13
+ if (!l) return null;
14
+ let u = r(n);
15
+ if (!u?.components?.schemas) return null;
16
+ let d = (s ?? Object.values(l)).filter((e) => typeof e == "string").map((t) => {
17
+ let n = c(t), r = e(n), i = r ? o.schema(u.components?.schemas?.[a(r)]) : void 0;
18
+ if (i) return {
18
19
  $ref: n,
19
- "$ref-value": a
20
+ "$ref-value": i
20
21
  };
21
- }).filter(a);
22
- return l.length === 0 ? null : {
23
- ...i.schema(t),
24
- oneOf: l
22
+ }).filter(i);
23
+ return d.length === 0 ? null : {
24
+ ...o.schema(t),
25
+ oneOf: d
25
26
  };
26
- }, l = (e, r, s = e ? c(e, r) : null) => e ? t.map((t) => t === "oneOf" && s ? {
27
+ }, u = (e, r, a = e ? l(e, r) : null) => e ? t.map((t) => t === "oneOf" && a ? {
27
28
  composition: t,
28
- value: s
29
- } : n(e, t) && o(e) && e.items ? {
29
+ value: a
30
+ } : n(e, t) && s(e) && e.items ? {
30
31
  composition: t,
31
- value: i.schema(e.items)
32
- } : e[t] && !(o(e) && e.items && typeof e.items == "object" && t in e.items) ? {
32
+ value: o.schema(e.items)
33
+ } : e[t] && !(s(e) && e.items && typeof e.items == "object" && t in e.items) ? {
33
34
  composition: t,
34
- value: i.schema(e)
35
- } : null).filter(a) : [];
35
+ value: o.schema(e)
36
+ } : null).filter(i) : [];
36
37
  //#endregion
37
- export { l as getCompositionsToRender, c as inferDiscriminatorMappingComposition };
38
+ export { u as getCompositionsToRender, l as inferDiscriminatorMappingComposition };
38
39
 
39
40
  //# sourceMappingURL=get-compositions-to-render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-compositions-to-render.js","names":[],"sources":["../../../src/schema/helpers/get-compositions-to-render.ts"],"sourcesContent":["import { isDefined } from '@scalar/helpers/array/is-defined'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { OpenApiDocument, SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\nimport { getRefName } from './get-ref-name'\nimport { type CompositionKeyword, compositions } from './schema-composition'\nimport { shouldRenderArrayItemComposition } from './should-render-array-item-composition'\nimport { unwrapForRead } from './unwrap-for-read'\n\ntype CompositionToRender = {\n composition: CompositionKeyword\n value: SchemaObject\n}\n\ntype DocumentSchemaLookup = Pick<OpenApiDocument, 'components'>\n\nconst normalizeDiscriminatorMappingRef = (value: string) =>\n value.startsWith('#/') || value.includes('/') ? value : `#/components/schemas/${value}`\n\n/**\n * Builds a synthetic `oneOf` composition from a `discriminator.mapping` when the\n * schema declares a mapping but no explicit `oneOf`/`anyOf`. This is the shape\n * NSwag emits for polymorphic types, where the base type is a plain object with\n * a discriminator mapping pointing at the concrete variants.\n *\n * Returns `null` when there is nothing to infer (an explicit composition is\n * already present, no document to resolve refs against, or no resolvable refs).\n */\nexport const inferDiscriminatorMappingComposition = (\n value: SchemaObject,\n documentProp?: DocumentSchemaLookup,\n): SchemaObject | null => {\n if (value.oneOf || value.anyOf) {\n return null\n }\n\n // A schema without a mapping can never infer anything, so it is checked before the document is\n // touched at all: the document read below is by far the more expensive of the two.\n const mapping = value.discriminator?.mapping\n\n if (!mapping) {\n return null\n }\n\n // Reading `components.schemas` per row through the reactive and detect-changes layers is the\n // dominant cost of this helper, so the document is unwrapped once here. See `unwrapForRead`.\n const document = unwrapForRead(documentProp)\n\n if (!document?.components?.schemas) {\n return null\n }\n\n const refs = Object.values(mapping)\n .filter((mappingValue): mappingValue is string => typeof mappingValue === 'string')\n .map((mappingValue) => {\n const ref = normalizeDiscriminatorMappingRef(mappingValue)\n const refName = getRefName(ref)\n const refValue = refName ? resolve.schema(document.components?.schemas?.[refName]) : undefined\n\n if (!refValue) {\n return undefined\n }\n\n return {\n $ref: ref,\n '$ref-value': refValue,\n }\n })\n .filter(isDefined)\n\n if (refs.length === 0) {\n return null\n }\n\n return {\n ...resolve.schema(value),\n oneOf: refs,\n }\n}\n\n/**\n * Computes which compositions should be rendered and with which values\n *\n * @param value - The schema object to check for compositions\n * @returns Array of compositions to render with their values\n */\nexport const getCompositionsToRender = (\n value: SchemaObject | undefined,\n document?: DocumentSchemaLookup,\n /**\n * The `oneOf` inferred from a bare `discriminator.mapping`, when the caller has\n * already computed it. `SchemaProperty` needs the same value to decide whether\n * to suppress the duplicate base object block, so it passes it here to avoid\n * inferring twice. Omit it and it is inferred from `value`.\n */\n inferredDiscriminatorComposition: SchemaObject | null = value\n ? inferDiscriminatorMappingComposition(value, document)\n : null,\n): CompositionToRender[] => {\n if (!value) {\n return []\n }\n\n return compositions\n .map((composition) => {\n if (composition === 'oneOf' && inferredDiscriminatorComposition) {\n return {\n composition,\n value: inferredDiscriminatorComposition,\n }\n }\n\n // Check for array item-level composition first (more specific case)\n if (shouldRenderArrayItemComposition(value, composition) && isArraySchema(value) && value.items) {\n return {\n composition,\n value: resolve.schema(value.items),\n }\n }\n\n // Check for property-level composition\n if (value[composition]) {\n // Skip if array items have this composition (even if complex/not rendered)\n const hasArrayItemComposition =\n isArraySchema(value) && value.items && typeof value.items === 'object' && composition in value.items\n\n if (!hasArrayItemComposition) {\n return {\n composition,\n value: resolve.schema(value),\n }\n }\n }\n\n return null\n })\n .filter(isDefined)\n}\n"],"mappings":";;;;;;;;AAiBA,IAAM,KAAoC,MACxC,EAAM,WAAW,IAAI,KAAK,EAAM,SAAS,GAAG,IAAI,IAAQ,wBAAwB,KAWrE,KACX,GACA,MACwB;CACxB,IAAI,EAAM,SAAS,EAAM,OACvB,OAAO;CAKT,IAAM,IAAU,EAAM,eAAe;CAErC,IAAI,CAAC,GACH,OAAO;CAKT,IAAM,IAAW,EAAc,CAAY;CAE3C,IAAI,CAAC,GAAU,YAAY,SACzB,OAAO;CAGT,IAAM,IAAO,OAAO,OAAO,CAAO,CAAC,CAChC,QAAQ,MAAyC,OAAO,KAAiB,QAAQ,CAAC,CAClF,KAAK,MAAiB;EACrB,IAAM,IAAM,EAAiC,CAAY,GACnD,IAAU,EAAW,CAAG,GACxB,IAAW,IAAU,EAAQ,OAAO,EAAS,YAAY,UAAU,EAAQ,IAAI,KAAA;EAEhF,OAIL,OAAO;GACL,MAAM;GACN,cAAc;EAChB;CACF,CAAC,CAAC,CACD,OAAO,CAAS;CAMnB,OAJI,EAAK,WAAW,IACX,OAGF;EACL,GAAG,EAAQ,OAAO,CAAK;EACvB,OAAO;CACT;AACF,GAQa,KACX,GACA,GAOA,IAAwD,IACpD,EAAqC,GAAO,CAAQ,IACpD,SAEC,IAIE,EACJ,KAAK,MACA,MAAgB,WAAW,IACtB;CACL;CACA,OAAO;AACT,IAIE,EAAiC,GAAO,CAAW,KAAK,EAAc,CAAK,KAAK,EAAM,QACjF;CACL;CACA,OAAO,EAAQ,OAAO,EAAM,KAAK;AACnC,IAIE,EAAM,MAKJ,EAFF,EAAc,CAAK,KAAK,EAAM,SAAS,OAAO,EAAM,SAAU,YAAY,KAAe,EAAM,SAGxF;CACL;CACA,OAAO,EAAQ,OAAO,CAAK;AAC7B,IAIG,IACR,CAAC,CACD,OAAO,CAAS,IApCV,CAAC"}
1
+ {"version":3,"file":"get-compositions-to-render.js","names":[],"sources":["../../../src/schema/helpers/get-compositions-to-render.ts"],"sourcesContent":["import { isDefined } from '@scalar/helpers/array/is-defined'\nimport { unescapeJsonPointerSegment } from '@scalar/helpers/json/unescape-json-pointer-segment'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { OpenApiDocument, SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\nimport { getRefName } from './get-ref-name'\nimport { type CompositionKeyword, compositions } from './schema-composition'\nimport { shouldRenderArrayItemComposition } from './should-render-array-item-composition'\nimport { unwrapForRead } from './unwrap-for-read'\n\ntype CompositionToRender = {\n composition: CompositionKeyword\n value: SchemaObject\n}\n\ntype DocumentSchemaLookup = Pick<OpenApiDocument, 'components'>\n\nconst normalizeDiscriminatorMappingRef = (value: string) =>\n value.startsWith('#/') || value.includes('/') ? value : `#/components/schemas/${value}`\n\n/**\n * Builds a synthetic `oneOf` composition from a `discriminator.mapping` when the\n * schema declares a mapping but no explicit `oneOf`/`anyOf`. This is the shape\n * NSwag emits for polymorphic types, where the base type is a plain object with\n * a discriminator mapping pointing at the concrete variants.\n *\n * Returns `null` when there is nothing to infer (an explicit composition is\n * already present, no document to resolve refs against, or no resolvable refs).\n */\nexport const inferDiscriminatorMappingComposition = (\n value: SchemaObject,\n documentProp?: DocumentSchemaLookup,\n /** Inheritance can supply ordered variants, including schemas that share a mapped value. */\n variantRefs?: readonly string[],\n): SchemaObject | null => {\n if (value.oneOf || value.anyOf) {\n return null\n }\n\n // A schema without a mapping can never infer anything, so it is checked before the document is\n // touched at all: the document read below is by far the more expensive of the two.\n const mapping = value.discriminator?.mapping\n\n if (!mapping) {\n return null\n }\n\n // Reading `components.schemas` per row through the reactive and detect-changes layers is the\n // dominant cost of this helper, so the document is unwrapped once here. See `unwrapForRead`.\n const document = unwrapForRead(documentProp)\n\n if (!document?.components?.schemas) {\n return null\n }\n\n const refs = (variantRefs ?? Object.values(mapping))\n .filter((mappingValue): mappingValue is string => typeof mappingValue === 'string')\n .map((mappingValue) => {\n const ref = normalizeDiscriminatorMappingRef(mappingValue)\n const refName = getRefName(ref)\n const refValue = refName\n ? resolve.schema(document.components?.schemas?.[unescapeJsonPointerSegment(refName)])\n : undefined\n\n if (!refValue) {\n return undefined\n }\n\n return {\n $ref: ref,\n '$ref-value': refValue,\n }\n })\n .filter(isDefined)\n\n if (refs.length === 0) {\n return null\n }\n\n return {\n ...resolve.schema(value),\n oneOf: refs,\n }\n}\n\n/**\n * Computes which compositions should be rendered and with which values\n *\n * @param value - The schema object to check for compositions\n * @returns Array of compositions to render with their values\n */\nexport const getCompositionsToRender = (\n value: SchemaObject | undefined,\n document?: DocumentSchemaLookup,\n /**\n * The `oneOf` inferred from a bare `discriminator.mapping`, when the caller has\n * already computed it. `SchemaProperty` needs the same value to decide whether\n * to suppress the duplicate base object block, so it passes it here to avoid\n * inferring twice. Omit it and it is inferred from `value`.\n */\n inferredDiscriminatorComposition: SchemaObject | null = value\n ? inferDiscriminatorMappingComposition(value, document)\n : null,\n): CompositionToRender[] => {\n if (!value) {\n return []\n }\n\n return compositions\n .map((composition) => {\n if (composition === 'oneOf' && inferredDiscriminatorComposition) {\n return {\n composition,\n value: inferredDiscriminatorComposition,\n }\n }\n\n // Check for array item-level composition first (more specific case)\n if (shouldRenderArrayItemComposition(value, composition) && isArraySchema(value) && value.items) {\n return {\n composition,\n value: resolve.schema(value.items),\n }\n }\n\n // Check for property-level composition\n if (value[composition]) {\n // Skip if array items have this composition (even if complex/not rendered)\n const hasArrayItemComposition =\n isArraySchema(value) && value.items && typeof value.items === 'object' && composition in value.items\n\n if (!hasArrayItemComposition) {\n return {\n composition,\n value: resolve.schema(value),\n }\n }\n }\n\n return null\n })\n .filter(isDefined)\n}\n"],"mappings":";;;;;;;;;AAkBA,IAAM,KAAoC,MACxC,EAAM,WAAW,IAAI,KAAK,EAAM,SAAS,GAAG,IAAI,IAAQ,wBAAwB,KAWrE,KACX,GACA,GAEA,MACwB;CACxB,IAAI,EAAM,SAAS,EAAM,OACvB,OAAO;CAKT,IAAM,IAAU,EAAM,eAAe;CAErC,IAAI,CAAC,GACH,OAAO;CAKT,IAAM,IAAW,EAAc,CAAY;CAE3C,IAAI,CAAC,GAAU,YAAY,SACzB,OAAO;CAGT,IAAM,KAAQ,KAAe,OAAO,OAAO,CAAO,EAAA,CAC/C,QAAQ,MAAyC,OAAO,KAAiB,QAAQ,CAAC,CAClF,KAAK,MAAiB;EACrB,IAAM,IAAM,EAAiC,CAAY,GACnD,IAAU,EAAW,CAAG,GACxB,IAAW,IACb,EAAQ,OAAO,EAAS,YAAY,UAAU,EAA2B,CAAO,EAAE,IAClF,KAAA;EAEC,OAIL,OAAO;GACL,MAAM;GACN,cAAc;EAChB;CACF,CAAC,CAAC,CACD,OAAO,CAAS;CAMnB,OAJI,EAAK,WAAW,IACX,OAGF;EACL,GAAG,EAAQ,OAAO,CAAK;EACvB,OAAO;CACT;AACF,GAQa,KACX,GACA,GAOA,IAAwD,IACpD,EAAqC,GAAO,CAAQ,IACpD,SAEC,IAIE,EACJ,KAAK,MACA,MAAgB,WAAW,IACtB;CACL;CACA,OAAO;AACT,IAIE,EAAiC,GAAO,CAAW,KAAK,EAAc,CAAK,KAAK,EAAM,QACjF;CACL;CACA,OAAO,EAAQ,OAAO,EAAM,KAAK;AACnC,IAIE,EAAM,MAKJ,EAFF,EAAc,CAAK,KAAK,EAAM,SAAS,OAAO,EAAM,SAAU,YAAY,KAAe,EAAM,SAGxF;CACL;CACA,OAAO,EAAQ,OAAO,CAAK;AAC7B,IAIG,IACR,CAAC,CACD,OAAO,CAAS,IApCV,CAAC"}
@@ -1,9 +1,12 @@
1
+ import type { ApiReferenceTranslationKey } from '@scalar/types/api-reference';
1
2
  import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
3
+ type SchemaTranslationKey = Extract<ApiReferenceTranslationKey, `schema.${string}`>;
2
4
  /**
3
- * Generate property description from type/format
5
+ * Get the translation key of the property description from type/format
4
6
  *
5
7
  * @param value - The schema object to generate description from
6
- * @returns Description string or null if no description available
8
+ * @returns Translation key or null if no description available
7
9
  */
8
- export declare const getPropertyDescription: (value: SchemaObject | undefined) => string | null;
10
+ export declare const getPropertyDescriptionKey: (value: SchemaObject | undefined) => SchemaTranslationKey | null;
11
+ export {};
9
12
  //# sourceMappingURL=get-property-description.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-property-description.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/get-property-description.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAoBhG;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,YAAY,GAAG,SAAS,KAAG,MAAM,GAAG,IAkBjF,CAAA"}
1
+ {"version":3,"file":"get-property-description.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/get-property-description.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAGhG,KAAK,oBAAoB,GAAG,OAAO,CAAC,0BAA0B,EAAE,UAAU,MAAM,EAAE,CAAC,CAAA;AAmBnF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,YAAY,GAAG,SAAS,KAAG,oBAAoB,GAAG,IAkBlG,CAAA"}
@@ -2,17 +2,17 @@ import { isSchema as e } from "@scalar/workspace-store/schemas/v3.2/strict/type-
2
2
  //#region src/schema/helpers/get-property-description.ts
3
3
  var t = {
4
4
  integer: {
5
- _default: "Integer numbers.",
6
- int32: "Signed 32-bit integers (commonly used integer type).",
7
- int64: "Signed 64-bit integers (long type)."
5
+ _default: "schema.typeInteger",
6
+ int32: "schema.formatInt32",
7
+ int64: "schema.formatInt64"
8
8
  },
9
9
  string: {
10
- date: "full-date notation as defined by RFC 3339, section 5.6, for example, 2017-07-21",
11
- "date-time": "the date-time notation as defined by RFC 3339, section 5.6, for example, 2017-07-21T17:32:28Z",
12
- password: "a hint to UIs to mask the input",
13
- base64: "base64-encoded characters, for example, U3dhZ2dlciByb2Nrcw==",
14
- byte: "base64-encoded characters, for example, U3dhZ2dlciByb2Nrcw==",
15
- binary: "binary data, used to describe files"
10
+ date: "schema.formatDate",
11
+ "date-time": "schema.formatDateTime",
12
+ password: "schema.formatPassword",
13
+ base64: "schema.formatBase64",
14
+ byte: "schema.formatBase64",
15
+ binary: "schema.formatBinary"
16
16
  }
17
17
  }, n = (n) => {
18
18
  if (!e(n)) return null;
@@ -22,6 +22,6 @@ var t = {
22
22
  return i ? i["format" in n && n.format || "contentEncoding" in n && n.contentEncoding || "_default"] ?? null : null;
23
23
  };
24
24
  //#endregion
25
- export { n as getPropertyDescription };
25
+ export { n as getPropertyDescriptionKey };
26
26
 
27
27
  //# sourceMappingURL=get-property-description.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-property-description.js","names":[],"sources":["../../../src/schema/helpers/get-property-description.ts"],"sourcesContent":["import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isSchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\n// Type descriptions for built-in types\nconst TYPE_DESCRIPTIONS: Record<string, Record<string, string>> = {\n integer: {\n _default: 'Integer numbers.',\n int32: 'Signed 32-bit integers (commonly used integer type).',\n int64: 'Signed 64-bit integers (long type).',\n },\n string: {\n 'date': 'full-date notation as defined by RFC 3339, section 5.6, for example, 2017-07-21',\n 'date-time': 'the date-time notation as defined by RFC 3339, section 5.6, for example, 2017-07-21T17:32:28Z',\n 'password': 'a hint to UIs to mask the input',\n 'base64': 'base64-encoded characters, for example, U3dhZ2dlciByb2Nrcw==',\n 'byte': 'base64-encoded characters, for example, U3dhZ2dlciByb2Nrcw==',\n 'binary': 'binary data, used to describe files',\n },\n} as const\n\n/**\n * Generate property description from type/format\n *\n * @param value - The schema object to generate description from\n * @returns Description string or null if no description available\n */\nexport const getPropertyDescription = (value: SchemaObject | undefined): string | null => {\n if (!isSchema(value)) {\n return null\n }\n /** Just grab the first type from the array if it's an array */\n const type = Array.isArray(value.type) ? value.type[0] : value.type\n if (!type) {\n return null\n }\n\n const typeDescriptions = TYPE_DESCRIPTIONS[type]\n if (!typeDescriptions) {\n return null\n }\n\n const format =\n ('format' in value && value.format) || ('contentEncoding' in value && value.contentEncoding) || '_default'\n return typeDescriptions[format] ?? null\n}\n"],"mappings":";;AAIA,IAAM,IAA4D;CAChE,SAAS;EACP,UAAU;EACV,OAAO;EACP,OAAO;CACT;CACA,QAAQ;EACN,MAAQ;EACR,aAAa;EACb,UAAY;EACZ,QAAU;EACV,MAAQ;EACR,QAAU;CACZ;AACF,GAQa,KAA0B,MAAmD;CACxF,IAAI,CAAC,EAAS,CAAK,GACjB,OAAO;CAGT,IAAM,IAAO,MAAM,QAAQ,EAAM,IAAI,IAAI,EAAM,KAAK,KAAK,EAAM;CAC/D,IAAI,CAAC,GACH,OAAO;CAGT,IAAM,IAAmB,EAAkB;CAO3C,OANK,IAME,EADJ,YAAY,KAAS,EAAM,UAAY,qBAAqB,KAAS,EAAM,mBAAoB,eAC/D,OAL1B;AAMX"}
1
+ {"version":3,"file":"get-property-description.js","names":[],"sources":["../../../src/schema/helpers/get-property-description.ts"],"sourcesContent":["import type { ApiReferenceTranslationKey } from '@scalar/types/api-reference'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isSchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\ntype SchemaTranslationKey = Extract<ApiReferenceTranslationKey, `schema.${string}`>\n\n// Type descriptions for built-in types\nconst TYPE_DESCRIPTIONS: Record<string, Record<string, SchemaTranslationKey>> = {\n integer: {\n _default: 'schema.typeInteger',\n int32: 'schema.formatInt32',\n int64: 'schema.formatInt64',\n },\n string: {\n 'date': 'schema.formatDate',\n 'date-time': 'schema.formatDateTime',\n 'password': 'schema.formatPassword',\n 'base64': 'schema.formatBase64',\n 'byte': 'schema.formatBase64',\n 'binary': 'schema.formatBinary',\n },\n} as const\n\n/**\n * Get the translation key of the property description from type/format\n *\n * @param value - The schema object to generate description from\n * @returns Translation key or null if no description available\n */\nexport const getPropertyDescriptionKey = (value: SchemaObject | undefined): SchemaTranslationKey | null => {\n if (!isSchema(value)) {\n return null\n }\n /** Just grab the first type from the array if it's an array */\n const type = Array.isArray(value.type) ? value.type[0] : value.type\n if (!type) {\n return null\n }\n\n const typeDescriptions = TYPE_DESCRIPTIONS[type]\n if (!typeDescriptions) {\n return null\n }\n\n const format =\n ('format' in value && value.format) || ('contentEncoding' in value && value.contentEncoding) || '_default'\n return typeDescriptions[format] ?? null\n}\n"],"mappings":";;AAOA,IAAM,IAA0E;CAC9E,SAAS;EACP,UAAU;EACV,OAAO;EACP,OAAO;CACT;CACA,QAAQ;EACN,MAAQ;EACR,aAAa;EACb,UAAY;EACZ,QAAU;EACV,MAAQ;EACR,QAAU;CACZ;AACF,GAQa,KAA6B,MAAiE;CACzG,IAAI,CAAC,EAAS,CAAK,GACjB,OAAO;CAGT,IAAM,IAAO,MAAM,QAAQ,EAAM,IAAI,IAAI,EAAM,KAAK,KAAK,EAAM;CAC/D,IAAI,CAAC,GACH,OAAO;CAGT,IAAM,IAAmB,EAAkB;CAO3C,OANK,IAME,EADJ,YAAY,KAAS,EAAM,UAAY,qBAAqB,KAAS,EAAM,mBAAoB,eAC/D,OAL1B;AAMX"}
@@ -1 +1 @@
1
- {"version":3,"file":"has-complex-array-items.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/has-complex-array-items.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAkDhG;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,GAAG,SAAS,KAAG,OA4BtE,CAAA"}
1
+ {"version":3,"file":"has-complex-array-items.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/has-complex-array-items.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AA0DhG;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,GAAG,SAAS,KAAG,OAqCtE,CAAA"}
@@ -6,12 +6,16 @@ var n = [
6
6
  "oneOf",
7
7
  "anyOf"
8
8
  ], r = (e) => "type" in e && e.type ? Array.isArray(e.type) ? e.type.includes("object") : e.type === "object" : "properties" in e, i = (e) => "$ref" in e || "discriminator" in e || n.some((t) => t in e), a = (n) => {
9
- if (!t(n) || typeof n.items != "object") return !1;
9
+ if (!t(n)) return !1;
10
+ if (typeof n.items == "boolean") return !0;
11
+ if (typeof n.items != "object") return !1;
10
12
  if ("$ref" in n.items) return !0;
11
13
  let a = e(n.items);
12
14
  return a ? r(a) || i(a) || t(a) : !1;
13
15
  }, o = (n) => {
14
- if (!n || !t(n) || typeof n.items != "object") return !1;
16
+ if (!n || !t(n)) return !1;
17
+ if (typeof n.items == "boolean") return !0;
18
+ if (typeof n.items != "object") return !1;
15
19
  if ("$ref" in n.items) return !0;
16
20
  let o = e(n.items);
17
21
  return o ? i(o) || r(o) ? !0 : a(o) : !1;
@@ -1 +1 @@
1
- {"version":3,"file":"has-complex-array-items.js","names":[],"sources":["../../../src/schema/helpers/has-complex-array-items.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\n/** Composition keywords that indicate complex schema structure */\nconst COMPOSITION_KEYWORDS = ['allOf', 'oneOf', 'anyOf'] as const\n\n/**\n * Checks if a schema has object type (either explicit type: 'object' or has properties)\n */\nconst isObjectType = (schema: SchemaObject): boolean => {\n // Check for explicit object type\n if ('type' in schema && schema.type) {\n if (Array.isArray(schema.type)) {\n return schema.type.includes('object')\n }\n return schema.type === 'object'\n }\n\n // Check for properties (implicit object type)\n return 'properties' in schema\n}\n\n/**\n * Checks if a schema has complex features (refs, compositions, discriminators)\n */\nconst hasComplexFeatures = (schema: SchemaObject): boolean =>\n '$ref' in schema || 'discriminator' in schema || COMPOSITION_KEYWORDS.some((keyword) => keyword in schema)\n\n/**\n * Checks if nested array items are complex\n */\nconst hasComplexNestedArrayItems = (items: SchemaObject): boolean => {\n if (!isArraySchema(items) || typeof items.items !== 'object') {\n return false\n }\n\n // Check for $ref in original nested items before resolving\n if ('$ref' in items.items) {\n return true\n }\n\n const nestedItems = getResolvedRef(items.items)\n if (!nestedItems) {\n return false\n }\n\n // Check if nested items are complex (objects, refs, compositions, or further nested arrays)\n return isObjectType(nestedItems) || hasComplexFeatures(nestedItems) || isArraySchema(nestedItems)\n}\n\n/**\n * Checks if array items have complex structure\n * like: objects, references, discriminators, compositions, or nested arrays with complex items\n *\n * @param value - The schema object to check\n * @returns true if the array has complex items, false otherwise\n */\nexport const hasComplexArrayItems = (value: SchemaObject | undefined): boolean => {\n // Early return for invalid inputs\n if (!value || !isArraySchema(value) || typeof value.items !== 'object') {\n return false\n }\n\n // Check for $ref in original items before resolving (in case ref can't be resolved)\n if ('$ref' in value.items) {\n return true\n }\n\n const items = getResolvedRef(value.items)\n if (!items) {\n return false\n }\n\n // Check for complex features (refs, compositions, discriminators)\n if (hasComplexFeatures(items)) {\n return true\n }\n\n // Check if items are objects\n if (isObjectType(items)) {\n return true\n }\n\n // Check if items are nested arrays with complex items\n return hasComplexNestedArrayItems(items)\n}\n"],"mappings":";;;AAKA,IAAM,IAAuB;CAAC;CAAS;CAAS;AAAO,GAKjD,KAAgB,MAEhB,UAAU,KAAU,EAAO,OACzB,MAAM,QAAQ,EAAO,IAAI,IACpB,EAAO,KAAK,SAAS,QAAQ,IAE/B,EAAO,SAAS,WAIlB,gBAAgB,GAMnB,KAAsB,MAC1B,UAAU,KAAU,mBAAmB,KAAU,EAAqB,MAAM,MAAY,KAAW,CAAM,GAKrG,KAA8B,MAAiC;CACnE,IAAI,CAAC,EAAc,CAAK,KAAK,OAAO,EAAM,SAAU,UAClD,OAAO;CAIT,IAAI,UAAU,EAAM,OAClB,OAAO;CAGT,IAAM,IAAc,EAAe,EAAM,KAAK;CAM9C,OALK,IAKE,EAAa,CAAW,KAAK,EAAmB,CAAW,KAAK,EAAc,CAAW,IAJvF;AAKX,GASa,KAAwB,MAA6C;CAEhF,IAAI,CAAC,KAAS,CAAC,EAAc,CAAK,KAAK,OAAO,EAAM,SAAU,UAC5D,OAAO;CAIT,IAAI,UAAU,EAAM,OAClB,OAAO;CAGT,IAAM,IAAQ,EAAe,EAAM,KAAK;CAgBxC,OAfK,IAKD,EAAmB,CAAK,KAKxB,EAAa,CAAK,IACb,KAIF,EAA2B,CAAK,IAd9B;AAeX"}
1
+ {"version":3,"file":"has-complex-array-items.js","names":[],"sources":["../../../src/schema/helpers/has-complex-array-items.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\n/** Composition keywords that indicate complex schema structure */\nconst COMPOSITION_KEYWORDS = ['allOf', 'oneOf', 'anyOf'] as const\n\n/**\n * Checks if a schema has object type (either explicit type: 'object' or has properties)\n */\nconst isObjectType = (schema: SchemaObject): boolean => {\n // Check for explicit object type\n if ('type' in schema && schema.type) {\n if (Array.isArray(schema.type)) {\n return schema.type.includes('object')\n }\n return schema.type === 'object'\n }\n\n // Check for properties (implicit object type)\n return 'properties' in schema\n}\n\n/**\n * Checks if a schema has complex features (refs, compositions, discriminators)\n */\nconst hasComplexFeatures = (schema: SchemaObject): boolean =>\n '$ref' in schema || 'discriminator' in schema || COMPOSITION_KEYWORDS.some((keyword) => keyword in schema)\n\n/**\n * Checks if nested array items are complex\n */\nconst hasComplexNestedArrayItems = (items: SchemaObject): boolean => {\n if (!isArraySchema(items)) {\n return false\n }\n\n if (typeof items.items === 'boolean') {\n return true\n }\n\n if (typeof items.items !== 'object') {\n return false\n }\n\n // Check for $ref in original nested items before resolving\n if ('$ref' in items.items) {\n return true\n }\n\n const nestedItems = getResolvedRef(items.items)\n if (!nestedItems) {\n return false\n }\n\n // Check if nested items are complex (objects, refs, compositions, or further nested arrays)\n return isObjectType(nestedItems) || hasComplexFeatures(nestedItems) || isArraySchema(nestedItems)\n}\n\n/**\n * Checks if array items have complex structure\n * like: objects, references, discriminators, compositions, or nested arrays with complex items\n *\n * @param value - The schema object to check\n * @returns true if the array has complex items, false otherwise\n */\nexport const hasComplexArrayItems = (value: SchemaObject | undefined): boolean => {\n // Early return for invalid inputs\n if (!value || !isArraySchema(value)) {\n return false\n }\n\n // Boolean item constraints need a child row to explain their validation meaning.\n if (typeof value.items === 'boolean') {\n return true\n }\n\n if (typeof value.items !== 'object') {\n return false\n }\n\n // Check for $ref in original items before resolving (in case ref can't be resolved)\n if ('$ref' in value.items) {\n return true\n }\n\n const items = getResolvedRef(value.items)\n if (!items) {\n return false\n }\n\n // Check for complex features (refs, compositions, discriminators)\n if (hasComplexFeatures(items)) {\n return true\n }\n\n // Check if items are objects\n if (isObjectType(items)) {\n return true\n }\n\n // Check if items are nested arrays with complex items\n return hasComplexNestedArrayItems(items)\n}\n"],"mappings":";;;AAKA,IAAM,IAAuB;CAAC;CAAS;CAAS;AAAO,GAKjD,KAAgB,MAEhB,UAAU,KAAU,EAAO,OACzB,MAAM,QAAQ,EAAO,IAAI,IACpB,EAAO,KAAK,SAAS,QAAQ,IAE/B,EAAO,SAAS,WAIlB,gBAAgB,GAMnB,KAAsB,MAC1B,UAAU,KAAU,mBAAmB,KAAU,EAAqB,MAAM,MAAY,KAAW,CAAM,GAKrG,KAA8B,MAAiC;CACnE,IAAI,CAAC,EAAc,CAAK,GACtB,OAAO;CAGT,IAAI,OAAO,EAAM,SAAU,WACzB,OAAO;CAGT,IAAI,OAAO,EAAM,SAAU,UACzB,OAAO;CAIT,IAAI,UAAU,EAAM,OAClB,OAAO;CAGT,IAAM,IAAc,EAAe,EAAM,KAAK;CAM9C,OALK,IAKE,EAAa,CAAW,KAAK,EAAmB,CAAW,KAAK,EAAc,CAAW,IAJvF;AAKX,GASa,KAAwB,MAA6C;CAEhF,IAAI,CAAC,KAAS,CAAC,EAAc,CAAK,GAChC,OAAO;CAIT,IAAI,OAAO,EAAM,SAAU,WACzB,OAAO;CAGT,IAAI,OAAO,EAAM,SAAU,UACzB,OAAO;CAIT,IAAI,UAAU,EAAM,OAClB,OAAO;CAGT,IAAM,IAAQ,EAAe,EAAM,KAAK;CAgBxC,OAfK,IAKD,EAAmB,CAAK,KAKxB,EAAa,CAAK,IACb,KAIF,EAA2B,CAAK,IAd9B;AAeX"}
@@ -1 +1 @@
1
- {"version":3,"file":"merge-all-of-schemas.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/merge-all-of-schemas.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAiDhG;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,YAAY,GAAG,SAAS,EACjC,aAAa,YAAY,EACzB,WAAU,GAAG,CAAC,MAAM,CAAa,KAChC,YA2DF,CAAA"}
1
+ {"version":3,"file":"merge-all-of-schemas.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/merge-all-of-schemas.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AA+ChG;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,YAAY,GAAG,SAAS,EACjC,aAAa,YAAY,EACzB,WAAU,GAAG,CAAC,MAAM,CAAa,KAChC,YA2DF,CAAA"}
@@ -10,7 +10,7 @@ var a = /* @__PURE__ */ new Set(["description", "title"]), o = [
10
10
  "x-enum-descriptions",
11
11
  "x-enumDescriptions"
12
12
  ], s = (e, t, n = !1) => {
13
- let i = e.enum === void 0 ? t.enum?.slice() : t.enum === void 0 ? e.enum.slice() : e.enum.filter((e) => t.enum?.some((t) => r(e, t)));
13
+ let i = e.enum?.filter((e) => t.enum === void 0 || t.enum.some((t) => r(e, t))) ?? t.enum?.slice();
14
14
  if (i === void 0) return {};
15
15
  let a = { enum: i };
16
16
  for (let s of o) {
@@ -22,7 +22,7 @@ var a = /* @__PURE__ */ new Set(["description", "title"]), o = [
22
22
  if (!e?.allOf?.length || !Array.isArray(e.allOf)) return n || {};
23
23
  let i = {}, { allOf: a, ...o } = e;
24
24
  for (let n of e.allOf) {
25
- if (!n || typeof n != "object") continue;
25
+ if (typeof n != "boolean" && (!n || typeof n != "object")) continue;
26
26
  let e = t.schema(n);
27
27
  if (e.allOf) {
28
28
  l(i, c(e, void 0, r), !1, r);
@@ -1 +1 @@
1
- {"version":3,"file":"merge-all-of-schemas.js","names":[],"sources":["../../../src/schema/helpers/merge-all-of-schemas.ts"],"sourcesContent":["import { isObjectEqual } from '@scalar/helpers/object/is-object-equal'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\n/**\n * Schema keywords whose value should reflect the *last* occurrence when merging\n * `allOf` members. Most keywords keep the first occurrence, but for human-facing\n * annotations a later subschema is expected to override an earlier one — matching\n * OpenAPI/JSON Schema tooling like Swagger UI.\n */\nconst LAST_WINS_KEYS = new Set<string>(['description', 'title'])\n\nconst ENUM_ANNOTATIONS = ['x-enum-varnames', 'x-enumNames', 'x-enum-descriptions', 'x-enumDescriptions'] as const\n\n/** Keep positional annotations attached to their values when intersecting enum constraints. */\nconst mergeEnums = (\n existing: SchemaObject,\n incoming: SchemaObject,\n override: boolean = false,\n): Partial<SchemaObject> => {\n const values =\n existing.enum === undefined\n ? incoming.enum?.slice()\n : incoming.enum === undefined\n ? existing.enum.slice()\n : existing.enum.filter((value) => incoming.enum?.some((candidate) => isObjectEqual(value, candidate)))\n\n if (values === undefined) {\n return {}\n }\n\n const merged: Partial<SchemaObject> = { enum: values }\n for (const key of ENUM_ANNOTATIONS) {\n const source = incoming[key] !== undefined && (override || existing[key] === undefined) ? incoming : existing\n const annotation = source[key]\n const sourceValues = source.enum\n if (Array.isArray(annotation)) {\n merged[key] =\n sourceValues === undefined\n ? annotation\n : values.map(\n (value) => annotation[sourceValues.findIndex((candidate) => isObjectEqual(value, candidate))] ?? '',\n )\n } else if (annotation !== undefined && (key === 'x-enum-descriptions' || key === 'x-enumDescriptions')) {\n merged[key] = annotation\n }\n }\n return merged\n}\n\n/**\n * Merges multiple OpenAPI schema objects into a single schema object.\n * Handles nested allOf compositions and merges properties recursively.\n *\n * @param schemas - Array of OpenAPI schema objects to merge\n * @param rootSchema - Optional root schema to merge with the result\n * @param seenRefs - `$ref` strings already being merged higher in the call stack\n * @returns Merged schema object\n */\nexport const mergeAllOfSchemas = (\n schemas: SchemaObject | undefined,\n rootSchema?: SchemaObject,\n seenRefs: Set<string> = new Set(),\n): SchemaObject => {\n // Handle max depth, empty or invalid input\n if (!schemas?.allOf?.length || !Array.isArray(schemas.allOf)) {\n return rootSchema || ({} as SchemaObject)\n }\n\n // Initialize result object once\n const result = {} as SchemaObject\n\n // Extract base schema properties (everything except allOf)\n const { allOf: _, ...baseSchema } = schemas\n\n // Process allOf schemas first\n for (const _schema of schemas.allOf) {\n if (!_schema || typeof _schema !== 'object') {\n continue\n }\n\n // Resolve ref if present\n const schema = resolve.schema(_schema)\n\n // Handle nested allOf recursively\n if (schema.allOf) {\n const nestedMerged = mergeAllOfSchemas(schema, undefined, seenRefs)\n mergeSchemaIntoResult(result, nestedMerged, false, seenRefs)\n continue\n }\n\n mergeSchemaIntoResult(result, schema, false, seenRefs)\n }\n\n // Apply base schema properties with precedence over allOf properties\n if (Object.keys(baseSchema).length > 0) {\n mergeSchemaIntoResult(result, baseSchema, true, seenRefs)\n }\n\n // Process root schema last if provided\n if (rootSchema && typeof rootSchema === 'object') {\n if (rootSchema.allOf) {\n const nestedMerged = mergeAllOfSchemas(rootSchema, undefined, seenRefs)\n mergeSchemaIntoResult(result, nestedMerged, true, seenRefs)\n } else {\n mergeSchemaIntoResult(result, rootSchema, true, seenRefs)\n }\n }\n\n // Drop a `discriminator` inherited from an `allOf` member: a merged subtype is\n // one concrete branch, not a choice-point, and keeping the base's mapping makes\n // it look like the base again, recursing the selector inference (issue #9674).\n // A discriminator the schema declares itself is kept.\n const declaresOwnDiscriminator =\n 'discriminator' in baseSchema ||\n Boolean(rootSchema && typeof rootSchema === 'object' && 'discriminator' in rootSchema)\n\n if ('discriminator' in result && !declaresOwnDiscriminator) {\n delete (result as Record<string, unknown>).discriminator\n }\n\n return result\n}\n\n/**\n * Efficiently merges a source schema into a target result object.\n * Handles all schema merging logic in a single optimized function.\n *\n * @param result - The target schema object to merge into\n * @param schema - The source schema object to merge from\n * @param override - Whether to override existing properties (default: false)\n */\nconst mergeSchemaIntoResult = (\n result: SchemaObject,\n schema: SchemaObject,\n override: boolean = false,\n seenRefs: Set<string> = new Set(),\n): void => {\n // Early return if schema is empty\n const schemaKeys = objectKeys(schema)\n if (schemaKeys.length === 0) {\n return\n }\n\n const mergedEnums = mergeEnums(result, schema, override)\n\n // Loop through all schema properties and handle them appropriately\n for (const key of schemaKeys) {\n const propertyName: string = key\n const value = getResolvedRef(schema[key]) as any\n\n if (value === undefined) {\n continue\n }\n\n // Required\n if (propertyName === 'required') {\n // Merge required fields with deduplication\n if (Array.isArray(value) && value.length > 0) {\n // @ts-expect-error\n if (result.required?.length) {\n // @ts-expect-error\n result.required = [...new Set([...result.required, ...value])]\n } else {\n // @ts-expect-error\n result.required = value.slice()\n }\n }\n }\n // Properties\n else if (propertyName === 'properties') {\n // Merge properties recursively\n if (value && typeof value === 'object') {\n // @ts-expect-error\n if (!result.properties) {\n // @ts-expect-error\n result.properties = {}\n }\n\n // @ts-expect-error\n mergePropertiesIntoResult(result.properties, value, seenRefs)\n }\n }\n // Items\n else if (propertyName === 'items') {\n // Handle items (for both arrays and objects with items)\n const items = resolve.schema(value)\n if (items) {\n if (isArraySchema(schema)) {\n // @ts-expect-error\n if (!result.items) {\n // @ts-expect-error\n result.items = {}\n }\n\n // Handle allOf within array items\n if (items.allOf) {\n const mergedItems = mergeAllOfSchemas(items, undefined, seenRefs)\n // @ts-expect-error\n Object.assign(result.items, mergedItems)\n } else {\n // @ts-expect-error\n mergeItemsIntoResult(getResolvedRef(result.items), items, seenRefs)\n }\n }\n // For non-array types with items.allOf, merge into properties\n else if (items.allOf) {\n const mergedItems = mergeAllOfSchemas(items, undefined, seenRefs)\n if ('properties' in mergedItems) {\n if (!('properties' in result)) {\n // @ts-expect-error\n result.properties = {}\n }\n\n 'properties' in result && mergePropertiesIntoResult(result.properties, mergedItems.properties, seenRefs)\n }\n }\n // For non-array types without allOf, still set items if not already set\n else if (!('items' in result)) {\n // @ts-expect-error\n result.items = items\n }\n }\n }\n // Enum values and their annotations are applied together after the other keywords.\n else if (key === 'enum') {\n continue\n }\n // OneOf/AnyOf\n else if (key === 'oneOf' || key === 'anyOf') {\n // Preserve the composition itself so its variants keep rendering as a\n // selector. Flattening the option properties into the parent would drop\n // the variant structure entirely and silently lose branches that have no\n // top-level `properties` (for example branches that are themselves an\n // `allOf`). The sibling `allOf` members stay on `result` as base\n // properties, which the Schema component renders above the selector.\n if (Array.isArray(value) && value.length > 0 && (override || result[key] === undefined)) {\n result[key] = value\n }\n }\n // Skip allOf as it's handled at a higher level\n else if (key === 'allOf') {\n continue\n }\n // For all other properties, preserve the first occurrence or override if specified.\n // Annotation keywords (see LAST_WINS_KEYS) always take the latest value so a later\n // allOf member can override an earlier one.\n else {\n if (override || LAST_WINS_KEYS.has(propertyName) || result[key] === undefined) {\n result[key] = value\n }\n }\n }\n Object.assign(result, mergedEnums)\n}\n\n/**\n * Efficiently merges properties into a result object without creating new objects.\n */\nconst mergePropertiesIntoResult = (\n result: Extract<SchemaObject, { type: 'object' }>['properties'],\n properties: Extract<SchemaObject, { type: 'object' }>['properties'],\n seenRefs: Set<string> = new Set(),\n): void => {\n const propertyKeys = Object.keys(properties ?? {})\n if (!properties || !result || propertyKeys.length === 0) {\n return\n }\n\n for (const key of propertyKeys) {\n const schema = resolve.schema(properties[key])\n if (!schema) {\n delete result[key]\n continue\n }\n\n if (typeof schema !== 'object') {\n result[key] = schema\n continue\n }\n\n if (!result[key]) {\n // Break self-referential cycles reached through `allOf`. When a brand-new\n // property's `$ref` is already being merged higher in the call stack,\n // keep the raw reference instead of recursing into its `allOf` forever.\n // This mirrors the guard in the \"merge existing property\" branch below and\n // covers schemas that point back at themselves through an `allOf` member\n // (e.g. a node whose `self` property $refs the node, which is an allOf).\n const rawProperty = properties[key]\n const newSchemaRef = (rawProperty as { $ref?: string })?.$ref\n if (rawProperty && typeof newSchemaRef === 'string' && seenRefs.has(newSchemaRef)) {\n result[key] = rawProperty\n continue\n }\n const nextNewSeenRefs = typeof newSchemaRef === 'string' ? new Set(seenRefs).add(newSchemaRef) : seenRefs\n\n // Handle new property with allOf\n if (schema.allOf) {\n result[key] = mergeAllOfSchemas(schema, undefined, nextNewSeenRefs)\n } else if (isArraySchema(schema) && resolve.schema(schema.items)?.allOf) {\n result[key] = {\n ...schema,\n items: mergeAllOfSchemas(resolve.schema(schema.items), undefined, seenRefs),\n }\n } else if (properties[key]) {\n result[key] = properties[key]\n }\n continue\n }\n\n // Merge existing property\n const existing = resolve.schema(result[key])\n\n // Break self-referential cycles: when this property's `$ref` is already\n // being merged higher in the call stack, keep the partially merged existing\n // schema instead of recursing into it again. This mirrors the guard in\n // `mergeItems` and covers schemas that point back at themselves through a\n // plain object property (e.g. a tree node whose `parent` $refs the node).\n const schemaRef = schema.$ref\n if (typeof schemaRef === 'string' && seenRefs.has(schemaRef)) {\n result[key] = existing\n continue\n }\n const nextSeenRefs = typeof schemaRef === 'string' ? new Set(seenRefs).add(schemaRef) : seenRefs\n\n if (schema.allOf) {\n result[key] = mergeAllOfSchemas({ allOf: [existing, schema] } as SchemaObject, undefined, nextSeenRefs)\n } else if (isArraySchema(schema) && isArraySchema(existing) && schema.items) {\n const existingItems = resolve.schema(existing.items)\n result[key] = {\n ...existing,\n type: 'array',\n items: existingItems\n ? mergeItems(existingItems, resolve.schema(schema.items), nextSeenRefs)\n : resolve.schema(schema.items),\n }\n } else {\n // Create merged object with properties handled separately\n if ('properties' in existing && 'properties' in schema) {\n const merged = { ...existing, ...schema }\n merged.properties = { ...existing.properties }\n mergePropertiesIntoResult(merged.properties, schema.properties, nextSeenRefs)\n result[key] = merged\n }\n // Simple merge without property recursion\n else {\n result[key] = {\n ...schema,\n ...existing,\n ...mergeEnums(existing, schema),\n }\n }\n }\n }\n}\n\n/**\n * Efficiently merges array items into a result object.\n */\nconst mergeItemsIntoResult = (result: SchemaObject, items: SchemaObject, seenRefs: Set<string> = new Set()): void => {\n // Handle allOf in items\n if (items.allOf || result.allOf) {\n // Build array without spreads for better performance\n const allOfSchemas: SchemaObject[] = []\n\n if (result.allOf) {\n for (const schema of result.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(result)\n }\n\n if (items.allOf) {\n for (const schema of items.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(items)\n }\n\n const merged = mergeAllOfSchemas({ allOf: allOfSchemas } as SchemaObject, undefined, seenRefs)\n Object.assign(result, merged)\n return\n }\n\n // Regular merge\n Object.assign(result, items)\n\n // Merge properties if both have them\n if ('properties' in result && 'properties' in items) {\n mergePropertiesIntoResult(result.properties, items.properties, seenRefs)\n }\n}\n\n/**\n * Helper function for merging items that returns a new object.\n */\nconst mergeItems = (\n existing: SchemaObject,\n incoming: SchemaObject,\n seenRefs: Set<string> = new Set(),\n): SchemaObject => {\n const incomingRef = (incoming as { $ref?: string }).$ref\n\n if (typeof incomingRef === 'string') {\n if (seenRefs.has(incomingRef)) {\n return existing\n }\n return mergeItemsInner(existing, incoming, new Set(seenRefs).add(incomingRef))\n }\n\n return mergeItemsInner(existing, incoming, seenRefs)\n}\n\nconst mergeItemsInner = (\n existing: SchemaObject,\n incoming: SchemaObject,\n seenRefs: Set<string> = new Set(),\n): SchemaObject => {\n // Handle allOf in either schema\n if (existing.allOf || incoming.allOf) {\n // Build array without spreads for better performance\n const allOfSchemas: SchemaObject[] = []\n\n if (existing.allOf) {\n for (const schema of existing.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(existing)\n }\n\n if (incoming.allOf) {\n for (const schema of incoming.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(incoming)\n }\n\n return mergeAllOfSchemas({ allOf: allOfSchemas } as SchemaObject, undefined, seenRefs)\n }\n\n // Construct the merged object after narrowing both schemas so their property types survive.\n if ('properties' in existing && 'properties' in incoming) {\n const merged = { ...existing, ...incoming, properties: { ...existing.properties } }\n mergePropertiesIntoResult(merged.properties, incoming.properties, seenRefs)\n return merged\n }\n\n return { ...existing, ...incoming }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"merge-all-of-schemas.js","names":[],"sources":["../../../src/schema/helpers/merge-all-of-schemas.ts"],"sourcesContent":["import { isObjectEqual } from '@scalar/helpers/object/is-object-equal'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards'\n\n/**\n * Schema keywords whose value should reflect the *last* occurrence when merging\n * `allOf` members. Most keywords keep the first occurrence, but for human-facing\n * annotations a later subschema is expected to override an earlier one — matching\n * OpenAPI/JSON Schema tooling like Swagger UI.\n */\nconst LAST_WINS_KEYS = new Set<string>(['description', 'title'])\n\nconst ENUM_ANNOTATIONS = ['x-enum-varnames', 'x-enumNames', 'x-enum-descriptions', 'x-enumDescriptions'] as const\n\n/** Keep positional annotations attached to their values when intersecting enum constraints. */\nconst mergeEnums = (\n existing: SchemaObject,\n incoming: SchemaObject,\n override: boolean = false,\n): Partial<SchemaObject> => {\n const values =\n existing.enum?.filter(\n (value) => incoming.enum === undefined || incoming.enum.some((candidate) => isObjectEqual(value, candidate)),\n ) ?? incoming.enum?.slice()\n\n if (values === undefined) {\n return {}\n }\n\n const merged: Partial<SchemaObject> = { enum: values }\n for (const key of ENUM_ANNOTATIONS) {\n const source = incoming[key] !== undefined && (override || existing[key] === undefined) ? incoming : existing\n const annotation = source[key]\n const sourceValues = source.enum\n if (Array.isArray(annotation)) {\n merged[key] =\n sourceValues === undefined\n ? annotation\n : values.map(\n (value) => annotation[sourceValues.findIndex((candidate) => isObjectEqual(value, candidate))] ?? '',\n )\n } else if (annotation !== undefined && (key === 'x-enum-descriptions' || key === 'x-enumDescriptions')) {\n merged[key] = annotation\n }\n }\n return merged\n}\n\n/**\n * Merges multiple OpenAPI schema objects into a single schema object.\n * Handles nested allOf compositions and merges properties recursively.\n *\n * @param schemas - Array of OpenAPI schema objects to merge\n * @param rootSchema - Optional root schema to merge with the result\n * @param seenRefs - `$ref` strings already being merged higher in the call stack\n * @returns Merged schema object\n */\nexport const mergeAllOfSchemas = (\n schemas: SchemaObject | undefined,\n rootSchema?: SchemaObject,\n seenRefs: Set<string> = new Set(),\n): SchemaObject => {\n // Handle max depth, empty or invalid input\n if (!schemas?.allOf?.length || !Array.isArray(schemas.allOf)) {\n return rootSchema || ({} as SchemaObject)\n }\n\n // Initialize result object once\n const result = {} as SchemaObject\n\n // Extract base schema properties (everything except allOf)\n const { allOf: _, ...baseSchema } = schemas\n\n // Process allOf schemas first\n for (const _schema of schemas.allOf) {\n if (typeof _schema !== 'boolean' && (!_schema || typeof _schema !== 'object')) {\n continue\n }\n\n // Resolve ref if present\n const schema = resolve.schema(_schema)\n\n // Handle nested allOf recursively\n if (schema.allOf) {\n const nestedMerged = mergeAllOfSchemas(schema, undefined, seenRefs)\n mergeSchemaIntoResult(result, nestedMerged, false, seenRefs)\n continue\n }\n\n mergeSchemaIntoResult(result, schema, false, seenRefs)\n }\n\n // Apply base schema properties with precedence over allOf properties\n if (Object.keys(baseSchema).length > 0) {\n mergeSchemaIntoResult(result, baseSchema, true, seenRefs)\n }\n\n // Process root schema last if provided\n if (rootSchema && typeof rootSchema === 'object') {\n if (rootSchema.allOf) {\n const nestedMerged = mergeAllOfSchemas(rootSchema, undefined, seenRefs)\n mergeSchemaIntoResult(result, nestedMerged, true, seenRefs)\n } else {\n mergeSchemaIntoResult(result, rootSchema, true, seenRefs)\n }\n }\n\n // Drop a `discriminator` inherited from an `allOf` member: a merged subtype is\n // one concrete branch, not a choice-point, and keeping the base's mapping makes\n // it look like the base again, recursing the selector inference (issue #9674).\n // A discriminator the schema declares itself is kept.\n const declaresOwnDiscriminator =\n 'discriminator' in baseSchema ||\n Boolean(rootSchema && typeof rootSchema === 'object' && 'discriminator' in rootSchema)\n\n if ('discriminator' in result && !declaresOwnDiscriminator) {\n delete (result as Record<string, unknown>).discriminator\n }\n\n return result\n}\n\n/**\n * Efficiently merges a source schema into a target result object.\n * Handles all schema merging logic in a single optimized function.\n *\n * @param result - The target schema object to merge into\n * @param schema - The source schema object to merge from\n * @param override - Whether to override existing properties (default: false)\n */\nconst mergeSchemaIntoResult = (\n result: SchemaObject,\n schema: SchemaObject,\n override: boolean = false,\n seenRefs: Set<string> = new Set(),\n): void => {\n // Early return if schema is empty\n const schemaKeys = objectKeys(schema)\n if (schemaKeys.length === 0) {\n return\n }\n\n const mergedEnums = mergeEnums(result, schema, override)\n\n // Loop through all schema properties and handle them appropriately\n for (const key of schemaKeys) {\n const propertyName: string = key\n const value = getResolvedRef(schema[key]) as any\n\n if (value === undefined) {\n continue\n }\n\n // Required\n if (propertyName === 'required') {\n // Merge required fields with deduplication\n if (Array.isArray(value) && value.length > 0) {\n // @ts-expect-error\n if (result.required?.length) {\n // @ts-expect-error\n result.required = [...new Set([...result.required, ...value])]\n } else {\n // @ts-expect-error\n result.required = value.slice()\n }\n }\n }\n // Properties\n else if (propertyName === 'properties') {\n // Merge properties recursively\n if (value && typeof value === 'object') {\n // @ts-expect-error\n if (!result.properties) {\n // @ts-expect-error\n result.properties = {}\n }\n\n // @ts-expect-error\n mergePropertiesIntoResult(result.properties, value, seenRefs)\n }\n }\n // Items\n else if (propertyName === 'items') {\n // Handle items (for both arrays and objects with items)\n const items = resolve.schema(value)\n if (items) {\n if (isArraySchema(schema)) {\n // @ts-expect-error\n if (!result.items) {\n // @ts-expect-error\n result.items = {}\n }\n\n // Handle allOf within array items\n if (items.allOf) {\n const mergedItems = mergeAllOfSchemas(items, undefined, seenRefs)\n // @ts-expect-error\n Object.assign(result.items, mergedItems)\n } else {\n // @ts-expect-error\n mergeItemsIntoResult(getResolvedRef(result.items), items, seenRefs)\n }\n }\n // For non-array types with items.allOf, merge into properties\n else if (items.allOf) {\n const mergedItems = mergeAllOfSchemas(items, undefined, seenRefs)\n if ('properties' in mergedItems) {\n if (!('properties' in result)) {\n // @ts-expect-error\n result.properties = {}\n }\n\n 'properties' in result && mergePropertiesIntoResult(result.properties, mergedItems.properties, seenRefs)\n }\n }\n // For non-array types without allOf, still set items if not already set\n else if (!('items' in result)) {\n // @ts-expect-error\n result.items = items\n }\n }\n }\n // Enum values and their annotations are applied together after the other keywords.\n else if (key === 'enum') {\n continue\n }\n // OneOf/AnyOf\n else if (key === 'oneOf' || key === 'anyOf') {\n // Preserve the composition itself so its variants keep rendering as a\n // selector. Flattening the option properties into the parent would drop\n // the variant structure entirely and silently lose branches that have no\n // top-level `properties` (for example branches that are themselves an\n // `allOf`). The sibling `allOf` members stay on `result` as base\n // properties, which the Schema component renders above the selector.\n if (Array.isArray(value) && value.length > 0 && (override || result[key] === undefined)) {\n result[key] = value\n }\n }\n // Skip allOf as it's handled at a higher level\n else if (key === 'allOf') {\n continue\n }\n // For all other properties, preserve the first occurrence or override if specified.\n // Annotation keywords (see LAST_WINS_KEYS) always take the latest value so a later\n // allOf member can override an earlier one.\n else {\n if (override || LAST_WINS_KEYS.has(propertyName) || result[key] === undefined) {\n result[key] = value\n }\n }\n }\n Object.assign(result, mergedEnums)\n}\n\n/**\n * Efficiently merges properties into a result object without creating new objects.\n */\nconst mergePropertiesIntoResult = (\n result: Extract<SchemaObject, { type: 'object' }>['properties'],\n properties: Extract<SchemaObject, { type: 'object' }>['properties'],\n seenRefs: Set<string> = new Set(),\n): void => {\n const propertyKeys = Object.keys(properties ?? {})\n if (!properties || !result || propertyKeys.length === 0) {\n return\n }\n\n for (const key of propertyKeys) {\n const schema = resolve.schema(properties[key])\n if (!schema) {\n delete result[key]\n continue\n }\n\n if (typeof schema !== 'object') {\n result[key] = schema\n continue\n }\n\n if (!result[key]) {\n // Break self-referential cycles reached through `allOf`. When a brand-new\n // property's `$ref` is already being merged higher in the call stack,\n // keep the raw reference instead of recursing into its `allOf` forever.\n // This mirrors the guard in the \"merge existing property\" branch below and\n // covers schemas that point back at themselves through an `allOf` member\n // (e.g. a node whose `self` property $refs the node, which is an allOf).\n const rawProperty = properties[key]\n const newSchemaRef = (rawProperty as { $ref?: string })?.$ref\n if (rawProperty && typeof newSchemaRef === 'string' && seenRefs.has(newSchemaRef)) {\n result[key] = rawProperty\n continue\n }\n const nextNewSeenRefs = typeof newSchemaRef === 'string' ? new Set(seenRefs).add(newSchemaRef) : seenRefs\n\n // Handle new property with allOf\n if (schema.allOf) {\n result[key] = mergeAllOfSchemas(schema, undefined, nextNewSeenRefs)\n } else if (isArraySchema(schema) && resolve.schema(schema.items)?.allOf) {\n result[key] = {\n ...schema,\n items: mergeAllOfSchemas(resolve.schema(schema.items), undefined, seenRefs),\n }\n } else if (properties[key]) {\n result[key] = properties[key]\n }\n continue\n }\n\n // Merge existing property\n const existing = resolve.schema(result[key])\n\n // Break self-referential cycles: when this property's `$ref` is already\n // being merged higher in the call stack, keep the partially merged existing\n // schema instead of recursing into it again. This mirrors the guard in\n // `mergeItems` and covers schemas that point back at themselves through a\n // plain object property (e.g. a tree node whose `parent` $refs the node).\n const schemaRef = schema.$ref\n if (typeof schemaRef === 'string' && seenRefs.has(schemaRef)) {\n result[key] = existing\n continue\n }\n const nextSeenRefs = typeof schemaRef === 'string' ? new Set(seenRefs).add(schemaRef) : seenRefs\n\n if (schema.allOf) {\n result[key] = mergeAllOfSchemas({ allOf: [existing, schema] } as SchemaObject, undefined, nextSeenRefs)\n } else if (isArraySchema(schema) && isArraySchema(existing) && schema.items) {\n const existingItems = resolve.schema(existing.items)\n result[key] = {\n ...existing,\n type: 'array',\n items: existingItems\n ? mergeItems(existingItems, resolve.schema(schema.items), nextSeenRefs)\n : resolve.schema(schema.items),\n }\n } else {\n // Create merged object with properties handled separately\n if ('properties' in existing && 'properties' in schema) {\n const merged = { ...existing, ...schema }\n merged.properties = { ...existing.properties }\n mergePropertiesIntoResult(merged.properties, schema.properties, nextSeenRefs)\n result[key] = merged\n }\n // Simple merge without property recursion\n else {\n result[key] = {\n ...schema,\n ...existing,\n ...mergeEnums(existing, schema),\n }\n }\n }\n }\n}\n\n/**\n * Efficiently merges array items into a result object.\n */\nconst mergeItemsIntoResult = (result: SchemaObject, items: SchemaObject, seenRefs: Set<string> = new Set()): void => {\n // Handle allOf in items\n if (items.allOf || result.allOf) {\n // Build array without spreads for better performance\n const allOfSchemas: SchemaObject[] = []\n\n if (result.allOf) {\n for (const schema of result.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(result)\n }\n\n if (items.allOf) {\n for (const schema of items.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(items)\n }\n\n const merged = mergeAllOfSchemas({ allOf: allOfSchemas } as SchemaObject, undefined, seenRefs)\n Object.assign(result, merged)\n return\n }\n\n // Regular merge\n Object.assign(result, items)\n\n // Merge properties if both have them\n if ('properties' in result && 'properties' in items) {\n mergePropertiesIntoResult(result.properties, items.properties, seenRefs)\n }\n}\n\n/**\n * Helper function for merging items that returns a new object.\n */\nconst mergeItems = (\n existing: SchemaObject,\n incoming: SchemaObject,\n seenRefs: Set<string> = new Set(),\n): SchemaObject => {\n const incomingRef = (incoming as { $ref?: string }).$ref\n\n if (typeof incomingRef === 'string') {\n if (seenRefs.has(incomingRef)) {\n return existing\n }\n return mergeItemsInner(existing, incoming, new Set(seenRefs).add(incomingRef))\n }\n\n return mergeItemsInner(existing, incoming, seenRefs)\n}\n\nconst mergeItemsInner = (\n existing: SchemaObject,\n incoming: SchemaObject,\n seenRefs: Set<string> = new Set(),\n): SchemaObject => {\n // Handle allOf in either schema\n if (existing.allOf || incoming.allOf) {\n // Build array without spreads for better performance\n const allOfSchemas: SchemaObject[] = []\n\n if (existing.allOf) {\n for (const schema of existing.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(existing)\n }\n\n if (incoming.allOf) {\n for (const schema of incoming.allOf) {\n allOfSchemas.push(resolve.schema(schema))\n }\n } else {\n allOfSchemas.push(incoming)\n }\n\n return mergeAllOfSchemas({ allOf: allOfSchemas } as SchemaObject, undefined, seenRefs)\n }\n\n // Construct the merged object after narrowing both schemas so their property types survive.\n if ('properties' in existing && 'properties' in incoming) {\n const merged = { ...existing, ...incoming, properties: { ...existing.properties } }\n mergePropertiesIntoResult(merged.properties, incoming.properties, seenRefs)\n return merged\n }\n\n return { ...existing, ...incoming }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"optimize-value-for-display.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/optimize-value-for-display.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAIhG,6FAA6F;AAC7F,KAAK,aAAa,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAmD1D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAmHnG"}
1
+ {"version":3,"file":"optimize-value-for-display.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/optimize-value-for-display.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAKhG,6FAA6F;AAC7F,KAAK,aAAa,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAmD1D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAyHnG"}
@@ -1,7 +1,8 @@
1
- import { compositions as e } from "./schema-composition.js";
2
- import { resolve as t } from "@scalar/workspace-store/resolve";
1
+ import { schemaDiscriminator as e } from "../discriminator-metadata.js";
2
+ import { compositions as t } from "./schema-composition.js";
3
+ import { resolve as n } from "@scalar/workspace-store/resolve";
3
4
  //#region src/schema/helpers/optimize-value-for-display.ts
4
- function n(...e) {
5
+ function r(...e) {
5
6
  let t = {}, n = {}, r = /* @__PURE__ */ new Set(), i = !1, a = !1;
6
7
  for (let o of e) if (o) for (let [e, s] of Object.entries(o)) {
7
8
  if (e === "properties" && s && typeof s == "object") {
@@ -17,48 +18,48 @@ function n(...e) {
17
18
  }
18
19
  return i && (t.properties = n), a && (t.required = [...r]), t;
19
20
  }
20
- function r(r) {
21
- if (!r || typeof r != "object") return r;
22
- let i = e.find((e) => e in r && e !== "not");
23
- if (!i) return { ...r };
24
- let a = r[i];
25
- if (!Array.isArray(a)) return { ...r };
26
- let { [i]: o, nullable: s, ...c } = r, l = Object.keys(c).length > 0, { filteredSchemas: u, hasNullSchema: d } = a.reduce((e, n) => {
27
- let r = t.schema(n);
21
+ function i(i) {
22
+ if (!i || typeof i != "object" || i[e]?.inheritedVariants) return i;
23
+ let a = t.find((e) => e in i && e !== "not");
24
+ if (!a) return { ...i };
25
+ let o = i[a];
26
+ if (!Array.isArray(o)) return { ...i };
27
+ let { [a]: s, nullable: c, ...l } = i, u = Object.keys(l).length > 0, { filteredSchemas: d, hasNullSchema: f } = o.reduce((e, t) => {
28
+ let r = n.schema(t);
28
29
  return "type" in r && r.type === "null" ? e.hasNullSchema = !0 : e.filteredSchemas.push(r), e;
29
30
  }, {
30
31
  filteredSchemas: [],
31
32
  hasNullSchema: !1
32
- }), f = d || s === !0;
33
- if (u.length === 1) {
34
- let e = n(u[0], c);
35
- return f && (e.nullable = !0), e;
33
+ }), p = f || c === !0;
34
+ if (d.length === 1) {
35
+ let e = r(d[0], l);
36
+ return p && (e.nullable = !0), e;
36
37
  }
37
- if ((i === "oneOf" || i === "anyOf") && (l || u.some((e) => e.allOf))) {
38
- let { discriminator: e, ...a } = c, o = u.map((e) => {
39
- let r = t.schema(e);
40
- if (r.allOf?.length === 1) {
41
- let { allOf: e, ...i } = r, o = t.schema(e[0]);
42
- if ("properties" in i || "required" in i || "$ref" in i) {
43
- let { $ref: e, title: t, name: r, ...s } = o;
44
- return n(a, i, s);
38
+ if ((a === "oneOf" || a === "anyOf") && (u || d.some((e) => e.allOf))) {
39
+ let { discriminator: e, ...t } = l, o = d.map((e) => {
40
+ let i = n.schema(e);
41
+ if (i.allOf?.length === 1) {
42
+ let { allOf: e, ...a } = i, o = n.schema(e[0]);
43
+ if ("properties" in a || "required" in a || "$ref" in a) {
44
+ let { $ref: e, title: n, name: i, ...s } = o;
45
+ return r(t, a, s);
45
46
  }
46
- return n(a, i, o);
47
+ return r(t, a, o);
47
48
  }
48
- return n(a, r);
49
- }), s = { [i]: o };
50
- return typeof r.description == "string" && (s.description = r.description), f && (s.nullable = !0), s;
49
+ return r(t, i);
50
+ }), s = { [a]: o };
51
+ return typeof i.description == "string" && (s.description = i.description), p && (s.nullable = !0), s;
51
52
  }
52
- if (u.length !== a.length) {
53
+ if (d.length !== o.length) {
53
54
  let e = {
54
- ...r,
55
- [i]: u
55
+ ...i,
56
+ [a]: d
56
57
  };
57
- return f && (e.nullable = !0), e;
58
+ return p && (e.nullable = !0), e;
58
59
  }
59
- return { ...r };
60
+ return { ...i };
60
61
  }
61
62
  //#endregion
62
- export { r as optimizeValueForDisplay };
63
+ export { i as optimizeValueForDisplay };
63
64
 
64
65
  //# sourceMappingURL=optimize-value-for-display.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimize-value-for-display.js","names":[],"sources":["../../../src/schema/helpers/optimize-value-for-display.ts"],"sourcesContent":["import { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\n\nimport { compositions } from './schema-composition'\n\n/** Display normalization tracks null branches without changing the stored OpenAPI schema. */\ntype DisplaySchema = SchemaObject & { nullable?: boolean }\n\n/**\n * Shallow-merges schema-like objects, but unions `properties` and `required`\n * instead of letting a later object's `properties`/`required` completely\n * overwrite an earlier one's. Without this, a variant schema (e.g. a `oneOf`\n * branch) that declares its own `properties`/`required` would wipe out the\n * shared base fields factored out at the root (or via a sibling `allOf`)\n * instead of being combined with them (#9657).\n */\nfunction mergeSchemaProperties(...objects: (Record<string, unknown> | undefined)[]): Record<string, unknown> {\n const merged: Record<string, unknown> = {}\n const properties: Record<string, unknown> = {}\n const required = new Set<string>()\n let hasProperties = false\n let hasRequired = false\n\n for (const object of objects) {\n if (!object) {\n continue\n }\n\n for (const [key, val] of Object.entries(object)) {\n if (key === 'properties' && val && typeof val === 'object') {\n Object.assign(properties, val)\n hasProperties = true\n continue\n }\n\n if (key === 'required' && Array.isArray(val)) {\n for (const name of val) {\n required.add(name)\n }\n hasRequired = true\n continue\n }\n\n merged[key] = val\n }\n }\n\n if (hasProperties) {\n merged.properties = properties\n }\n if (hasRequired) {\n merged.required = [...required]\n }\n\n return merged\n}\n\n/**\n * Normalize compositions for display without changing the source schema. Null branches\n * become nullable state, single branches are flattened, and shared properties and\n * required fields are merged into variants so the renderer keeps their full context.\n */\nexport function optimizeValueForDisplay(value: DisplaySchema | undefined): DisplaySchema | undefined {\n if (!value || typeof value !== 'object') {\n return value\n }\n\n // Find the composition keyword early to avoid unnecessary work\n const composition = compositions.find((keyword) => keyword in value && keyword !== 'not')\n\n // If there's no relevant composition keyword, return a shallow copy\n if (!composition) {\n return { ...value }\n }\n\n const schemas = value[composition]\n if (!Array.isArray(schemas)) {\n return { ...value }\n }\n\n // Extract root properties efficiently (excluding composition and nullable)\n const { [composition]: _, nullable: originalNullable, ...rootProperties } = value\n const hasRootProperties = Object.keys(rootProperties).length > 0\n\n // Check for null schemas and filter them out in one pass\n const { filteredSchemas, hasNullSchema } = schemas.reduce<{\n filteredSchemas: SchemaObject[]\n hasNullSchema: boolean\n }>(\n (acc, _schema) => {\n const schema = resolve.schema(_schema)\n\n if ('type' in schema && schema.type === 'null') {\n acc.hasNullSchema = true\n } else {\n acc.filteredSchemas.push(schema)\n }\n return acc\n },\n { filteredSchemas: [], hasNullSchema: false },\n )\n\n // Determine if nullable should be set\n const shouldBeNullable = hasNullSchema || originalNullable === true\n\n // If only one schema remains after filtering, merge with root properties.\n // `properties`/`required` are unioned so sibling properties declared next to\n // the composition (e.g. `properties` alongside a single-`$ref` `allOf`) are\n // kept instead of being overwritten by the member schema's own `properties`.\n // Root-level annotations (title, description, …) win over the member's: they\n // describe the combined schema, not the base it extends.\n if (filteredSchemas.length === 1) {\n const mergedSchema = mergeSchemaProperties(filteredSchemas[0], rootProperties) as DisplaySchema\n if (shouldBeNullable) {\n mergedSchema.nullable = true\n }\n return mergedSchema\n }\n\n // Check if root properties should be merged into schemas\n const shouldMergeRootProperties =\n (composition === 'oneOf' || composition === 'anyOf') &&\n (hasRootProperties || filteredSchemas.some((schema) => schema.allOf))\n\n if (shouldMergeRootProperties) {\n // The discriminator belongs to the union, not to its variants. Copied into a variant, it\n // makes the variant look like a bare `discriminator.mapping` base, which then infers a\n // second selector inside the variant.\n const { discriminator: _discriminator, ...variantRootProperties } = rootProperties\n\n const mergedSchemas = filteredSchemas.map((_schema) => {\n const schema = resolve.schema(_schema)\n\n // Flatten single-item allOf and merge with root properties. If the\n // variant has its own properties/required/$ref, the allOf member's own\n // identity (`$ref`, `title`, `name`) is dropped before merging so it\n // cannot overwrite the variant's, which would otherwise mislabel the\n // flattened schema as the base it extends instead of the variant itself\n // (#9964). `getModelNameFromSchema` labels a variant by title → name →\n // $ref, so any of those leaking from the base is enough to mislabel it.\n // A variant that is a bare wrapper around the allOf member has no\n // identity of its own to protect, so the base's identity is kept as a\n // fallback label.\n if (schema.allOf?.length === 1) {\n const { allOf, ...otherProps } = schema\n const allOfMember = resolve.schema(allOf[0])!\n const variantHasOwnIdentity = 'properties' in otherProps || 'required' in otherProps || '$ref' in otherProps\n if (variantHasOwnIdentity) {\n const { $ref: _ref, title: _title, name: _name, ...allOfMemberWithoutIdentity } = allOfMember\n return mergeSchemaProperties(variantRootProperties, otherProps, allOfMemberWithoutIdentity)\n }\n return mergeSchemaProperties(variantRootProperties, otherProps, allOfMember)\n }\n return mergeSchemaProperties(variantRootProperties, schema)\n })\n\n // @ts-expect-error - We avoid using coerceValue here as it may be dangerous, so we type cast\n const result = { [composition]: mergedSchemas } as DisplaySchema\n if (typeof value.description === 'string') {\n result.description = value.description\n }\n if (shouldBeNullable) {\n result.nullable = true\n }\n return result\n }\n\n // Return with filtered schemas if any nulls were removed\n if (filteredSchemas.length !== schemas.length) {\n const result: DisplaySchema = { ...value, [composition]: filteredSchemas }\n if (shouldBeNullable) {\n result.nullable = true\n }\n return result\n }\n\n return { ...value }\n}\n"],"mappings":";;;AAgBA,SAAS,EAAsB,GAAG,GAA2E;CAC3G,IAAM,IAAkC,CAAC,GACnC,IAAsC,CAAC,GACvC,oBAAW,IAAI,IAAY,GAC7B,IAAgB,IAChB,IAAc;CAElB,KAAK,IAAM,KAAU,GACd,OAIL,KAAK,IAAM,CAAC,GAAK,MAAQ,OAAO,QAAQ,CAAM,GAAG;EAC/C,IAAI,MAAQ,gBAAgB,KAAO,OAAO,KAAQ,UAAU;GAE1D,AADA,OAAO,OAAO,GAAY,CAAG,GAC7B,IAAgB;GAChB;EACF;EAEA,IAAI,MAAQ,cAAc,MAAM,QAAQ,CAAG,GAAG;GAC5C,KAAK,IAAM,KAAQ,GACjB,EAAS,IAAI,CAAI;GAEnB,IAAc;GACd;EACF;EAEA,EAAO,KAAO;CAChB;CAUF,OAPI,MACF,EAAO,aAAa,IAElB,MACF,EAAO,WAAW,CAAC,GAAG,CAAQ,IAGzB;AACT;AAOA,SAAgB,EAAwB,GAA6D;CACnG,IAAI,CAAC,KAAS,OAAO,KAAU,UAC7B,OAAO;CAIT,IAAM,IAAc,EAAa,MAAM,MAAY,KAAW,KAAS,MAAY,KAAK;CAGxF,IAAI,CAAC,GACH,OAAO,EAAE,GAAG,EAAM;CAGpB,IAAM,IAAU,EAAM;CACtB,IAAI,CAAC,MAAM,QAAQ,CAAO,GACxB,OAAO,EAAE,GAAG,EAAM;CAIpB,IAAM,GAAG,IAAc,GAAG,UAAU,GAAkB,GAAG,MAAmB,GACtE,IAAoB,OAAO,KAAK,CAAc,CAAC,CAAC,SAAS,GAGzD,EAAE,oBAAiB,qBAAkB,EAAQ,QAIhD,GAAK,MAAY;EAChB,IAAM,IAAS,EAAQ,OAAO,CAAO;EAOrC,OALI,UAAU,KAAU,EAAO,SAAS,SACtC,EAAI,gBAAgB,KAEpB,EAAI,gBAAgB,KAAK,CAAM,GAE1B;CACT,GACA;EAAE,iBAAiB,CAAC;EAAG,eAAe;CAAM,CAC9C,GAGM,IAAmB,KAAiB,MAAqB;CAQ/D,IAAI,EAAgB,WAAW,GAAG;EAChC,IAAM,IAAe,EAAsB,EAAgB,IAAI,CAAc;EAI7E,OAHI,MACF,EAAa,WAAW,KAEnB;CACT;CAOA,KAHG,MAAgB,WAAW,MAAgB,aAC3C,KAAqB,EAAgB,MAAM,MAAW,EAAO,KAAK,IAEtC;EAI7B,IAAM,EAAE,eAAe,GAAgB,GAAG,MAA0B,GAE9D,IAAgB,EAAgB,KAAK,MAAY;GACrD,IAAM,IAAS,EAAQ,OAAO,CAAO;GAYrC,IAAI,EAAO,OAAO,WAAW,GAAG;IAC9B,IAAM,EAAE,UAAO,GAAG,MAAe,GAC3B,IAAc,EAAQ,OAAO,EAAM,EAAE;IAE3C,IAD8B,gBAAgB,KAAc,cAAc,KAAc,UAAU,GACvE;KACzB,IAAM,EAAE,MAAM,GAAM,OAAO,GAAQ,MAAM,GAAO,GAAG,MAA+B;KAClF,OAAO,EAAsB,GAAuB,GAAY,CAA0B;IAC5F;IACA,OAAO,EAAsB,GAAuB,GAAY,CAAW;GAC7E;GACA,OAAO,EAAsB,GAAuB,CAAM;EAC5D,CAAC,GAGK,IAAS,GAAG,IAAc,EAAc;EAO9C,OANI,OAAO,EAAM,eAAgB,aAC/B,EAAO,cAAc,EAAM,cAEzB,MACF,EAAO,WAAW,KAEb;CACT;CAGA,IAAI,EAAgB,WAAW,EAAQ,QAAQ;EAC7C,IAAM,IAAwB;GAAE,GAAG;IAAQ,IAAc;EAAgB;EAIzE,OAHI,MACF,EAAO,WAAW,KAEb;CACT;CAEA,OAAO,EAAE,GAAG,EAAM;AACpB"}
1
+ {"version":3,"file":"optimize-value-for-display.js","names":[],"sources":["../../../src/schema/helpers/optimize-value-for-display.ts"],"sourcesContent":["import { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document'\n\nimport { type DiscriminatorSchema, schemaDiscriminator } from '../discriminator-metadata'\nimport { compositions } from './schema-composition'\n\n/** Display normalization tracks null branches without changing the stored OpenAPI schema. */\ntype DisplaySchema = SchemaObject & { nullable?: boolean }\n\n/**\n * Shallow-merges schema-like objects, but unions `properties` and `required`\n * instead of letting a later object's `properties`/`required` completely\n * overwrite an earlier one's. Without this, a variant schema (e.g. a `oneOf`\n * branch) that declares its own `properties`/`required` would wipe out the\n * shared base fields factored out at the root (or via a sibling `allOf`)\n * instead of being combined with them (#9657).\n */\nfunction mergeSchemaProperties(...objects: (Record<string, unknown> | undefined)[]): Record<string, unknown> {\n const merged: Record<string, unknown> = {}\n const properties: Record<string, unknown> = {}\n const required = new Set<string>()\n let hasProperties = false\n let hasRequired = false\n\n for (const object of objects) {\n if (!object) {\n continue\n }\n\n for (const [key, val] of Object.entries(object)) {\n if (key === 'properties' && val && typeof val === 'object') {\n Object.assign(properties, val)\n hasProperties = true\n continue\n }\n\n if (key === 'required' && Array.isArray(val)) {\n for (const name of val) {\n required.add(name)\n }\n hasRequired = true\n continue\n }\n\n merged[key] = val\n }\n }\n\n if (hasProperties) {\n merged.properties = properties\n }\n if (hasRequired) {\n merged.required = [...required]\n }\n\n return merged\n}\n\n/**\n * Normalize compositions for display without changing the source schema. Null branches\n * become nullable state, single branches are flattened, and shared properties and\n * required fields are merged into variants so the renderer keeps their full context.\n */\nexport function optimizeValueForDisplay(value: DisplaySchema | undefined): DisplaySchema | undefined {\n if (!value || typeof value !== 'object') {\n return value\n }\n\n // Inferred AsyncAPI variants already carry complete concrete schemas. Flattening\n // them would lose reference identities and merge the base identity into descendants.\n if ((value as DiscriminatorSchema)[schemaDiscriminator]?.inheritedVariants) {\n return value\n }\n\n // Find the composition keyword early to avoid unnecessary work\n const composition = compositions.find((keyword) => keyword in value && keyword !== 'not')\n\n // If there's no relevant composition keyword, return a shallow copy\n if (!composition) {\n return { ...value }\n }\n\n const schemas = value[composition]\n if (!Array.isArray(schemas)) {\n return { ...value }\n }\n\n // Extract root properties efficiently (excluding composition and nullable)\n const { [composition]: _, nullable: originalNullable, ...rootProperties } = value\n const hasRootProperties = Object.keys(rootProperties).length > 0\n\n // Check for null schemas and filter them out in one pass\n const { filteredSchemas, hasNullSchema } = schemas.reduce<{\n filteredSchemas: SchemaObject[]\n hasNullSchema: boolean\n }>(\n (acc, _schema) => {\n const schema = resolve.schema(_schema)\n\n if ('type' in schema && schema.type === 'null') {\n acc.hasNullSchema = true\n } else {\n acc.filteredSchemas.push(schema)\n }\n return acc\n },\n { filteredSchemas: [], hasNullSchema: false },\n )\n\n // Determine if nullable should be set\n const shouldBeNullable = hasNullSchema || originalNullable === true\n\n // If only one schema remains after filtering, merge with root properties.\n // `properties`/`required` are unioned so sibling properties declared next to\n // the composition (e.g. `properties` alongside a single-`$ref` `allOf`) are\n // kept instead of being overwritten by the member schema's own `properties`.\n // Root-level annotations (title, description, …) win over the member's: they\n // describe the combined schema, not the base it extends.\n if (filteredSchemas.length === 1) {\n const mergedSchema = mergeSchemaProperties(filteredSchemas[0], rootProperties) as DisplaySchema\n if (shouldBeNullable) {\n mergedSchema.nullable = true\n }\n return mergedSchema\n }\n\n // Check if root properties should be merged into schemas\n const shouldMergeRootProperties =\n (composition === 'oneOf' || composition === 'anyOf') &&\n (hasRootProperties || filteredSchemas.some((schema) => schema.allOf))\n\n if (shouldMergeRootProperties) {\n // The discriminator belongs to the union, not to its variants. Copied into a variant, it\n // makes the variant look like a bare `discriminator.mapping` base, which then infers a\n // second selector inside the variant.\n const { discriminator: _discriminator, ...variantRootProperties } = rootProperties\n\n const mergedSchemas = filteredSchemas.map((_schema) => {\n const schema = resolve.schema(_schema)\n\n // Flatten single-item allOf and merge with root properties. If the\n // variant has its own properties/required/$ref, the allOf member's own\n // identity (`$ref`, `title`, `name`) is dropped before merging so it\n // cannot overwrite the variant's, which would otherwise mislabel the\n // flattened schema as the base it extends instead of the variant itself\n // (#9964). `getModelNameFromSchema` labels a variant by title → name →\n // $ref, so any of those leaking from the base is enough to mislabel it.\n // A variant that is a bare wrapper around the allOf member has no\n // identity of its own to protect, so the base's identity is kept as a\n // fallback label.\n if (schema.allOf?.length === 1) {\n const { allOf, ...otherProps } = schema\n const allOfMember = resolve.schema(allOf[0])!\n const variantHasOwnIdentity = 'properties' in otherProps || 'required' in otherProps || '$ref' in otherProps\n if (variantHasOwnIdentity) {\n const { $ref: _ref, title: _title, name: _name, ...allOfMemberWithoutIdentity } = allOfMember\n return mergeSchemaProperties(variantRootProperties, otherProps, allOfMemberWithoutIdentity)\n }\n return mergeSchemaProperties(variantRootProperties, otherProps, allOfMember)\n }\n return mergeSchemaProperties(variantRootProperties, schema)\n })\n\n // @ts-expect-error - We avoid using coerceValue here as it may be dangerous, so we type cast\n const result = { [composition]: mergedSchemas } as DisplaySchema\n if (typeof value.description === 'string') {\n result.description = value.description\n }\n if (shouldBeNullable) {\n result.nullable = true\n }\n return result\n }\n\n // Return with filtered schemas if any nulls were removed\n if (filteredSchemas.length !== schemas.length) {\n const result: DisplaySchema = { ...value, [composition]: filteredSchemas }\n if (shouldBeNullable) {\n result.nullable = true\n }\n return result\n }\n\n return { ...value }\n}\n"],"mappings":";;;;AAiBA,SAAS,EAAsB,GAAG,GAA2E;CAC3G,IAAM,IAAkC,CAAC,GACnC,IAAsC,CAAC,GACvC,oBAAW,IAAI,IAAY,GAC7B,IAAgB,IAChB,IAAc;CAElB,KAAK,IAAM,KAAU,GACd,OAIL,KAAK,IAAM,CAAC,GAAK,MAAQ,OAAO,QAAQ,CAAM,GAAG;EAC/C,IAAI,MAAQ,gBAAgB,KAAO,OAAO,KAAQ,UAAU;GAE1D,AADA,OAAO,OAAO,GAAY,CAAG,GAC7B,IAAgB;GAChB;EACF;EAEA,IAAI,MAAQ,cAAc,MAAM,QAAQ,CAAG,GAAG;GAC5C,KAAK,IAAM,KAAQ,GACjB,EAAS,IAAI,CAAI;GAEnB,IAAc;GACd;EACF;EAEA,EAAO,KAAO;CAChB;CAUF,OAPI,MACF,EAAO,aAAa,IAElB,MACF,EAAO,WAAW,CAAC,GAAG,CAAQ,IAGzB;AACT;AAOA,SAAgB,EAAwB,GAA6D;CAOnG,IANI,CAAC,KAAS,OAAO,KAAU,YAM1B,EAA8B,EAAoB,EAAE,mBACvD,OAAO;CAIT,IAAM,IAAc,EAAa,MAAM,MAAY,KAAW,KAAS,MAAY,KAAK;CAGxF,IAAI,CAAC,GACH,OAAO,EAAE,GAAG,EAAM;CAGpB,IAAM,IAAU,EAAM;CACtB,IAAI,CAAC,MAAM,QAAQ,CAAO,GACxB,OAAO,EAAE,GAAG,EAAM;CAIpB,IAAM,GAAG,IAAc,GAAG,UAAU,GAAkB,GAAG,MAAmB,GACtE,IAAoB,OAAO,KAAK,CAAc,CAAC,CAAC,SAAS,GAGzD,EAAE,oBAAiB,qBAAkB,EAAQ,QAIhD,GAAK,MAAY;EAChB,IAAM,IAAS,EAAQ,OAAO,CAAO;EAOrC,OALI,UAAU,KAAU,EAAO,SAAS,SACtC,EAAI,gBAAgB,KAEpB,EAAI,gBAAgB,KAAK,CAAM,GAE1B;CACT,GACA;EAAE,iBAAiB,CAAC;EAAG,eAAe;CAAM,CAC9C,GAGM,IAAmB,KAAiB,MAAqB;CAQ/D,IAAI,EAAgB,WAAW,GAAG;EAChC,IAAM,IAAe,EAAsB,EAAgB,IAAI,CAAc;EAI7E,OAHI,MACF,EAAa,WAAW,KAEnB;CACT;CAOA,KAHG,MAAgB,WAAW,MAAgB,aAC3C,KAAqB,EAAgB,MAAM,MAAW,EAAO,KAAK,IAEtC;EAI7B,IAAM,EAAE,eAAe,GAAgB,GAAG,MAA0B,GAE9D,IAAgB,EAAgB,KAAK,MAAY;GACrD,IAAM,IAAS,EAAQ,OAAO,CAAO;GAYrC,IAAI,EAAO,OAAO,WAAW,GAAG;IAC9B,IAAM,EAAE,UAAO,GAAG,MAAe,GAC3B,IAAc,EAAQ,OAAO,EAAM,EAAE;IAE3C,IAD8B,gBAAgB,KAAc,cAAc,KAAc,UAAU,GACvE;KACzB,IAAM,EAAE,MAAM,GAAM,OAAO,GAAQ,MAAM,GAAO,GAAG,MAA+B;KAClF,OAAO,EAAsB,GAAuB,GAAY,CAA0B;IAC5F;IACA,OAAO,EAAsB,GAAuB,GAAY,CAAW;GAC7E;GACA,OAAO,EAAsB,GAAuB,CAAM;EAC5D,CAAC,GAGK,IAAS,GAAG,IAAc,EAAc;EAO9C,OANI,OAAO,EAAM,eAAgB,aAC/B,EAAO,cAAc,EAAM,cAEzB,MACF,EAAO,WAAW,KAEb;CACT;CAGA,IAAI,EAAgB,WAAW,EAAQ,QAAQ;EAC7C,IAAM,IAAwB;GAAE,GAAG;IAAQ,IAAc;EAAgB;EAIzE,OAHI,MACF,EAAO,WAAW,KAEb;CACT;CAEA,OAAO,EAAE,GAAG,EAAM;AACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"partition-all-of-compositions.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/partition-all-of-compositions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAGhG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,KAAK,aAAa,GAAG,OAAO,CAAC,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,CAAA;AAEnE,iFAAiF;AACjF,KAAK,YAAY,GACb;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACxC;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,EAAE,aAAa,CAAA;IAC1B,qFAAqF;IACrF,KAAK,EAAE,YAAY,CAAA;IACnB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAmFL;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,YAAY,GAAG,SAAS,KAAG;IAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;CAmFvG,CAAA"}
1
+ {"version":3,"file":"partition-all-of-compositions.d.ts","sourceRoot":"","sources":["../../../src/schema/helpers/partition-all-of-compositions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,8DAA8D,CAAA;AAGrH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,KAAK,aAAa,GAAG,OAAO,CAAC,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,CAAA;AAEnE,iFAAiF;AACjF,KAAK,YAAY,GACb;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACxC;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,EAAE,aAAa,CAAA;IAC1B,qFAAqF;IACrF,KAAK,EAAE,YAAY,CAAA;IACnB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AA+FL;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,YAAY,GAAG,SAAS,KAAG;IAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;CAsFvG,CAAA"}