@scalar/api-reference 1.64.1 → 1.65.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/browser/chunks/{AgentScalarChatInterface-D1mzA447.js → AgentScalarChatInterface-B8091hGB.js} +4 -4
  3. package/dist/browser/chunks/ScalarTextInput.vue-Y69qfG1_.js +27 -0
  4. package/dist/browser/chunks/basic-shape-diamond.svg-o5eiY2I7.js +1 -1
  5. package/dist/browser/chunks/basic-shape-hexagon.svg-CGuS7mbd.js +1 -1
  6. package/dist/browser/chunks/basic-shape-primary-circle-ellipse-round.svg-DDIpXiBm.js +1 -1
  7. package/dist/browser/chunks/basic-shape-primary-square-rectangle.svg-DzVEJHMB.js +1 -1
  8. package/dist/browser/chunks/basic-shape-shield.svg-BZzapRqv.js +1 -1
  9. package/dist/browser/chunks/browser-CTPPEMEL.js +1 -1
  10. package/dist/browser/chunks/computer-device-desktop-monitor.svg-OSM05r1I.js +1 -1
  11. package/dist/browser/chunks/computer-device-desktop.svg-BMFzGZ27.js +1 -1
  12. package/dist/browser/chunks/computer-device-laptop.svg-CMAjzuB-.js +1 -1
  13. package/dist/browser/chunks/computer-device-mobile-phone-android-samsung-back.svg-D4xBONmL.js +1 -1
  14. package/dist/browser/chunks/computer-device-mobile-phone-android-samsung.svg-gbMJLjJw.js +1 -1
  15. package/dist/browser/chunks/computer-device-mobile-phone-iphone-x-back.svg-Bl1rmdKA.js +1 -1
  16. package/dist/browser/chunks/computer-device-mobile-phone-iphone-x.svg-DVetP0aa.js +1 -1
  17. package/dist/browser/chunks/computer-device-mobile-tablet-touch.svg-Zi88BP4L.js +1 -1
  18. package/dist/browser/chunks/computer-device-mobile-tablet.svg-C1ggisWP.js +1 -1
  19. package/dist/browser/chunks/computer-device-network-ethernet-cat6.svg-BIUymdC1.js +1 -1
  20. package/dist/browser/chunks/computer-device-network-lan-www.svg-CoFUlIVO.js +1 -1
  21. package/dist/browser/chunks/computer-device-network-wifi-connection.svg-DeWsacxI.js +1 -1
  22. package/dist/browser/chunks/computer-device-network-wifi-router.svg-BjpZEot4.js +1 -1
  23. package/dist/browser/chunks/ecology-science-erlenmeyer-flask.svg-ftjGGirE.js +1 -1
  24. package/dist/browser/chunks/image-flash-lightning.svg-DYQ0W4Fi.js +1 -1
  25. package/dist/browser/chunks/image-picture-flower.svg-Bfe5SVDf.js +1 -1
  26. package/dist/browser/chunks/interface-alert-exclamation-diamond.svg-D1HePDNM.js +1 -1
  27. package/dist/browser/chunks/interface-alert-exclamation-triangle-warning.svg-CILUsxBC.js +1 -1
  28. package/dist/browser/chunks/interface-alert-information-circle.svg-9LrbJM5J.js +1 -1
  29. package/dist/browser/chunks/interface-award-crown.svg-DllWgiU1.js +1 -1
  30. package/dist/browser/chunks/interface-bookmark-tag.svg-Dc-JL-Kc.js +1 -1
  31. package/dist/browser/chunks/interface-bookmark.svg-Dc-JL-Kc.js +1 -1
  32. package/dist/browser/chunks/interface-calendar-date-one.svg-DO2jelhF.js +1 -1
  33. package/dist/browser/chunks/interface-content-book-open-pages.svg-BJjMjIgA.js +1 -1
  34. package/dist/browser/chunks/interface-content-book-page.svg-C6rKB2fs.js +1 -1
  35. package/dist/browser/chunks/interface-content-file.svg-CS0q2FKx.js +1 -1
  36. package/dist/browser/chunks/interface-content-folder.svg-CThTWsJX.js +1 -1
  37. package/dist/browser/chunks/interface-copy-clipboard.svg-DdN67cLv.js +1 -1
  38. package/dist/browser/chunks/interface-edit-attachment.svg-Ciizphuh.js +1 -1
  39. package/dist/browser/chunks/interface-edit-binocular.svg-Dw1nDqmL.js +1 -1
  40. package/dist/browser/chunks/interface-edit-magic-wand.svg-BYS0jm_E.js +1 -1
  41. package/dist/browser/chunks/interface-edit-tool-paint-roller.svg-NioSHZC2.js +1 -1
  42. package/dist/browser/chunks/interface-edit-tool-pencil.svg-P87QFlat.js +1 -1
  43. package/dist/browser/chunks/interface-favorite-award.svg-DBBAChSi.js +1 -1
  44. package/dist/browser/chunks/interface-favorite-flag.svg-HlhPomHY.js +1 -1
  45. package/dist/browser/chunks/interface-favorite-heart.svg-Cqu2GYDo.js +1 -1
  46. package/dist/browser/chunks/interface-favorite-star.svg-BD4JY_J2.js +1 -1
  47. package/dist/browser/chunks/interface-favorite-stars-sparkles.svg-BXi6aO8q.js +1 -1
  48. package/dist/browser/chunks/interface-hierarchy-flowchart.svg-CDEVSsD4.js +1 -1
  49. package/dist/browser/chunks/interface-home-house.svg-DJetUjwj.js +1 -1
  50. package/dist/browser/chunks/interface-hyperlink.svg-DJ1LREmz.js +1 -1
  51. package/dist/browser/chunks/interface-lighting-brightness.svg-TGKAaHYV.js +1 -1
  52. package/dist/browser/chunks/interface-lock-closed.svg-3hehWr3i.js +1 -1
  53. package/dist/browser/chunks/interface-lock-open-unlock.svg-CuXKcv1m.js +1 -1
  54. package/dist/browser/chunks/interface-login-key.svg-Chwvvywd.js +1 -1
  55. package/dist/browser/chunks/interface-search.svg-JDE3fk0u.js +1 -1
  56. package/dist/browser/chunks/interface-setting-cog.svg-BBCkeh4K.js +1 -1
  57. package/dist/browser/chunks/interface-share-megaphone-bullhorn.svg-CDdxF-4y.js +1 -1
  58. package/dist/browser/chunks/interface-share-rocket.svg-DSbdn_o7.js +1 -1
  59. package/dist/browser/chunks/interface-share-satellite.svg-CefBVZvY.js +1 -1
  60. package/dist/browser/chunks/interface-share-space-ship.svg-tFA2dsSU.js +1 -1
  61. package/dist/browser/chunks/interface-share.svg-BpOGopyv.js +1 -1
  62. package/dist/browser/chunks/interface-signal-square.svg-BcX_BoaC.js +1 -1
  63. package/dist/browser/chunks/interface-time-clock-circle.svg-C8B_L_RM.js +1 -1
  64. package/dist/browser/chunks/interface-time-hour-glass.svg-qw-oeoVn.js +1 -1
  65. package/dist/browser/chunks/interface-users-multiple.svg-Cs13Eewq.js +1 -1
  66. package/dist/browser/chunks/interface-weather-moon.svg-CV-oDTae.js +1 -1
  67. package/dist/browser/chunks/mail-chat-bubble-square.svg-dpauJhin.js +1 -1
  68. package/dist/browser/chunks/mail-send-email-paper-airplane.svg-BBofxojL.js +1 -1
  69. package/dist/browser/chunks/mail-send-envelope.svg-DyENgYOI.js +1 -1
  70. package/dist/browser/chunks/modal-C-pxwP3A.js +102 -0
  71. package/dist/browser/chunks/money-cashier-receipt.svg-dNTr5aio.js +1 -1
  72. package/dist/browser/chunks/money-currency-dollar-pay.svg-1ZESPtFY.js +1 -1
  73. package/dist/browser/chunks/money-graph-arrow-increase.svg-kEZ2u2z2.js +1 -1
  74. package/dist/browser/chunks/money-graph-bar-chart-increase.svg-B-t2UWB3.js +1 -1
  75. package/dist/browser/chunks/nature-ecology-leaf.svg-DZ2GJV8m.js +1 -1
  76. package/dist/browser/chunks/phone-telephone.svg-C12QjpN7.js +1 -1
  77. package/dist/browser/chunks/programming-bug.svg-wLTsruN9.js +1 -1
  78. package/dist/browser/chunks/programming-cloud.svg-3XU6dNUg.js +1 -1
  79. package/dist/browser/chunks/programming-computer-database-server.svg-B1JrHSPd.js +1 -1
  80. package/dist/browser/chunks/programming-computer-database.svg-BxHSuFl7.js +1 -1
  81. package/dist/browser/chunks/programming-module-four-layout.svg-CeV35q45.js +1 -1
  82. package/dist/browser/chunks/programming-module-three.svg-YIBpLt45.js +1 -1
  83. package/dist/browser/chunks/programming-module.svg-CU_pEibI.js +1 -1
  84. package/dist/browser/chunks/programming-script-code.svg-CLzinmHT.js +1 -1
  85. package/dist/browser/chunks/runtime-core.esm-bundler-CqqEw5ds.js +1 -1
  86. package/dist/browser/chunks/shopping-cart.svg-Brzddu3K.js +1 -1
  87. package/dist/browser/chunks/shopping-gift-present.svg-l2K48g7L.js +1 -1
  88. package/dist/browser/chunks/shopping-shipping-box-parcel-package.svg-DesGopPo.js +1 -1
  89. package/dist/browser/chunks/tag-new-circle.svg-DE-VaLZU.js +1 -1
  90. package/dist/browser/chunks/travel-map-earth-globe.svg-DLaOMzx6.js +1 -1
  91. package/dist/browser/chunks/vendor-B93Hdr0r.js +306 -0
  92. package/dist/browser/standalone.esm.js +20 -20
  93. package/dist/browser/standalone.js +235 -232
  94. package/dist/components/AgentScalar/OpenMCPButton.vue.d.ts.map +1 -1
  95. package/dist/components/AgentScalar/OpenMCPButton.vue.js +1 -1
  96. package/dist/components/AgentScalar/OpenMCPButton.vue.js.map +1 -1
  97. package/dist/components/AgentScalar/OpenMCPButton.vue.script.js.map +1 -1
  98. package/dist/components/ApiReference.vue.d.ts.map +1 -1
  99. package/dist/components/ApiReference.vue.js +1 -1
  100. package/dist/components/ApiReference.vue.js.map +1 -1
  101. package/dist/components/ApiReference.vue.script.js +8 -8
  102. package/dist/components/ApiReference.vue.script.js.map +1 -1
  103. package/dist/components/Content/AsyncApi/index.d.ts +3 -0
  104. package/dist/components/Content/AsyncApi/index.d.ts.map +1 -1
  105. package/dist/components/Content/Schema/SchemaProperty.vue.d.ts.map +1 -1
  106. package/dist/components/Content/Schema/SchemaProperty.vue.js +1 -1
  107. package/dist/components/Content/Schema/SchemaProperty.vue.js.map +1 -1
  108. package/dist/components/Content/Schema/SchemaProperty.vue.script.js +5 -0
  109. package/dist/components/Content/Schema/SchemaProperty.vue.script.js.map +1 -1
  110. package/dist/components/Content/Schema/SchemaPropertyHeading.vue.d.ts +6 -0
  111. package/dist/components/Content/Schema/SchemaPropertyHeading.vue.d.ts.map +1 -1
  112. package/dist/components/Content/Schema/SchemaPropertyHeading.vue.js +1 -1
  113. package/dist/components/Content/Schema/SchemaPropertyHeading.vue.js.map +1 -1
  114. package/dist/components/Content/Schema/SchemaPropertyHeading.vue.script.js +5 -1
  115. package/dist/components/Content/Schema/SchemaPropertyHeading.vue.script.js.map +1 -1
  116. package/dist/components/Content/Schema/helpers/get-ref-name.d.ts +16 -0
  117. package/dist/components/Content/Schema/helpers/get-ref-name.d.ts.map +1 -1
  118. package/dist/components/Content/Schema/helpers/get-ref-name.js +28 -1
  119. package/dist/components/Content/Schema/helpers/get-ref-name.js.map +1 -1
  120. package/dist/components/Content/Schema/helpers/is-model-linkable.d.ts +15 -0
  121. package/dist/components/Content/Schema/helpers/is-model-linkable.d.ts.map +1 -0
  122. package/dist/components/Content/Schema/helpers/is-model-linkable.js +22 -0
  123. package/dist/components/Content/Schema/helpers/is-model-linkable.js.map +1 -0
  124. package/dist/components/Content/Schema/helpers/schema-name.d.ts +6 -1
  125. package/dist/components/Content/Schema/helpers/schema-name.d.ts.map +1 -1
  126. package/dist/components/Content/Schema/helpers/schema-name.js +5 -4
  127. package/dist/components/Content/Schema/helpers/schema-name.js.map +1 -1
  128. package/dist/components/Content/Schema/types.d.ts +7 -0
  129. package/dist/components/Content/Schema/types.d.ts.map +1 -1
  130. package/dist/components/index.d.ts +1 -0
  131. package/dist/components/index.d.ts.map +1 -1
  132. package/dist/components/index.js +5 -1
  133. package/dist/features/Operation/components/Header.vue.d.ts +2 -0
  134. package/dist/features/Operation/components/Header.vue.d.ts.map +1 -1
  135. package/dist/features/Operation/components/Header.vue.js.map +1 -1
  136. package/dist/features/Operation/components/Header.vue.script.js +3 -1
  137. package/dist/features/Operation/components/Header.vue.script.js.map +1 -1
  138. package/dist/features/Operation/components/Headers.vue.d.ts +2 -0
  139. package/dist/features/Operation/components/Headers.vue.d.ts.map +1 -1
  140. package/dist/features/Operation/components/Headers.vue.js +1 -1
  141. package/dist/features/Operation/components/Headers.vue.js.map +1 -1
  142. package/dist/features/Operation/components/Headers.vue.script.js +4 -1
  143. package/dist/features/Operation/components/Headers.vue.script.js.map +1 -1
  144. package/dist/features/Operation/components/OperationParameters.vue.d.ts.map +1 -1
  145. package/dist/features/Operation/components/OperationParameters.vue.js.map +1 -1
  146. package/dist/features/Operation/components/OperationParameters.vue.script.js +2 -2
  147. package/dist/features/Operation/components/OperationParameters.vue.script.js.map +1 -1
  148. package/dist/features/Operation/components/ParameterListItem.vue.d.ts.map +1 -1
  149. package/dist/features/Operation/components/ParameterListItem.vue.js +1 -1
  150. package/dist/features/Operation/components/ParameterListItem.vue.js.map +1 -1
  151. package/dist/features/Operation/components/ParameterListItem.vue.script.js +3 -0
  152. package/dist/features/Operation/components/ParameterListItem.vue.script.js.map +1 -1
  153. package/dist/features/Operation/components/RequestBody.vue.d.ts.map +1 -1
  154. package/dist/features/Operation/components/RequestBody.vue.js +1 -1
  155. package/dist/features/Operation/components/RequestBody.vue.js.map +1 -1
  156. package/dist/features/Operation/components/RequestBody.vue.script.js +10 -1
  157. package/dist/features/Operation/components/RequestBody.vue.script.js.map +1 -1
  158. package/dist/features/Operation/layouts/ModernLayout.vue.script.js.map +1 -1
  159. package/dist/features/Search/components/SearchResult.vue.d.ts.map +1 -1
  160. package/dist/features/Search/components/SearchResult.vue.js.map +1 -1
  161. package/dist/features/Search/components/SearchResult.vue.script.js +2 -2
  162. package/dist/features/Search/components/SearchResult.vue.script.js.map +1 -1
  163. package/dist/helpers/build-models-index.d.ts +15 -0
  164. package/dist/helpers/build-models-index.d.ts.map +1 -0
  165. package/dist/helpers/build-models-index.js +28 -0
  166. package/dist/helpers/build-models-index.js.map +1 -0
  167. package/dist/helpers/storage.d.ts +16 -0
  168. package/dist/helpers/storage.d.ts.map +1 -1
  169. package/dist/style.css +418 -409
  170. package/dist/vue-styles.css +370 -361
  171. package/package.json +13 -13
  172. package/dist/browser/chunks/ScalarTextInput.vue-OfiA6SHf.js +0 -27
  173. package/dist/browser/chunks/modal-BS4e2gew.js +0 -99
  174. package/dist/browser/chunks/vendor-DWZAEyBy.js +0 -306
  175. package/dist/features/Operation/helpers/should-ignore-entity.d.ts +0 -8
  176. package/dist/features/Operation/helpers/should-ignore-entity.d.ts.map +0 -1
  177. package/dist/features/Operation/helpers/should-ignore-entity.js +0 -9
  178. package/dist/features/Operation/helpers/should-ignore-entity.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaProperty.vue.script.js","names":[],"sources":["../../../../src/components/Content/Schema/SchemaProperty.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ScalarMarkdown } from '@scalar/components/markdown'\nimport { ScalarWrappingText } from '@scalar/components/wrapping-text'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n isDynamicRef,\n resolveDynamicRef,\n} from '@scalar/workspace-store/helpers/dynamic-ref'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type {\n DiscriminatorObject,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\nimport { computed, type Component } from 'vue'\n\nimport { WithBreadcrumb } from '@/components/Anchor'\nimport {\n resolveDynamicSchema,\n useDynamicScope,\n} from '@/components/Content/Schema/helpers/dynamic-scope'\nimport { isTypeObject } from '@/components/Content/Schema/helpers/is-type-object'\nimport { getCycleKey } from '@/components/Content/Schema/helpers/schema-cycle'\nimport type { SchemaOptions } from '@/components/Content/Schema/types'\nimport { SpecificationExtension } from '@/features/specification-extension'\n\nimport { getCompositionsToRender } from './helpers/get-compositions-to-render'\nimport { getEnumValues } from './helpers/get-enum-values'\nimport { getPropertyDescription } from './helpers/get-property-description'\nimport { hasComplexArrayItems } from './helpers/has-complex-array-items'\nimport { optimizeValueForDisplay } from './helpers/optimize-value-for-display'\nimport type { CompositionKeyword } from './helpers/schema-composition'\nimport { shouldDisplayDescription } from './helpers/should-display-description'\nimport { shouldDisplayHeading } from './helpers/should-display-heading'\nimport Schema from './Schema.vue'\nimport SchemaComposition from './SchemaComposition.vue'\nimport SchemaEnums from './SchemaEnums.vue'\nimport SchemaPropertyHeading from './SchemaPropertyHeading.vue'\n\n/**\n * Note: We're taking in a prop called `value` which should be a JSON Schema.\n *\n * We're using `optimizeValueForDisplay` to merge null types in compositions (anyOf, allOf, oneOf, not).\n * So you should basically use the optimizedValue everywhere in the component.\n */\n\n/** Composition keywords that hold a list of schemas and can be flattened when they contain a single member. */\nconst SINGLE_ITEM_COMPOSITIONS = ['oneOf', 'anyOf', 'allOf'] as const\n\nconst props = withDefaults(\n defineProps<{\n is?: string | Component\n schema: SchemaObject | undefined\n noncollapsible?: boolean\n level?: number\n name?: string\n required?: boolean\n compact?: boolean\n discriminator?: DiscriminatorObject\n description?: string\n hideModelNames?: boolean\n hideHeading?: boolean\n /** When the root schema was resolved from a $ref, pass the ref name for display (e.g. \"Data\"). */\n modelName?: string | null\n variant?: 'additionalProperties' | 'patternProperties'\n breadcrumb?: string[]\n eventBus: WorkspaceEventBus | null\n options: SchemaOptions\n /** Enum values for property names (from JSON Schema propertyNames keyword). */\n propertyNamesEnum?: string[]\n /** Resolved propertyNames schema, used to show key constraints like `format`. */\n propertyNamesSchema?: SchemaObject\n /** When \"requestBody\", composition selection is synced with the example snippet */\n schemaContext?: string\n /** Internal path used to sync nested request body compositions with the code sample */\n compositionPath?: string[]\n /** Internal path segment for this property when building nested composition keys */\n compositionPathSegment?: string\n /** Stable identity of this property's schema, used for cycle detection. */\n cycleKey?: unknown\n }>(),\n {\n level: 0,\n required: false,\n compact: false,\n hideModelNames: false,\n },\n)\n\n/** The dynamic scope inherited from the enclosing schema resources, used to bind `$dynamicRef`s. */\nconst dynamicScope = useDynamicScope()\n\n/**\n * Simplified composition with `null` type.\n *\n * A top-level `$dynamicRef` (e.g. a linked-list `next` node) is bound to its concrete type via the\n * dynamic scope first; for ordinary schemas this is a no-op.\n */\nconst optimizedValue = computed(() =>\n optimizeValueForDisplay(resolveDynamicSchema(props.schema, dynamicScope)),\n)\n\nconst childBreadcrumb = computed<string[] | undefined>(() =>\n props.breadcrumb\n ? // A named property extends the breadcrumb with its own name. A nameless\n // container (e.g. a response object, rendered without a name to avoid a\n // duplicate heading) passes its breadcrumb straight through so its\n // properties stay linkable.\n props.name\n ? [...props.breadcrumb, props.name]\n : props.breadcrumb\n : undefined,\n)\n\nconst currentCompositionPath = computed<string[]>(() =>\n props.compositionPathSegment\n ? [...(props.compositionPath ?? []), props.compositionPathSegment]\n : (props.compositionPath ?? []),\n)\n\nconst arrayItemsCompositionPath = computed<string[]>(() => [\n ...currentCompositionPath.value,\n 'items',\n])\n\nconst shouldHaveLink = computed(() => props.level <= 2)\n\n/**\n * The array schema used for item inspection, with a `$dynamicRef` item bound to its concrete type.\n *\n * Returns the schema unchanged unless `items` is a `$dynamicRef` that resolves against the dynamic\n * scope, so ordinary arrays (including `$ref` items) keep their existing behavior exactly.\n */\nconst arrayValueWithBoundItems = computed(() => {\n const value = optimizedValue.value\n if (!value || !isArraySchema(value) || !isDynamicRef(value.items)) {\n return value\n }\n\n const bound = resolveDynamicRef(value.items.$dynamicRef, dynamicScope)\n return bound ? ({ ...value, items: bound } as SchemaObject) : value\n})\n\n/** Checks if array items have complex structure */\nconst hasComplexArrayItemsComputed = computed(() =>\n hasComplexArrayItems(arrayValueWithBoundItems.value),\n)\n\n/** Check if enum should be displayed (from value schema or from propertyNames) */\nconst hasEnum = computed(() => enumValues.value.length > 0)\n\n/** Determine if object properties should be displayed */\nconst shouldRenderObjectProperties = computed(() => {\n const value = optimizedValue.value\n if (!value) {\n return false\n }\n\n if (!('properties' in value || 'additionalProperties' in value)) {\n return false\n }\n\n // `allOf` already merges the factored-out sibling `properties` into its\n // rendered result (see `mergeAllOfSchemas`), so rendering a separate object\n // block here would show those properties twice. Let the composition handle it.\n if ('allOf' in value) {\n return false\n }\n\n // A schema may factor its common `properties` out to the top level alongside\n // a composition keyword (anyOf/oneOf/not), as described in the JSON Schema\n // \"factoring schemas\" guide. `isTypeObject` deliberately rejects such schemas\n // so the composition is rendered, but the factored-out properties must still\n // show. Unlike `allOf`, these compositions do not merge sibling properties.\n // Render them unless the schema is an explicit non-object (scalar or array)\n // type. See https://github.com/scalar/scalar/issues/8593\n const type = (value as { type?: unknown }).type\n const isExplicitNonObject = typeof type === 'string' && type !== 'object'\n\n return isTypeObject(value) || !isExplicitNonObject\n})\n\n/** Determine if array of objects should be rendered */\nconst shouldRenderArrayOfObjects = computed(() => {\n const value = optimizedValue.value\n if (!value || !isArraySchema(value) || typeof value.items !== 'object') {\n return false\n }\n\n return hasComplexArrayItemsComputed.value\n})\n\n/** Extract enum values from schema or array items */\nconst enumValues = computed(() => getEnumValues(optimizedValue.value))\n\n/** Generate property description from type/format */\nconst propertyDescription = computed(() =>\n getPropertyDescription(optimizedValue.value),\n)\n\n/** Determine if description should be displayed */\nconst displayDescription = computed(() =>\n shouldDisplayDescription(optimizedValue.value, props.description),\n)\n\n/**\n * The schema used to render the object's own properties.\n *\n * Composition keywords are stripped so the nested object renders only its\n * properties. The compositions are rendered separately below; leaving them here\n * would route the nested `Schema` back through `SchemaProperty` and recurse.\n *\n * The `discriminator` is stripped too: its variant selector is part of the\n * composition rendered below (including the one inferred from a bare\n * `discriminator.mapping`), so keeping it here would make the nested `Schema`\n * infer and render a second, identical selector.\n *\n * When the property already renders the description, we also drop it to avoid\n * repeating it in the nested object schema card.\n */\nconst objectSchemaForChildren = computed(() => {\n const value = optimizedValue.value\n if (!value) {\n return value\n }\n\n const {\n oneOf: _oneOf,\n anyOf: _anyOf,\n allOf: _allOf,\n not: _not,\n discriminator: _discriminator,\n ...objectSchema\n } = value as Record<string, unknown>\n\n if (displayDescription.value && 'description' in objectSchema) {\n const { description: _description, ...schemaWithoutDescription } =\n objectSchema\n return schemaWithoutDescription as SchemaObject\n }\n\n return objectSchema as SchemaObject\n})\n\n/** Determine if property heading should be displayed */\nconst shouldDisplayHeadingComputed = computed(() =>\n shouldDisplayHeading(optimizedValue.value, props.name, props.required),\n)\n\n/** Computes which compositions should be rendered and with which values */\nconst compositionsToRender = computed(() =>\n getCompositionsToRender(optimizedValue.value, props.options.document),\n)\nconst getCompositionDiscriminator = (\n composition: CompositionKeyword,\n): DiscriminatorObject | undefined =>\n composition === 'allOf'\n ? (props.schema?.discriminator ?? props.discriminator)\n : props.schema?.discriminator\n\n/**\n * Get resolved array items for rendering (with any `$dynamicRef` bound to the concrete type).\n *\n * When the items are wrapped in a single-item composition (e.g. `items: { allOf: [{ type: 'object', ... }] }`), we\n * flatten that wrapper into its plain form. A composition with a single member is equivalent to that member, so\n * keeping the composition keyword only makes the items render through an extra schema layer, which adds an\n * unnecessary level of nesting and duplicates the item description. See https://github.com/scalar/scalar/issues/5900\n */\nconst resolvedArrayItems = computed(() => {\n const value = arrayValueWithBoundItems.value\n if (!value || !isArraySchema(value) || typeof value.items !== 'object') {\n return undefined\n }\n\n const items = resolve.schema(value.items)\n const hasSingleItemComposition = SINGLE_ITEM_COMPOSITIONS.some(\n (keyword) =>\n Array.isArray(items?.[keyword]) && items[keyword]?.length === 1,\n )\n\n return hasSingleItemComposition ? optimizeValueForDisplay(items) : items\n})\n\n/**\n * Cycle key for the array items schema, derived from the raw (unresolved) items\n * so a self-referential array element is detected as a cycle.\n */\nconst arrayItemsCycleKey = computed(() => {\n const value = optimizedValue.value\n if (!value || !isArraySchema(value)) {\n return undefined\n }\n return getCycleKey(value.items)\n})\n\n/** Check if discriminator matches current property */\nconst isDiscriminatorProperty = computed(() =>\n Boolean(props.name && props.discriminator?.propertyName === props.name),\n)\n</script>\n<template>\n <component\n :is=\"is ?? 'li'\"\n class=\"property\"\n :class=\"[\n `property--level-${level}`,\n {\n 'property--compact': compact,\n 'property--deprecated': optimizedValue?.deprecated,\n },\n ]\">\n <SchemaPropertyHeading\n v-if=\"shouldDisplayHeadingComputed\"\n class=\"group\"\n :enum=\"hasEnum\"\n :eventBus=\"eventBus\"\n :hideModelNames\n :isDiscriminator=\"isDiscriminatorProperty\"\n :modelName=\"modelName\"\n :propertyNames=\"propertyNamesSchema\"\n :required\n :value=\"optimizedValue\">\n <template\n v-if=\"name\"\n #name>\n <WithBreadcrumb\n :breadcrumb=\"shouldHaveLink ? childBreadcrumb : undefined\"\n :eventBus=\"eventBus\">\n <span\n v-if=\"variant === 'patternProperties'\"\n class=\"property-name-pattern-properties\">\n <ScalarWrappingText\n preset=\"property\"\n :text=\"name\" />\n </span>\n <span\n v-else-if=\"variant === 'additionalProperties'\"\n class=\"property-name-additional-properties\">\n <ScalarWrappingText\n preset=\"property\"\n :text=\"name\" />\n </span>\n <ScalarWrappingText\n v-else\n preset=\"property\"\n :text=\"name\" />\n </WithBreadcrumb>\n </template>\n <template\n v-if=\"optimizedValue?.example !== undefined\"\n #example>\n Example:\n {{ optimizedValue.example }}\n </template>\n </SchemaPropertyHeading>\n\n <!-- Description -->\n <div\n v-if=\"displayDescription || propertyDescription\"\n class=\"property-description\">\n <ScalarMarkdown\n :value=\"displayDescription || propertyDescription || ''\" />\n </div>\n\n <!-- Enum for property names -->\n <SchemaEnums\n v-if=\"propertyNamesEnum && propertyNamesEnum.length > 0\"\n propertyNames\n :value=\"{ enum: propertyNamesEnum } as SchemaObject\" />\n\n <!-- Enum values -->\n <!-- The array items card rendered below already lists these same values. -->\n <SchemaEnums\n v-if=\"enumValues.length > 0 && !shouldRenderArrayOfObjects\"\n :value=\"optimizedValue\" />\n\n <!-- Object -->\n <div\n v-if=\"shouldRenderObjectProperties\"\n class=\"children\">\n <Schema\n :breadcrumb=\"childBreadcrumb\"\n :compact=\"compact\"\n :compositionPath=\"currentCompositionPath\"\n :cycleKey=\"cycleKey\"\n :eventBus=\"eventBus\"\n :hideModelNames\n :level=\"level + 1\"\n :name=\"name\"\n :noncollapsible=\"noncollapsible\"\n :options=\"options\"\n :schema=\"objectSchemaForChildren\"\n :schemaContext=\"schemaContext\" />\n </div>\n\n <!-- Array of objects or nested arrays -->\n <div\n v-if=\"shouldRenderArrayOfObjects && resolvedArrayItems\"\n class=\"children\">\n <Schema\n :compact=\"compact\"\n :compositionPath=\"arrayItemsCompositionPath\"\n :cycleKey=\"arrayItemsCycleKey\"\n :eventBus=\"eventBus\"\n :hideModelNames\n :level=\"level + 1\"\n :name=\"name\"\n :noncollapsible=\"noncollapsible\"\n :options=\"options\"\n :schema=\"resolve.schema(resolvedArrayItems)\"\n :schemaContext=\"schemaContext\" />\n </div>\n\n <!-- Compositions -->\n <SchemaComposition\n v-for=\"compositionData in compositionsToRender\"\n :key=\"compositionData.composition\"\n :breadcrumb=\"breadcrumb\"\n :compact=\"compact\"\n :composition=\"compositionData.composition\"\n :compositionPath=\"currentCompositionPath\"\n :discriminator=\"getCompositionDiscriminator(compositionData.composition)\"\n :eventBus=\"eventBus\"\n :hideHeading=\"hideHeading\"\n :hideModelNames\n :level=\"level\"\n :name=\"name\"\n :noncollapsible=\"noncollapsible\"\n :options=\"options\"\n :schema=\"compositionData.value\"\n :schemaContext=\"schemaContext\" />\n <SpecificationExtension :value=\"optimizedValue\" />\n </component>\n</template>\n\n<style scoped>\n.property {\n color: var(--scalar-color-1);\n display: flex;\n flex-direction: column;\n padding: 10px;\n font-size: var(--scalar-small);\n position: relative;\n}\n\n/** Remove top padding for top level schema card */\n.property.property--level-0:has(\n > .property-rule\n > .schema-card\n > .schema-properties.schema-properties-open\n > ul\n > li.property\n ) {\n padding-top: 0;\n}\n\n.property--compact.property--level-0,\n.property--compact.property--level-1 {\n padding: 10px 0;\n}\n\n.composition-panel .property.property.property.property--level-0 {\n padding: 0px;\n}\n\n.property--compact.property--level-0\n .composition-panel\n .property--compact.property--level-1 {\n padding: 8px;\n}\n\n/* if a property doesn't have a heading, remove the top padding */\n.property:has(> .property-rule:nth-of-type(1)):not(.property--compact) {\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n.property--deprecated {\n background: repeating-linear-gradient(\n -45deg,\n var(--scalar-background-2) 0,\n var(--scalar-background-2) 2px,\n transparent 2px,\n transparent 5px\n );\n background-size: 100%;\n}\n\n.property--deprecated > * {\n opacity: 0.75;\n}\n\n.property-description {\n margin-top: 6px;\n line-height: 1.4;\n font-size: var(--scalar-small);\n}\n\n.property-description:has(+ .property-rule) {\n margin-bottom: 9px;\n}\n\n:deep(.property-description) * {\n color: var(--scalar-color-2) !important;\n}\n\n.property:not(:last-of-type) {\n border-bottom: var(--scalar-border-width) solid var(--scalar-border-color);\n}\n\n.property-description + .children,\n.children + .property-rule {\n margin-top: 9px;\n}\n\n.children {\n display: flex;\n flex-direction: column;\n}\n\n.children .property--compact.property--level-1 {\n padding: 12px;\n}\n\n.property-example-value {\n all: unset;\n font-family: var(--scalar-font-code);\n padding: 6px;\n border-top: var(--scalar-border-width) solid var(--scalar-border-color);\n}\n\n.property-rule {\n border-radius: var(--scalar-radius-lg);\n display: flex;\n flex-direction: column;\n}\n\n.property--level-2 :deep(.relative > button) {\n left: -2rem;\n}\n\n.property-rule\n :deep(\n .composition-panel\n .schema-card--level-1\n > .schema-properties.schema-properties-open\n ) {\n border-radius: 0 0 var(--scalar-radius-lg) var(--scalar-radius-lg);\n}\n\n.property-rule\n :deep(.composition-panel > .schema-card > .schema-card-description) {\n padding: 10px;\n border-left: var(--scalar-border-width) solid var(--scalar-border-color);\n border-right: var(--scalar-border-width) solid var(--scalar-border-color);\n\n & + .schema-properties {\n margin-top: 0;\n }\n}\n\n.property-example {\n background: transparent;\n border: none;\n display: flex;\n flex-direction: row;\n gap: 8px;\n}\n\n.property-example-label,\n.property-example-value {\n padding: 3px 0 0 0;\n}\n\n.property-example-value {\n background: var(--scalar-background-2);\n border-top: 0;\n border-radius: var(--scalar-radius);\n padding: 3px 4px;\n}\n\n.property-name {\n font-family: var(--scalar-font-code);\n font-weight: var(--scalar-semibold);\n}\n\n.property-name-additional-properties::before,\n.property-name-pattern-properties::before {\n text-transform: uppercase;\n font-size: var(--scalar-micro);\n display: inline-block;\n padding: 2px 4px;\n border-radius: var(--scalar-radius);\n color: var(--scalar-color-1);\n border: var(--scalar-border-width) solid var(--scalar-border-color);\n background-color: var(--scalar-background-2);\n margin-right: 4px;\n}\n\n.property-name-pattern-properties::before {\n content: 'regex';\n}\n\n.property-name-additional-properties,\n.property-name-pattern-properties {\n border: 1px dashed var(--scalar-border-color);\n color: var(--scalar-color-accent);\n display: inline-block;\n padding: 2px;\n border-radius: var(--scalar-radius);\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"SchemaProperty.vue.script.js","names":[],"sources":["../../../../src/components/Content/Schema/SchemaProperty.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ScalarMarkdown } from '@scalar/components/markdown'\nimport { ScalarWrappingText } from '@scalar/components/wrapping-text'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n isDynamicRef,\n resolveDynamicRef,\n} from '@scalar/workspace-store/helpers/dynamic-ref'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type {\n DiscriminatorObject,\n SchemaObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isArraySchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\nimport { computed, type Component } from 'vue'\n\nimport { WithBreadcrumb } from '@/components/Anchor'\nimport {\n resolveDynamicSchema,\n useDynamicScope,\n} from '@/components/Content/Schema/helpers/dynamic-scope'\nimport { isTypeObject } from '@/components/Content/Schema/helpers/is-type-object'\nimport { getCycleKey } from '@/components/Content/Schema/helpers/schema-cycle'\nimport type { SchemaOptions } from '@/components/Content/Schema/types'\nimport { SpecificationExtension } from '@/features/specification-extension'\n\nimport { getCompositionsToRender } from './helpers/get-compositions-to-render'\nimport { getEnumValues } from './helpers/get-enum-values'\nimport { getPropertyDescription } from './helpers/get-property-description'\nimport { hasComplexArrayItems } from './helpers/has-complex-array-items'\nimport { optimizeValueForDisplay } from './helpers/optimize-value-for-display'\nimport type { CompositionKeyword } from './helpers/schema-composition'\nimport { shouldDisplayDescription } from './helpers/should-display-description'\nimport { shouldDisplayHeading } from './helpers/should-display-heading'\nimport Schema from './Schema.vue'\nimport SchemaComposition from './SchemaComposition.vue'\nimport SchemaEnums from './SchemaEnums.vue'\nimport SchemaPropertyHeading from './SchemaPropertyHeading.vue'\n\n/**\n * Note: We're taking in a prop called `value` which should be a JSON Schema.\n *\n * We're using `optimizeValueForDisplay` to merge null types in compositions (anyOf, allOf, oneOf, not).\n * So you should basically use the optimizedValue everywhere in the component.\n */\n\n/** Composition keywords that hold a list of schemas and can be flattened when they contain a single member. */\nconst SINGLE_ITEM_COMPOSITIONS = ['oneOf', 'anyOf', 'allOf'] as const\n\nconst props = withDefaults(\n defineProps<{\n is?: string | Component\n schema: SchemaObject | undefined\n noncollapsible?: boolean\n level?: number\n name?: string\n required?: boolean\n compact?: boolean\n discriminator?: DiscriminatorObject\n description?: string\n hideModelNames?: boolean\n hideHeading?: boolean\n /** When the root schema was resolved from a $ref, pass the ref name for display (e.g. \"Data\"). */\n modelName?: string | null\n variant?: 'additionalProperties' | 'patternProperties'\n breadcrumb?: string[]\n eventBus: WorkspaceEventBus | null\n options: SchemaOptions\n /** Enum values for property names (from JSON Schema propertyNames keyword). */\n propertyNamesEnum?: string[]\n /** Resolved propertyNames schema, used to show key constraints like `format`. */\n propertyNamesSchema?: SchemaObject\n /** When \"requestBody\", composition selection is synced with the example snippet */\n schemaContext?: string\n /** Internal path used to sync nested request body compositions with the code sample */\n compositionPath?: string[]\n /** Internal path segment for this property when building nested composition keys */\n compositionPathSegment?: string\n /** Stable identity of this property's schema, used for cycle detection. */\n cycleKey?: unknown\n }>(),\n {\n level: 0,\n required: false,\n compact: false,\n hideModelNames: false,\n },\n)\n\n/** The dynamic scope inherited from the enclosing schema resources, used to bind `$dynamicRef`s. */\nconst dynamicScope = useDynamicScope()\n\n/**\n * Simplified composition with `null` type.\n *\n * A top-level `$dynamicRef` (e.g. a linked-list `next` node) is bound to its concrete type via the\n * dynamic scope first; for ordinary schemas this is a no-op.\n */\nconst optimizedValue = computed(() =>\n optimizeValueForDisplay(resolveDynamicSchema(props.schema, dynamicScope)),\n)\n\nconst childBreadcrumb = computed<string[] | undefined>(() =>\n props.breadcrumb\n ? // A named property extends the breadcrumb with its own name. A nameless\n // container (e.g. a response object, rendered without a name to avoid a\n // duplicate heading) passes its breadcrumb straight through so its\n // properties stay linkable.\n props.name\n ? [...props.breadcrumb, props.name]\n : props.breadcrumb\n : undefined,\n)\n\nconst currentCompositionPath = computed<string[]>(() =>\n props.compositionPathSegment\n ? [...(props.compositionPath ?? []), props.compositionPathSegment]\n : (props.compositionPath ?? []),\n)\n\nconst arrayItemsCompositionPath = computed<string[]>(() => [\n ...currentCompositionPath.value,\n 'items',\n])\n\nconst shouldHaveLink = computed(() => props.level <= 2)\n\n/**\n * The array schema used for item inspection, with a `$dynamicRef` item bound to its concrete type.\n *\n * Returns the schema unchanged unless `items` is a `$dynamicRef` that resolves against the dynamic\n * scope, so ordinary arrays (including `$ref` items) keep their existing behavior exactly.\n */\nconst arrayValueWithBoundItems = computed(() => {\n const value = optimizedValue.value\n if (!value || !isArraySchema(value) || !isDynamicRef(value.items)) {\n return value\n }\n\n const bound = resolveDynamicRef(value.items.$dynamicRef, dynamicScope)\n return bound ? ({ ...value, items: bound } as SchemaObject) : value\n})\n\n/** Checks if array items have complex structure */\nconst hasComplexArrayItemsComputed = computed(() =>\n hasComplexArrayItems(arrayValueWithBoundItems.value),\n)\n\n/** Check if enum should be displayed (from value schema or from propertyNames) */\nconst hasEnum = computed(() => enumValues.value.length > 0)\n\n/** Determine if object properties should be displayed */\nconst shouldRenderObjectProperties = computed(() => {\n const value = optimizedValue.value\n if (!value) {\n return false\n }\n\n if (!('properties' in value || 'additionalProperties' in value)) {\n return false\n }\n\n // `allOf` already merges the factored-out sibling `properties` into its\n // rendered result (see `mergeAllOfSchemas`), so rendering a separate object\n // block here would show those properties twice. Let the composition handle it.\n if ('allOf' in value) {\n return false\n }\n\n // A schema may factor its common `properties` out to the top level alongside\n // a composition keyword (anyOf/oneOf/not), as described in the JSON Schema\n // \"factoring schemas\" guide. `isTypeObject` deliberately rejects such schemas\n // so the composition is rendered, but the factored-out properties must still\n // show. Unlike `allOf`, these compositions do not merge sibling properties.\n // Render them unless the schema is an explicit non-object (scalar or array)\n // type. See https://github.com/scalar/scalar/issues/8593\n const type = (value as { type?: unknown }).type\n const isExplicitNonObject = typeof type === 'string' && type !== 'object'\n\n return isTypeObject(value) || !isExplicitNonObject\n})\n\n/** Determine if array of objects should be rendered */\nconst shouldRenderArrayOfObjects = computed(() => {\n const value = optimizedValue.value\n if (!value || !isArraySchema(value) || typeof value.items !== 'object') {\n return false\n }\n\n return hasComplexArrayItemsComputed.value\n})\n\n/** Extract enum values from schema or array items */\nconst enumValues = computed(() => getEnumValues(optimizedValue.value))\n\n/** Generate property description from type/format */\nconst propertyDescription = computed(() =>\n getPropertyDescription(optimizedValue.value),\n)\n\n/** Determine if description should be displayed */\nconst displayDescription = computed(() =>\n shouldDisplayDescription(optimizedValue.value, props.description),\n)\n\n/**\n * The schema used to render the object's own properties.\n *\n * Composition keywords are stripped so the nested object renders only its\n * properties. The compositions are rendered separately below; leaving them here\n * would route the nested `Schema` back through `SchemaProperty` and recurse.\n *\n * The `discriminator` is stripped too: its variant selector is part of the\n * composition rendered below (including the one inferred from a bare\n * `discriminator.mapping`), so keeping it here would make the nested `Schema`\n * infer and render a second, identical selector.\n *\n * When the property already renders the description, we also drop it to avoid\n * repeating it in the nested object schema card.\n */\nconst objectSchemaForChildren = computed(() => {\n const value = optimizedValue.value\n if (!value) {\n return value\n }\n\n const {\n oneOf: _oneOf,\n anyOf: _anyOf,\n allOf: _allOf,\n not: _not,\n discriminator: _discriminator,\n ...objectSchema\n } = value as Record<string, unknown>\n\n if (displayDescription.value && 'description' in objectSchema) {\n const { description: _description, ...schemaWithoutDescription } =\n objectSchema\n return schemaWithoutDescription as SchemaObject\n }\n\n return objectSchema as SchemaObject\n})\n\n/** Determine if property heading should be displayed */\nconst shouldDisplayHeadingComputed = computed(() =>\n shouldDisplayHeading(optimizedValue.value, props.name, props.required),\n)\n\n/** Computes which compositions should be rendered and with which values */\nconst compositionsToRender = computed(() =>\n getCompositionsToRender(optimizedValue.value, props.options.document),\n)\nconst getCompositionDiscriminator = (\n composition: CompositionKeyword,\n): DiscriminatorObject | undefined =>\n composition === 'allOf'\n ? (props.schema?.discriminator ?? props.discriminator)\n : props.schema?.discriminator\n\n/**\n * Get resolved array items for rendering (with any `$dynamicRef` bound to the concrete type).\n *\n * When the items are wrapped in a single-item composition (e.g. `items: { allOf: [{ type: 'object', ... }] }`), we\n * flatten that wrapper into its plain form. A composition with a single member is equivalent to that member, so\n * keeping the composition keyword only makes the items render through an extra schema layer, which adds an\n * unnecessary level of nesting and duplicates the item description. See https://github.com/scalar/scalar/issues/5900\n */\nconst resolvedArrayItems = computed(() => {\n const value = arrayValueWithBoundItems.value\n if (!value || !isArraySchema(value) || typeof value.items !== 'object') {\n return undefined\n }\n\n const items = resolve.schema(value.items)\n const hasSingleItemComposition = SINGLE_ITEM_COMPOSITIONS.some(\n (keyword) =>\n Array.isArray(items?.[keyword]) && items[keyword]?.length === 1,\n )\n\n return hasSingleItemComposition ? optimizeValueForDisplay(items) : items\n})\n\n/**\n * Cycle key for the array items schema, derived from the raw (unresolved) items\n * so a self-referential array element is detected as a cycle.\n */\nconst arrayItemsCycleKey = computed(() => {\n const value = optimizedValue.value\n if (!value || !isArraySchema(value)) {\n return undefined\n }\n return getCycleKey(value.items)\n})\n\n/** Check if discriminator matches current property */\nconst isDiscriminatorProperty = computed(() =>\n Boolean(props.name && props.discriminator?.propertyName === props.name),\n)\n</script>\n<template>\n <component\n :is=\"is ?? 'li'\"\n class=\"property\"\n :class=\"[\n `property--level-${level}`,\n {\n 'property--compact': compact,\n 'property--deprecated': optimizedValue?.deprecated,\n },\n ]\">\n <SchemaPropertyHeading\n v-if=\"shouldDisplayHeadingComputed\"\n class=\"group\"\n :enum=\"hasEnum\"\n :eventBus=\"eventBus\"\n :hideModelNames\n :isDiscriminator=\"isDiscriminatorProperty\"\n :modelLinkOptions=\"{\n hideModels: options.hideModels,\n document: options.document,\n }\"\n :modelName=\"modelName\"\n :propertyNames=\"propertyNamesSchema\"\n :required\n :value=\"optimizedValue\">\n <template\n v-if=\"name\"\n #name>\n <WithBreadcrumb\n :breadcrumb=\"shouldHaveLink ? childBreadcrumb : undefined\"\n :eventBus=\"eventBus\">\n <span\n v-if=\"variant === 'patternProperties'\"\n class=\"property-name-pattern-properties\">\n <ScalarWrappingText\n preset=\"property\"\n :text=\"name\" />\n </span>\n <span\n v-else-if=\"variant === 'additionalProperties'\"\n class=\"property-name-additional-properties\">\n <ScalarWrappingText\n preset=\"property\"\n :text=\"name\" />\n </span>\n <ScalarWrappingText\n v-else\n preset=\"property\"\n :text=\"name\" />\n </WithBreadcrumb>\n </template>\n <template\n v-if=\"optimizedValue?.example !== undefined\"\n #example>\n Example:\n {{ optimizedValue.example }}\n </template>\n </SchemaPropertyHeading>\n\n <!-- Description -->\n <div\n v-if=\"displayDescription || propertyDescription\"\n class=\"property-description\">\n <ScalarMarkdown\n :value=\"displayDescription || propertyDescription || ''\" />\n </div>\n\n <!-- Enum for property names -->\n <SchemaEnums\n v-if=\"propertyNamesEnum && propertyNamesEnum.length > 0\"\n propertyNames\n :value=\"{ enum: propertyNamesEnum } as SchemaObject\" />\n\n <!-- Enum values -->\n <!-- The array items card rendered below already lists these same values. -->\n <SchemaEnums\n v-if=\"enumValues.length > 0 && !shouldRenderArrayOfObjects\"\n :value=\"optimizedValue\" />\n\n <!-- Object -->\n <div\n v-if=\"shouldRenderObjectProperties\"\n class=\"children\">\n <Schema\n :breadcrumb=\"childBreadcrumb\"\n :compact=\"compact\"\n :compositionPath=\"currentCompositionPath\"\n :cycleKey=\"cycleKey\"\n :eventBus=\"eventBus\"\n :hideModelNames\n :level=\"level + 1\"\n :name=\"name\"\n :noncollapsible=\"noncollapsible\"\n :options=\"options\"\n :schema=\"objectSchemaForChildren\"\n :schemaContext=\"schemaContext\" />\n </div>\n\n <!-- Array of objects or nested arrays -->\n <div\n v-if=\"shouldRenderArrayOfObjects && resolvedArrayItems\"\n class=\"children\">\n <Schema\n :compact=\"compact\"\n :compositionPath=\"arrayItemsCompositionPath\"\n :cycleKey=\"arrayItemsCycleKey\"\n :eventBus=\"eventBus\"\n :hideModelNames\n :level=\"level + 1\"\n :name=\"name\"\n :noncollapsible=\"noncollapsible\"\n :options=\"options\"\n :schema=\"resolve.schema(resolvedArrayItems)\"\n :schemaContext=\"schemaContext\" />\n </div>\n\n <!-- Compositions -->\n <SchemaComposition\n v-for=\"compositionData in compositionsToRender\"\n :key=\"compositionData.composition\"\n :breadcrumb=\"breadcrumb\"\n :compact=\"compact\"\n :composition=\"compositionData.composition\"\n :compositionPath=\"currentCompositionPath\"\n :discriminator=\"getCompositionDiscriminator(compositionData.composition)\"\n :eventBus=\"eventBus\"\n :hideHeading=\"hideHeading\"\n :hideModelNames\n :level=\"level\"\n :name=\"name\"\n :noncollapsible=\"noncollapsible\"\n :options=\"options\"\n :schema=\"compositionData.value\"\n :schemaContext=\"schemaContext\" />\n <SpecificationExtension :value=\"optimizedValue\" />\n </component>\n</template>\n\n<style scoped>\n.property {\n color: var(--scalar-color-1);\n display: flex;\n flex-direction: column;\n padding: 10px;\n font-size: var(--scalar-small);\n position: relative;\n}\n\n/** Remove top padding for top level schema card */\n.property.property--level-0:has(\n > .property-rule\n > .schema-card\n > .schema-properties.schema-properties-open\n > ul\n > li.property\n ) {\n padding-top: 0;\n}\n\n.property--compact.property--level-0,\n.property--compact.property--level-1 {\n padding: 10px 0;\n}\n\n.composition-panel .property.property.property.property--level-0 {\n padding: 0px;\n}\n\n.property--compact.property--level-0\n .composition-panel\n .property--compact.property--level-1 {\n padding: 8px;\n}\n\n/* if a property doesn't have a heading, remove the top padding */\n.property:has(> .property-rule:nth-of-type(1)):not(.property--compact) {\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n.property--deprecated {\n background: repeating-linear-gradient(\n -45deg,\n var(--scalar-background-2) 0,\n var(--scalar-background-2) 2px,\n transparent 2px,\n transparent 5px\n );\n background-size: 100%;\n}\n\n.property--deprecated > * {\n opacity: 0.75;\n}\n\n.property-description {\n margin-top: 6px;\n line-height: 1.4;\n font-size: var(--scalar-small);\n}\n\n.property-description:has(+ .property-rule) {\n margin-bottom: 9px;\n}\n\n:deep(.property-description) * {\n color: var(--scalar-color-2) !important;\n}\n\n.property:not(:last-of-type) {\n border-bottom: var(--scalar-border-width) solid var(--scalar-border-color);\n}\n\n.property-description + .children,\n.children + .property-rule {\n margin-top: 9px;\n}\n\n.children {\n display: flex;\n flex-direction: column;\n}\n\n.children .property--compact.property--level-1 {\n padding: 12px;\n}\n\n.property-example-value {\n all: unset;\n font-family: var(--scalar-font-code);\n padding: 6px;\n border-top: var(--scalar-border-width) solid var(--scalar-border-color);\n}\n\n.property-rule {\n border-radius: var(--scalar-radius-lg);\n display: flex;\n flex-direction: column;\n}\n\n.property--level-2 :deep(.relative > button) {\n left: -2rem;\n}\n\n.property-rule\n :deep(\n .composition-panel\n .schema-card--level-1\n > .schema-properties.schema-properties-open\n ) {\n border-radius: 0 0 var(--scalar-radius-lg) var(--scalar-radius-lg);\n}\n\n.property-rule\n :deep(.composition-panel > .schema-card > .schema-card-description) {\n padding: 10px;\n border-left: var(--scalar-border-width) solid var(--scalar-border-color);\n border-right: var(--scalar-border-width) solid var(--scalar-border-color);\n\n & + .schema-properties {\n margin-top: 0;\n }\n}\n\n.property-example {\n background: transparent;\n border: none;\n display: flex;\n flex-direction: row;\n gap: 8px;\n}\n\n.property-example-label,\n.property-example-value {\n padding: 3px 0 0 0;\n}\n\n.property-example-value {\n background: var(--scalar-background-2);\n border-top: 0;\n border-radius: var(--scalar-radius);\n padding: 3px 4px;\n}\n\n.property-name {\n font-family: var(--scalar-font-code);\n font-weight: var(--scalar-semibold);\n}\n\n.property-name-additional-properties::before,\n.property-name-pattern-properties::before {\n text-transform: uppercase;\n font-size: var(--scalar-micro);\n display: inline-block;\n padding: 2px 4px;\n border-radius: var(--scalar-radius);\n color: var(--scalar-color-1);\n border: var(--scalar-border-width) solid var(--scalar-border-color);\n background-color: var(--scalar-background-2);\n margin-right: 4px;\n}\n\n.property-name-pattern-properties::before {\n content: 'regex';\n}\n\n.property-name-additional-properties,\n.property-name-pattern-properties {\n border: 1px dashed var(--scalar-border-color);\n color: var(--scalar-color-accent);\n display: inline-block;\n padding: 2px;\n border-radius: var(--scalar-radius);\n}\n</style>\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { WorkspaceEventBus } from '@scalar/workspace-store/events';
2
2
  import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
3
+ import { type ModelLinkOptions } from './helpers/is-model-linkable.js';
3
4
  type __VLS_Props = {
4
5
  value: SchemaObject | undefined;
5
6
  enum?: boolean;
@@ -8,6 +9,11 @@ type __VLS_Props = {
8
9
  additional?: boolean;
9
10
  withExamples?: boolean;
10
11
  hideModelNames?: boolean;
12
+ /**
13
+ * Config for deciding whether a model name links to the models section. When the section or
14
+ * the referenced model is hidden there is nothing to scroll to, so the name renders as plain text.
15
+ */
16
+ modelLinkOptions?: ModelLinkOptions;
11
17
  /** When the schema was resolved from a $ref, pass the ref name so it displays as e.g. "Data" instead of "object". */
12
18
  modelName?: string | null;
13
19
  /** Resolved propertyNames schema, used to surface key constraints like `format` for additional properties. */
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaPropertyHeading.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/Content/Schema/SchemaPropertyHeading.vue"],"names":[],"mappings":"AAugBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAoBhG,KAAK,WAAW,GAAG;IACf,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,qHAAqH;IACrH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,8GAA8G;IAC9G,aAAa,CAAC,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;CACpC,CAAC;AAqnBJ,QAAA,IAAI,OAAO,IAAW,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAK5C,QAAA,MAAM,UAAU;cAroBD,OAAO;cAQP,iBAAiB,GAAG,IAAI;oBALlB,OAAO;qBAJN,OAAO;kBAGV,OAAO;6EAsoBxB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"SchemaPropertyHeading.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/Content/Schema/SchemaPropertyHeading.vue"],"names":[],"mappings":"AAqhBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAA;AAchG,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,6BAA6B,CAAA;AAOpC,KAAK,WAAW,GAAG;IACf,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,qHAAqH;IACrH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,8GAA8G;IAC9G,aAAa,CAAC,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;CACpC,CAAC;AA2nBJ,QAAA,IAAI,OAAO,IAAW,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAK5C,QAAA,MAAM,UAAU;cAhpBD,OAAO;cAaP,iBAAiB,GAAG,IAAI;oBAVlB,OAAO;qBAJN,OAAO;kBAGV,OAAO;6EAipBxB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../_virtual/_plugin-vue_exp
2
2
  import SchemaPropertyHeading_vue_vue_type_script_setup_true_lang_default from "./SchemaPropertyHeading.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/components/Content/Schema/SchemaPropertyHeading.vue
5
- var SchemaPropertyHeading_default = /*#__PURE__*/ _plugin_vue_export_helper_default(SchemaPropertyHeading_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-74d321d3"]]);
5
+ var SchemaPropertyHeading_default = /*#__PURE__*/ _plugin_vue_export_helper_default(SchemaPropertyHeading_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-9f90ca8e"]]);
6
6
  //#endregion
7
7
  export { SchemaPropertyHeading_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaPropertyHeading.vue.js","names":[],"sources":["../../../../src/components/Content/Schema/SchemaPropertyHeading.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n isArraySchema,\n isNumberSchema,\n isStringSchema,\n} from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\nimport { computed, toRef } from 'vue'\n\nimport { Badge } from '@/components/Badge'\nimport LinkButton from '@/components/Content/Schema/LinkButton.vue'\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport { useLocalization } from '@/features/localization'\n\nimport { getSchemaType } from './helpers/get-schema-type'\nimport { getModelNameFromSchema } from './helpers/schema-name'\nimport RenderString from './RenderString.vue'\nimport SchemaPropertyDefault from './SchemaPropertyDefault.vue'\nimport SchemaPropertyDetail from './SchemaPropertyDetail.vue'\nimport SchemaPropertyExamples from './SchemaPropertyExamples.vue'\n\nconst props = withDefaults(\n defineProps<{\n value: SchemaObject | undefined\n enum?: boolean\n isDiscriminator?: boolean\n required?: boolean\n additional?: boolean\n withExamples?: boolean\n hideModelNames?: boolean\n /** When the schema was resolved from a $ref, pass the ref name so it displays as e.g. \"Data\" instead of \"object\". */\n modelName?: string | null\n /** Resolved propertyNames schema, used to surface key constraints like `format` for additional properties. */\n propertyNames?: SchemaObject\n eventBus?: WorkspaceEventBus | null\n }>(),\n {\n isDiscriminator: false,\n required: false,\n withExamples: true,\n hideModelNames: false,\n eventBus: null,\n },\n)\nconst { translate } = useLocalization()\n\n// Convert to reactive refs for composables\nconst valueRef = toRef(props, 'value')\n\nconst constValue = computed(() => {\n if (!valueRef.value) {\n return undefined\n }\n\n const schema = valueRef.value\n\n // Direct const value\n if (schema.const !== undefined) {\n return schema.const\n }\n\n // Single-item enum acts as const\n if (schema.enum?.length === 1) {\n return schema.enum[0]\n }\n\n // Check items for const values (for arrays)\n if (isArraySchema(schema) && schema.items) {\n const items = resolve.schema(schema.items)\n\n if (isDefined(items.const)) {\n return items.const\n }\n\n if (items.enum?.length === 1) {\n return items.enum[0]\n }\n }\n\n return undefined\n})\n\ntype ValidationProperty = {\n key: string\n value: string | number\n prefix?: string\n code?: boolean\n truncate?: boolean\n}\n\n/**\n * Constraints that live on a leaf (string or number) schema: length, pattern,\n * format and numeric ranges. Extracted so they can be surfaced for a primitive\n * schema as well as for a primitive array's items, which are not rendered on\n * their own. See https://github.com/scalar/scalar/issues/9690\n */\nconst getLeafConstraints = (schema: SchemaObject) => {\n const properties: ValidationProperty[] = []\n\n if (isStringSchema(schema)) {\n if (schema.minLength) {\n properties.push({\n key: 'min-length',\n prefix: `${translate('common.minLength')}: `,\n value: schema.minLength,\n })\n }\n\n if (schema.maxLength) {\n properties.push({\n key: 'max-length',\n prefix: `${translate('common.maxLength')}: `,\n value: schema.maxLength,\n })\n }\n\n if (schema.pattern) {\n properties.push({\n key: 'pattern',\n value: schema.pattern,\n code: true,\n truncate: true,\n })\n }\n }\n\n if ((isStringSchema(schema) || isNumberSchema(schema)) && schema.format) {\n properties.push({\n key: 'format',\n value: schema.format,\n truncate: true,\n })\n }\n\n if (isNumberSchema(schema)) {\n if (isDefined(schema.exclusiveMinimum)) {\n properties.push({\n key: 'exclusive-minimum',\n prefix: `${translate('common.greaterThan')}: `,\n value: schema.exclusiveMinimum,\n })\n }\n\n if (isDefined(schema.minimum)) {\n properties.push({\n key: 'minimum',\n prefix: `${translate('common.min')}: `,\n value: schema.minimum,\n })\n }\n\n if (isDefined(schema.exclusiveMaximum)) {\n properties.push({\n key: 'exclusive-maximum',\n prefix: `${translate('common.lessThan')}: `,\n value: schema.exclusiveMaximum,\n })\n }\n\n if (isDefined(schema.maximum)) {\n properties.push({\n key: 'maximum',\n prefix: `${translate('common.max')}: `,\n value: schema.maximum,\n })\n }\n\n if (isDefined(schema.multipleOf)) {\n properties.push({\n key: 'multiple-of',\n prefix: `${translate('common.multipleOf')}: `,\n value: schema.multipleOf,\n })\n }\n }\n\n return properties\n}\n\nconst validationProperties = computed(() => {\n if (!valueRef.value) {\n return []\n }\n\n const schema = valueRef.value\n const properties: ValidationProperty[] = []\n\n // Array validation properties\n if (isArraySchema(schema)) {\n if (schema.minItems || schema.maxItems) {\n properties.push({\n key: 'array-range',\n value: `${schema.minItems || ''}…${schema.maxItems || ''}`,\n })\n }\n\n // Unique items\n if (schema.uniqueItems) {\n properties.push({\n key: 'unique-items',\n value: `${translate('common.unique')}!`,\n })\n }\n }\n\n properties.push(...getLeafConstraints(schema))\n\n // Primitive array items carry their own constraints (e.g. an array of `uuid`\n // strings) but are not rendered separately, so surface them here.\n if (isArraySchema(schema) && schema.items) {\n properties.push(...getLeafConstraints(resolve.schema(schema.items)))\n }\n\n return properties\n})\n\n/** Link data for navigating to the referenced model in the sidebar. */\nconst modelLink = computed(() => {\n if (!props.value) {\n return null\n }\n\n if (props.hideModelNames) {\n return null\n }\n\n if (props.modelName) {\n return { schemaKey: props.modelName, label: props.modelName }\n }\n\n const modelName = getModelNameFromSchema(props.value)\n if (modelName) {\n return { schemaKey: modelName.schemaKey, label: modelName.label }\n }\n\n if (isArraySchema(props.value) && props.value.items) {\n const itemName = getModelNameFromSchema(props.value.items)\n return itemName\n ? { schemaKey: itemName.schemaKey, label: `${itemName.label}[]` }\n : null\n }\n\n return null\n})\n\n/** Check if we should show the type information */\nconst shouldShowType = computed(() => {\n if (!props.value || !('type' in props.value)) {\n return false\n }\n\n // Always show type for arrays, even when items have const values\n if (props.value.type === 'array') {\n return true\n }\n\n // For non-arrays, only show if no const value at the schema level\n return !constValue.value\n})\n\n/** Get the display type */\nconst displayType = computed(() => {\n if (!props.value) {\n return ''\n }\n return getSchemaType(props.value)\n})\n\n/**\n * Type and format of the property keys, derived from the propertyNames schema.\n *\n * For a map keyed by UUIDs this renders e.g. \"string · uuid\" so the key\n * constraints are not lost. Returns undefined when there is nothing to show.\n */\nconst propertyNamesDetail = computed(() => {\n const schema = props.propertyNames\n if (!schema) {\n return undefined\n }\n\n const parts = [getSchemaType(schema)]\n if ('format' in schema && typeof schema.format === 'string') {\n parts.push(schema.format)\n }\n\n const detail = parts.filter(Boolean).join(' · ')\n return detail.length > 0 ? detail : undefined\n})\n\nconst exampleValue = computed(() => {\n // Treat only `undefined` as \"not set\" — `null` is a valid example value on a nullable schema.\n if (\n props.value &&\n 'example' in props.value &&\n props.value.example !== undefined\n ) {\n return props.value.example\n }\n\n if (props.value && isArraySchema(props.value)) {\n const itemsSchema = resolve.schema(props.value.items)\n if (\n itemsSchema &&\n 'example' in itemsSchema &&\n itemsSchema.example !== undefined\n ) {\n return itemsSchema.example\n }\n }\n\n return undefined\n})\n</script>\n<template>\n <div class=\"property-heading\">\n <div\n v-if=\"$slots.name\"\n class=\"property-name\"\n :class=\"{ deprecated: props.value?.deprecated }\">\n <slot name=\"name\" />\n </div>\n <div\n v-if=\"props.isDiscriminator\"\n class=\"property-discriminator\">\n {{ translate('common.discriminator') }}\n </div>\n <template v-if=\"props.value\">\n <!-- Type information -->\n <SchemaPropertyDetail\n v-if=\"shouldShowType\"\n truncate>\n <ScreenReader>{{ translate('common.type') }}:</ScreenReader>\n {{ displayType }}\n <template v-if=\"modelLink\">\n ·\n <LinkButton\n v-if=\"props.eventBus && modelLink.schemaKey\"\n @click=\"\n props.eventBus.emit('scroll-to:model-by-name', {\n name: modelLink.schemaKey,\n })\n \">\n {{ modelLink.label }}\n </LinkButton>\n <template v-else>{{ modelLink.label }}</template>\n </template>\n </SchemaPropertyDetail>\n\n <!-- Key constraints from propertyNames (e.g. \"keys: string · uuid\") -->\n <SchemaPropertyDetail\n v-if=\"propertyNamesDetail\"\n truncate>\n <template #prefix>{{ translate('common.keys') }}:</template>\n {{ propertyNamesDetail }}\n </SchemaPropertyDetail>\n\n <!-- Dynamic validation properties from composable -->\n <SchemaPropertyDetail\n v-for=\"property in validationProperties\"\n :key=\"property.key\"\n :code=\"property.code\"\n :truncate=\"property.truncate\">\n <ScreenReader v-if=\"property.key === 'format'\">\n {{ translate('common.format') }}:\n </ScreenReader>\n <ScreenReader v-else-if=\"property.key === 'pattern'\">\n {{ translate('common.pattern') }}:\n </ScreenReader>\n <template\n v-if=\"property.prefix\"\n #prefix>\n {{ property.prefix }}\n </template>\n {{ property.value }}\n </SchemaPropertyDetail>\n\n <!-- Enum indicator -->\n <SchemaPropertyDetail v-if=\"props.enum\">\n {{ translate('common.enum') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.additional\"\n class=\"property-additional\">\n <template v-if=\"props.value?.['x-additionalPropertiesName']\">\n {{ props.value['x-additionalPropertiesName'] }}\n </template>\n <template v-else>{{ translate('common.additionalProperties') }}</template>\n </div>\n <div\n v-if=\"props.value?.deprecated\"\n class=\"property-deprecated\">\n <Badge>{{ translate('common.deprecated') }}</Badge>\n </div>\n <!-- Don't use `isDefined` here, we want to show `const` when the value is `null` -->\n <div\n v-if=\"constValue !== undefined\"\n class=\"property-const\">\n <SchemaPropertyDetail truncate>\n <template #prefix>{{ translate('common.const') }}: </template>\n <RenderString :value=\"constValue\" />\n </SchemaPropertyDetail>\n </div>\n <template v-else>\n <!-- Shows only when a composition is used (so props.value?.type is undefined) -->\n <SchemaPropertyDetail v-if=\"(props.value as any)?.nullable === true\">\n {{ translate('common.nullable') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.value?.writeOnly\"\n class=\"property-write-only\">\n {{ translate('common.writeOnly') }}\n </div>\n <div\n v-else-if=\"props.value?.readOnly\"\n class=\"property-read-only\">\n {{ translate('common.readOnly') }}\n </div>\n <div\n v-if=\"props.required\"\n class=\"property-required\">\n {{ translate('common.required') }}\n </div>\n <SchemaPropertyDefault :value=\"props.value?.default\" />\n <SchemaPropertyExamples\n v-if=\"props.withExamples\"\n :example=\"exampleValue\"\n :examples=\"props.value?.examples\" />\n </div>\n</template>\n<style scoped>\n.property-heading {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n row-gap: 9px;\n white-space: nowrap;\n}\n\n.property-heading:has(+ .children),\n.property-heading:has(+ .property-rule) {\n margin-bottom: 9px;\n}\n\n.property-heading > * {\n margin-right: 9px;\n}\n\n.property-heading:last-child {\n margin-right: 0;\n}\n\n.property-heading > .property-detail:not(:last-of-type) {\n margin-right: 0;\n}\n\n.property-name {\n max-width: 100%;\n font-family: var(--scalar-font-code);\n font-weight: var(--scalar-bold);\n font-size: var(--scalar-font-size-4);\n white-space: normal;\n overflow-wrap: break-word;\n}\n\n.property-additional {\n font-family: var(--scalar-font-code);\n}\n\n.property-required,\n.property-optional {\n color: var(--scalar-color-2);\n}\n\n.property-required {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-orange);\n}\n\n.property-read-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-blue);\n}\n\n.property-write-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-green);\n}\n\n.property-discriminator {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-purple);\n}\n\n.property-detail {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-2);\n display: flex;\n align-items: center;\n\n min-width: 0;\n}\n\n.property-const {\n color: var(--scalar-color-1);\n}\n\n.deprecated {\n text-decoration: line-through;\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"SchemaPropertyHeading.vue.js","names":[],"sources":["../../../../src/components/Content/Schema/SchemaPropertyHeading.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n isArraySchema,\n isNumberSchema,\n isStringSchema,\n} from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\nimport { computed, toRef } from 'vue'\n\nimport { Badge } from '@/components/Badge'\nimport LinkButton from '@/components/Content/Schema/LinkButton.vue'\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport { useLocalization } from '@/features/localization'\n\nimport { getSchemaType } from './helpers/get-schema-type'\nimport {\n isModelLinkable,\n type ModelLinkOptions,\n} from './helpers/is-model-linkable'\nimport { getModelNameFromSchema } from './helpers/schema-name'\nimport RenderString from './RenderString.vue'\nimport SchemaPropertyDefault from './SchemaPropertyDefault.vue'\nimport SchemaPropertyDetail from './SchemaPropertyDetail.vue'\nimport SchemaPropertyExamples from './SchemaPropertyExamples.vue'\n\nconst props = withDefaults(\n defineProps<{\n value: SchemaObject | undefined\n enum?: boolean\n isDiscriminator?: boolean\n required?: boolean\n additional?: boolean\n withExamples?: boolean\n hideModelNames?: boolean\n /**\n * Config for deciding whether a model name links to the models section. When the section or\n * the referenced model is hidden there is nothing to scroll to, so the name renders as plain text.\n */\n modelLinkOptions?: ModelLinkOptions\n /** When the schema was resolved from a $ref, pass the ref name so it displays as e.g. \"Data\" instead of \"object\". */\n modelName?: string | null\n /** Resolved propertyNames schema, used to surface key constraints like `format` for additional properties. */\n propertyNames?: SchemaObject\n eventBus?: WorkspaceEventBus | null\n }>(),\n {\n isDiscriminator: false,\n required: false,\n withExamples: true,\n hideModelNames: false,\n eventBus: null,\n },\n)\nconst { translate } = useLocalization()\n\n// Convert to reactive refs for composables\nconst valueRef = toRef(props, 'value')\n\nconst constValue = computed(() => {\n if (!valueRef.value) {\n return undefined\n }\n\n const schema = valueRef.value\n\n // Direct const value\n if (schema.const !== undefined) {\n return schema.const\n }\n\n // Single-item enum acts as const\n if (schema.enum?.length === 1) {\n return schema.enum[0]\n }\n\n // Check items for const values (for arrays)\n if (isArraySchema(schema) && schema.items) {\n const items = resolve.schema(schema.items)\n\n if (isDefined(items.const)) {\n return items.const\n }\n\n if (items.enum?.length === 1) {\n return items.enum[0]\n }\n }\n\n return undefined\n})\n\ntype ValidationProperty = {\n key: string\n value: string | number\n prefix?: string\n code?: boolean\n truncate?: boolean\n}\n\n/**\n * Constraints that live on a leaf (string or number) schema: length, pattern,\n * format and numeric ranges. Extracted so they can be surfaced for a primitive\n * schema as well as for a primitive array's items, which are not rendered on\n * their own. See https://github.com/scalar/scalar/issues/9690\n */\nconst getLeafConstraints = (schema: SchemaObject) => {\n const properties: ValidationProperty[] = []\n\n if (isStringSchema(schema)) {\n if (schema.minLength) {\n properties.push({\n key: 'min-length',\n prefix: `${translate('common.minLength')}: `,\n value: schema.minLength,\n })\n }\n\n if (schema.maxLength) {\n properties.push({\n key: 'max-length',\n prefix: `${translate('common.maxLength')}: `,\n value: schema.maxLength,\n })\n }\n\n if (schema.pattern) {\n properties.push({\n key: 'pattern',\n value: schema.pattern,\n code: true,\n truncate: true,\n })\n }\n }\n\n if ((isStringSchema(schema) || isNumberSchema(schema)) && schema.format) {\n properties.push({\n key: 'format',\n value: schema.format,\n truncate: true,\n })\n }\n\n if (isNumberSchema(schema)) {\n if (isDefined(schema.exclusiveMinimum)) {\n properties.push({\n key: 'exclusive-minimum',\n prefix: `${translate('common.greaterThan')}: `,\n value: schema.exclusiveMinimum,\n })\n }\n\n if (isDefined(schema.minimum)) {\n properties.push({\n key: 'minimum',\n prefix: `${translate('common.min')}: `,\n value: schema.minimum,\n })\n }\n\n if (isDefined(schema.exclusiveMaximum)) {\n properties.push({\n key: 'exclusive-maximum',\n prefix: `${translate('common.lessThan')}: `,\n value: schema.exclusiveMaximum,\n })\n }\n\n if (isDefined(schema.maximum)) {\n properties.push({\n key: 'maximum',\n prefix: `${translate('common.max')}: `,\n value: schema.maximum,\n })\n }\n\n if (isDefined(schema.multipleOf)) {\n properties.push({\n key: 'multiple-of',\n prefix: `${translate('common.multipleOf')}: `,\n value: schema.multipleOf,\n })\n }\n }\n\n return properties\n}\n\nconst validationProperties = computed(() => {\n if (!valueRef.value) {\n return []\n }\n\n const schema = valueRef.value\n const properties: ValidationProperty[] = []\n\n // Array validation properties\n if (isArraySchema(schema)) {\n if (schema.minItems || schema.maxItems) {\n properties.push({\n key: 'array-range',\n value: `${schema.minItems || ''}…${schema.maxItems || ''}`,\n })\n }\n\n // Unique items\n if (schema.uniqueItems) {\n properties.push({\n key: 'unique-items',\n value: `${translate('common.unique')}!`,\n })\n }\n }\n\n properties.push(...getLeafConstraints(schema))\n\n // Primitive array items carry their own constraints (e.g. an array of `uuid`\n // strings) but are not rendered separately, so surface them here.\n if (isArraySchema(schema) && schema.items) {\n properties.push(...getLeafConstraints(resolve.schema(schema.items)))\n }\n\n return properties\n})\n\n/** Link data for navigating to the referenced model in the sidebar. */\nconst modelLink = computed(() => {\n if (!props.value) {\n return null\n }\n\n if (props.hideModelNames) {\n return null\n }\n\n if (props.modelName) {\n return { schemaKey: props.modelName, label: props.modelName }\n }\n\n const modelName = getModelNameFromSchema(props.value)\n if (modelName) {\n return { schemaKey: modelName.schemaKey, label: modelName.label }\n }\n\n if (isArraySchema(props.value) && props.value.items) {\n const itemName = getModelNameFromSchema(props.value.items)\n return itemName\n ? { schemaKey: itemName.schemaKey, label: `${itemName.label}[]` }\n : null\n }\n\n return null\n})\n\n/** Whether the model name links to the models section, or renders as plain text. */\nconst modelLinkable = computed(() =>\n isModelLinkable(modelLink.value?.schemaKey, props.modelLinkOptions ?? {}),\n)\n\n/** Check if we should show the type information */\nconst shouldShowType = computed(() => {\n if (!props.value || !('type' in props.value)) {\n return false\n }\n\n // Always show type for arrays, even when items have const values\n if (props.value.type === 'array') {\n return true\n }\n\n // For non-arrays, only show if no const value at the schema level\n return !constValue.value\n})\n\n/** Get the display type */\nconst displayType = computed(() => {\n if (!props.value) {\n return ''\n }\n return getSchemaType(props.value)\n})\n\n/**\n * Type and format of the property keys, derived from the propertyNames schema.\n *\n * For a map keyed by UUIDs this renders e.g. \"string · uuid\" so the key\n * constraints are not lost. Returns undefined when there is nothing to show.\n */\nconst propertyNamesDetail = computed(() => {\n const schema = props.propertyNames\n if (!schema) {\n return undefined\n }\n\n const parts = [getSchemaType(schema)]\n if ('format' in schema && typeof schema.format === 'string') {\n parts.push(schema.format)\n }\n\n const detail = parts.filter(Boolean).join(' · ')\n return detail.length > 0 ? detail : undefined\n})\n\nconst exampleValue = computed(() => {\n // Treat only `undefined` as \"not set\" — `null` is a valid example value on a nullable schema.\n if (\n props.value &&\n 'example' in props.value &&\n props.value.example !== undefined\n ) {\n return props.value.example\n }\n\n if (props.value && isArraySchema(props.value)) {\n const itemsSchema = resolve.schema(props.value.items)\n if (\n itemsSchema &&\n 'example' in itemsSchema &&\n itemsSchema.example !== undefined\n ) {\n return itemsSchema.example\n }\n }\n\n return undefined\n})\n</script>\n<template>\n <div class=\"property-heading\">\n <div\n v-if=\"$slots.name\"\n class=\"property-name\"\n :class=\"{ deprecated: props.value?.deprecated }\">\n <slot name=\"name\" />\n </div>\n <div\n v-if=\"props.isDiscriminator\"\n class=\"property-discriminator\">\n {{ translate('common.discriminator') }}\n </div>\n <template v-if=\"props.value\">\n <!-- Type information -->\n <SchemaPropertyDetail\n v-if=\"shouldShowType\"\n truncate>\n <ScreenReader>{{ translate('common.type') }}:</ScreenReader>\n {{ displayType }}\n <template v-if=\"modelLink\">\n ·\n <LinkButton\n v-if=\"props.eventBus && modelLink.schemaKey && modelLinkable\"\n @click=\"\n props.eventBus.emit('scroll-to:model-by-name', {\n name: modelLink.schemaKey,\n })\n \">\n {{ modelLink.label }}\n </LinkButton>\n <template v-else>{{ modelLink.label }}</template>\n </template>\n </SchemaPropertyDetail>\n\n <!-- Key constraints from propertyNames (e.g. \"keys: string · uuid\") -->\n <SchemaPropertyDetail\n v-if=\"propertyNamesDetail\"\n truncate>\n <template #prefix>{{ translate('common.keys') }}:</template>\n {{ propertyNamesDetail }}\n </SchemaPropertyDetail>\n\n <!-- Dynamic validation properties from composable -->\n <SchemaPropertyDetail\n v-for=\"property in validationProperties\"\n :key=\"property.key\"\n :code=\"property.code\"\n :truncate=\"property.truncate\">\n <ScreenReader v-if=\"property.key === 'format'\">\n {{ translate('common.format') }}:\n </ScreenReader>\n <ScreenReader v-else-if=\"property.key === 'pattern'\">\n {{ translate('common.pattern') }}:\n </ScreenReader>\n <template\n v-if=\"property.prefix\"\n #prefix>\n {{ property.prefix }}\n </template>\n {{ property.value }}\n </SchemaPropertyDetail>\n\n <!-- Enum indicator -->\n <SchemaPropertyDetail v-if=\"props.enum\">\n {{ translate('common.enum') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.additional\"\n class=\"property-additional\">\n <template v-if=\"props.value?.['x-additionalPropertiesName']\">\n {{ props.value['x-additionalPropertiesName'] }}\n </template>\n <template v-else>{{ translate('common.additionalProperties') }}</template>\n </div>\n <div\n v-if=\"props.value?.deprecated\"\n class=\"property-deprecated\">\n <Badge>{{ translate('common.deprecated') }}</Badge>\n </div>\n <!-- Don't use `isDefined` here, we want to show `const` when the value is `null` -->\n <div\n v-if=\"constValue !== undefined\"\n class=\"property-const\">\n <SchemaPropertyDetail truncate>\n <template #prefix>{{ translate('common.const') }}: </template>\n <RenderString :value=\"constValue\" />\n </SchemaPropertyDetail>\n </div>\n <template v-else>\n <!-- Shows only when a composition is used (so props.value?.type is undefined) -->\n <SchemaPropertyDetail v-if=\"(props.value as any)?.nullable === true\">\n {{ translate('common.nullable') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.value?.writeOnly\"\n class=\"property-write-only\">\n {{ translate('common.writeOnly') }}\n </div>\n <div\n v-else-if=\"props.value?.readOnly\"\n class=\"property-read-only\">\n {{ translate('common.readOnly') }}\n </div>\n <div\n v-if=\"props.required\"\n class=\"property-required\">\n {{ translate('common.required') }}\n </div>\n <SchemaPropertyDefault :value=\"props.value?.default\" />\n <SchemaPropertyExamples\n v-if=\"props.withExamples\"\n :example=\"exampleValue\"\n :examples=\"props.value?.examples\" />\n </div>\n</template>\n<style scoped>\n.property-heading {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n row-gap: 9px;\n white-space: nowrap;\n}\n\n.property-heading:has(+ .children),\n.property-heading:has(+ .property-rule) {\n margin-bottom: 9px;\n}\n\n.property-heading > * {\n margin-right: 9px;\n}\n\n.property-heading:last-child {\n margin-right: 0;\n}\n\n.property-heading > .property-detail:not(:last-of-type) {\n margin-right: 0;\n}\n\n.property-name {\n max-width: 100%;\n font-family: var(--scalar-font-code);\n font-weight: var(--scalar-bold);\n font-size: var(--scalar-font-size-4);\n white-space: normal;\n overflow-wrap: break-word;\n}\n\n.property-additional {\n font-family: var(--scalar-font-code);\n}\n\n.property-required,\n.property-optional {\n color: var(--scalar-color-2);\n}\n\n.property-required {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-orange);\n}\n\n.property-read-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-blue);\n}\n\n.property-write-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-green);\n}\n\n.property-discriminator {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-purple);\n}\n\n.property-detail {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-2);\n display: flex;\n align-items: center;\n\n min-width: 0;\n}\n\n.property-const {\n color: var(--scalar-color-1);\n}\n\n.deprecated {\n text-decoration: line-through;\n}\n</style>\n"],"mappings":""}
@@ -4,6 +4,7 @@ import ScreenReader_default from "../../ScreenReader.vue.js";
4
4
  import { getSchemaType } from "./helpers/get-schema-type.js";
5
5
  import { getModelNameFromSchema } from "./helpers/schema-name.js";
6
6
  import LinkButton_default from "./LinkButton.vue.js";
7
+ import { isModelLinkable } from "./helpers/is-model-linkable.js";
7
8
  import RenderString_default from "./RenderString.vue.js";
8
9
  import SchemaPropertyDefault_default from "./SchemaPropertyDefault.vue.js";
9
10
  import SchemaPropertyDetail_default from "./SchemaPropertyDetail.vue.js";
@@ -70,6 +71,7 @@ var SchemaPropertyHeading_vue_vue_type_script_setup_true_lang_default = /*@__PUR
70
71
  type: Boolean,
71
72
  default: false
72
73
  },
74
+ modelLinkOptions: {},
73
75
  modelName: {},
74
76
  propertyNames: {},
75
77
  eventBus: { default: null }
@@ -183,6 +185,8 @@ var SchemaPropertyHeading_vue_vue_type_script_setup_true_lang_default = /*@__PUR
183
185
  }
184
186
  return null;
185
187
  });
188
+ /** Whether the model name links to the models section, or renders as plain text. */
189
+ const modelLinkable = computed(() => isModelLinkable(modelLink.value?.schemaKey, props.modelLinkOptions ?? {}));
186
190
  /** Check if we should show the type information */
187
191
  const shouldShowType = computed(() => {
188
192
  if (!props.value || !("type" in props.value)) return false;
@@ -233,7 +237,7 @@ var SchemaPropertyHeading_vue_vue_type_script_setup_true_lang_default = /*@__PUR
233
237
  _: 1
234
238
  }),
235
239
  createTextVNode(" " + toDisplayString(displayType.value) + " ", 1),
236
- modelLink.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [_cache[1] || (_cache[1] = createTextVNode(" · ", -1)), props.eventBus && modelLink.value.schemaKey ? (openBlock(), createBlock(LinkButton_default, {
240
+ modelLink.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [_cache[1] || (_cache[1] = createTextVNode(" · ", -1)), props.eventBus && modelLink.value.schemaKey && modelLinkable.value ? (openBlock(), createBlock(LinkButton_default, {
237
241
  key: 0,
238
242
  onClick: _cache[0] || (_cache[0] = ($event) => props.eventBus.emit("scroll-to:model-by-name", { name: modelLink.value.schemaKey }))
239
243
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaPropertyHeading.vue.script.js","names":["$slots"],"sources":["../../../../src/components/Content/Schema/SchemaPropertyHeading.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n isArraySchema,\n isNumberSchema,\n isStringSchema,\n} from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\nimport { computed, toRef } from 'vue'\n\nimport { Badge } from '@/components/Badge'\nimport LinkButton from '@/components/Content/Schema/LinkButton.vue'\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport { useLocalization } from '@/features/localization'\n\nimport { getSchemaType } from './helpers/get-schema-type'\nimport { getModelNameFromSchema } from './helpers/schema-name'\nimport RenderString from './RenderString.vue'\nimport SchemaPropertyDefault from './SchemaPropertyDefault.vue'\nimport SchemaPropertyDetail from './SchemaPropertyDetail.vue'\nimport SchemaPropertyExamples from './SchemaPropertyExamples.vue'\n\nconst props = withDefaults(\n defineProps<{\n value: SchemaObject | undefined\n enum?: boolean\n isDiscriminator?: boolean\n required?: boolean\n additional?: boolean\n withExamples?: boolean\n hideModelNames?: boolean\n /** When the schema was resolved from a $ref, pass the ref name so it displays as e.g. \"Data\" instead of \"object\". */\n modelName?: string | null\n /** Resolved propertyNames schema, used to surface key constraints like `format` for additional properties. */\n propertyNames?: SchemaObject\n eventBus?: WorkspaceEventBus | null\n }>(),\n {\n isDiscriminator: false,\n required: false,\n withExamples: true,\n hideModelNames: false,\n eventBus: null,\n },\n)\nconst { translate } = useLocalization()\n\n// Convert to reactive refs for composables\nconst valueRef = toRef(props, 'value')\n\nconst constValue = computed(() => {\n if (!valueRef.value) {\n return undefined\n }\n\n const schema = valueRef.value\n\n // Direct const value\n if (schema.const !== undefined) {\n return schema.const\n }\n\n // Single-item enum acts as const\n if (schema.enum?.length === 1) {\n return schema.enum[0]\n }\n\n // Check items for const values (for arrays)\n if (isArraySchema(schema) && schema.items) {\n const items = resolve.schema(schema.items)\n\n if (isDefined(items.const)) {\n return items.const\n }\n\n if (items.enum?.length === 1) {\n return items.enum[0]\n }\n }\n\n return undefined\n})\n\ntype ValidationProperty = {\n key: string\n value: string | number\n prefix?: string\n code?: boolean\n truncate?: boolean\n}\n\n/**\n * Constraints that live on a leaf (string or number) schema: length, pattern,\n * format and numeric ranges. Extracted so they can be surfaced for a primitive\n * schema as well as for a primitive array's items, which are not rendered on\n * their own. See https://github.com/scalar/scalar/issues/9690\n */\nconst getLeafConstraints = (schema: SchemaObject) => {\n const properties: ValidationProperty[] = []\n\n if (isStringSchema(schema)) {\n if (schema.minLength) {\n properties.push({\n key: 'min-length',\n prefix: `${translate('common.minLength')}: `,\n value: schema.minLength,\n })\n }\n\n if (schema.maxLength) {\n properties.push({\n key: 'max-length',\n prefix: `${translate('common.maxLength')}: `,\n value: schema.maxLength,\n })\n }\n\n if (schema.pattern) {\n properties.push({\n key: 'pattern',\n value: schema.pattern,\n code: true,\n truncate: true,\n })\n }\n }\n\n if ((isStringSchema(schema) || isNumberSchema(schema)) && schema.format) {\n properties.push({\n key: 'format',\n value: schema.format,\n truncate: true,\n })\n }\n\n if (isNumberSchema(schema)) {\n if (isDefined(schema.exclusiveMinimum)) {\n properties.push({\n key: 'exclusive-minimum',\n prefix: `${translate('common.greaterThan')}: `,\n value: schema.exclusiveMinimum,\n })\n }\n\n if (isDefined(schema.minimum)) {\n properties.push({\n key: 'minimum',\n prefix: `${translate('common.min')}: `,\n value: schema.minimum,\n })\n }\n\n if (isDefined(schema.exclusiveMaximum)) {\n properties.push({\n key: 'exclusive-maximum',\n prefix: `${translate('common.lessThan')}: `,\n value: schema.exclusiveMaximum,\n })\n }\n\n if (isDefined(schema.maximum)) {\n properties.push({\n key: 'maximum',\n prefix: `${translate('common.max')}: `,\n value: schema.maximum,\n })\n }\n\n if (isDefined(schema.multipleOf)) {\n properties.push({\n key: 'multiple-of',\n prefix: `${translate('common.multipleOf')}: `,\n value: schema.multipleOf,\n })\n }\n }\n\n return properties\n}\n\nconst validationProperties = computed(() => {\n if (!valueRef.value) {\n return []\n }\n\n const schema = valueRef.value\n const properties: ValidationProperty[] = []\n\n // Array validation properties\n if (isArraySchema(schema)) {\n if (schema.minItems || schema.maxItems) {\n properties.push({\n key: 'array-range',\n value: `${schema.minItems || ''}…${schema.maxItems || ''}`,\n })\n }\n\n // Unique items\n if (schema.uniqueItems) {\n properties.push({\n key: 'unique-items',\n value: `${translate('common.unique')}!`,\n })\n }\n }\n\n properties.push(...getLeafConstraints(schema))\n\n // Primitive array items carry their own constraints (e.g. an array of `uuid`\n // strings) but are not rendered separately, so surface them here.\n if (isArraySchema(schema) && schema.items) {\n properties.push(...getLeafConstraints(resolve.schema(schema.items)))\n }\n\n return properties\n})\n\n/** Link data for navigating to the referenced model in the sidebar. */\nconst modelLink = computed(() => {\n if (!props.value) {\n return null\n }\n\n if (props.hideModelNames) {\n return null\n }\n\n if (props.modelName) {\n return { schemaKey: props.modelName, label: props.modelName }\n }\n\n const modelName = getModelNameFromSchema(props.value)\n if (modelName) {\n return { schemaKey: modelName.schemaKey, label: modelName.label }\n }\n\n if (isArraySchema(props.value) && props.value.items) {\n const itemName = getModelNameFromSchema(props.value.items)\n return itemName\n ? { schemaKey: itemName.schemaKey, label: `${itemName.label}[]` }\n : null\n }\n\n return null\n})\n\n/** Check if we should show the type information */\nconst shouldShowType = computed(() => {\n if (!props.value || !('type' in props.value)) {\n return false\n }\n\n // Always show type for arrays, even when items have const values\n if (props.value.type === 'array') {\n return true\n }\n\n // For non-arrays, only show if no const value at the schema level\n return !constValue.value\n})\n\n/** Get the display type */\nconst displayType = computed(() => {\n if (!props.value) {\n return ''\n }\n return getSchemaType(props.value)\n})\n\n/**\n * Type and format of the property keys, derived from the propertyNames schema.\n *\n * For a map keyed by UUIDs this renders e.g. \"string · uuid\" so the key\n * constraints are not lost. Returns undefined when there is nothing to show.\n */\nconst propertyNamesDetail = computed(() => {\n const schema = props.propertyNames\n if (!schema) {\n return undefined\n }\n\n const parts = [getSchemaType(schema)]\n if ('format' in schema && typeof schema.format === 'string') {\n parts.push(schema.format)\n }\n\n const detail = parts.filter(Boolean).join(' · ')\n return detail.length > 0 ? detail : undefined\n})\n\nconst exampleValue = computed(() => {\n // Treat only `undefined` as \"not set\" — `null` is a valid example value on a nullable schema.\n if (\n props.value &&\n 'example' in props.value &&\n props.value.example !== undefined\n ) {\n return props.value.example\n }\n\n if (props.value && isArraySchema(props.value)) {\n const itemsSchema = resolve.schema(props.value.items)\n if (\n itemsSchema &&\n 'example' in itemsSchema &&\n itemsSchema.example !== undefined\n ) {\n return itemsSchema.example\n }\n }\n\n return undefined\n})\n</script>\n<template>\n <div class=\"property-heading\">\n <div\n v-if=\"$slots.name\"\n class=\"property-name\"\n :class=\"{ deprecated: props.value?.deprecated }\">\n <slot name=\"name\" />\n </div>\n <div\n v-if=\"props.isDiscriminator\"\n class=\"property-discriminator\">\n {{ translate('common.discriminator') }}\n </div>\n <template v-if=\"props.value\">\n <!-- Type information -->\n <SchemaPropertyDetail\n v-if=\"shouldShowType\"\n truncate>\n <ScreenReader>{{ translate('common.type') }}:</ScreenReader>\n {{ displayType }}\n <template v-if=\"modelLink\">\n ·\n <LinkButton\n v-if=\"props.eventBus && modelLink.schemaKey\"\n @click=\"\n props.eventBus.emit('scroll-to:model-by-name', {\n name: modelLink.schemaKey,\n })\n \">\n {{ modelLink.label }}\n </LinkButton>\n <template v-else>{{ modelLink.label }}</template>\n </template>\n </SchemaPropertyDetail>\n\n <!-- Key constraints from propertyNames (e.g. \"keys: string · uuid\") -->\n <SchemaPropertyDetail\n v-if=\"propertyNamesDetail\"\n truncate>\n <template #prefix>{{ translate('common.keys') }}:</template>\n {{ propertyNamesDetail }}\n </SchemaPropertyDetail>\n\n <!-- Dynamic validation properties from composable -->\n <SchemaPropertyDetail\n v-for=\"property in validationProperties\"\n :key=\"property.key\"\n :code=\"property.code\"\n :truncate=\"property.truncate\">\n <ScreenReader v-if=\"property.key === 'format'\">\n {{ translate('common.format') }}:\n </ScreenReader>\n <ScreenReader v-else-if=\"property.key === 'pattern'\">\n {{ translate('common.pattern') }}:\n </ScreenReader>\n <template\n v-if=\"property.prefix\"\n #prefix>\n {{ property.prefix }}\n </template>\n {{ property.value }}\n </SchemaPropertyDetail>\n\n <!-- Enum indicator -->\n <SchemaPropertyDetail v-if=\"props.enum\">\n {{ translate('common.enum') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.additional\"\n class=\"property-additional\">\n <template v-if=\"props.value?.['x-additionalPropertiesName']\">\n {{ props.value['x-additionalPropertiesName'] }}\n </template>\n <template v-else>{{ translate('common.additionalProperties') }}</template>\n </div>\n <div\n v-if=\"props.value?.deprecated\"\n class=\"property-deprecated\">\n <Badge>{{ translate('common.deprecated') }}</Badge>\n </div>\n <!-- Don't use `isDefined` here, we want to show `const` when the value is `null` -->\n <div\n v-if=\"constValue !== undefined\"\n class=\"property-const\">\n <SchemaPropertyDetail truncate>\n <template #prefix>{{ translate('common.const') }}: </template>\n <RenderString :value=\"constValue\" />\n </SchemaPropertyDetail>\n </div>\n <template v-else>\n <!-- Shows only when a composition is used (so props.value?.type is undefined) -->\n <SchemaPropertyDetail v-if=\"(props.value as any)?.nullable === true\">\n {{ translate('common.nullable') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.value?.writeOnly\"\n class=\"property-write-only\">\n {{ translate('common.writeOnly') }}\n </div>\n <div\n v-else-if=\"props.value?.readOnly\"\n class=\"property-read-only\">\n {{ translate('common.readOnly') }}\n </div>\n <div\n v-if=\"props.required\"\n class=\"property-required\">\n {{ translate('common.required') }}\n </div>\n <SchemaPropertyDefault :value=\"props.value?.default\" />\n <SchemaPropertyExamples\n v-if=\"props.withExamples\"\n :example=\"exampleValue\"\n :examples=\"props.value?.examples\" />\n </div>\n</template>\n<style scoped>\n.property-heading {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n row-gap: 9px;\n white-space: nowrap;\n}\n\n.property-heading:has(+ .children),\n.property-heading:has(+ .property-rule) {\n margin-bottom: 9px;\n}\n\n.property-heading > * {\n margin-right: 9px;\n}\n\n.property-heading:last-child {\n margin-right: 0;\n}\n\n.property-heading > .property-detail:not(:last-of-type) {\n margin-right: 0;\n}\n\n.property-name {\n max-width: 100%;\n font-family: var(--scalar-font-code);\n font-weight: var(--scalar-bold);\n font-size: var(--scalar-font-size-4);\n white-space: normal;\n overflow-wrap: break-word;\n}\n\n.property-additional {\n font-family: var(--scalar-font-code);\n}\n\n.property-required,\n.property-optional {\n color: var(--scalar-color-2);\n}\n\n.property-required {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-orange);\n}\n\n.property-read-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-blue);\n}\n\n.property-write-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-green);\n}\n\n.property-discriminator {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-purple);\n}\n\n.property-detail {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-2);\n display: flex;\n align-items: center;\n\n min-width: 0;\n}\n\n.property-const {\n color: var(--scalar-color-1);\n}\n\n.deprecated {\n text-decoration: line-through;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"SchemaPropertyHeading.vue.script.js","names":["$slots"],"sources":["../../../../src/components/Content/Schema/SchemaPropertyHeading.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n isArraySchema,\n isNumberSchema,\n isStringSchema,\n} from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\nimport { computed, toRef } from 'vue'\n\nimport { Badge } from '@/components/Badge'\nimport LinkButton from '@/components/Content/Schema/LinkButton.vue'\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport { useLocalization } from '@/features/localization'\n\nimport { getSchemaType } from './helpers/get-schema-type'\nimport {\n isModelLinkable,\n type ModelLinkOptions,\n} from './helpers/is-model-linkable'\nimport { getModelNameFromSchema } from './helpers/schema-name'\nimport RenderString from './RenderString.vue'\nimport SchemaPropertyDefault from './SchemaPropertyDefault.vue'\nimport SchemaPropertyDetail from './SchemaPropertyDetail.vue'\nimport SchemaPropertyExamples from './SchemaPropertyExamples.vue'\n\nconst props = withDefaults(\n defineProps<{\n value: SchemaObject | undefined\n enum?: boolean\n isDiscriminator?: boolean\n required?: boolean\n additional?: boolean\n withExamples?: boolean\n hideModelNames?: boolean\n /**\n * Config for deciding whether a model name links to the models section. When the section or\n * the referenced model is hidden there is nothing to scroll to, so the name renders as plain text.\n */\n modelLinkOptions?: ModelLinkOptions\n /** When the schema was resolved from a $ref, pass the ref name so it displays as e.g. \"Data\" instead of \"object\". */\n modelName?: string | null\n /** Resolved propertyNames schema, used to surface key constraints like `format` for additional properties. */\n propertyNames?: SchemaObject\n eventBus?: WorkspaceEventBus | null\n }>(),\n {\n isDiscriminator: false,\n required: false,\n withExamples: true,\n hideModelNames: false,\n eventBus: null,\n },\n)\nconst { translate } = useLocalization()\n\n// Convert to reactive refs for composables\nconst valueRef = toRef(props, 'value')\n\nconst constValue = computed(() => {\n if (!valueRef.value) {\n return undefined\n }\n\n const schema = valueRef.value\n\n // Direct const value\n if (schema.const !== undefined) {\n return schema.const\n }\n\n // Single-item enum acts as const\n if (schema.enum?.length === 1) {\n return schema.enum[0]\n }\n\n // Check items for const values (for arrays)\n if (isArraySchema(schema) && schema.items) {\n const items = resolve.schema(schema.items)\n\n if (isDefined(items.const)) {\n return items.const\n }\n\n if (items.enum?.length === 1) {\n return items.enum[0]\n }\n }\n\n return undefined\n})\n\ntype ValidationProperty = {\n key: string\n value: string | number\n prefix?: string\n code?: boolean\n truncate?: boolean\n}\n\n/**\n * Constraints that live on a leaf (string or number) schema: length, pattern,\n * format and numeric ranges. Extracted so they can be surfaced for a primitive\n * schema as well as for a primitive array's items, which are not rendered on\n * their own. See https://github.com/scalar/scalar/issues/9690\n */\nconst getLeafConstraints = (schema: SchemaObject) => {\n const properties: ValidationProperty[] = []\n\n if (isStringSchema(schema)) {\n if (schema.minLength) {\n properties.push({\n key: 'min-length',\n prefix: `${translate('common.minLength')}: `,\n value: schema.minLength,\n })\n }\n\n if (schema.maxLength) {\n properties.push({\n key: 'max-length',\n prefix: `${translate('common.maxLength')}: `,\n value: schema.maxLength,\n })\n }\n\n if (schema.pattern) {\n properties.push({\n key: 'pattern',\n value: schema.pattern,\n code: true,\n truncate: true,\n })\n }\n }\n\n if ((isStringSchema(schema) || isNumberSchema(schema)) && schema.format) {\n properties.push({\n key: 'format',\n value: schema.format,\n truncate: true,\n })\n }\n\n if (isNumberSchema(schema)) {\n if (isDefined(schema.exclusiveMinimum)) {\n properties.push({\n key: 'exclusive-minimum',\n prefix: `${translate('common.greaterThan')}: `,\n value: schema.exclusiveMinimum,\n })\n }\n\n if (isDefined(schema.minimum)) {\n properties.push({\n key: 'minimum',\n prefix: `${translate('common.min')}: `,\n value: schema.minimum,\n })\n }\n\n if (isDefined(schema.exclusiveMaximum)) {\n properties.push({\n key: 'exclusive-maximum',\n prefix: `${translate('common.lessThan')}: `,\n value: schema.exclusiveMaximum,\n })\n }\n\n if (isDefined(schema.maximum)) {\n properties.push({\n key: 'maximum',\n prefix: `${translate('common.max')}: `,\n value: schema.maximum,\n })\n }\n\n if (isDefined(schema.multipleOf)) {\n properties.push({\n key: 'multiple-of',\n prefix: `${translate('common.multipleOf')}: `,\n value: schema.multipleOf,\n })\n }\n }\n\n return properties\n}\n\nconst validationProperties = computed(() => {\n if (!valueRef.value) {\n return []\n }\n\n const schema = valueRef.value\n const properties: ValidationProperty[] = []\n\n // Array validation properties\n if (isArraySchema(schema)) {\n if (schema.minItems || schema.maxItems) {\n properties.push({\n key: 'array-range',\n value: `${schema.minItems || ''}…${schema.maxItems || ''}`,\n })\n }\n\n // Unique items\n if (schema.uniqueItems) {\n properties.push({\n key: 'unique-items',\n value: `${translate('common.unique')}!`,\n })\n }\n }\n\n properties.push(...getLeafConstraints(schema))\n\n // Primitive array items carry their own constraints (e.g. an array of `uuid`\n // strings) but are not rendered separately, so surface them here.\n if (isArraySchema(schema) && schema.items) {\n properties.push(...getLeafConstraints(resolve.schema(schema.items)))\n }\n\n return properties\n})\n\n/** Link data for navigating to the referenced model in the sidebar. */\nconst modelLink = computed(() => {\n if (!props.value) {\n return null\n }\n\n if (props.hideModelNames) {\n return null\n }\n\n if (props.modelName) {\n return { schemaKey: props.modelName, label: props.modelName }\n }\n\n const modelName = getModelNameFromSchema(props.value)\n if (modelName) {\n return { schemaKey: modelName.schemaKey, label: modelName.label }\n }\n\n if (isArraySchema(props.value) && props.value.items) {\n const itemName = getModelNameFromSchema(props.value.items)\n return itemName\n ? { schemaKey: itemName.schemaKey, label: `${itemName.label}[]` }\n : null\n }\n\n return null\n})\n\n/** Whether the model name links to the models section, or renders as plain text. */\nconst modelLinkable = computed(() =>\n isModelLinkable(modelLink.value?.schemaKey, props.modelLinkOptions ?? {}),\n)\n\n/** Check if we should show the type information */\nconst shouldShowType = computed(() => {\n if (!props.value || !('type' in props.value)) {\n return false\n }\n\n // Always show type for arrays, even when items have const values\n if (props.value.type === 'array') {\n return true\n }\n\n // For non-arrays, only show if no const value at the schema level\n return !constValue.value\n})\n\n/** Get the display type */\nconst displayType = computed(() => {\n if (!props.value) {\n return ''\n }\n return getSchemaType(props.value)\n})\n\n/**\n * Type and format of the property keys, derived from the propertyNames schema.\n *\n * For a map keyed by UUIDs this renders e.g. \"string · uuid\" so the key\n * constraints are not lost. Returns undefined when there is nothing to show.\n */\nconst propertyNamesDetail = computed(() => {\n const schema = props.propertyNames\n if (!schema) {\n return undefined\n }\n\n const parts = [getSchemaType(schema)]\n if ('format' in schema && typeof schema.format === 'string') {\n parts.push(schema.format)\n }\n\n const detail = parts.filter(Boolean).join(' · ')\n return detail.length > 0 ? detail : undefined\n})\n\nconst exampleValue = computed(() => {\n // Treat only `undefined` as \"not set\" — `null` is a valid example value on a nullable schema.\n if (\n props.value &&\n 'example' in props.value &&\n props.value.example !== undefined\n ) {\n return props.value.example\n }\n\n if (props.value && isArraySchema(props.value)) {\n const itemsSchema = resolve.schema(props.value.items)\n if (\n itemsSchema &&\n 'example' in itemsSchema &&\n itemsSchema.example !== undefined\n ) {\n return itemsSchema.example\n }\n }\n\n return undefined\n})\n</script>\n<template>\n <div class=\"property-heading\">\n <div\n v-if=\"$slots.name\"\n class=\"property-name\"\n :class=\"{ deprecated: props.value?.deprecated }\">\n <slot name=\"name\" />\n </div>\n <div\n v-if=\"props.isDiscriminator\"\n class=\"property-discriminator\">\n {{ translate('common.discriminator') }}\n </div>\n <template v-if=\"props.value\">\n <!-- Type information -->\n <SchemaPropertyDetail\n v-if=\"shouldShowType\"\n truncate>\n <ScreenReader>{{ translate('common.type') }}:</ScreenReader>\n {{ displayType }}\n <template v-if=\"modelLink\">\n ·\n <LinkButton\n v-if=\"props.eventBus && modelLink.schemaKey && modelLinkable\"\n @click=\"\n props.eventBus.emit('scroll-to:model-by-name', {\n name: modelLink.schemaKey,\n })\n \">\n {{ modelLink.label }}\n </LinkButton>\n <template v-else>{{ modelLink.label }}</template>\n </template>\n </SchemaPropertyDetail>\n\n <!-- Key constraints from propertyNames (e.g. \"keys: string · uuid\") -->\n <SchemaPropertyDetail\n v-if=\"propertyNamesDetail\"\n truncate>\n <template #prefix>{{ translate('common.keys') }}:</template>\n {{ propertyNamesDetail }}\n </SchemaPropertyDetail>\n\n <!-- Dynamic validation properties from composable -->\n <SchemaPropertyDetail\n v-for=\"property in validationProperties\"\n :key=\"property.key\"\n :code=\"property.code\"\n :truncate=\"property.truncate\">\n <ScreenReader v-if=\"property.key === 'format'\">\n {{ translate('common.format') }}:\n </ScreenReader>\n <ScreenReader v-else-if=\"property.key === 'pattern'\">\n {{ translate('common.pattern') }}:\n </ScreenReader>\n <template\n v-if=\"property.prefix\"\n #prefix>\n {{ property.prefix }}\n </template>\n {{ property.value }}\n </SchemaPropertyDetail>\n\n <!-- Enum indicator -->\n <SchemaPropertyDetail v-if=\"props.enum\">\n {{ translate('common.enum') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.additional\"\n class=\"property-additional\">\n <template v-if=\"props.value?.['x-additionalPropertiesName']\">\n {{ props.value['x-additionalPropertiesName'] }}\n </template>\n <template v-else>{{ translate('common.additionalProperties') }}</template>\n </div>\n <div\n v-if=\"props.value?.deprecated\"\n class=\"property-deprecated\">\n <Badge>{{ translate('common.deprecated') }}</Badge>\n </div>\n <!-- Don't use `isDefined` here, we want to show `const` when the value is `null` -->\n <div\n v-if=\"constValue !== undefined\"\n class=\"property-const\">\n <SchemaPropertyDetail truncate>\n <template #prefix>{{ translate('common.const') }}: </template>\n <RenderString :value=\"constValue\" />\n </SchemaPropertyDetail>\n </div>\n <template v-else>\n <!-- Shows only when a composition is used (so props.value?.type is undefined) -->\n <SchemaPropertyDetail v-if=\"(props.value as any)?.nullable === true\">\n {{ translate('common.nullable') }}\n </SchemaPropertyDetail>\n </template>\n <div\n v-if=\"props.value?.writeOnly\"\n class=\"property-write-only\">\n {{ translate('common.writeOnly') }}\n </div>\n <div\n v-else-if=\"props.value?.readOnly\"\n class=\"property-read-only\">\n {{ translate('common.readOnly') }}\n </div>\n <div\n v-if=\"props.required\"\n class=\"property-required\">\n {{ translate('common.required') }}\n </div>\n <SchemaPropertyDefault :value=\"props.value?.default\" />\n <SchemaPropertyExamples\n v-if=\"props.withExamples\"\n :example=\"exampleValue\"\n :examples=\"props.value?.examples\" />\n </div>\n</template>\n<style scoped>\n.property-heading {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n row-gap: 9px;\n white-space: nowrap;\n}\n\n.property-heading:has(+ .children),\n.property-heading:has(+ .property-rule) {\n margin-bottom: 9px;\n}\n\n.property-heading > * {\n margin-right: 9px;\n}\n\n.property-heading:last-child {\n margin-right: 0;\n}\n\n.property-heading > .property-detail:not(:last-of-type) {\n margin-right: 0;\n}\n\n.property-name {\n max-width: 100%;\n font-family: var(--scalar-font-code);\n font-weight: var(--scalar-bold);\n font-size: var(--scalar-font-size-4);\n white-space: normal;\n overflow-wrap: break-word;\n}\n\n.property-additional {\n font-family: var(--scalar-font-code);\n}\n\n.property-required,\n.property-optional {\n color: var(--scalar-color-2);\n}\n\n.property-required {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-orange);\n}\n\n.property-read-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-blue);\n}\n\n.property-write-only {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-green);\n}\n\n.property-discriminator {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-purple);\n}\n\n.property-detail {\n font-size: var(--scalar-mini);\n color: var(--scalar-color-2);\n display: flex;\n align-items: center;\n\n min-width: 0;\n}\n\n.property-const {\n color: var(--scalar-color-1);\n}\n\n.deprecated {\n text-decoration: line-through;\n}\n</style>\n"],"mappings":"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"}
@@ -6,4 +6,20 @@
6
6
  * @example SchemaName from #/components/schemas/SchemaName
7
7
  */
8
8
  export declare const getRefName: (ref: string) => string | null | undefined;
9
+ /**
10
+ * Gets the models-section key for a `$ref`, but only when the ref actually
11
+ * targets `#/components/schemas/`.
12
+ *
13
+ * The models index used for navigation is built exclusively from
14
+ * `components.schemas`, so a ref into any other bucket (`parameters`,
15
+ * `responses`, ...) or an external file (`./other.yaml#/Foo`) has no navigable
16
+ * target. Returning `null` for those keeps the name visible as plain text while
17
+ * avoiding a dead link.
18
+ *
19
+ * @example
20
+ * getSchemaRefName('#/components/schemas/Planet') // 'Planet'
21
+ * getSchemaRefName('#/components/parameters/Planet') // null
22
+ * getSchemaRefName('./planets.yaml#/Planet') // null
23
+ */
24
+ export declare const getSchemaRefName: (ref: string) => string | null;
9
25
  //# sourceMappingURL=get-ref-name.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-ref-name.d.ts","sourceRoot":"","sources":["../../../../../src/components/Content/Schema/helpers/get-ref-name.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,8BAWrC,CAAA"}
1
+ {"version":3,"file":"get-ref-name.d.ts","sourceRoot":"","sources":["../../../../../src/components/Content/Schema/helpers/get-ref-name.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,8BAWrC,CAAA;AASD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAWvD,CAAA"}
@@ -13,7 +13,34 @@ var getRefName = (ref) => {
13
13
  if (match) return match[1];
14
14
  return null;
15
15
  };
16
+ /**
17
+ * Matches a local reference that points at `#/components/schemas/<name>` and
18
+ * captures the schema name. Intentionally strict: only refs that resolve to a
19
+ * navigable model in `components.schemas` should be linkable.
20
+ */
21
+ var COMPONENTS_SCHEMAS_REF = /^#\/components\/schemas\/([^/]+)$/;
22
+ /**
23
+ * Gets the models-section key for a `$ref`, but only when the ref actually
24
+ * targets `#/components/schemas/`.
25
+ *
26
+ * The models index used for navigation is built exclusively from
27
+ * `components.schemas`, so a ref into any other bucket (`parameters`,
28
+ * `responses`, ...) or an external file (`./other.yaml#/Foo`) has no navigable
29
+ * target. Returning `null` for those keeps the name visible as plain text while
30
+ * avoiding a dead link.
31
+ *
32
+ * @example
33
+ * getSchemaRefName('#/components/schemas/Planet') // 'Planet'
34
+ * getSchemaRefName('#/components/parameters/Planet') // null
35
+ * getSchemaRefName('./planets.yaml#/Planet') // null
36
+ */
37
+ var getSchemaRefName = (ref) => {
38
+ if (!ref) return null;
39
+ const match = ref.match(COMPONENTS_SCHEMAS_REF);
40
+ if (match?.[1]) return decodeURIComponent(match[1]);
41
+ return null;
42
+ };
16
43
  //#endregion
17
- export { getRefName };
44
+ export { getRefName, getSchemaRefName };
18
45
 
19
46
  //# sourceMappingURL=get-ref-name.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-ref-name.js","names":[],"sources":["../../../../../src/components/Content/Schema/helpers/get-ref-name.ts"],"sourcesContent":["import { REGEX } from '@scalar/helpers/regex/regex-helpers'\n\n/**\n * Gets the \"name\" of the schema from the ref path\n * TODO: this will change so fix it when the new refs are out\n * Then add tests\n *\n * @example SchemaName from #/components/schemas/SchemaName\n */\nexport const getRefName = (ref: string) => {\n if (!ref) {\n return null\n }\n\n const match = ref.match(REGEX.REF_NAME)\n if (match) {\n return match[1]\n }\n\n return null\n}\n"],"mappings":";;;;;;;;;AASA,IAAa,cAAc,QAAgB;CACzC,IAAI,CAAC,KACH,OAAO;CAGT,MAAM,QAAQ,IAAI,MAAM,MAAM,QAAQ;CACtC,IAAI,OACF,OAAO,MAAM;CAGf,OAAO;AACT"}
1
+ {"version":3,"file":"get-ref-name.js","names":[],"sources":["../../../../../src/components/Content/Schema/helpers/get-ref-name.ts"],"sourcesContent":["import { REGEX } from '@scalar/helpers/regex/regex-helpers'\n\n/**\n * Gets the \"name\" of the schema from the ref path\n * TODO: this will change so fix it when the new refs are out\n * Then add tests\n *\n * @example SchemaName from #/components/schemas/SchemaName\n */\nexport const getRefName = (ref: string) => {\n if (!ref) {\n return null\n }\n\n const match = ref.match(REGEX.REF_NAME)\n if (match) {\n return match[1]\n }\n\n return null\n}\n\n/**\n * Matches a local reference that points at `#/components/schemas/<name>` and\n * captures the schema name. Intentionally strict: only refs that resolve to a\n * navigable model in `components.schemas` should be linkable.\n */\nconst COMPONENTS_SCHEMAS_REF = /^#\\/components\\/schemas\\/([^/]+)$/\n\n/**\n * Gets the models-section key for a `$ref`, but only when the ref actually\n * targets `#/components/schemas/`.\n *\n * The models index used for navigation is built exclusively from\n * `components.schemas`, so a ref into any other bucket (`parameters`,\n * `responses`, ...) or an external file (`./other.yaml#/Foo`) has no navigable\n * target. Returning `null` for those keeps the name visible as plain text while\n * avoiding a dead link.\n *\n * @example\n * getSchemaRefName('#/components/schemas/Planet') // 'Planet'\n * getSchemaRefName('#/components/parameters/Planet') // null\n * getSchemaRefName('./planets.yaml#/Planet') // null\n */\nexport const getSchemaRefName = (ref: string): string | null => {\n if (!ref) {\n return null\n }\n\n const match = ref.match(COMPONENTS_SCHEMAS_REF)\n if (match?.[1]) {\n return decodeURIComponent(match[1])\n }\n\n return null\n}\n"],"mappings":";;;;;;;;;AASA,IAAa,cAAc,QAAgB;CACzC,IAAI,CAAC,KACH,OAAO;CAGT,MAAM,QAAQ,IAAI,MAAM,MAAM,QAAQ;CACtC,IAAI,OACF,OAAO,MAAM;CAGf,OAAO;AACT;;;;;;AAOA,IAAM,yBAAyB;;;;;;;;;;;;;;;;AAiB/B,IAAa,oBAAoB,QAA+B;CAC9D,IAAI,CAAC,KACH,OAAO;CAGT,MAAM,QAAQ,IAAI,MAAM,sBAAsB;CAC9C,IAAI,QAAQ,IACV,OAAO,mBAAmB,MAAM,EAAE;CAGpC,OAAO;AACT"}
@@ -0,0 +1,15 @@
1
+ import type { SchemaOptions } from '../types';
2
+ /** The slice of schema options needed to decide whether a model name renders as a link. */
3
+ export type ModelLinkOptions = Pick<SchemaOptions, 'hideModels' | 'document'>;
4
+ /**
5
+ * A model name normally links to its entry in the models section. It should render as plain
6
+ * text when there is nothing to scroll to:
7
+ *
8
+ * - the whole models section is hidden via `hideModels`, or
9
+ * - the referenced schema itself is hidden via `x-internal` / `x-scalar-ignore`.
10
+ *
11
+ * The hidden check mirrors how the sidebar decides which schemas to drop (see `traverseSchemas`),
12
+ * so the link only shows when the model actually exists in the models section.
13
+ */
14
+ export declare const isModelLinkable: (schemaKey: string | null | undefined, { hideModels, document }: ModelLinkOptions) => boolean;
15
+ //# sourceMappingURL=is-model-linkable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-model-linkable.d.ts","sourceRoot":"","sources":["../../../../../src/components/Content/Schema/helpers/is-model-linkable.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7C,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,UAAU,CAAC,CAAA;AAE7E;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,0BAA0B,gBAAgB,KACzC,OAQF,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { getResolvedRef, mergeSiblingReferences } from "@scalar/workspace-store/helpers/get-resolved-ref";
2
+ import { isHidden } from "@scalar/workspace-store/helpers/is-hidden";
3
+ //#region src/components/Content/Schema/helpers/is-model-linkable.ts
4
+ /**
5
+ * A model name normally links to its entry in the models section. It should render as plain
6
+ * text when there is nothing to scroll to:
7
+ *
8
+ * - the whole models section is hidden via `hideModels`, or
9
+ * - the referenced schema itself is hidden via `x-internal` / `x-scalar-ignore`.
10
+ *
11
+ * The hidden check mirrors how the sidebar decides which schemas to drop (see `traverseSchemas`),
12
+ * so the link only shows when the model actually exists in the models section.
13
+ */
14
+ var isModelLinkable = (schemaKey, { hideModels, document }) => {
15
+ if (!schemaKey || hideModels) return false;
16
+ const schema = document?.components?.schemas?.[schemaKey];
17
+ return !isHidden(getResolvedRef(schema, mergeSiblingReferences));
18
+ };
19
+ //#endregion
20
+ export { isModelLinkable };
21
+
22
+ //# sourceMappingURL=is-model-linkable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-model-linkable.js","names":[],"sources":["../../../../../src/components/Content/Schema/helpers/is-model-linkable.ts"],"sourcesContent":["import { getResolvedRef, mergeSiblingReferences } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { isHidden } from '@scalar/workspace-store/helpers/is-hidden'\n\nimport type { SchemaOptions } from '../types'\n\n/** The slice of schema options needed to decide whether a model name renders as a link. */\nexport type ModelLinkOptions = Pick<SchemaOptions, 'hideModels' | 'document'>\n\n/**\n * A model name normally links to its entry in the models section. It should render as plain\n * text when there is nothing to scroll to:\n *\n * - the whole models section is hidden via `hideModels`, or\n * - the referenced schema itself is hidden via `x-internal` / `x-scalar-ignore`.\n *\n * The hidden check mirrors how the sidebar decides which schemas to drop (see `traverseSchemas`),\n * so the link only shows when the model actually exists in the models section.\n */\nexport const isModelLinkable = (\n schemaKey: string | null | undefined,\n { hideModels, document }: ModelLinkOptions,\n): boolean => {\n if (!schemaKey || hideModels) {\n return false\n }\n\n const schema = document?.components?.schemas?.[schemaKey]\n\n return !isHidden(getResolvedRef(schema, mergeSiblingReferences))\n}\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAa,mBACX,WACA,EAAE,YAAY,eACF;CACZ,IAAI,CAAC,aAAa,YAChB,OAAO;CAGT,MAAM,SAAS,UAAU,YAAY,UAAU;CAE/C,OAAO,CAAC,SAAS,eAAe,QAAQ,sBAAsB,CAAC;AACjE"}
@@ -5,7 +5,12 @@ import type { SchemaObject, SchemaReferenceType } from '@scalar/workspace-store/
5
5
  * Handles $ref, title, name, type, and schema dictionary lookup
6
6
  */
7
7
  export declare const getModelNameFromSchema: (schemaOrRef: SchemaObject | SchemaReferenceType<SchemaObject>) => {
8
- /** The key in components.schemas (extracted from $ref), used for sidebar navigation. */
8
+ /**
9
+ * The key in `components.schemas` (extracted from `$ref`), used for sidebar
10
+ * navigation. Only set when the `$ref` actually targets
11
+ * `#/components/schemas/`; `null` for refs into other component buckets or
12
+ * external files, so those never render a dead link.
13
+ */
9
14
  schemaKey: string | null;
10
15
  /** The human-readable name to display (schema.title, schema.name, or ref key). */
11
16
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-name.d.ts","sourceRoot":"","sources":["../../../../../src/components/Content/Schema/helpers/schema-name.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,8DAA8D,CAAA;AAIrH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,YAAY,GAAG,mBAAmB,CAAC,YAAY,CAAC,KAC5D;IACD,wFAAwF;IACxF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,IAwBH,CAAA"}
1
+ {"version":3,"file":"schema-name.d.ts","sourceRoot":"","sources":["../../../../../src/components/Content/Schema/helpers/schema-name.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,8DAA8D,CAAA;AAIrH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,YAAY,GAAG,mBAAmB,CAAC,YAAY,CAAC,KAC5D;IACD;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,IA4BH,CAAA"}
@@ -1,4 +1,4 @@
1
- import { getRefName } from "./get-ref-name.js";
1
+ import { getRefName, getSchemaRefName } from "./get-ref-name.js";
2
2
  import { resolve } from "@scalar/workspace-store/resolve";
3
3
  //#region src/components/Content/Schema/helpers/schema-name.ts
4
4
  /**
@@ -9,7 +9,7 @@ import { resolve } from "@scalar/workspace-store/resolve";
9
9
  var getModelNameFromSchema = (schemaOrRef) => {
10
10
  if (!schemaOrRef) return null;
11
11
  const schema = resolve.schema(schemaOrRef);
12
- const schemaKey = "$ref" in schemaOrRef ? getRefName(schemaOrRef.$ref) ?? null : null;
12
+ const schemaKey = "$ref" in schemaOrRef ? getSchemaRefName(schemaOrRef.$ref) : null;
13
13
  if (schema.title) return {
14
14
  schemaKey,
15
15
  label: schema.title
@@ -19,9 +19,10 @@ var getModelNameFromSchema = (schemaOrRef) => {
19
19
  label: schema.name
20
20
  };
21
21
  if ("$ref" in schemaOrRef) {
22
- if (schemaKey) return {
22
+ const label = getRefName(schemaOrRef.$ref);
23
+ if (label) return {
23
24
  schemaKey,
24
- label: schemaKey
25
+ label
25
26
  };
26
27
  }
27
28
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-name.js","names":[],"sources":["../../../../../src/components/Content/Schema/helpers/schema-name.ts"],"sourcesContent":["import { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject, SchemaReferenceType } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport { getRefName } from './get-ref-name'\n\n/**\n * Extract schema name from various schema formats\n *\n * Handles $ref, title, name, type, and schema dictionary lookup\n */\nexport const getModelNameFromSchema = (\n schemaOrRef: SchemaObject | SchemaReferenceType<SchemaObject>,\n): {\n /** The key in components.schemas (extracted from $ref), used for sidebar navigation. */\n schemaKey: string | null\n /** The human-readable name to display (schema.title, schema.name, or ref key). */\n label: string\n} | null => {\n if (!schemaOrRef) {\n return null\n }\n\n const schema = resolve.schema(schemaOrRef)\n\n const schemaKey = '$ref' in schemaOrRef ? (getRefName(schemaOrRef.$ref) ?? null) : null\n\n if (schema.title) {\n return { schemaKey, label: schema.title }\n }\n\n if (schema.name) {\n return { schemaKey, label: schema.name }\n }\n\n if ('$ref' in schemaOrRef) {\n if (schemaKey) {\n return { schemaKey, label: schemaKey }\n }\n }\n\n return null\n}\n"],"mappings":";;;;;;;;AAUA,IAAa,0BACX,gBAMU;CACV,IAAI,CAAC,aACH,OAAO;CAGT,MAAM,SAAS,QAAQ,OAAO,WAAW;CAEzC,MAAM,YAAY,UAAU,cAAe,WAAW,YAAY,IAAI,KAAK,OAAQ;CAEnF,IAAI,OAAO,OACT,OAAO;EAAE;EAAW,OAAO,OAAO;CAAM;CAG1C,IAAI,OAAO,MACT,OAAO;EAAE;EAAW,OAAO,OAAO;CAAK;CAGzC,IAAI,UAAU;MACR,WACF,OAAO;GAAE;GAAW,OAAO;EAAU;CAAA;CAIzC,OAAO;AACT"}
1
+ {"version":3,"file":"schema-name.js","names":[],"sources":["../../../../../src/components/Content/Schema/helpers/schema-name.ts"],"sourcesContent":["import { resolve } from '@scalar/workspace-store/resolve'\nimport type { SchemaObject, SchemaReferenceType } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport { getRefName, getSchemaRefName } from './get-ref-name'\n\n/**\n * Extract schema name from various schema formats\n *\n * Handles $ref, title, name, type, and schema dictionary lookup\n */\nexport const getModelNameFromSchema = (\n schemaOrRef: SchemaObject | SchemaReferenceType<SchemaObject>,\n): {\n /**\n * The key in `components.schemas` (extracted from `$ref`), used for sidebar\n * navigation. Only set when the `$ref` actually targets\n * `#/components/schemas/`; `null` for refs into other component buckets or\n * external files, so those never render a dead link.\n */\n schemaKey: string | null\n /** The human-readable name to display (schema.title, schema.name, or ref key). */\n label: string\n} | null => {\n if (!schemaOrRef) {\n return null\n }\n\n const schema = resolve.schema(schemaOrRef)\n\n // Only refs into `#/components/schemas/` are navigable in the models section.\n const schemaKey = '$ref' in schemaOrRef ? getSchemaRefName(schemaOrRef.$ref) : null\n\n if (schema.title) {\n return { schemaKey, label: schema.title }\n }\n\n if (schema.name) {\n return { schemaKey, label: schema.name }\n }\n\n if ('$ref' in schemaOrRef) {\n // Fall back to the last ref segment as a display label, even for\n // non-schema refs. The name still shows, it just is not a link.\n const label = getRefName(schemaOrRef.$ref)\n if (label) {\n return { schemaKey, label }\n }\n }\n\n return null\n}\n"],"mappings":";;;;;;;;AAUA,IAAa,0BACX,gBAWU;CACV,IAAI,CAAC,aACH,OAAO;CAGT,MAAM,SAAS,QAAQ,OAAO,WAAW;CAGzC,MAAM,YAAY,UAAU,cAAc,iBAAiB,YAAY,IAAI,IAAI;CAE/E,IAAI,OAAO,OACT,OAAO;EAAE;EAAW,OAAO,OAAO;CAAM;CAG1C,IAAI,OAAO,MACT,OAAO;EAAE;EAAW,OAAO,OAAO;CAAK;CAGzC,IAAI,UAAU,aAAa;EAGzB,MAAM,QAAQ,WAAW,YAAY,IAAI;EACzC,IAAI,OACF,OAAO;GAAE;GAAW;EAAM;CAE9B;CAEA,OAAO;AACT"}
@@ -16,6 +16,13 @@ export type SchemaOptions = {
16
16
  orderRequiredPropertiesFirst?: ApiReferenceConfiguration['orderRequiredPropertiesFirst'];
17
17
  /** Expand all nested schema properties by default while keeping the toggle available */
18
18
  expandAllSchemaProperties?: ApiReferenceConfiguration['expandAllSchemaProperties'];
19
+ /**
20
+ * Whether the models section is hidden.
21
+ *
22
+ * Model names stay visible, but there is no models section to scroll to, so they
23
+ * render as plain text instead of links.
24
+ */
25
+ hideModels?: ApiReferenceConfiguration['hideModels'];
19
26
  /**
20
27
  * The document the schema belongs to.
21
28
  *