@scalar/workspace-store 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +2 -2
  3. package/dist/client.d.ts +40 -4
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +58 -23
  6. package/dist/client.js.map +2 -2
  7. package/dist/events/bus.d.ts +13 -1
  8. package/dist/events/bus.d.ts.map +1 -1
  9. package/dist/events/bus.js +46 -10
  10. package/dist/events/bus.js.map +3 -3
  11. package/dist/events/definitions/cookie.d.ts +20 -0
  12. package/dist/events/definitions/cookie.d.ts.map +1 -0
  13. package/dist/events/definitions/cookie.js +1 -0
  14. package/dist/events/definitions/cookie.js.map +7 -0
  15. package/dist/events/definitions/document.d.ts +8 -2
  16. package/dist/events/definitions/document.d.ts.map +1 -1
  17. package/dist/events/definitions/index.d.ts +4 -1
  18. package/dist/events/definitions/index.d.ts.map +1 -1
  19. package/dist/events/definitions/operation.d.ts +0 -13
  20. package/dist/events/definitions/operation.d.ts.map +1 -1
  21. package/dist/events/definitions/server.d.ts +2 -2
  22. package/dist/events/definitions/server.d.ts.map +1 -1
  23. package/dist/events/definitions/tabs.d.ts +40 -0
  24. package/dist/events/definitions/tabs.d.ts.map +1 -0
  25. package/dist/events/definitions/tabs.js +1 -0
  26. package/dist/events/definitions/tabs.js.map +7 -0
  27. package/dist/events/definitions/ui.d.ts +39 -4
  28. package/dist/events/definitions/ui.d.ts.map +1 -1
  29. package/dist/events/definitions/workspace.d.ts +18 -0
  30. package/dist/events/definitions/workspace.d.ts.map +1 -0
  31. package/dist/events/definitions/workspace.js +1 -0
  32. package/dist/events/definitions/workspace.js.map +7 -0
  33. package/dist/helpers/generate-unique-value.d.ts +19 -6
  34. package/dist/helpers/generate-unique-value.d.ts.map +1 -1
  35. package/dist/helpers/generate-unique-value.js +12 -7
  36. package/dist/helpers/generate-unique-value.js.map +2 -2
  37. package/dist/helpers/unpack-proxy.d.ts +14 -1
  38. package/dist/helpers/unpack-proxy.d.ts.map +1 -1
  39. package/dist/helpers/unpack-proxy.js +51 -1
  40. package/dist/helpers/unpack-proxy.js.map +3 -3
  41. package/dist/mutators/auth.d.ts +1 -1
  42. package/dist/mutators/auth.d.ts.map +1 -1
  43. package/dist/mutators/auth.js +24 -21
  44. package/dist/mutators/auth.js.map +2 -2
  45. package/dist/mutators/cookie.d.ts +21 -13
  46. package/dist/mutators/cookie.d.ts.map +1 -1
  47. package/dist/mutators/cookie.js +34 -26
  48. package/dist/mutators/cookie.js.map +3 -3
  49. package/dist/mutators/document.d.ts +9 -2
  50. package/dist/mutators/document.d.ts.map +1 -1
  51. package/dist/mutators/document.js +18 -3
  52. package/dist/mutators/document.js.map +2 -2
  53. package/dist/mutators/index.d.ts +4 -14
  54. package/dist/mutators/index.d.ts.map +1 -1
  55. package/dist/mutators/index.js +15 -9
  56. package/dist/mutators/index.js.map +2 -2
  57. package/dist/mutators/operation.d.ts +23 -101
  58. package/dist/mutators/operation.d.ts.map +1 -1
  59. package/dist/mutators/operation.js +132 -96
  60. package/dist/mutators/operation.js.map +2 -2
  61. package/dist/mutators/server.d.ts +1 -1
  62. package/dist/mutators/server.d.ts.map +1 -1
  63. package/dist/mutators/server.js +6 -5
  64. package/dist/mutators/server.js.map +2 -2
  65. package/dist/mutators/workspace.d.ts +6 -0
  66. package/dist/mutators/workspace.d.ts.map +1 -0
  67. package/dist/mutators/workspace.js +24 -0
  68. package/dist/mutators/workspace.js.map +7 -0
  69. package/dist/navigation/get-navigation-options.d.ts.map +1 -1
  70. package/dist/navigation/get-navigation-options.js +4 -4
  71. package/dist/navigation/get-navigation-options.js.map +2 -2
  72. package/dist/navigation/helpers/traverse-document.d.ts +1 -0
  73. package/dist/navigation/helpers/traverse-document.d.ts.map +1 -1
  74. package/dist/navigation/helpers/traverse-document.js +16 -2
  75. package/dist/navigation/helpers/traverse-document.js.map +2 -2
  76. package/dist/navigation/helpers/traverse-examples.js +2 -2
  77. package/dist/navigation/helpers/traverse-examples.js.map +2 -2
  78. package/dist/navigation/helpers/traverse-paths.d.ts +6 -3
  79. package/dist/navigation/helpers/traverse-paths.d.ts.map +1 -1
  80. package/dist/navigation/helpers/traverse-paths.js +4 -9
  81. package/dist/navigation/helpers/traverse-paths.js.map +2 -2
  82. package/dist/navigation/helpers/traverse-tags.d.ts +0 -1
  83. package/dist/navigation/helpers/traverse-tags.d.ts.map +1 -1
  84. package/dist/navigation/helpers/traverse-tags.js +57 -49
  85. package/dist/navigation/helpers/traverse-tags.js.map +3 -3
  86. package/dist/persistence/index.d.ts +6 -0
  87. package/dist/persistence/index.d.ts.map +1 -1
  88. package/dist/persistence/index.js +18 -0
  89. package/dist/persistence/index.js.map +2 -2
  90. package/dist/persistence/indexdb.d.ts +1 -0
  91. package/dist/persistence/indexdb.d.ts.map +1 -1
  92. package/dist/persistence/indexdb.js +6 -1
  93. package/dist/persistence/indexdb.js.map +2 -2
  94. package/dist/plugins/client/persistence.d.ts.map +1 -1
  95. package/dist/plugins/client/persistence.js +6 -0
  96. package/dist/plugins/client/persistence.js.map +2 -2
  97. package/dist/schemas/extensions/document/x-scalar-environments.d.ts +1 -0
  98. package/dist/schemas/extensions/document/x-scalar-environments.d.ts.map +1 -1
  99. package/dist/schemas/extensions/document/x-scalar-environments.js.map +2 -2
  100. package/dist/schemas/extensions/document/x-scalar-set-operation-security.d.ts +13 -0
  101. package/dist/schemas/extensions/document/x-scalar-set-operation-security.d.ts.map +1 -0
  102. package/dist/schemas/extensions/document/x-scalar-set-operation-security.js +8 -0
  103. package/dist/schemas/extensions/document/x-scalar-set-operation-security.js.map +7 -0
  104. package/dist/schemas/extensions/general/x-scalar-cookies.d.ts +36 -0
  105. package/dist/schemas/extensions/general/x-scalar-cookies.d.ts.map +1 -0
  106. package/dist/schemas/extensions/general/x-scalar-cookies.js +15 -0
  107. package/dist/schemas/extensions/general/x-scalar-cookies.js.map +7 -0
  108. package/dist/schemas/extensions/general/x-scalar-order.d.ts +12 -0
  109. package/dist/schemas/extensions/general/x-scalar-order.d.ts.map +1 -0
  110. package/dist/schemas/extensions/general/x-scalar-order.js +8 -0
  111. package/dist/schemas/extensions/general/x-scalar-order.js.map +7 -0
  112. package/dist/schemas/extensions/tag/x-tag-groups.d.ts +10 -5
  113. package/dist/schemas/extensions/tag/x-tag-groups.d.ts.map +1 -1
  114. package/dist/schemas/extensions/tag/x-tag-groups.js +15 -10
  115. package/dist/schemas/extensions/tag/x-tag-groups.js.map +2 -2
  116. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts +18 -0
  117. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts.map +1 -0
  118. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.js +8 -0
  119. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.js.map +7 -0
  120. package/dist/schemas/extensions.d.ts +1 -1
  121. package/dist/schemas/extensions.js +1 -1
  122. package/dist/schemas/extensions.js.map +2 -2
  123. package/dist/schemas/inmemory-workspace.d.ts +41 -27
  124. package/dist/schemas/inmemory-workspace.d.ts.map +1 -1
  125. package/dist/schemas/navigation.d.ts +4 -1
  126. package/dist/schemas/navigation.d.ts.map +1 -1
  127. package/dist/schemas/navigation.js +2 -1
  128. package/dist/schemas/navigation.js.map +2 -2
  129. package/dist/schemas/reference-config/index.d.ts +20 -13
  130. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  131. package/dist/schemas/reference-config/settings.d.ts +20 -13
  132. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  133. package/dist/schemas/reference-config/settings.js +2 -0
  134. package/dist/schemas/reference-config/settings.js.map +2 -2
  135. package/dist/schemas/v3.1/strict/openapi-document.d.ts +685 -448
  136. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  137. package/dist/schemas/v3.1/strict/openapi-document.js +10 -10
  138. package/dist/schemas/v3.1/strict/openapi-document.js.map +2 -2
  139. package/dist/schemas/v3.1/strict/operation.d.ts +1 -5
  140. package/dist/schemas/v3.1/strict/operation.d.ts.map +1 -1
  141. package/dist/schemas/v3.1/strict/operation.js +1 -5
  142. package/dist/schemas/v3.1/strict/operation.js.map +2 -2
  143. package/dist/schemas/v3.1/strict/tag.d.ts +4 -1
  144. package/dist/schemas/v3.1/strict/tag.d.ts.map +1 -1
  145. package/dist/schemas/v3.1/strict/tag.js +3 -1
  146. package/dist/schemas/v3.1/strict/tag.js.map +2 -2
  147. package/dist/schemas/v3.1/strict/type-guards.d.ts +6 -0
  148. package/dist/schemas/v3.1/strict/type-guards.d.ts.map +1 -1
  149. package/dist/schemas/v3.1/strict/type-guards.js +4 -0
  150. package/dist/schemas/v3.1/strict/type-guards.js.map +2 -2
  151. package/dist/schemas/workspace-specification/config.d.ts +20 -13
  152. package/dist/schemas/workspace-specification/config.d.ts.map +1 -1
  153. package/dist/schemas/workspace-specification/index.d.ts +21 -14
  154. package/dist/schemas/workspace-specification/index.d.ts.map +1 -1
  155. package/dist/schemas/workspace.d.ts +170 -109
  156. package/dist/schemas/workspace.d.ts.map +1 -1
  157. package/dist/schemas/workspace.js +8 -6
  158. package/dist/schemas/workspace.js.map +2 -2
  159. package/dist/server.d.ts +1 -1
  160. package/dist/workspace-plugin.d.ts +3 -0
  161. package/dist/workspace-plugin.d.ts.map +1 -1
  162. package/package.json +8 -7
  163. package/dist/schemas/extensions/document/x-scalar-document-security.d.ts +0 -13
  164. package/dist/schemas/extensions/document/x-scalar-document-security.d.ts.map +0 -1
  165. package/dist/schemas/extensions/document/x-scalar-document-security.js +0 -8
  166. package/dist/schemas/extensions/document/x-scalar-document-security.js.map +0 -7
  167. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.d.ts +0 -13
  168. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.d.ts.map +0 -1
  169. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.js +0 -9
  170. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.js.map +0 -7
  171. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.d.ts +0 -32
  172. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.d.ts.map +0 -1
  173. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.js +0 -13
  174. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/operation.ts"],
4
- "sourcesContent": ["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\n\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport type { WorkspaceDocument } from '@/schemas'\n\n/**\n * Describes the minimal identity for an operation in the workspace document.\n * It is used by mutators to find the target operation under `paths`.\n *\n * Example:\n * ```ts\n * const meta: OperationMeta = { method: 'get', path: '/users/{id}' }\n * ```\n */\nexport type OperationMeta = {\n method: HttpMethod\n path: string\n}\n\n/**\n * Extends {@link OperationMeta} with an `exampleKey` to address a specific\n * example variant (e.g. per environment or scenario) for request/parameters.\n *\n * Example:\n * ```ts\n * const meta: OperationExampleMeta = {\n * method: 'post',\n * path: '/upload',\n * exampleKey: 'default',\n * }\n * ```\n */\nexport type OperationExampleMeta = OperationMeta & {\n exampleKey: string\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Operation Draft Mutators\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Updates the `summary` of an operation.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationSummary({\n * document,\n * meta: { method: 'get', path: '/users/{id}' },\n * payload: { summary: 'Get a single user' },\n * })\n * ```\n */\nexport const updateOperationSummary = ({\n document,\n meta,\n payload: { summary },\n}: {\n document: WorkspaceDocument | null\n payload: { summary: string }\n meta: OperationMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method as HttpMethod])\n\n if (!operation) {\n return\n }\n\n operation.summary = summary\n}\n\n/**\n * Stores the chosen HTTP method under `x-scalar-method` on the operation.\n * This does not move the operation to a different method slot under `paths`;\n * it records the desired method as an extension for downstream consumers.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationMethodDraft({\n * document,\n * meta: { method: 'get', path: '/users' },\n * payload: { method: 'post' },\n * })\n * ```\n */\nexport const updateOperationMethodDraft = ({\n document,\n meta,\n payload: { method },\n}: {\n document: WorkspaceDocument | null\n payload: { method: HttpMethod }\n meta: OperationMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n if (!operation) {\n return\n }\n\n operation['x-scalar-method'] = method\n}\n\n/**\n * Records a normalized path for the operation under `x-scalar-path`, and\n * synchronizes path parameters in `operation.parameters` with the placeholders\n * present in the provided `path` (e.g. `/users/{id}`). Existing non-path\n * parameters are preserved.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationPathDraft({\n * document,\n * meta: { method: 'get', path: '/users/{id}' },\n * payload: { path: '/users/{id}' },\n * })\n * ```\n */\nexport const updateOperationPathDraft = ({\n document,\n meta,\n payload: { path },\n}: {\n document: WorkspaceDocument | null\n payload: { path: string }\n meta: OperationMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n if (!operation) {\n return\n }\n\n operation['x-scalar-path'] = path\n\n // Extract the path variables from the path\n const pathVariables = Array.from(path.matchAll(/{([^\\/}]+)}/g), (m) => m[1])\n\n // now we need to update the operation path variables\n const pathVariablesWithoutPathParameters = operation.parameters?.filter((it) => getResolvedRef(it).in !== 'path')\n\n operation.parameters = [\n ...(pathVariablesWithoutPathParameters ?? []),\n ...pathVariables.map((it) => ({\n name: it ?? '',\n in: 'path' as const,\n required: true,\n })),\n ]\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Operation Parameters Mutators\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Adds a parameter to the operation with an example value tracked by `exampleKey`.\n * For `path` parameters `required` is set to true automatically.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * addOperationParameter({\n * document,\n * type: 'query',\n * meta: { method: 'get', path: '/search', exampleKey: 'default' },\n * payload: { key: 'q', value: 'john', isEnabled: true },\n * })\n * ```\n */\nexport const addOperationParameter = ({\n document,\n meta,\n payload,\n type,\n}: {\n document: WorkspaceDocument | null\n type: 'header' | 'path' | 'query' | 'cookie'\n payload: {\n key: string\n value: string\n isEnabled: boolean\n }\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Initialize parameters array if it doesn't exist\n if (!operation.parameters) {\n operation.parameters = []\n }\n\n // Add the new parameter\n operation.parameters.push({\n name: payload.key,\n in: type,\n required: type === 'path' ? true : false,\n examples: {\n [meta.exampleKey]: {\n value: payload.value,\n 'x-disabled': !payload.isEnabled,\n },\n },\n })\n}\n\n/**\n * Updates an existing parameter of a given `type` by its index within that\n * type subset (e.g. the N-th query parameter). Supports updating name, value,\n * and enabled state for the targeted example.\n * Safely no-ops if the document, operation, or parameter does not exist.\n *\n * Example:\n * ```ts\n * updateOperationParameter({\n * document,\n * type: 'query',\n * index: 0,\n * meta: { method: 'get', path: '/search', exampleKey: 'default' },\n * payload: { value: 'alice', isEnabled: true },\n * })\n * ```\n */\nexport const updateOperationParameter = ({\n document,\n meta,\n type,\n payload,\n index,\n}: {\n document: WorkspaceDocument | null\n type: 'header' | 'path' | 'query' | 'cookie'\n index: number\n payload: Partial<{\n key: string\n value: string\n isEnabled: boolean\n }>\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Get all resolved parameters of the specified type\n // The passed index corresponds to this filtered list\n const resolvedParameters = operation.parameters?.map((it) => getResolvedRef(it)).filter((it) => it.in === type) ?? []\n const parameter = resolvedParameters[index]\n\n // Don't proceed if parameter doesn't exist\n if (!parameter) {\n return\n }\n\n parameter.name = payload.key ?? parameter.name ?? ''\n\n // TODO: handle content-type parameters\n if ('examples' in parameter) {\n if (!parameter.examples) {\n parameter.examples = {}\n }\n\n const example = getResolvedRef(parameter.examples[meta.exampleKey])\n\n if (!example) {\n return\n }\n\n example.value = payload.value ?? example?.value ?? ''\n example['x-disabled'] = payload.isEnabled === undefined ? example['x-disabled'] : !payload.isEnabled\n }\n}\n\n/**\n * Removes a parameter from the operation by resolving its position within\n * the filtered list of parameters of the specified `type`.\n * Safely no-ops if the document, operation, or parameter does not exist.\n *\n * Example:\n * ```ts\n * deleteOperationParameter({\n * document,\n * type: 'header',\n * index: 1,\n * meta: { method: 'get', path: '/users', exampleKey: 'default' },\n * })\n * ```\n */\nexport const deleteOperationParameter = ({\n document,\n meta,\n index,\n type,\n}: {\n document: WorkspaceDocument | null\n type: 'header' | 'path' | 'query' | 'cookie'\n index: number\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Translate the index from the filtered list to the actual parameters array\n const resolvedParameters = operation.parameters?.map((it) => getResolvedRef(it)).filter((it) => it.in === type) ?? []\n const parameter = resolvedParameters[index]\n\n // Don't proceed if parameter doesn't exist\n if (!parameter) {\n return\n }\n\n const actualIndex = operation.parameters?.findIndex((it) => getResolvedRef(it) === parameter) as number\n\n // Remove the parameter from the operation\n operation.parameters?.splice(actualIndex, 1)\n}\n\n/**\n * Deletes all parameters of a given `type` from the operation.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * deleteAllOperationParameters({\n * document,\n * type: 'cookie',\n * meta: { method: 'get', path: '/users' },\n * })\n * ```\n */\nexport const deleteAllOperationParameters = ({\n document,\n meta,\n type,\n}: {\n document: WorkspaceDocument | null\n type: 'header' | 'path' | 'query' | 'cookie'\n meta: OperationMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Filter out parameters of the specified type\n operation.parameters = operation.parameters?.filter((it) => getResolvedRef(it).in !== type) ?? []\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Operation Request Body Mutators\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Sets the selected request-body content type for the current `exampleKey`.\n * This stores the selection under `x-scalar-selected-content-type` on the\n * resolved requestBody. Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationRequestBodyContentType({\n * document,\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * payload: { contentType: 'multipart/form-data' },\n * })\n * ```\n */\nexport const updateOperationRequestBodyContentType = ({\n document,\n meta,\n payload,\n}: {\n document: WorkspaceDocument | null\n payload: {\n contentType: string\n }\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!['x-scalar-selected-content-type']) {\n requestBody!['x-scalar-selected-content-type'] = {}\n }\n\n requestBody!['x-scalar-selected-content-type'][meta.exampleKey] = payload.contentType\n}\n\n/**\n * Creates or updates a concrete example value for a specific request-body\n * `contentType` and `exampleKey`. Safely no-ops if the document or operation\n * does not exist.\n *\n * Example:\n * ```ts\n * updateOperationRequestBodyExample({\n * document,\n * contentType: 'application/json',\n * meta: { method: 'post', path: '/users', exampleKey: 'default' },\n * payload: { value: JSON.stringify({ name: 'Ada' }) },\n * })\n * ```\n */\nexport const updateOperationRequestBodyExample = ({\n document,\n meta,\n payload,\n contentType,\n}: {\n document: WorkspaceDocument | null\n contentType: string\n payload: {\n value: string | File | undefined\n }\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!.content[contentType]) {\n requestBody!.content[contentType] = {\n examples: {},\n }\n }\n\n // Ensure examples object exists and get a resolved reference\n const mediaType = requestBody!.content[contentType]!\n mediaType.examples ??= {}\n const examples = getResolvedRef(mediaType.examples)!\n\n const example = getResolvedRef(examples[meta.exampleKey])\n\n if (!example) {\n examples[meta.exampleKey] = {\n value: payload.value,\n }\n return\n }\n\n example.value = payload.value\n}\n\n/**\n * Appends a form-data row to the request-body example identified by\n * `contentType` and `exampleKey`. Initializes the example as an array when\n * needed. Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * addOperationRequestBodyFormRow({\n * document,\n * contentType: 'multipart/form-data',\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * payload: { key: 'file', value: new File(['x'], 'a.txt') },\n * })\n * ```\n */\nexport const addOperationRequestBodyFormRow = ({\n document,\n meta,\n payload,\n contentType,\n}: {\n document: WorkspaceDocument | null\n payload: Partial<{ key: string; value?: string | File }>\n contentType: string\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!.content[contentType]) {\n requestBody!.content[contentType] = {\n examples: {},\n }\n }\n\n if (!requestBody!.content[contentType]!.examples) {\n requestBody!.content[contentType]!.examples = {}\n }\n\n const examples = getResolvedRef(requestBody!.content[contentType]!.examples)\n\n const example = getResolvedRef(examples[meta.exampleKey])\n\n if (!example || !Array.isArray(example.value)) {\n examples[meta.exampleKey] = {\n value: [\n {\n name: payload.key,\n value: payload.value,\n },\n ],\n }\n return\n }\n\n // Add the new row to the example\n example.value.push({\n name: payload.key ?? '',\n value: payload.value ?? '',\n })\n}\n\n/**\n * Updates a form-data row at a given `index` for the specified example and\n * `contentType`. Setting `payload.value` to `null` clears the value (sets to\n * `undefined`). Safely no-ops if the document, operation, or example does not exist.\n *\n * Example:\n * ```ts\n * updateOperationRequestBodyFormRow({\n * document,\n * index: 0,\n * contentType: 'multipart/form-data',\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * payload: { key: 'description', value: 'Profile picture' },\n * })\n * ```\n */\nexport const updateOperationRequestBodyFormRow = ({\n document,\n meta,\n index,\n payload,\n contentType,\n}: {\n document: WorkspaceDocument | null\n index: number\n payload: Partial<{ key: string; value: string | File | null }>\n contentType: string\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!.content[contentType]) {\n return\n }\n\n const examples = getResolvedRef(requestBody!.content[contentType]!.examples)\n\n if (!examples) {\n return\n }\n\n const example = getResolvedRef(examples[meta.exampleKey])\n\n if (!example || !Array.isArray(example.value)) {\n return\n }\n\n example.value[index] = {\n name: payload.key ?? example.value[index]?.name ?? '',\n value: payload.value === null ? undefined : (payload.value ?? example.value[index]?.value ?? ''),\n }\n}\n\n/**\n * Deletes a form-data row at a given `index` from the example for the given\n * `contentType`. If the example becomes empty, the example entry is removed.\n * Safely no-ops if the document, operation, example, or row does not exist.\n *\n * Example:\n * ```ts\n * deleteOperationRequestBodyFormRow({\n * document,\n * index: 0,\n * contentType: 'multipart/form-data',\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * })\n * ```\n */\nexport const deleteOperationRequestBodyFormRow = ({\n document,\n meta,\n index,\n contentType,\n}: {\n document: WorkspaceDocument | null\n index: number\n contentType: string\n meta: OperationExampleMeta\n}) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n const requestBody = getResolvedRef(operation.requestBody)\n\n if (!requestBody) {\n return\n }\n\n if (!requestBody.content[contentType]) {\n return\n }\n\n const examples = getResolvedRef(requestBody.content[contentType]!.examples)\n\n if (!examples) {\n return\n }\n\n const example = getResolvedRef(examples[meta.exampleKey])\n\n if (!example || !Array.isArray(example.value)) {\n return\n }\n\n example.value.splice(index, 1)\n\n if (example.value.length === 0) {\n delete requestBody.content[contentType]!.examples![meta.exampleKey]\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { findVariables } from '@scalar/helpers/regex/find-variables'\n\nimport type { OperationEvents } from '@/events/definitions/operation'\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport type { WorkspaceDocument } from '@/schemas'\nimport type { ParameterObject } from '@/schemas/v3.1/strict/openapi-document'\nimport type { ReferenceType } from '@/schemas/v3.1/strict/reference'\nimport { isContentTypeParameterObject } from '@/schemas/v3.1/strict/type-guards'\n\n/**\n * Describes the minimal identity for an operation in the workspace document.\n * It is used by mutators to find the target operation under `paths`.\n *\n * Example:\n * ```ts\n * const meta: OperationMeta = { method: 'get', path: '/users/{id}' }\n * ```\n */\nexport type OperationMeta = {\n method: HttpMethod\n path: string\n}\n\n/**\n * Extends {@link OperationMeta} with an `exampleKey` to address a specific\n * example variant (e.g. per environment or scenario) for request/parameters.\n *\n * Example:\n * ```ts\n * const meta: OperationExampleMeta = {\n * method: 'post',\n * path: '/upload',\n * exampleKey: 'default',\n * }\n * ```\n */\nexport type OperationExampleMeta = OperationMeta & {\n exampleKey: string\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Helper Functions for Path Parameter Synchronization\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Creates a map of parameter names to their character positions in a path.\n * Used to detect renamed path parameters by position matching.\n */\nconst getParameterPositions = (path: string, parameters: readonly string[]): Record<string, number> => {\n const positions: Record<string, number> = {}\n\n for (const paramName of parameters) {\n const position = path.indexOf(`{${paramName}}`)\n if (position !== -1) {\n positions[paramName] = position\n }\n }\n\n return positions\n}\n\n/**\n * Syncs path parameters when the path changes.\n *\n * Preserves parameter configurations by:\n * 1. Keeping parameters with matching names\n * 2. Renaming parameters at the same position\n * 3. Creating new parameters with empty examples\n * 4. Removing parameters that no longer exist in the new path\n */\nconst syncParametersForPathChange = (\n newPath: string,\n oldPath: string,\n existingParameters: ReferenceType<ParameterObject>[],\n): ReferenceType<ParameterObject>[] => {\n // Extract path parameter names from both paths\n const oldPathParams = findVariables(oldPath, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n const newPathParams = findVariables(newPath, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n\n const oldPositions = getParameterPositions(oldPath, oldPathParams)\n const newPositions = getParameterPositions(newPath, newPathParams)\n\n // Separate path and non-path parameters, keeping original references\n const pathParameters: ReferenceType<ParameterObject>[] = []\n const nonPathParameters: ReferenceType<ParameterObject>[] = []\n\n for (const param of existingParameters) {\n const resolved = getResolvedRef(param)\n if (resolved?.in === 'path') {\n pathParameters.push(param)\n } else {\n nonPathParameters.push(param)\n }\n }\n\n // Create a map of existing path parameters by name for quick lookup\n const existingPathParamsByName = new Map<string, ReferenceType<ParameterObject>>()\n for (const param of pathParameters) {\n const resolved = getResolvedRef(param)\n if (resolved?.name) {\n existingPathParamsByName.set(resolved.name, param)\n }\n }\n\n const usedOldParams = new Set<string>()\n const syncedPathParameters: ReferenceType<ParameterObject>[] = []\n\n for (const newParamName of newPathParams) {\n // Case 1: Parameter with same name exists - preserve its config\n if (existingPathParamsByName.has(newParamName)) {\n syncedPathParameters.push(existingPathParamsByName.get(newParamName)!)\n usedOldParams.add(newParamName)\n continue\n }\n\n // Case 2: Check for parameter at same position (likely a rename)\n const newParamPosition = newPositions[newParamName]\n const oldParamAtPosition = oldPathParams.find(\n (oldParam) => oldPositions[oldParam] === newParamPosition && !usedOldParams.has(oldParam),\n )\n\n if (oldParamAtPosition && existingPathParamsByName.has(oldParamAtPosition)) {\n // Rename: transfer the old parameter's config to the new name\n const oldParam = existingPathParamsByName.get(oldParamAtPosition)!\n const resolved = getResolvedRef(oldParam)\n if (resolved) {\n resolved.name = newParamName\n syncedPathParameters.push(oldParam)\n usedOldParams.add(oldParamAtPosition)\n continue\n }\n }\n\n // Case 3: New parameter - create with empty examples\n syncedPathParameters.push({\n name: newParamName,\n in: 'path',\n })\n }\n\n // Return all parameters: synced path parameters + preserved non-path parameters\n return [...syncedPathParameters, ...nonPathParameters]\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Operation Draft Mutators\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Updates the `summary` of an operation.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationSummary(\n * document,\n * {\n * meta: { method: 'get', path: '/users/{id}' },\n * payload: { summary: 'Get a single user' },\n * })\n * ```\n */\nexport const updateOperationSummary = (\n document: WorkspaceDocument | null,\n { meta, payload: { summary } }: OperationEvents['operation:update:summary'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method as HttpMethod])\n if (!operation) {\n return\n }\n\n operation.summary = summary\n}\n\n/**\n * Stores the chosen HTTP method under `x-scalar-method` on the operation.\n * This does not move the operation to a different method slot under `paths`;\n * it records the desired method as an extension for downstream consumers.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationMethodDraft({\n * document,\n * meta: { method: 'get', path: '/users' },\n * payload: { method: 'post' },\n * })\n * ```\n */\nexport const updateOperationMethod = (\n document: WorkspaceDocument | null,\n { meta, payload: { method } }: OperationEvents['operation:update:method'],\n) => {\n const operation = getResolvedRef(document?.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n console.error('Operation not found', { meta, document })\n return\n }\n\n /** Ensure the path exists */\n const path = document?.paths?.[meta.path]\n if (!path) {\n console.error('Path not found', { meta, document })\n return\n }\n\n path[method] = unpackProxyObject(operation)\n delete path[meta.method]\n}\n\n/**\n * Moves the operation to a new path in the document and synchronizes path\n * parameters in `operation.parameters` with the placeholders present in the\n * provided `path` (e.g. `/users/{id}`). When path parameters change,\n * intelligently syncs them by preserving configurations for renamed parameters\n * (detected by position) and existing parameters. Existing non-path parameters\n * are preserved. The operation is removed from the old path location.\n *\n * Example:\n * ```ts\n * updateOperationPath({\n * document,\n * meta: { method: 'get', path: '/users/{id}' },\n * payload: { path: '/users/{userId}' },\n * })\n * ```\n */\nexport const updateOperationPath = (\n document: WorkspaceDocument | null,\n { meta, payload: { path } }: OperationEvents['operation:update:path'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n return\n }\n\n // If the path has not changed, no need to move the operation\n if (meta.path === path) {\n return\n }\n\n // Sync path parameters if either the old or new path has path parameters\n const oldPathParams = findVariables(meta.path, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n const newPathParams = findVariables(path, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n\n if (oldPathParams.length > 0 || newPathParams.length > 0) {\n const existingParameters = operation.parameters ?? []\n operation.parameters = syncParametersForPathChange(path, meta.path, existingParameters)\n }\n\n // Initialize the paths object if it does not exist\n if (!document.paths) {\n document.paths = {}\n }\n\n // Initialize the new path if it does not exist\n if (!document.paths[path]) {\n document.paths[path] = {}\n }\n\n // Move the operation to the new path\n document.paths[path][meta.method] = unpackProxyObject(operation)\n\n // Remove the operation from the old path\n const oldPath = document.paths[meta.path]\n if (oldPath) {\n delete oldPath[meta.method]\n\n // If the old path has no more operations, remove the path entry\n if (Object.keys(oldPath).length === 0) {\n delete document.paths[meta.path]\n }\n }\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Operation Parameters Mutators\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Adds a parameter to the operation with an example value tracked by `exampleKey`.\n * For `path` parameters `required` is set to true automatically.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * addOperationParameter({\n * document,\n * type: 'query',\n * meta: { method: 'get', path: '/search', exampleKey: 'default' },\n * payload: { key: 'q', value: 'john', isEnabled: true },\n * })\n * ```\n */\nexport const addOperationParameter = (\n document: WorkspaceDocument | null,\n { meta, payload, type }: OperationEvents['operation:add:parameter'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Initialize parameters array if it doesn't exist\n if (!operation.parameters) {\n operation.parameters = []\n }\n\n // Add the new parameter\n operation.parameters.push({\n name: payload.key,\n in: type,\n required: type === 'path' ? true : false,\n examples: {\n [meta.exampleKey]: {\n value: payload.value,\n 'x-disabled': !payload.isEnabled,\n },\n },\n })\n}\n\n/**\n * Updates an existing parameter of a given `type` by its index within that\n * type subset (e.g. the N-th query parameter). Supports updating name, value,\n * and enabled state for the targeted example.\n * Safely no-ops if the document, operation, or parameter does not exist.\n *\n * Example:\n * ```ts\n * updateOperationParameter({\n * document,\n * type: 'query',\n * index: 0,\n * meta: { method: 'get', path: '/search', exampleKey: 'default' },\n * payload: { value: 'alice', isEnabled: true },\n * })\n * ```\n */\nexport const updateOperationParameter = (\n document: WorkspaceDocument | null,\n { meta, type, payload, index }: OperationEvents['operation:update:parameter'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Get all resolved parameters of the specified type\n // The passed index corresponds to this filtered list\n const resolvedParameters = operation.parameters?.map((it) => getResolvedRef(it)).filter((it) => it.in === type) ?? []\n const parameter = resolvedParameters[index]\n if (!parameter) {\n return\n }\n\n parameter.name = payload.key ?? parameter.name ?? ''\n\n if (isContentTypeParameterObject(parameter)) {\n // TODO: handle content-type parameters\n return\n }\n\n if (!parameter.examples) {\n parameter.examples = {}\n }\n\n const example = getResolvedRef(parameter.examples[meta.exampleKey])\n\n // Create the example if it doesn't exist\n if (!example) {\n parameter.examples[meta.exampleKey] = {\n value: payload.value ?? '',\n 'x-disabled': payload.isEnabled === undefined ? false : !payload.isEnabled,\n }\n return\n }\n\n // Update existing example value\n example.value = payload.value ?? example?.value ?? ''\n example['x-disabled'] = payload.isEnabled === undefined ? example['x-disabled'] : !payload.isEnabled\n}\n\n/**\n * Removes a parameter from the operation by resolving its position within\n * the filtered list of parameters of the specified `type`.\n * Safely no-ops if the document, operation, or parameter does not exist.\n *\n * Example:\n * ```ts\n * deleteOperationParameter({\n * document,\n * type: 'header',\n * index: 1,\n * meta: { method: 'get', path: '/users', exampleKey: 'default' },\n * })\n * ```\n */\nexport const deleteOperationParameter = (\n document: WorkspaceDocument | null,\n { meta, index, type }: OperationEvents['operation:delete:parameter'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n // Translate the index from the filtered list to the actual parameters array\n const resolvedParameters = operation.parameters?.map((it) => getResolvedRef(it)).filter((it) => it.in === type) ?? []\n const parameter = resolvedParameters[index]\n if (!parameter) {\n return\n }\n\n const actualIndex = operation.parameters?.findIndex((it) => getResolvedRef(it) === parameter) as number\n\n // Remove the parameter from the operation\n operation.parameters?.splice(actualIndex, 1)\n}\n\n/**\n * Deletes all parameters of a given `type` from the operation.\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * deleteAllOperationParameters({\n * document,\n * type: 'cookie',\n * meta: { method: 'get', path: '/users' },\n * })\n * ```\n */\nexport const deleteAllOperationParameters = (\n document: WorkspaceDocument | null,\n { meta, type }: OperationEvents['operation:delete-all:parameters'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n return\n }\n\n // Filter out parameters of the specified type\n operation.parameters = operation.parameters?.filter((it) => getResolvedRef(it).in !== type) ?? []\n}\n\n/** ------------------------------------------------------------------------------------------------\n * Operation Request Body Mutators\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Sets the selected request-body content type for the current `exampleKey`.\n * This stores the selection under `x-scalar-selected-content-type` on the\n * resolved requestBody. Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationRequestBodyContentType({\n * document,\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * payload: { contentType: 'multipart/form-data' },\n * })\n * ```\n */\nexport const updateOperationRequestBodyContentType = (\n document: WorkspaceDocument | null,\n { meta, payload }: OperationEvents['operation:update:requestBody:contentType'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!['x-scalar-selected-content-type']) {\n requestBody!['x-scalar-selected-content-type'] = {}\n }\n\n requestBody!['x-scalar-selected-content-type'][meta.exampleKey] = payload.contentType\n}\n\n/**\n * Creates or updates a concrete example value for a specific request-body\n * `contentType` and `exampleKey`. Safely no-ops if the document or operation\n * does not exist.\n *\n * Example:\n * ```ts\n * updateOperationRequestBodyExample({\n * document,\n * contentType: 'application/json',\n * meta: { method: 'post', path: '/users', exampleKey: 'default' },\n * payload: { value: JSON.stringify({ name: 'Ada' }) },\n * })\n * ```\n */\nexport const updateOperationRequestBodyExample = (\n document: WorkspaceDocument | null,\n { meta, payload, contentType }: OperationEvents['operation:update:requestBody:value'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!.content[contentType]) {\n requestBody!.content[contentType] = {\n examples: {},\n }\n }\n\n // Ensure examples object exists and get a resolved reference\n const mediaType = requestBody!.content[contentType]!\n mediaType.examples ??= {}\n const examples = getResolvedRef(mediaType.examples)!\n\n const example = getResolvedRef(examples[meta.exampleKey])\n if (!example) {\n examples[meta.exampleKey] = {\n value: payload.value,\n }\n return\n }\n\n example.value = payload.value\n}\n\n/**\n * Appends a form-data row to the request-body example identified by\n * `contentType` and `exampleKey`. Initializes the example as an array when\n * needed. Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * addOperationRequestBodyFormRow({\n * document,\n * contentType: 'multipart/form-data',\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * payload: { key: 'file', value: new File(['x'], 'a.txt') },\n * })\n * ```\n */\nexport const addOperationRequestBodyFormRow = (\n document: WorkspaceDocument | null,\n { meta, payload, contentType }: OperationEvents['operation:add:requestBody:formRow'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n\n // Don't proceed if operation doesn't exist\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!.content[contentType]) {\n requestBody!.content[contentType] = {\n examples: {},\n }\n }\n\n if (!requestBody!.content[contentType]!.examples) {\n requestBody!.content[contentType]!.examples = {}\n }\n\n const examples = getResolvedRef(requestBody!.content[contentType]!.examples)\n\n const example = getResolvedRef(examples[meta.exampleKey])\n\n if (!example || !Array.isArray(example.value)) {\n examples[meta.exampleKey] = {\n value: [\n {\n name: payload.key,\n value: payload.value,\n },\n ],\n }\n return\n }\n\n // Add the new row to the example\n example.value.push({\n name: payload.key ?? '',\n value: payload.value ?? '',\n })\n}\n\n/**\n * Updates a form-data row at a given `index` for the specified example and\n * `contentType`. Setting `payload.value` to `null` clears the value (sets to\n * `undefined`). Safely no-ops if the document, operation, or example does not exist.\n *\n * Example:\n * ```ts\n * updateOperationRequestBodyFormRow({\n * document,\n * index: 0,\n * contentType: 'multipart/form-data',\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * payload: { key: 'description', value: 'Profile picture' },\n * })\n * ```\n */\nexport const updateOperationRequestBodyFormRow = (\n document: WorkspaceDocument | null,\n { meta, index, payload, contentType }: OperationEvents['operation:update:requestBody:formRow'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n return\n }\n\n let requestBody = getResolvedRef(operation.requestBody)\n if (!requestBody) {\n operation.requestBody = {\n content: {},\n }\n requestBody = getResolvedRef(operation.requestBody)\n }\n\n if (!requestBody!.content[contentType]) {\n return\n }\n\n const examples = getResolvedRef(requestBody!.content[contentType]!.examples)\n if (!examples) {\n return\n }\n\n const example = getResolvedRef(examples[meta.exampleKey])\n if (!example || !Array.isArray(example.value)) {\n return\n }\n\n example.value[index] = {\n name: payload.key ?? example.value[index]?.name ?? '',\n value: payload.value === null ? undefined : (payload.value ?? example.value[index]?.value ?? ''),\n }\n}\n\n/**\n * Deletes a form-data row at a given `index` from the example for the given\n * `contentType`. If the example becomes empty, the example entry is removed.\n * Safely no-ops if the document, operation, example, or row does not exist.\n *\n * Example:\n * ```ts\n * deleteOperationRequestBodyFormRow({\n * document,\n * index: 0,\n * contentType: 'multipart/form-data',\n * meta: { method: 'post', path: '/upload', exampleKey: 'default' },\n * })\n * ```\n */\nexport const deleteOperationRequestBodyFormRow = (\n document: WorkspaceDocument | null,\n { meta, index, contentType }: OperationEvents['operation:delete:requestBody:formRow'],\n) => {\n if (!document) {\n return\n }\n\n const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method])\n if (!operation) {\n return\n }\n\n const requestBody = getResolvedRef(operation.requestBody)\n if (!requestBody) {\n return\n }\n\n if (!requestBody.content[contentType]) {\n return\n }\n\n const examples = getResolvedRef(requestBody.content[contentType]!.examples)\n if (!examples) {\n return\n }\n\n const example = getResolvedRef(examples[meta.exampleKey])\n if (!example || !Array.isArray(example.value)) {\n return\n }\n\n example.value.splice(index, 1)\n\n if (example.value.length === 0) {\n delete requestBody.content[contentType]!.examples![meta.exampleKey]\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,qBAAqB;AAG9B,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAIlC,SAAS,oCAAoC;AAyC7C,MAAM,wBAAwB,CAAC,MAAc,eAA0D;AACrG,QAAM,YAAoC,CAAC;AAE3C,aAAW,aAAa,YAAY;AAClC,UAAM,WAAW,KAAK,QAAQ,IAAI,SAAS,GAAG;AAC9C,QAAI,aAAa,IAAI;AACnB,gBAAU,SAAS,IAAI;AAAA,IACzB;AAAA,EACF;AAEA,SAAO;AACT;AAWA,MAAM,8BAA8B,CAClC,SACA,SACA,uBACqC;AAErC,QAAM,gBAAgB,cAAc,SAAS,EAAE,aAAa,MAAM,YAAY,MAAM,CAAC,EAAE;AAAA,IACrF,CAAC,MAAmB,MAAM;AAAA,EAC5B;AACA,QAAM,gBAAgB,cAAc,SAAS,EAAE,aAAa,MAAM,YAAY,MAAM,CAAC,EAAE;AAAA,IACrF,CAAC,MAAmB,MAAM;AAAA,EAC5B;AAEA,QAAM,eAAe,sBAAsB,SAAS,aAAa;AACjE,QAAM,eAAe,sBAAsB,SAAS,aAAa;AAGjE,QAAM,iBAAmD,CAAC;AAC1D,QAAM,oBAAsD,CAAC;AAE7D,aAAW,SAAS,oBAAoB;AACtC,UAAM,WAAW,eAAe,KAAK;AACrC,QAAI,UAAU,OAAO,QAAQ;AAC3B,qBAAe,KAAK,KAAK;AAAA,IAC3B,OAAO;AACL,wBAAkB,KAAK,KAAK;AAAA,IAC9B;AAAA,EACF;AAGA,QAAM,2BAA2B,oBAAI,IAA4C;AACjF,aAAW,SAAS,gBAAgB;AAClC,UAAM,WAAW,eAAe,KAAK;AACrC,QAAI,UAAU,MAAM;AAClB,+BAAyB,IAAI,SAAS,MAAM,KAAK;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,uBAAyD,CAAC;AAEhE,aAAW,gBAAgB,eAAe;AAExC,QAAI,yBAAyB,IAAI,YAAY,GAAG;AAC9C,2BAAqB,KAAK,yBAAyB,IAAI,YAAY,CAAE;AACrE,oBAAc,IAAI,YAAY;AAC9B;AAAA,IACF;AAGA,UAAM,mBAAmB,aAAa,YAAY;AAClD,UAAM,qBAAqB,cAAc;AAAA,MACvC,CAAC,aAAa,aAAa,QAAQ,MAAM,oBAAoB,CAAC,cAAc,IAAI,QAAQ;AAAA,IAC1F;AAEA,QAAI,sBAAsB,yBAAyB,IAAI,kBAAkB,GAAG;AAE1E,YAAM,WAAW,yBAAyB,IAAI,kBAAkB;AAChE,YAAM,WAAW,eAAe,QAAQ;AACxC,UAAI,UAAU;AACZ,iBAAS,OAAO;AAChB,6BAAqB,KAAK,QAAQ;AAClC,sBAAc,IAAI,kBAAkB;AACpC;AAAA,MACF;AAAA,IACF;AAGA,yBAAqB,KAAK;AAAA,MACxB,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AAAA,EACH;AAGA,SAAO,CAAC,GAAG,sBAAsB,GAAG,iBAAiB;AACvD;AAoBO,MAAM,yBAAyB,CACpC,UACA,EAAE,MAAM,SAAS,EAAE,QAAQ,EAAE,MAC1B;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAoB,CAAC;AACzF,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,YAAU,UAAU;AACtB;AAiBO,MAAM,wBAAwB,CACnC,UACA,EAAE,MAAM,SAAS,EAAE,OAAO,EAAE,MACzB;AACH,QAAM,YAAY,eAAe,UAAU,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC5E,MAAI,CAAC,WAAW;AACd,YAAQ,MAAM,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvD;AAAA,EACF;AAGA,QAAM,OAAO,UAAU,QAAQ,KAAK,IAAI;AACxC,MAAI,CAAC,MAAM;AACT,YAAQ,MAAM,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClD;AAAA,EACF;AAEA,OAAK,MAAM,IAAI,kBAAkB,SAAS;AAC1C,SAAO,KAAK,KAAK,MAAM;AACzB;AAmBO,MAAM,sBAAsB,CACjC,UACA,EAAE,MAAM,SAAS,EAAE,KAAK,EAAE,MACvB;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAGA,MAAI,KAAK,SAAS,MAAM;AACtB;AAAA,EACF;AAGA,QAAM,gBAAgB,cAAc,KAAK,MAAM,EAAE,aAAa,MAAM,YAAY,MAAM,CAAC,EAAE;AAAA,IACvF,CAAC,MAAmB,MAAM;AAAA,EAC5B;AACA,QAAM,gBAAgB,cAAc,MAAM,EAAE,aAAa,MAAM,YAAY,MAAM,CAAC,EAAE;AAAA,IAClF,CAAC,MAAmB,MAAM;AAAA,EAC5B;AAEA,MAAI,cAAc,SAAS,KAAK,cAAc,SAAS,GAAG;AACxD,UAAM,qBAAqB,UAAU,cAAc,CAAC;AACpD,cAAU,aAAa,4BAA4B,MAAM,KAAK,MAAM,kBAAkB;AAAA,EACxF;AAGA,MAAI,CAAC,SAAS,OAAO;AACnB,aAAS,QAAQ,CAAC;AAAA,EACpB;AAGA,MAAI,CAAC,SAAS,MAAM,IAAI,GAAG;AACzB,aAAS,MAAM,IAAI,IAAI,CAAC;AAAA,EAC1B;AAGA,WAAS,MAAM,IAAI,EAAE,KAAK,MAAM,IAAI,kBAAkB,SAAS;AAG/D,QAAM,UAAU,SAAS,MAAM,KAAK,IAAI;AACxC,MAAI,SAAS;AACX,WAAO,QAAQ,KAAK,MAAM;AAG1B,QAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACrC,aAAO,SAAS,MAAM,KAAK,IAAI;AAAA,IACjC;AAAA,EACF;AACF;AAqBO,MAAM,wBAAwB,CACnC,UACA,EAAE,MAAM,SAAS,KAAK,MACnB;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAG3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAGA,MAAI,CAAC,UAAU,YAAY;AACzB,cAAU,aAAa,CAAC;AAAA,EAC1B;AAGA,YAAU,WAAW,KAAK;AAAA,IACxB,MAAM,QAAQ;AAAA,IACd,IAAI;AAAA,IACJ,UAAU,SAAS,SAAS,OAAO;AAAA,IACnC,UAAU;AAAA,MACR,CAAC,KAAK,UAAU,GAAG;AAAA,QACjB,OAAO,QAAQ;AAAA,QACf,cAAc,CAAC,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAmBO,MAAM,2BAA2B,CACtC,UACA,EAAE,MAAM,MAAM,SAAS,MAAM,MAC1B;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAG3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAIA,QAAM,qBAAqB,UAAU,YAAY,IAAI,CAAC,OAAO,eAAe,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,IAAI,KAAK,CAAC;AACpH,QAAM,YAAY,mBAAmB,KAAK;AAC1C,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,YAAU,OAAO,QAAQ,OAAO,UAAU,QAAQ;AAElD,MAAI,6BAA6B,SAAS,GAAG;AAE3C;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,UAAU;AACvB,cAAU,WAAW,CAAC;AAAA,EACxB;AAEA,QAAM,UAAU,eAAe,UAAU,SAAS,KAAK,UAAU,CAAC;AAGlE,MAAI,CAAC,SAAS;AACZ,cAAU,SAAS,KAAK,UAAU,IAAI;AAAA,MACpC,OAAO,QAAQ,SAAS;AAAA,MACxB,cAAc,QAAQ,cAAc,SAAY,QAAQ,CAAC,QAAQ;AAAA,IACnE;AACA;AAAA,EACF;AAGA,UAAQ,QAAQ,QAAQ,SAAS,SAAS,SAAS;AACnD,UAAQ,YAAY,IAAI,QAAQ,cAAc,SAAY,QAAQ,YAAY,IAAI,CAAC,QAAQ;AAC7F;AAiBO,MAAM,2BAA2B,CACtC,UACA,EAAE,MAAM,OAAO,KAAK,MACjB;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAG3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAGA,QAAM,qBAAqB,UAAU,YAAY,IAAI,CAAC,OAAO,eAAe,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,IAAI,KAAK,CAAC;AACpH,QAAM,YAAY,mBAAmB,KAAK;AAC1C,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,QAAM,cAAc,UAAU,YAAY,UAAU,CAAC,OAAO,eAAe,EAAE,MAAM,SAAS;AAG5F,YAAU,YAAY,OAAO,aAAa,CAAC;AAC7C;AAeO,MAAM,+BAA+B,CAC1C,UACA,EAAE,MAAM,KAAK,MACV;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAGA,YAAU,aAAa,UAAU,YAAY,OAAO,CAAC,OAAO,eAAe,EAAE,EAAE,OAAO,IAAI,KAAK,CAAC;AAClG;AAoBO,MAAM,wCAAwC,CACnD,UACA,EAAE,MAAM,QAAQ,MACb;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,MAAI,cAAc,eAAe,UAAU,WAAW;AACtD,MAAI,CAAC,aAAa;AAChB,cAAU,cAAc;AAAA,MACtB,SAAS,CAAC;AAAA,IACZ;AACA,kBAAc,eAAe,UAAU,WAAW;AAAA,EACpD;AAEA,MAAI,CAAC,YAAa,gCAAgC,GAAG;AACnD,gBAAa,gCAAgC,IAAI,CAAC;AAAA,EACpD;AAEA,cAAa,gCAAgC,EAAE,KAAK,UAAU,IAAI,QAAQ;AAC5E;AAiBO,MAAM,oCAAoC,CAC/C,UACA,EAAE,MAAM,SAAS,YAAY,MAC1B;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,MAAI,cAAc,eAAe,UAAU,WAAW;AACtD,MAAI,CAAC,aAAa;AAChB,cAAU,cAAc;AAAA,MACtB,SAAS,CAAC;AAAA,IACZ;AACA,kBAAc,eAAe,UAAU,WAAW;AAAA,EACpD;AAEA,MAAI,CAAC,YAAa,QAAQ,WAAW,GAAG;AACtC,gBAAa,QAAQ,WAAW,IAAI;AAAA,MAClC,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AAGA,QAAM,YAAY,YAAa,QAAQ,WAAW;AAClD,YAAU,aAAa,CAAC;AACxB,QAAM,WAAW,eAAe,UAAU,QAAQ;AAElD,QAAM,UAAU,eAAe,SAAS,KAAK,UAAU,CAAC;AACxD,MAAI,CAAC,SAAS;AACZ,aAAS,KAAK,UAAU,IAAI;AAAA,MAC1B,OAAO,QAAQ;AAAA,IACjB;AACA;AAAA,EACF;AAEA,UAAQ,QAAQ,QAAQ;AAC1B;AAiBO,MAAM,iCAAiC,CAC5C,UACA,EAAE,MAAM,SAAS,YAAY,MAC1B;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAG3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,MAAI,cAAc,eAAe,UAAU,WAAW;AAEtD,MAAI,CAAC,aAAa;AAChB,cAAU,cAAc;AAAA,MACtB,SAAS,CAAC;AAAA,IACZ;AACA,kBAAc,eAAe,UAAU,WAAW;AAAA,EACpD;AAEA,MAAI,CAAC,YAAa,QAAQ,WAAW,GAAG;AACtC,gBAAa,QAAQ,WAAW,IAAI;AAAA,MAClC,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AAEA,MAAI,CAAC,YAAa,QAAQ,WAAW,EAAG,UAAU;AAChD,gBAAa,QAAQ,WAAW,EAAG,WAAW,CAAC;AAAA,EACjD;AAEA,QAAM,WAAW,eAAe,YAAa,QAAQ,WAAW,EAAG,QAAQ;AAE3E,QAAM,UAAU,eAAe,SAAS,KAAK,UAAU,CAAC;AAExD,MAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,QAAQ,KAAK,GAAG;AAC7C,aAAS,KAAK,UAAU,IAAI;AAAA,MAC1B,OAAO;AAAA,QACL;AAAA,UACE,MAAM,QAAQ;AAAA,UACd,OAAO,QAAQ;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AAGA,UAAQ,MAAM,KAAK;AAAA,IACjB,MAAM,QAAQ,OAAO;AAAA,IACrB,OAAO,QAAQ,SAAS;AAAA,EAC1B,CAAC;AACH;AAkBO,MAAM,oCAAoC,CAC/C,UACA,EAAE,MAAM,OAAO,SAAS,YAAY,MACjC;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,MAAI,cAAc,eAAe,UAAU,WAAW;AACtD,MAAI,CAAC,aAAa;AAChB,cAAU,cAAc;AAAA,MACtB,SAAS,CAAC;AAAA,IACZ;AACA,kBAAc,eAAe,UAAU,WAAW;AAAA,EACpD;AAEA,MAAI,CAAC,YAAa,QAAQ,WAAW,GAAG;AACtC;AAAA,EACF;AAEA,QAAM,WAAW,eAAe,YAAa,QAAQ,WAAW,EAAG,QAAQ;AAC3E,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,UAAU,eAAe,SAAS,KAAK,UAAU,CAAC;AACxD,MAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,QAAQ,KAAK,GAAG;AAC7C;AAAA,EACF;AAEA,UAAQ,MAAM,KAAK,IAAI;AAAA,IACrB,MAAM,QAAQ,OAAO,QAAQ,MAAM,KAAK,GAAG,QAAQ;AAAA,IACnD,OAAO,QAAQ,UAAU,OAAO,SAAa,QAAQ,SAAS,QAAQ,MAAM,KAAK,GAAG,SAAS;AAAA,EAC/F;AACF;AAiBO,MAAM,oCAAoC,CAC/C,UACA,EAAE,MAAM,OAAO,YAAY,MACxB;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,YAAY,eAAe,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AAC3E,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,QAAM,cAAc,eAAe,UAAU,WAAW;AACxD,MAAI,CAAC,aAAa;AAChB;AAAA,EACF;AAEA,MAAI,CAAC,YAAY,QAAQ,WAAW,GAAG;AACrC;AAAA,EACF;AAEA,QAAM,WAAW,eAAe,YAAY,QAAQ,WAAW,EAAG,QAAQ;AAC1E,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,QAAM,UAAU,eAAe,SAAS,KAAK,UAAU,CAAC;AACxD,MAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,QAAQ,KAAK,GAAG;AAC7C;AAAA,EACF;AAEA,UAAQ,MAAM,OAAO,OAAO,CAAC;AAE7B,MAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,WAAO,YAAY,QAAQ,WAAW,EAAG,SAAU,KAAK,UAAU;AAAA,EACpE;AACF;",
6
6
  "names": []
7
7
  }
@@ -43,5 +43,5 @@ export declare const updateServerVariables: (document: WorkspaceDocument | null,
43
43
  * @param index - The index of the server to update
44
44
  * @returns the url of the selected server or undefined if the server is not found
45
45
  */
46
- export declare const updateSelectedServer: (document: WorkspaceDocument | null, { index }: ServerEvents["server:update:selected"]) => string | undefined;
46
+ export declare const updateSelectedServer: (document: WorkspaceDocument | null, { url }: ServerEvents["server:update:selected"]) => string | undefined;
47
47
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mutators/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,wCAAwC,CAAA;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAI,UAAU,iBAAiB,GAAG,IAAI,KAAG,YAAY,GAAG,SAc7E,CAAA;AAgFD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,YAAY,CAAC,sBAAsB,CAAC,KACtD,YAAY,GAAG,SA+BjB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,WAAW,YAAY,CAAC,sBAAsB,CAAC,SAY/G,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAChC,UAAU,iBAAiB,GAAG,IAAI,EAClC,uBAAuB,YAAY,CAAC,yBAAyB,CAAC,sFAkB/D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,iBAAiB,GAAG,IAAI,EAClC,WAAW,YAAY,CAAC,wBAAwB,CAAC,KAChD,MAAM,GAAG,SAUX,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mutators/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,wCAAwC,CAAA;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAI,UAAU,iBAAiB,GAAG,IAAI,KAAG,YAAY,GAAG,SAc7E,CAAA;AAgFD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,YAAY,CAAC,sBAAsB,CAAC,KACtD,YAAY,GAAG,SA+BjB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,WAAW,YAAY,CAAC,sBAAsB,CAAC,SAY/G,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAChC,UAAU,iBAAiB,GAAG,IAAI,EAClC,uBAAuB,YAAY,CAAC,yBAAyB,CAAC,sFAkB/D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,YAAY,CAAC,wBAAwB,CAAC,KAC9C,MAAM,GAAG,SAaX,CAAA"}
@@ -99,13 +99,14 @@ const updateServerVariables = (document, { index, key, value }) => {
99
99
  }
100
100
  return variable;
101
101
  };
102
- const updateSelectedServer = (document, { index }) => {
103
- const url = document?.servers?.[index]?.url;
104
- if (!url) {
105
- console.error("Server not found", index, document?.servers);
102
+ const updateSelectedServer = (document, { url }) => {
103
+ if (!document) {
104
+ return;
105
+ }
106
+ if (!document.servers?.some((server) => server.url === url)) {
106
107
  return;
107
108
  }
108
- document["x-scalar-selected-server"] = url;
109
+ document["x-scalar-selected-server"] = document["x-scalar-selected-server"] === url ? void 0 : url;
109
110
  return document["x-scalar-selected-server"];
110
111
  };
111
112
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/server.ts"],
4
- "sourcesContent": ["import { findVariables } from '@scalar/helpers/regex/find-variables'\n\nimport type { ServerEvents } from '@/events/definitions/server'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport { type ServerObject, ServerObjectSchema } from '@/schemas/v3.1/strict/openapi-document'\nimport type { WorkspaceDocument } from '@/schemas/workspace'\n\n/**\n * Adds a new ServerObject to the document.\n *\n * @param document - The document to add the server to\n * @returns the new server object or undefined if the document is not found\n */\nexport const addServer = (document: WorkspaceDocument | null): ServerObject | undefined => {\n if (!document) {\n return undefined\n }\n\n const parsed = coerceValue(ServerObjectSchema, {})\n\n // Initialize the servers array if it doesn't exist\n if (!document.servers) {\n document.servers = []\n }\n\n document.servers.push(parsed)\n return parsed\n}\n\n/**\n * Creates a map of variable names to their character positions in a URL.\n * Used to detect renamed variables by position matching.\n */\nconst getVariablePositions = (url: string, variables: readonly string[]): Record<string, number> => {\n const positions: Record<string, number> = {}\n\n for (const varName of variables) {\n const position = url.indexOf(`{${varName}}`)\n if (position !== -1) {\n positions[varName] = position\n }\n }\n\n return positions\n}\n\ntype VariableConfig = {\n description?: string\n default?: string\n enum?: string[]\n}\n\n/**\n * Syncs server variables when the URL changes.\n *\n * Preserves variable configurations by:\n * 1. Keeping variables with matching names\n * 2. Renaming variables at the same position\n * 3. Creating new variables with empty defaults\n */\nconst syncVariablesForUrlChange = (\n newUrl: string,\n oldUrl: string,\n existingVariables: Record<string, VariableConfig>,\n): Record<string, VariableConfig> => {\n // Filter out undefined values from findVariables results\n const oldVariables = findVariables(oldUrl, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n const newVariables = findVariables(newUrl, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n\n const oldPositions = getVariablePositions(oldUrl, oldVariables)\n const newPositions = getVariablePositions(newUrl, newVariables)\n\n const usedOldVariables = new Set<string>()\n const syncedVariables: Record<string, VariableConfig> = {}\n\n for (const newVar of newVariables) {\n // Case 1: Variable with same name exists - preserve its config\n if (existingVariables[newVar]) {\n syncedVariables[newVar] = existingVariables[newVar]\n usedOldVariables.add(newVar)\n continue\n }\n\n // Case 2: Check for variable at same position (likely a rename)\n const newVarPosition = newPositions[newVar]\n const oldVarAtPosition = oldVariables.find(\n (oldVar) => oldPositions[oldVar] === newVarPosition && !usedOldVariables.has(oldVar),\n )\n\n if (oldVarAtPosition && existingVariables[oldVarAtPosition]) {\n // Rename: transfer the old variable's config to the new name\n syncedVariables[newVar] = existingVariables[oldVarAtPosition]\n usedOldVariables.add(oldVarAtPosition)\n continue\n }\n\n // Case 3: New variable - create with empty default\n syncedVariables[newVar] = { default: '' }\n }\n\n return syncedVariables\n}\n\n/**\n * Updates a ServerObject in the document.\n * When the URL changes, intelligently syncs variables by preserving configurations\n * for renamed variables (detected by position) and existing variables.\n *\n * @param document - The document containing the server to update\n * @param index - The index of the server to update\n * @param server - The partial server object with fields to update\n * @returns the updated server object or undefined if the server is not found\n */\nexport const updateServer = (\n document: WorkspaceDocument | null,\n { index, server }: ServerEvents['server:update:server'],\n): ServerObject | undefined => {\n const oldServer = document?.servers?.[index]\n\n if (!oldServer) {\n console.error('Server not found at index:', index)\n return undefined\n }\n\n const oldUrl = oldServer.url\n const updatedServer = coerceValue(ServerObjectSchema, { ...oldServer, ...server })\n\n // Sync variables if the URL changed\n const hasUrlChanged = oldUrl && oldUrl !== updatedServer.url\n if (hasUrlChanged) {\n const existingVariables = updatedServer.variables ?? {}\n updatedServer.variables = syncVariablesForUrlChange(updatedServer.url, oldUrl, existingVariables)\n\n // If the selected server is the one being updated, set the selected server to the new server\n if (document['x-scalar-selected-server'] === oldUrl) {\n document['x-scalar-selected-server'] = updatedServer.url\n }\n }\n\n // Ensure servers array exists and update the server at the specified index\n if (!document.servers) {\n document.servers = [updatedServer]\n } else {\n document.servers[index] = updatedServer\n }\n\n return updatedServer\n}\n\n/**\n * Deletes a ServerObject at the specified index from the target array.\n *\n * @param document - The document to delete the server from\n * @param index - The index of the server to delete.\n */\nexport const deleteServer = (document: WorkspaceDocument | null, { index }: ServerEvents['server:delete:server']) => {\n if (!document?.servers) {\n return\n }\n\n const url = document.servers[index]?.url\n document.servers.splice(index, 1)\n\n // If the selected server is the one being deleted, set the selected server to the first one after removal\n if (document['x-scalar-selected-server'] === url) {\n document['x-scalar-selected-server'] = document.servers[0]?.url ?? undefined\n }\n}\n\n/**\n * Updates a server variable for the selected server\n *\n * @param document - The document to update the server variables in\n * @param index - The index of the server to update\n * @param key - The key of the variable to update\n * @param value - The new value of the variable\n * @returns the updated variable or undefined if the variable is not found\n */\nexport const updateServerVariables = (\n document: WorkspaceDocument | null,\n { index, key, value }: ServerEvents['server:update:variables'],\n) => {\n const variable = document?.servers?.[index]?.variables?.[key]\n if (!variable) {\n console.error('Variable not found', key, index)\n return\n }\n\n variable.default = value\n\n // Now we need to make the url reflect the new variable value\n const url = document?.servers?.[index]?.url\n if (!url) {\n console.error('URL not found', index)\n return\n }\n\n return variable\n}\n\n/**\n * Updates the selected server for the document\n *\n * @param document - The document to update the selected server in\n * @param index - The index of the server to update\n * @returns the url of the selected server or undefined if the server is not found\n */\nexport const updateSelectedServer = (\n document: WorkspaceDocument | null,\n { index }: ServerEvents['server:update:selected'],\n): string | undefined => {\n const url = document?.servers?.[index]?.url\n if (!url) {\n console.error('Server not found', index, document?.servers)\n return\n }\n\n // Set it and return the url\n document['x-scalar-selected-server'] = url\n return document['x-scalar-selected-server']\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { findVariables } from '@scalar/helpers/regex/find-variables'\n\nimport type { ServerEvents } from '@/events/definitions/server'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport { type ServerObject, ServerObjectSchema } from '@/schemas/v3.1/strict/openapi-document'\nimport type { WorkspaceDocument } from '@/schemas/workspace'\n\n/**\n * Adds a new ServerObject to the document.\n *\n * @param document - The document to add the server to\n * @returns the new server object or undefined if the document is not found\n */\nexport const addServer = (document: WorkspaceDocument | null): ServerObject | undefined => {\n if (!document) {\n return undefined\n }\n\n const parsed = coerceValue(ServerObjectSchema, {})\n\n // Initialize the servers array if it doesn't exist\n if (!document.servers) {\n document.servers = []\n }\n\n document.servers.push(parsed)\n return parsed\n}\n\n/**\n * Creates a map of variable names to their character positions in a URL.\n * Used to detect renamed variables by position matching.\n */\nconst getVariablePositions = (url: string, variables: readonly string[]): Record<string, number> => {\n const positions: Record<string, number> = {}\n\n for (const varName of variables) {\n const position = url.indexOf(`{${varName}}`)\n if (position !== -1) {\n positions[varName] = position\n }\n }\n\n return positions\n}\n\ntype VariableConfig = {\n description?: string\n default?: string\n enum?: string[]\n}\n\n/**\n * Syncs server variables when the URL changes.\n *\n * Preserves variable configurations by:\n * 1. Keeping variables with matching names\n * 2. Renaming variables at the same position\n * 3. Creating new variables with empty defaults\n */\nconst syncVariablesForUrlChange = (\n newUrl: string,\n oldUrl: string,\n existingVariables: Record<string, VariableConfig>,\n): Record<string, VariableConfig> => {\n // Filter out undefined values from findVariables results\n const oldVariables = findVariables(oldUrl, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n const newVariables = findVariables(newUrl, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n\n const oldPositions = getVariablePositions(oldUrl, oldVariables)\n const newPositions = getVariablePositions(newUrl, newVariables)\n\n const usedOldVariables = new Set<string>()\n const syncedVariables: Record<string, VariableConfig> = {}\n\n for (const newVar of newVariables) {\n // Case 1: Variable with same name exists - preserve its config\n if (existingVariables[newVar]) {\n syncedVariables[newVar] = existingVariables[newVar]\n usedOldVariables.add(newVar)\n continue\n }\n\n // Case 2: Check for variable at same position (likely a rename)\n const newVarPosition = newPositions[newVar]\n const oldVarAtPosition = oldVariables.find(\n (oldVar) => oldPositions[oldVar] === newVarPosition && !usedOldVariables.has(oldVar),\n )\n\n if (oldVarAtPosition && existingVariables[oldVarAtPosition]) {\n // Rename: transfer the old variable's config to the new name\n syncedVariables[newVar] = existingVariables[oldVarAtPosition]\n usedOldVariables.add(oldVarAtPosition)\n continue\n }\n\n // Case 3: New variable - create with empty default\n syncedVariables[newVar] = { default: '' }\n }\n\n return syncedVariables\n}\n\n/**\n * Updates a ServerObject in the document.\n * When the URL changes, intelligently syncs variables by preserving configurations\n * for renamed variables (detected by position) and existing variables.\n *\n * @param document - The document containing the server to update\n * @param index - The index of the server to update\n * @param server - The partial server object with fields to update\n * @returns the updated server object or undefined if the server is not found\n */\nexport const updateServer = (\n document: WorkspaceDocument | null,\n { index, server }: ServerEvents['server:update:server'],\n): ServerObject | undefined => {\n const oldServer = document?.servers?.[index]\n\n if (!oldServer) {\n console.error('Server not found at index:', index)\n return undefined\n }\n\n const oldUrl = oldServer.url\n const updatedServer = coerceValue(ServerObjectSchema, { ...oldServer, ...server })\n\n // Sync variables if the URL changed\n const hasUrlChanged = oldUrl && oldUrl !== updatedServer.url\n if (hasUrlChanged) {\n const existingVariables = updatedServer.variables ?? {}\n updatedServer.variables = syncVariablesForUrlChange(updatedServer.url, oldUrl, existingVariables)\n\n // If the selected server is the one being updated, set the selected server to the new server\n if (document['x-scalar-selected-server'] === oldUrl) {\n document['x-scalar-selected-server'] = updatedServer.url\n }\n }\n\n // Ensure servers array exists and update the server at the specified index\n if (!document.servers) {\n document.servers = [updatedServer]\n } else {\n document.servers[index] = updatedServer\n }\n\n return updatedServer\n}\n\n/**\n * Deletes a ServerObject at the specified index from the target array.\n *\n * @param document - The document to delete the server from\n * @param index - The index of the server to delete.\n */\nexport const deleteServer = (document: WorkspaceDocument | null, { index }: ServerEvents['server:delete:server']) => {\n if (!document?.servers) {\n return\n }\n\n const url = document.servers[index]?.url\n document.servers.splice(index, 1)\n\n // If the selected server is the one being deleted, set the selected server to the first one after removal\n if (document['x-scalar-selected-server'] === url) {\n document['x-scalar-selected-server'] = document.servers[0]?.url ?? undefined\n }\n}\n\n/**\n * Updates a server variable for the selected server\n *\n * @param document - The document to update the server variables in\n * @param index - The index of the server to update\n * @param key - The key of the variable to update\n * @param value - The new value of the variable\n * @returns the updated variable or undefined if the variable is not found\n */\nexport const updateServerVariables = (\n document: WorkspaceDocument | null,\n { index, key, value }: ServerEvents['server:update:variables'],\n) => {\n const variable = document?.servers?.[index]?.variables?.[key]\n if (!variable) {\n console.error('Variable not found', key, index)\n return\n }\n\n variable.default = value\n\n // Now we need to make the url reflect the new variable value\n const url = document?.servers?.[index]?.url\n if (!url) {\n console.error('URL not found', index)\n return\n }\n\n return variable\n}\n\n/**\n * Updates the selected server for the document\n *\n * @param document - The document to update the selected server in\n * @param index - The index of the server to update\n * @returns the url of the selected server or undefined if the server is not found\n */\nexport const updateSelectedServer = (\n document: WorkspaceDocument | null,\n { url }: ServerEvents['server:update:selected'],\n): string | undefined => {\n if (!document) {\n return\n }\n\n // If no servers match then return undefined\n if (!document.servers?.some((server) => server.url === url)) {\n return\n }\n\n // [un]set it and return the url\n document['x-scalar-selected-server'] = document['x-scalar-selected-server'] === url ? undefined : url\n return document['x-scalar-selected-server']\n}\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAG9B,SAAS,mBAAmB;AAC5B,SAA4B,0BAA0B;AAS/C,MAAM,YAAY,CAAC,aAAiE;AACzF,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,YAAY,oBAAoB,CAAC,CAAC;AAGjD,MAAI,CAAC,SAAS,SAAS;AACrB,aAAS,UAAU,CAAC;AAAA,EACtB;AAEA,WAAS,QAAQ,KAAK,MAAM;AAC5B,SAAO;AACT;AAMA,MAAM,uBAAuB,CAAC,KAAa,cAAyD;AAClG,QAAM,YAAoC,CAAC;AAE3C,aAAW,WAAW,WAAW;AAC/B,UAAM,WAAW,IAAI,QAAQ,IAAI,OAAO,GAAG;AAC3C,QAAI,aAAa,IAAI;AACnB,gBAAU,OAAO,IAAI;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAgBA,MAAM,4BAA4B,CAChC,QACA,QACA,sBACmC;AAEnC,QAAM,eAAe,cAAc,QAAQ,EAAE,aAAa,MAAM,YAAY,MAAM,CAAC,EAAE;AAAA,IACnF,CAAC,MAAmB,MAAM;AAAA,EAC5B;AACA,QAAM,eAAe,cAAc,QAAQ,EAAE,aAAa,MAAM,YAAY,MAAM,CAAC,EAAE;AAAA,IACnF,CAAC,MAAmB,MAAM;AAAA,EAC5B;AAEA,QAAM,eAAe,qBAAqB,QAAQ,YAAY;AAC9D,QAAM,eAAe,qBAAqB,QAAQ,YAAY;AAE9D,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,kBAAkD,CAAC;AAEzD,aAAW,UAAU,cAAc;AAEjC,QAAI,kBAAkB,MAAM,GAAG;AAC7B,sBAAgB,MAAM,IAAI,kBAAkB,MAAM;AAClD,uBAAiB,IAAI,MAAM;AAC3B;AAAA,IACF;AAGA,UAAM,iBAAiB,aAAa,MAAM;AAC1C,UAAM,mBAAmB,aAAa;AAAA,MACpC,CAAC,WAAW,aAAa,MAAM,MAAM,kBAAkB,CAAC,iBAAiB,IAAI,MAAM;AAAA,IACrF;AAEA,QAAI,oBAAoB,kBAAkB,gBAAgB,GAAG;AAE3D,sBAAgB,MAAM,IAAI,kBAAkB,gBAAgB;AAC5D,uBAAiB,IAAI,gBAAgB;AACrC;AAAA,IACF;AAGA,oBAAgB,MAAM,IAAI,EAAE,SAAS,GAAG;AAAA,EAC1C;AAEA,SAAO;AACT;AAYO,MAAM,eAAe,CAC1B,UACA,EAAE,OAAO,OAAO,MACa;AAC7B,QAAM,YAAY,UAAU,UAAU,KAAK;AAE3C,MAAI,CAAC,WAAW;AACd,YAAQ,MAAM,8BAA8B,KAAK;AACjD,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,UAAU;AACzB,QAAM,gBAAgB,YAAY,oBAAoB,EAAE,GAAG,WAAW,GAAG,OAAO,CAAC;AAGjF,QAAM,gBAAgB,UAAU,WAAW,cAAc;AACzD,MAAI,eAAe;AACjB,UAAM,oBAAoB,cAAc,aAAa,CAAC;AACtD,kBAAc,YAAY,0BAA0B,cAAc,KAAK,QAAQ,iBAAiB;AAGhG,QAAI,SAAS,0BAA0B,MAAM,QAAQ;AACnD,eAAS,0BAA0B,IAAI,cAAc;AAAA,IACvD;AAAA,EACF;AAGA,MAAI,CAAC,SAAS,SAAS;AACrB,aAAS,UAAU,CAAC,aAAa;AAAA,EACnC,OAAO;AACL,aAAS,QAAQ,KAAK,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAQO,MAAM,eAAe,CAAC,UAAoC,EAAE,MAAM,MAA4C;AACnH,MAAI,CAAC,UAAU,SAAS;AACtB;AAAA,EACF;AAEA,QAAM,MAAM,SAAS,QAAQ,KAAK,GAAG;AACrC,WAAS,QAAQ,OAAO,OAAO,CAAC;AAGhC,MAAI,SAAS,0BAA0B,MAAM,KAAK;AAChD,aAAS,0BAA0B,IAAI,SAAS,QAAQ,CAAC,GAAG,OAAO;AAAA,EACrE;AACF;AAWO,MAAM,wBAAwB,CACnC,UACA,EAAE,OAAO,KAAK,MAAM,MACjB;AACH,QAAM,WAAW,UAAU,UAAU,KAAK,GAAG,YAAY,GAAG;AAC5D,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM,sBAAsB,KAAK,KAAK;AAC9C;AAAA,EACF;AAEA,WAAS,UAAU;AAGnB,QAAM,MAAM,UAAU,UAAU,KAAK,GAAG;AACxC,MAAI,CAAC,KAAK;AACR,YAAQ,MAAM,iBAAiB,KAAK;AACpC;AAAA,EACF;AAEA,SAAO;AACT;AASO,MAAM,uBAAuB,CAClC,UACA,EAAE,IAAI,MACiB;AACvB,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAGA,MAAI,CAAC,SAAS,SAAS,KAAK,CAAC,WAAW,OAAO,QAAQ,GAAG,GAAG;AAC3D;AAAA,EACF;AAGA,WAAS,0BAA0B,IAAI,SAAS,0BAA0B,MAAM,MAAM,SAAY;AAClG,SAAO,SAAS,0BAA0B;AAC5C;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,6 @@
1
+ import type { WorkspaceEvents } from '../events/definitions/workspace.js';
2
+ import type { Workspace } from '../schemas.js';
3
+ export declare const updateActiveProxy: (workspace: Workspace | null, payload: WorkspaceEvents["workspace:update:active-proxy"]) => void;
4
+ export declare const updateColorMode: (workspace: Workspace | null, payload: WorkspaceEvents["workspace:update:color-mode"]) => void;
5
+ export declare const updateTheme: (workspace: Workspace | null, payload: WorkspaceEvents["workspace:update:theme"]) => void;
6
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/mutators/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,SAAS,eAAe,CAAC,+BAA+B,CAAC,SAM1D,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,WAAW,SAAS,GAAG,IAAI,EAC3B,SAAS,eAAe,CAAC,6BAA6B,CAAC,SAMxD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,WAAW,SAAS,GAAG,IAAI,EAAE,SAAS,eAAe,CAAC,wBAAwB,CAAC,SAK1G,CAAA"}
@@ -0,0 +1,24 @@
1
+ const updateActiveProxy = (workspace, payload) => {
2
+ if (!workspace) {
3
+ return;
4
+ }
5
+ workspace["x-scalar-active-proxy"] = payload ?? void 0;
6
+ };
7
+ const updateColorMode = (workspace, payload) => {
8
+ if (!workspace) {
9
+ return;
10
+ }
11
+ workspace["x-scalar-color-mode"] = payload;
12
+ };
13
+ const updateTheme = (workspace, payload) => {
14
+ if (!workspace) {
15
+ return;
16
+ }
17
+ workspace["x-scalar-theme"] = payload;
18
+ };
19
+ export {
20
+ updateActiveProxy,
21
+ updateColorMode,
22
+ updateTheme
23
+ };
24
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/mutators/workspace.ts"],
4
+ "sourcesContent": ["import type { WorkspaceEvents } from '@/events/definitions/workspace'\nimport type { Workspace } from '@/schemas'\n\nexport const updateActiveProxy = (\n workspace: Workspace | null,\n payload: WorkspaceEvents['workspace:update:active-proxy'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-active-proxy'] = payload ?? undefined\n}\n\nexport const updateColorMode = (\n workspace: Workspace | null,\n payload: WorkspaceEvents['workspace:update:color-mode'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-color-mode'] = payload\n}\n\nexport const updateTheme = (workspace: Workspace | null, payload: WorkspaceEvents['workspace:update:theme']) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-theme'] = payload\n}\n"],
5
+ "mappings": "AAGO,MAAM,oBAAoB,CAC/B,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,uBAAuB,IAAI,WAAW;AAClD;AAEO,MAAM,kBAAkB,CAC7B,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,qBAAqB,IAAI;AACrC;AAEO,MAAM,cAAc,CAAC,WAA6B,YAAuD;AAC9G,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,gBAAgB,IAAI;AAChC;",
6
+ "names": []
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"get-navigation-options.d.ts","sourceRoot":"","sources":["../../src/navigation/get-navigation-options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAE7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAA;AAErF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,EAAE,SAAS,qBAAqB,KAAG,mBAkH3F,CAAA"}
1
+ {"version":3,"file":"get-navigation-options.d.ts","sourceRoot":"","sources":["../../src/navigation/get-navigation-options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAE7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAA;AAErF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,EAAE,SAAS,qBAAqB,KAAG,mBAoH3F,CAAA"}
@@ -19,20 +19,20 @@ const getNavigationOptions = (documentName, config) => {
19
19
  return `${documentId}/tag/${slug(props.tag.name ?? "")}`;
20
20
  }
21
21
  if (props.type === "operation") {
22
- const tagId = `${generateId({
22
+ const prefixTag = props.parentTag ? `${generateId({
23
23
  type: "tag",
24
24
  tag: props.parentTag.tag,
25
25
  parentId: props.parentTag.id
26
- })}`;
26
+ })}/` : `${documentId}/`;
27
27
  if (referenceConfig?.generateOperationSlug) {
28
- return `${tagId}/${referenceConfig.generateOperationSlug({
28
+ return `${prefixTag}${referenceConfig.generateOperationSlug({
29
29
  path: props.path,
30
30
  operationId: props.operation.operationId,
31
31
  method: props.method,
32
32
  summary: props.operation.summary
33
33
  })}`;
34
34
  }
35
- return `${tagId}/${props.method}${props.path}`;
35
+ return `${prefixTag}${props.method}/${slug(props.path)}`;
36
36
  }
37
37
  if (props.type === "webhook") {
38
38
  const prefixTag = props.parentTag ? `${generateId({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/navigation/get-navigation-options.ts"],
4
- "sourcesContent": ["import { slug } from 'github-slugger'\n\nimport type { TraverseSpecOptions } from '@/navigation/types'\nimport type { IdGenerator } from '@/schemas/navigation'\nimport type { DocumentConfiguration } from '@/schemas/workspace-specification/config'\n\n/**\n * Returns options for traversing an OpenAPI document, allowing customization of\n * how IDs and slugs are generated for tags, headings, models, operations, and webhooks.\n * The returned options can be influenced by the provided DocumentConfiguration\n */\nexport const getNavigationOptions = (documentName: string, config?: DocumentConfiguration): TraverseSpecOptions => {\n const referenceConfig = config?.['x-scalar-reference-config']\n\n const generateId: IdGenerator = (props) => {\n const documentId = `${slug(documentName)}`\n\n // -------- Default text id generation logic --------\n if (props.type === 'text') {\n if (referenceConfig?.generateHeadingSlug) {\n return referenceConfig?.generateHeadingSlug({ slug: props.slug })\n }\n\n if (props.slug) {\n return `${documentId}/description/${props.slug}`\n }\n\n return `${documentId}/`\n }\n\n // -------- Default tag id generation logic --------\n if (props.type === 'tag') {\n if (referenceConfig?.generateTagSlug) {\n return `${documentId}/tag/${referenceConfig.generateTagSlug(props.tag)}`\n }\n\n return `${documentId}/tag/${slug(props.tag.name ?? '')}`\n }\n\n // -------- Default operation id generation logic --------\n if (props.type === 'operation') {\n const tagId = `${generateId({\n type: 'tag',\n tag: props.parentTag.tag,\n parentId: props.parentTag.id,\n })}`\n\n if (referenceConfig?.generateOperationSlug) {\n return `${tagId}/${referenceConfig.generateOperationSlug({\n path: props.path,\n operationId: props.operation.operationId,\n method: props.method,\n summary: props.operation.summary,\n })}`\n }\n\n return `${tagId}/${props.method}${props.path}`\n }\n\n // -------- Default webhook id generation logic --------\n if (props.type === 'webhook') {\n const prefixTag = props.parentTag\n ? `${generateId({\n type: 'tag',\n parentId: props.parentTag.id,\n tag: props.parentTag.tag,\n })}/`\n : `${documentId}/`\n\n if (referenceConfig?.generateWebhookSlug) {\n return `${prefixTag}webhook/${referenceConfig.generateWebhookSlug({\n name: props.name,\n method: props.method,\n })}`\n }\n\n return `${prefixTag}webhook/${props.method}/${slug(props.name)}`\n }\n\n // -------- Default model id generation logic --------\n if (props.type === 'model') {\n if (!props.name) {\n return `${documentId}/models`\n }\n\n const prefixTag = props.parentTag\n ? `${generateId({\n type: 'tag',\n parentId: props.parentTag.id,\n tag: props.parentTag.tag,\n })}/`\n : `${documentId}/`\n\n if (referenceConfig?.generateModelSlug) {\n return `${prefixTag}model/${referenceConfig.generateModelSlug({\n name: props.name,\n })}`\n }\n\n return `${prefixTag}model/${slug(props.name)}`\n }\n\n if (props.type === 'example') {\n return `${props.parentId}/example/${slug(props.name)}`\n }\n\n if (props.type === 'document') {\n // -------- Default document id generation logic --------\n return documentId\n }\n\n console.warn('[WARNING]: unhandled id generation for navigation item:', props)\n return 'unknown-id'\n }\n\n const hideModels = referenceConfig?.features?.showModels === false\n const operationsSorter: TraverseSpecOptions['operationsSorter'] = referenceConfig?.operationsSorter\n const tagsSorter: TraverseSpecOptions['tagsSorter'] = referenceConfig?.tagSort\n\n return {\n hideModels,\n operationsSorter,\n tagsSorter,\n generateId,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { slug } from 'github-slugger'\n\nimport type { TraverseSpecOptions } from '@/navigation/types'\nimport type { IdGenerator } from '@/schemas/navigation'\nimport type { DocumentConfiguration } from '@/schemas/workspace-specification/config'\n\n/**\n * Returns options for traversing an OpenAPI document, allowing customization of\n * how IDs and slugs are generated for tags, headings, models, operations, and webhooks.\n * The returned options can be influenced by the provided DocumentConfiguration\n */\nexport const getNavigationOptions = (documentName: string, config?: DocumentConfiguration): TraverseSpecOptions => {\n const referenceConfig = config?.['x-scalar-reference-config']\n\n const generateId: IdGenerator = (props) => {\n const documentId = `${slug(documentName)}`\n\n // -------- Default text id generation logic --------\n if (props.type === 'text') {\n if (referenceConfig?.generateHeadingSlug) {\n return referenceConfig?.generateHeadingSlug({ slug: props.slug })\n }\n\n if (props.slug) {\n return `${documentId}/description/${props.slug}`\n }\n\n return `${documentId}/`\n }\n\n // -------- Default tag id generation logic --------\n if (props.type === 'tag') {\n if (referenceConfig?.generateTagSlug) {\n return `${documentId}/tag/${referenceConfig.generateTagSlug(props.tag)}`\n }\n\n return `${documentId}/tag/${slug(props.tag.name ?? '')}`\n }\n\n // -------- Default operation id generation logic --------\n if (props.type === 'operation') {\n const prefixTag = props.parentTag\n ? `${generateId({\n type: 'tag',\n tag: props.parentTag.tag,\n parentId: props.parentTag.id,\n })}/`\n : `${documentId}/`\n\n if (referenceConfig?.generateOperationSlug) {\n return `${prefixTag}${referenceConfig.generateOperationSlug({\n path: props.path,\n operationId: props.operation.operationId,\n method: props.method,\n summary: props.operation.summary,\n })}`\n }\n\n return `${prefixTag}${props.method}/${slug(props.path)}`\n }\n\n // -------- Default webhook id generation logic --------\n if (props.type === 'webhook') {\n const prefixTag = props.parentTag\n ? `${generateId({\n type: 'tag',\n parentId: props.parentTag.id,\n tag: props.parentTag.tag,\n })}/`\n : `${documentId}/`\n\n if (referenceConfig?.generateWebhookSlug) {\n return `${prefixTag}webhook/${referenceConfig.generateWebhookSlug({\n name: props.name,\n method: props.method,\n })}`\n }\n\n return `${prefixTag}webhook/${props.method}/${slug(props.name)}`\n }\n\n // -------- Default model id generation logic --------\n if (props.type === 'model') {\n if (!props.name) {\n return `${documentId}/models`\n }\n\n const prefixTag = props.parentTag\n ? `${generateId({\n type: 'tag',\n parentId: props.parentTag.id,\n tag: props.parentTag.tag,\n })}/`\n : `${documentId}/`\n\n if (referenceConfig?.generateModelSlug) {\n return `${prefixTag}model/${referenceConfig.generateModelSlug({\n name: props.name,\n })}`\n }\n\n return `${prefixTag}model/${slug(props.name)}`\n }\n\n if (props.type === 'example') {\n return `${props.parentId}/example/${slug(props.name)}`\n }\n\n if (props.type === 'document') {\n // -------- Default document id generation logic --------\n return documentId\n }\n\n console.warn('[WARNING]: unhandled id generation for navigation item:', props)\n return 'unknown-id'\n }\n\n const hideModels = referenceConfig?.features?.showModels === false\n const operationsSorter: TraverseSpecOptions['operationsSorter'] = referenceConfig?.operationsSorter\n const tagsSorter: TraverseSpecOptions['tagsSorter'] = referenceConfig?.tagSort\n\n return {\n hideModels,\n operationsSorter,\n tagsSorter,\n generateId,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -16,5 +16,6 @@ export declare const traverseDocument: (documentName: string, document: OpenApiD
16
16
  title: string;
17
17
  name: string;
18
18
  children: TraversedEntry[];
19
+ icon: string | undefined;
19
20
  };
20
21
  //# sourceMappingURL=traverse-document.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"traverse-document.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-document.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAA;AAQrF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,cAAc,MAAM,EAAE,UAAU,eAAe,EAAE,SAAS,qBAAqB;;;;;;CA8F/G,CAAA"}
1
+ {"version":3,"file":"traverse-document.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-document.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAqB,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAA;AAQrF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,cAAc,MAAM,EAAE,UAAU,eAAe,EAAE,SAAS,qBAAqB;;;;;;;CAkH/G,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { unpackProxyObject } from "../../helpers/unpack-proxy.js";
1
2
  import { getNavigationOptions } from "../../navigation/get-navigation-options.js";
2
3
  import { traverseDescription } from "./traverse-description.js";
3
4
  import { traversePaths } from "./traverse-paths.js";
@@ -22,7 +23,7 @@ const traverseDocument = (documentName, document, config) => {
22
23
  parentId: documentId,
23
24
  info: document.info
24
25
  });
25
- traversePaths({ document, tagsMap, generateId, documentId });
26
+ const { untaggedOperations } = traversePaths({ document, tagsMap, generateId, documentId });
26
27
  const untaggedWebhooksParentId = generateId({
27
28
  type: "webhook",
28
29
  name: "",
@@ -42,6 +43,7 @@ const traverseDocument = (documentName, document, config) => {
42
43
  options: { tagsSorter, operationsSorter, generateId }
43
44
  });
44
45
  entries.push(...tagsEntries);
46
+ entries.push(...untaggedOperations);
45
47
  if (untaggedWebhooks.length) {
46
48
  entries.push({
47
49
  type: "tag",
@@ -73,12 +75,24 @@ const traverseDocument = (documentName, document, config) => {
73
75
  });
74
76
  }
75
77
  }
78
+ const sortOrder = document["x-scalar-order"];
79
+ if (sortOrder) {
80
+ entries.sort((a, b) => {
81
+ const indexA = sortOrder.indexOf(a.id);
82
+ const indexB = sortOrder.indexOf(b.id);
83
+ const safeIndexA = indexA === -1 ? Number.POSITIVE_INFINITY : indexA;
84
+ const safeIndexB = indexB === -1 ? Number.POSITIVE_INFINITY : indexB;
85
+ return safeIndexA - safeIndexB;
86
+ });
87
+ document["x-scalar-order"] = unpackProxyObject(entries.map((entry) => entry.id));
88
+ }
76
89
  return {
77
90
  id: documentId,
78
91
  type: "document",
79
92
  title: document.info.title,
80
93
  name: documentName,
81
- children: entries
94
+ children: entries,
95
+ icon: document["x-scalar-icon"]
82
96
  };
83
97
  };
84
98
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/navigation/helpers/traverse-document.ts"],
4
- "sourcesContent": ["import { getNavigationOptions } from '@/navigation/get-navigation-options'\nimport type { TagsMap } from '@/navigation/types'\nimport type { TraversedDocument, TraversedEntry } from '@/schemas/navigation'\nimport type { OpenApiDocument } from '@/schemas/v3.1/strict/openapi-document'\nimport type { DocumentConfiguration } from '@/schemas/workspace-specification/config'\n\nimport { traverseDescription } from './traverse-description'\nimport { traversePaths } from './traverse-paths'\nimport { traverseSchemas } from './traverse-schemas'\nimport { traverseTags } from './traverse-tags'\nimport { traverseWebhooks } from './traverse-webhooks'\n\n/**\n * Traverses an OpenAPI Document to generate navigation structure and metadata.\n *\n * This function processes the OpenAPI document to create:\n * - A hierarchical navigation structure for the sidebar\n * - A mapping of IDs to titles for mobile header navigation\n * - Tag-based organization of operations and webhooks\n * - Optional schema/model documentation\n */\nexport const traverseDocument = (documentName: string, document: OpenApiDocument, config?: DocumentConfiguration) => {\n const { hideModels, tagsSorter, operationsSorter, generateId } = getNavigationOptions(documentName, config)\n\n const documentId = generateId({\n type: 'document',\n info: document.info,\n name: documentName,\n })\n\n /** Map of tags and their entries */\n const tagsMap: TagsMap = new Map(\n document.tags?.map((tag) => [\n tag.name ?? 'Untitled Tag',\n { id: generateId({ type: 'tag', tag, parentId: documentId }), parentId: documentId, tag, entries: [] },\n ]) ?? [],\n )\n\n /** Generate entries for the document info description field */\n const entries: TraversedEntry[] = traverseDescription({\n generateId,\n parentId: documentId,\n info: document.info,\n })\n\n /** Traverse all the document path */\n traversePaths({ document, tagsMap, generateId, documentId })\n\n const untaggedWebhooksParentId = generateId({\n type: 'webhook',\n name: '',\n parentId: documentId,\n })\n\n const untaggedWebhooks = traverseWebhooks({\n document,\n generateId,\n tagsMap,\n untaggedWebhooksParentId,\n documentId,\n })\n\n const tagsEntries = traverseTags({\n document,\n tagsMap,\n documentId,\n options: { tagsSorter, operationsSorter, generateId },\n })\n\n // Add tagged operations, webhooks and tagGroups\n entries.push(...tagsEntries)\n\n // Add untagged webhooks\n if (untaggedWebhooks.length) {\n entries.push({\n type: 'tag',\n id: untaggedWebhooksParentId,\n title: 'Webhooks',\n name: 'Webhooks',\n children: untaggedWebhooks,\n isGroup: false,\n isWebhooks: true,\n })\n }\n\n // Add models if they are not hidden\n if (!hideModels && document.components?.schemas) {\n const untaggedModels = traverseSchemas({\n documentId,\n document,\n generateId,\n tagsMap,\n })\n\n if (untaggedModels.length) {\n entries.push({\n type: 'models',\n id: generateId({\n type: 'model',\n parentId: documentId,\n }),\n title: 'Models',\n name: 'Models',\n children: untaggedModels,\n })\n }\n }\n\n return {\n id: documentId,\n type: 'document',\n title: document.info.title,\n name: documentName,\n children: entries,\n } satisfies TraversedDocument\n}\n"],
5
- "mappings": "AAAA,SAAS,4BAA4B;AAMrC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AAW1B,MAAM,mBAAmB,CAAC,cAAsB,UAA2B,WAAmC;AACnH,QAAM,EAAE,YAAY,YAAY,kBAAkB,WAAW,IAAI,qBAAqB,cAAc,MAAM;AAE1G,QAAM,aAAa,WAAW;AAAA,IAC5B,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,IACf,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,UAAmB,IAAI;AAAA,IAC3B,SAAS,MAAM,IAAI,CAAC,QAAQ;AAAA,MAC1B,IAAI,QAAQ;AAAA,MACZ,EAAE,IAAI,WAAW,EAAE,MAAM,OAAO,KAAK,UAAU,WAAW,CAAC,GAAG,UAAU,YAAY,KAAK,SAAS,CAAC,EAAE;AAAA,IACvG,CAAC,KAAK,CAAC;AAAA,EACT;AAGA,QAAM,UAA4B,oBAAoB;AAAA,IACpD;AAAA,IACA,UAAU;AAAA,IACV,MAAM,SAAS;AAAA,EACjB,CAAC;AAGD,gBAAc,EAAE,UAAU,SAAS,YAAY,WAAW,CAAC;AAE3D,QAAM,2BAA2B,WAAW;AAAA,IAC1C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,EACZ,CAAC;AAED,QAAM,mBAAmB,iBAAiB;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,cAAc,aAAa;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,EAAE,YAAY,kBAAkB,WAAW;AAAA,EACtD,CAAC;AAGD,UAAQ,KAAK,GAAG,WAAW;AAG3B,MAAI,iBAAiB,QAAQ;AAC3B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAGA,MAAI,CAAC,cAAc,SAAS,YAAY,SAAS;AAC/C,UAAM,iBAAiB,gBAAgB;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,eAAe,QAAQ;AACzB,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAI,WAAW;AAAA,UACb,MAAM;AAAA,UACN,UAAU;AAAA,QACZ,CAAC;AAAA,QACD,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,SAAS,KAAK;AAAA,IACrB,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AACF;",
4
+ "sourcesContent": ["import { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport { getNavigationOptions } from '@/navigation/get-navigation-options'\nimport type { TagsMap } from '@/navigation/types'\nimport type { TraversedDocument, TraversedEntry } from '@/schemas/navigation'\nimport type { OpenApiDocument } from '@/schemas/v3.1/strict/openapi-document'\nimport type { DocumentConfiguration } from '@/schemas/workspace-specification/config'\n\nimport { traverseDescription } from './traverse-description'\nimport { traversePaths } from './traverse-paths'\nimport { traverseSchemas } from './traverse-schemas'\nimport { traverseTags } from './traverse-tags'\nimport { traverseWebhooks } from './traverse-webhooks'\n\n/**\n * Traverses an OpenAPI Document to generate navigation structure and metadata.\n *\n * This function processes the OpenAPI document to create:\n * - A hierarchical navigation structure for the sidebar\n * - A mapping of IDs to titles for mobile header navigation\n * - Tag-based organization of operations and webhooks\n * - Optional schema/model documentation\n */\nexport const traverseDocument = (documentName: string, document: OpenApiDocument, config?: DocumentConfiguration) => {\n const { hideModels, tagsSorter, operationsSorter, generateId } = getNavigationOptions(documentName, config)\n\n const documentId = generateId({\n type: 'document',\n info: document.info,\n name: documentName,\n })\n\n /** Map of tags and their entries */\n const tagsMap: TagsMap = new Map(\n document.tags?.map((tag) => [\n tag.name ?? 'Untitled Tag',\n { id: generateId({ type: 'tag', tag, parentId: documentId }), parentId: documentId, tag, entries: [] },\n ]) ?? [],\n )\n\n /** Generate entries for the document info description field */\n const entries: TraversedEntry[] = traverseDescription({\n generateId,\n parentId: documentId,\n info: document.info,\n })\n\n /** Traverse all the document path */\n const { untaggedOperations } = traversePaths({ document, tagsMap, generateId, documentId })\n\n const untaggedWebhooksParentId = generateId({\n type: 'webhook',\n name: '',\n parentId: documentId,\n })\n\n const untaggedWebhooks = traverseWebhooks({\n document,\n generateId,\n tagsMap,\n untaggedWebhooksParentId,\n documentId,\n })\n\n const tagsEntries = traverseTags({\n document,\n tagsMap,\n documentId,\n options: { tagsSorter, operationsSorter, generateId },\n })\n\n // Add tagged operations, webhooks and tagGroups\n entries.push(...tagsEntries)\n // Add untagged operations\n entries.push(...untaggedOperations)\n\n // Add untagged webhooks\n if (untaggedWebhooks.length) {\n entries.push({\n type: 'tag',\n id: untaggedWebhooksParentId,\n title: 'Webhooks',\n name: 'Webhooks',\n children: untaggedWebhooks,\n isGroup: false,\n isWebhooks: true,\n })\n }\n\n // Add models if they are not hidden\n if (!hideModels && document.components?.schemas) {\n const untaggedModels = traverseSchemas({\n documentId,\n document,\n generateId,\n tagsMap,\n })\n\n if (untaggedModels.length) {\n entries.push({\n type: 'models',\n id: generateId({\n type: 'model',\n parentId: documentId,\n }),\n title: 'Models',\n name: 'Models',\n children: untaggedModels,\n })\n }\n }\n\n const sortOrder = document['x-scalar-order']\n\n // Try to sort the entries using the x-scalar-order\n if (sortOrder) {\n entries.sort((a, b) => {\n const indexA = sortOrder.indexOf(a.id)\n const indexB = sortOrder.indexOf(b.id)\n // If an id is not found, treat it as \"infinity\" so those items go last.\n const safeIndexA = indexA === -1 ? Number.POSITIVE_INFINITY : indexA\n const safeIndexB = indexB === -1 ? Number.POSITIVE_INFINITY : indexB\n return safeIndexA - safeIndexB\n })\n\n // Now update the sort order of the entries\n document['x-scalar-order'] = unpackProxyObject(entries.map((entry) => entry.id))\n }\n\n return {\n id: documentId,\n type: 'document',\n title: document.info.title,\n name: documentName,\n children: entries,\n icon: document['x-scalar-icon'],\n } satisfies TraversedDocument\n}\n"],
5
+ "mappings": "AAAA,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AAMrC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AAW1B,MAAM,mBAAmB,CAAC,cAAsB,UAA2B,WAAmC;AACnH,QAAM,EAAE,YAAY,YAAY,kBAAkB,WAAW,IAAI,qBAAqB,cAAc,MAAM;AAE1G,QAAM,aAAa,WAAW;AAAA,IAC5B,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,IACf,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,UAAmB,IAAI;AAAA,IAC3B,SAAS,MAAM,IAAI,CAAC,QAAQ;AAAA,MAC1B,IAAI,QAAQ;AAAA,MACZ,EAAE,IAAI,WAAW,EAAE,MAAM,OAAO,KAAK,UAAU,WAAW,CAAC,GAAG,UAAU,YAAY,KAAK,SAAS,CAAC,EAAE;AAAA,IACvG,CAAC,KAAK,CAAC;AAAA,EACT;AAGA,QAAM,UAA4B,oBAAoB;AAAA,IACpD;AAAA,IACA,UAAU;AAAA,IACV,MAAM,SAAS;AAAA,EACjB,CAAC;AAGD,QAAM,EAAE,mBAAmB,IAAI,cAAc,EAAE,UAAU,SAAS,YAAY,WAAW,CAAC;AAE1F,QAAM,2BAA2B,WAAW;AAAA,IAC1C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,EACZ,CAAC;AAED,QAAM,mBAAmB,iBAAiB;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,cAAc,aAAa;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,EAAE,YAAY,kBAAkB,WAAW;AAAA,EACtD,CAAC;AAGD,UAAQ,KAAK,GAAG,WAAW;AAE3B,UAAQ,KAAK,GAAG,kBAAkB;AAGlC,MAAI,iBAAiB,QAAQ;AAC3B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAGA,MAAI,CAAC,cAAc,SAAS,YAAY,SAAS;AAC/C,UAAM,iBAAiB,gBAAgB;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,eAAe,QAAQ;AACzB,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAI,WAAW;AAAA,UACb,MAAM;AAAA,UACN,UAAU;AAAA,QACZ,CAAC;AAAA,QACD,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,YAAY,SAAS,gBAAgB;AAG3C,MAAI,WAAW;AACb,YAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,YAAM,SAAS,UAAU,QAAQ,EAAE,EAAE;AACrC,YAAM,SAAS,UAAU,QAAQ,EAAE,EAAE;AAErC,YAAM,aAAa,WAAW,KAAK,OAAO,oBAAoB;AAC9D,YAAM,aAAa,WAAW,KAAK,OAAO,oBAAoB;AAC9D,aAAO,aAAa;AAAA,IACtB,CAAC;AAGD,aAAS,gBAAgB,IAAI,kBAAkB,QAAQ,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAAA,EACjF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,SAAS,KAAK;AAAA,IACrB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM,SAAS,eAAe;AAAA,EAChC;AACF;",
6
6
  "names": []
7
7
  }
@@ -11,7 +11,7 @@ const traverseOperationExamples = (operation) => {
11
11
  }
12
12
  if (operation.parameters) {
13
13
  operation.parameters.forEach((_parameter) => {
14
- const parameter = getResolvedRef(_parameter);
14
+ const parameter = getResolvedRef(_parameter) ?? {};
15
15
  if ("content" in parameter && parameter.content) {
16
16
  Object.values(parameter.content).forEach((mediaType) => {
17
17
  Object.keys(mediaType.examples ?? {}).forEach((key) => {
@@ -28,7 +28,7 @@ const traverseOperationExamples = (operation) => {
28
28
  }
29
29
  if (operation.responses) {
30
30
  Object.values(operation.responses).forEach((response) => {
31
- const resolvedResponse = getResolvedRef(response);
31
+ const resolvedResponse = getResolvedRef(response) ?? {};
32
32
  if ("content" in resolvedResponse && resolvedResponse.content) {
33
33
  Object.values(resolvedResponse.content ?? {}).forEach((mediaType) => {
34
34
  Object.keys(mediaType.examples ?? {}).forEach((key) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/navigation/helpers/traverse-examples.ts"],
4
- "sourcesContent": ["import { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport type { OperationObject } from '@/schemas/v3.1/strict/openapi-document'\n\n/**\n * Traverse the OpenAPI operation object and extract all example values.\n *\n * @param operation - The OpenAPI operation object to extract examples from\n */\nexport const traverseOperationExamples = (operation: OperationObject) => {\n const examples = new Set<string>()\n\n // Add all examples from request bodies\n if (operation.requestBody) {\n const requestBody = getResolvedRef(operation.requestBody)\n\n Object.values(requestBody.content ?? {}).forEach((mediaType) => {\n Object.keys(mediaType.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n })\n }\n\n // Add all examples from parameters\n if (operation.parameters) {\n operation.parameters.forEach((_parameter) => {\n const parameter = getResolvedRef(_parameter)\n\n if ('content' in parameter && parameter.content) {\n Object.values(parameter.content).forEach((mediaType) => {\n Object.keys(mediaType.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n })\n }\n\n if ('examples' in parameter && parameter.examples) {\n Object.keys(parameter.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n }\n })\n }\n\n // Add all examples from responses\n if (operation.responses) {\n Object.values(operation.responses).forEach((response) => {\n const resolvedResponse = getResolvedRef(response)\n\n if ('content' in resolvedResponse && resolvedResponse.content) {\n Object.values(resolvedResponse.content ?? {}).forEach((mediaType) => {\n Object.keys(mediaType.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n })\n }\n\n // TODO: handle headers?\n })\n }\n\n return Array.from(examples)\n}\n"],
5
- "mappings": "AAAA,SAAS,sBAAsB;AAQxB,MAAM,4BAA4B,CAAC,cAA+B;AACvE,QAAM,WAAW,oBAAI,IAAY;AAGjC,MAAI,UAAU,aAAa;AACzB,UAAM,cAAc,eAAe,UAAU,WAAW;AAExD,WAAO,OAAO,YAAY,WAAW,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc;AAC9D,aAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,iBAAS,IAAI,GAAG;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,YAAY;AACxB,cAAU,WAAW,QAAQ,CAAC,eAAe;AAC3C,YAAM,YAAY,eAAe,UAAU;AAE3C,UAAI,aAAa,aAAa,UAAU,SAAS;AAC/C,eAAO,OAAO,UAAU,OAAO,EAAE,QAAQ,CAAC,cAAc;AACtD,iBAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,qBAAS,IAAI,GAAG;AAAA,UAClB,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAEA,UAAI,cAAc,aAAa,UAAU,UAAU;AACjD,eAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,mBAAS,IAAI,GAAG;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,WAAW;AACvB,WAAO,OAAO,UAAU,SAAS,EAAE,QAAQ,CAAC,aAAa;AACvD,YAAM,mBAAmB,eAAe,QAAQ;AAEhD,UAAI,aAAa,oBAAoB,iBAAiB,SAAS;AAC7D,eAAO,OAAO,iBAAiB,WAAW,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc;AACnE,iBAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,qBAAS,IAAI,GAAG;AAAA,UAClB,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IAGF,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,QAAQ;AAC5B;",
4
+ "sourcesContent": ["import { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport type { OperationObject } from '@/schemas/v3.1/strict/openapi-document'\n\n/**\n * Traverse the OpenAPI operation object and extract all example values.\n *\n * @param operation - The OpenAPI operation object to extract examples from\n */\nexport const traverseOperationExamples = (operation: OperationObject) => {\n const examples = new Set<string>()\n\n // Add all examples from request bodies\n if (operation.requestBody) {\n const requestBody = getResolvedRef(operation.requestBody)\n\n Object.values(requestBody.content ?? {}).forEach((mediaType) => {\n Object.keys(mediaType.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n })\n }\n\n // Add all examples from parameters\n if (operation.parameters) {\n operation.parameters.forEach((_parameter) => {\n const parameter = getResolvedRef(_parameter) ?? {}\n\n if ('content' in parameter && parameter.content) {\n Object.values(parameter.content).forEach((mediaType) => {\n Object.keys(mediaType.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n })\n }\n\n if ('examples' in parameter && parameter.examples) {\n Object.keys(parameter.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n }\n })\n }\n\n // Add all examples from responses\n if (operation.responses) {\n Object.values(operation.responses).forEach((response) => {\n const resolvedResponse = getResolvedRef(response) ?? {}\n\n if ('content' in resolvedResponse && resolvedResponse.content) {\n Object.values(resolvedResponse.content ?? {}).forEach((mediaType) => {\n Object.keys(mediaType.examples ?? {}).forEach((key) => {\n examples.add(key)\n })\n })\n }\n\n // TODO: handle headers?\n })\n }\n\n return Array.from(examples)\n}\n"],
5
+ "mappings": "AAAA,SAAS,sBAAsB;AAQxB,MAAM,4BAA4B,CAAC,cAA+B;AACvE,QAAM,WAAW,oBAAI,IAAY;AAGjC,MAAI,UAAU,aAAa;AACzB,UAAM,cAAc,eAAe,UAAU,WAAW;AAExD,WAAO,OAAO,YAAY,WAAW,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc;AAC9D,aAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,iBAAS,IAAI,GAAG;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,YAAY;AACxB,cAAU,WAAW,QAAQ,CAAC,eAAe;AAC3C,YAAM,YAAY,eAAe,UAAU,KAAK,CAAC;AAEjD,UAAI,aAAa,aAAa,UAAU,SAAS;AAC/C,eAAO,OAAO,UAAU,OAAO,EAAE,QAAQ,CAAC,cAAc;AACtD,iBAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,qBAAS,IAAI,GAAG;AAAA,UAClB,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAEA,UAAI,cAAc,aAAa,UAAU,UAAU;AACjD,eAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,mBAAS,IAAI,GAAG;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,WAAW;AACvB,WAAO,OAAO,UAAU,SAAS,EAAE,QAAQ,CAAC,aAAa;AACvD,YAAM,mBAAmB,eAAe,QAAQ,KAAK,CAAC;AAEtD,UAAI,aAAa,oBAAoB,iBAAiB,SAAS;AAC7D,eAAO,OAAO,iBAAiB,WAAW,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc;AACnE,iBAAO,KAAK,UAAU,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACrD,qBAAS,IAAI,GAAG;AAAA,UAClB,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IAGF,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,QAAQ;AAC5B;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,5 @@
1
1
  import type { TagsMap, TraverseSpecOptions } from '../../navigation/types.js';
2
+ import type { TraversedOperation } from '../../schemas/navigation.js';
2
3
  import type { OpenApiDocument, OperationObject } from '../../schemas/v3.1/strict/openapi-document.js';
3
4
  export declare const isDeprecatedOperation: (operation: OperationObject) => boolean;
4
5
  /**
@@ -7,7 +8,7 @@ export declare const isDeprecatedOperation: (operation: OperationObject) => bool
7
8
  * This function processes each path and its operations to:
8
9
  * - Filter out internal operations (marked with x-internal) and operations to ignore (marked with x-scalar-ignore)
9
10
  * - Group operations by their tags
10
- * - Create a default tag group for untagged operations
11
+ * - Collect operations without tags to be added at the document level
11
12
  * - Generate unique references and IDs for each operation
12
13
  *
13
14
  * TODO: filter out internal and scalar-ignore tags
@@ -16,7 +17,7 @@ export declare const isDeprecatedOperation: (operation: OperationObject) => bool
16
17
  * @param tagsDict - Dictionary mapping tag names to their OpenAPI tag objects
17
18
  * @param entitiesMap - Map to store operation IDs and titles for mobile header navigation
18
19
  * @param getOperationId - Function to generate unique IDs for operations
19
- * @returns Map of tag names to arrays of traversed operations
20
+ * @returns Object containing the tagsMap and an array of untagged operations
20
21
  */
21
22
  export declare const traversePaths: ({ document, tagsMap, generateId, documentId, }: {
22
23
  document: OpenApiDocument;
@@ -26,5 +27,7 @@ export declare const traversePaths: ({ document, tagsMap, generateId, documentId
26
27
  generateId: TraverseSpecOptions["generateId"];
27
28
  /** Document ID */
28
29
  documentId: string;
29
- }) => void;
30
+ }) => {
31
+ untaggedOperations: TraversedOperation[];
32
+ };
30
33
  //# sourceMappingURL=traverse-paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"traverse-paths.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-paths.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAGtE,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAI9F,eAAO,MAAM,qBAAqB,GAAI,WAAW,eAAe,YAE/D,CAAA;AAoED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,GAAI,gDAK3B;IACD,QAAQ,EAAE,eAAe,CAAA;IACzB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,0DAA0D;IAC1D,UAAU,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAA;IAC7C,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,SA+DA,CAAA"}
1
+ {"version":3,"file":"traverse-paths.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-paths.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAEtE,OAAO,KAAK,EAA+B,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAI9F,eAAO,MAAM,qBAAqB,GAAI,WAAW,eAAe,YAE/D,CAAA;AAoED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,GAAI,gDAK3B;IACD,QAAQ,EAAE,eAAe,CAAA;IACzB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,0DAA0D;IAC1D,UAAU,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAA;IAC7C,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,KAAG;IAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAA;CA2D7C,CAAA"}
@@ -55,6 +55,7 @@ const traversePaths = ({
55
55
  generateId,
56
56
  documentId
57
57
  }) => {
58
+ const untaggedOperations = [];
58
59
  Object.entries(document.paths ?? {}).forEach(([path, pathItemObject]) => {
59
60
  const pathKeys = objectKeys(pathItemObject ?? {}).filter((key) => isHttpMethod(key));
60
61
  pathKeys.forEach((method) => {
@@ -88,26 +89,20 @@ const traversePaths = ({
88
89
  );
89
90
  });
90
91
  } else {
91
- const { tag, id: tagId } = getTag({
92
- tagsMap,
93
- name: "default",
94
- documentId,
95
- generateId
96
- });
97
- tagsMap.get("default")?.entries.push(
92
+ untaggedOperations.push(
98
93
  createOperationEntry({
99
94
  ref,
100
95
  operation,
101
96
  method,
102
97
  path,
103
- parentTag: { tag, id: tagId },
104
98
  generateId,
105
- parentId: tagId
99
+ parentId: documentId
106
100
  })
107
101
  );
108
102
  }
109
103
  });
110
104
  });
105
+ return { untaggedOperations };
111
106
  };
112
107
  export {
113
108
  isDeprecatedOperation,