@scalar/workspace-store 0.19.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 (188) hide show
  1. package/CHANGELOG.md +44 -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/auth.d.ts +20 -2
  12. package/dist/events/definitions/auth.d.ts.map +1 -1
  13. package/dist/events/definitions/cookie.d.ts +20 -0
  14. package/dist/events/definitions/cookie.d.ts.map +1 -0
  15. package/dist/events/definitions/cookie.js +1 -0
  16. package/dist/events/definitions/cookie.js.map +7 -0
  17. package/dist/events/definitions/document.d.ts +11 -1
  18. package/dist/events/definitions/document.d.ts.map +1 -1
  19. package/dist/events/definitions/index.d.ts +4 -2
  20. package/dist/events/definitions/index.d.ts.map +1 -1
  21. package/dist/events/definitions/operation.d.ts +0 -13
  22. package/dist/events/definitions/operation.d.ts.map +1 -1
  23. package/dist/events/definitions/server.d.ts +20 -28
  24. package/dist/events/definitions/server.d.ts.map +1 -1
  25. package/dist/events/definitions/tabs.d.ts +40 -0
  26. package/dist/events/definitions/tabs.d.ts.map +1 -0
  27. package/dist/events/definitions/tabs.js +1 -0
  28. package/dist/events/definitions/tabs.js.map +7 -0
  29. package/dist/events/definitions/ui.d.ts +39 -4
  30. package/dist/events/definitions/ui.d.ts.map +1 -1
  31. package/dist/events/definitions/workspace.d.ts +18 -0
  32. package/dist/events/definitions/workspace.d.ts.map +1 -0
  33. package/dist/events/definitions/workspace.js +1 -0
  34. package/dist/events/definitions/workspace.js.map +7 -0
  35. package/dist/events/index.d.ts +2 -2
  36. package/dist/events/index.d.ts.map +1 -1
  37. package/dist/events/index.js.map +2 -2
  38. package/dist/helpers/generate-unique-value.d.ts +19 -6
  39. package/dist/helpers/generate-unique-value.d.ts.map +1 -1
  40. package/dist/helpers/generate-unique-value.js +12 -7
  41. package/dist/helpers/generate-unique-value.js.map +2 -2
  42. package/dist/helpers/unpack-proxy.d.ts +14 -1
  43. package/dist/helpers/unpack-proxy.d.ts.map +1 -1
  44. package/dist/helpers/unpack-proxy.js +51 -1
  45. package/dist/helpers/unpack-proxy.js.map +3 -3
  46. package/dist/mutators/auth.d.ts +10 -73
  47. package/dist/mutators/auth.d.ts.map +1 -1
  48. package/dist/mutators/auth.js +47 -111
  49. package/dist/mutators/auth.js.map +2 -2
  50. package/dist/mutators/cookie.d.ts +21 -13
  51. package/dist/mutators/cookie.d.ts.map +1 -1
  52. package/dist/mutators/cookie.js +34 -26
  53. package/dist/mutators/cookie.js.map +3 -3
  54. package/dist/mutators/document.d.ts +13 -0
  55. package/dist/mutators/document.d.ts.map +1 -0
  56. package/dist/mutators/document.js +25 -0
  57. package/dist/mutators/document.js.map +7 -0
  58. package/dist/mutators/index.d.ts +13 -20
  59. package/dist/mutators/index.d.ts.map +1 -1
  60. package/dist/mutators/index.js +49 -8
  61. package/dist/mutators/index.js.map +3 -3
  62. package/dist/mutators/operation.d.ts +23 -101
  63. package/dist/mutators/operation.d.ts.map +1 -1
  64. package/dist/mutators/operation.js +132 -96
  65. package/dist/mutators/operation.js.map +2 -2
  66. package/dist/mutators/server.d.ts +43 -8
  67. package/dist/mutators/server.d.ts.map +1 -1
  68. package/dist/mutators/server.js +113 -20
  69. package/dist/mutators/server.js.map +2 -2
  70. package/dist/mutators/workspace.d.ts +6 -0
  71. package/dist/mutators/workspace.d.ts.map +1 -0
  72. package/dist/mutators/workspace.js +24 -0
  73. package/dist/mutators/workspace.js.map +7 -0
  74. package/dist/navigation/get-navigation-options.d.ts.map +1 -1
  75. package/dist/navigation/get-navigation-options.js +4 -4
  76. package/dist/navigation/get-navigation-options.js.map +2 -2
  77. package/dist/navigation/helpers/traverse-document.d.ts +2 -0
  78. package/dist/navigation/helpers/traverse-document.d.ts.map +1 -1
  79. package/dist/navigation/helpers/traverse-document.js +18 -3
  80. package/dist/navigation/helpers/traverse-document.js.map +2 -2
  81. package/dist/navigation/helpers/traverse-examples.js +2 -2
  82. package/dist/navigation/helpers/traverse-examples.js.map +2 -2
  83. package/dist/navigation/helpers/traverse-paths.d.ts +6 -3
  84. package/dist/navigation/helpers/traverse-paths.d.ts.map +1 -1
  85. package/dist/navigation/helpers/traverse-paths.js +4 -9
  86. package/dist/navigation/helpers/traverse-paths.js.map +2 -2
  87. package/dist/navigation/helpers/traverse-tags.d.ts +0 -1
  88. package/dist/navigation/helpers/traverse-tags.d.ts.map +1 -1
  89. package/dist/navigation/helpers/traverse-tags.js +57 -49
  90. package/dist/navigation/helpers/traverse-tags.js.map +3 -3
  91. package/dist/persistence/index.d.ts +6 -0
  92. package/dist/persistence/index.d.ts.map +1 -1
  93. package/dist/persistence/index.js +18 -0
  94. package/dist/persistence/index.js.map +2 -2
  95. package/dist/persistence/indexdb.d.ts +1 -0
  96. package/dist/persistence/indexdb.d.ts.map +1 -1
  97. package/dist/persistence/indexdb.js +6 -1
  98. package/dist/persistence/indexdb.js.map +2 -2
  99. package/dist/plugins/client/persistence.d.ts +2 -1
  100. package/dist/plugins/client/persistence.d.ts.map +1 -1
  101. package/dist/plugins/client/persistence.js +17 -9
  102. package/dist/plugins/client/persistence.js.map +2 -2
  103. package/dist/schemas/extensions/document/x-scalar-environments.d.ts +1 -0
  104. package/dist/schemas/extensions/document/x-scalar-environments.d.ts.map +1 -1
  105. package/dist/schemas/extensions/document/x-scalar-environments.js.map +2 -2
  106. package/dist/schemas/extensions/document/x-scalar-set-operation-security.d.ts +13 -0
  107. package/dist/schemas/extensions/document/x-scalar-set-operation-security.d.ts.map +1 -0
  108. package/dist/schemas/extensions/document/x-scalar-set-operation-security.js +8 -0
  109. package/dist/schemas/extensions/document/x-scalar-set-operation-security.js.map +7 -0
  110. package/dist/schemas/extensions/general/x-scalar-cookies.d.ts +36 -0
  111. package/dist/schemas/extensions/general/x-scalar-cookies.d.ts.map +1 -0
  112. package/dist/schemas/extensions/general/x-scalar-cookies.js +15 -0
  113. package/dist/schemas/extensions/general/x-scalar-cookies.js.map +7 -0
  114. package/dist/schemas/extensions/general/x-scalar-order.d.ts +12 -0
  115. package/dist/schemas/extensions/general/x-scalar-order.d.ts.map +1 -0
  116. package/dist/schemas/extensions/general/x-scalar-order.js +8 -0
  117. package/dist/schemas/extensions/general/x-scalar-order.js.map +7 -0
  118. package/dist/schemas/extensions/security/x-scalar-selected-security.d.ts +7 -7
  119. package/dist/schemas/extensions/security/x-scalar-selected-security.d.ts.map +1 -1
  120. package/dist/schemas/extensions/security/x-scalar-selected-security.js +2 -2
  121. package/dist/schemas/extensions/security/x-scalar-selected-security.js.map +2 -2
  122. package/dist/schemas/extensions/server/x-scalar-selected-server.d.ts +8 -0
  123. package/dist/schemas/extensions/server/x-scalar-selected-server.d.ts.map +1 -0
  124. package/dist/schemas/extensions/server/x-scalar-selected-server.js +8 -0
  125. package/dist/schemas/extensions/server/x-scalar-selected-server.js.map +7 -0
  126. package/dist/schemas/extensions/tag/x-tag-groups.d.ts +10 -5
  127. package/dist/schemas/extensions/tag/x-tag-groups.d.ts.map +1 -1
  128. package/dist/schemas/extensions/tag/x-tag-groups.js +15 -10
  129. package/dist/schemas/extensions/tag/x-tag-groups.js.map +2 -2
  130. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts +18 -0
  131. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts.map +1 -0
  132. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.js +8 -0
  133. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.js.map +7 -0
  134. package/dist/schemas/extensions.d.ts +1 -1
  135. package/dist/schemas/extensions.js +1 -1
  136. package/dist/schemas/extensions.js.map +2 -2
  137. package/dist/schemas/inmemory-workspace.d.ts +59 -33
  138. package/dist/schemas/inmemory-workspace.d.ts.map +1 -1
  139. package/dist/schemas/navigation.d.ts +9 -1
  140. package/dist/schemas/navigation.d.ts.map +1 -1
  141. package/dist/schemas/navigation.js +3 -1
  142. package/dist/schemas/navigation.js.map +2 -2
  143. package/dist/schemas/reference-config/index.d.ts +29 -16
  144. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  145. package/dist/schemas/reference-config/settings.d.ts +29 -16
  146. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  147. package/dist/schemas/reference-config/settings.js +2 -0
  148. package/dist/schemas/reference-config/settings.js.map +2 -2
  149. package/dist/schemas/v3.1/strict/openapi-document.d.ts +992 -549
  150. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  151. package/dist/schemas/v3.1/strict/openapi-document.js +14 -6
  152. package/dist/schemas/v3.1/strict/openapi-document.js.map +2 -2
  153. package/dist/schemas/v3.1/strict/operation.d.ts +3 -7
  154. package/dist/schemas/v3.1/strict/operation.d.ts.map +1 -1
  155. package/dist/schemas/v3.1/strict/operation.js +1 -5
  156. package/dist/schemas/v3.1/strict/operation.js.map +2 -2
  157. package/dist/schemas/v3.1/strict/tag.d.ts +4 -1
  158. package/dist/schemas/v3.1/strict/tag.d.ts.map +1 -1
  159. package/dist/schemas/v3.1/strict/tag.js +3 -1
  160. package/dist/schemas/v3.1/strict/tag.js.map +2 -2
  161. package/dist/schemas/v3.1/strict/type-guards.d.ts +6 -0
  162. package/dist/schemas/v3.1/strict/type-guards.d.ts.map +1 -1
  163. package/dist/schemas/v3.1/strict/type-guards.js +4 -0
  164. package/dist/schemas/v3.1/strict/type-guards.js.map +2 -2
  165. package/dist/schemas/workspace-specification/config.d.ts +29 -16
  166. package/dist/schemas/workspace-specification/config.d.ts.map +1 -1
  167. package/dist/schemas/workspace-specification/index.d.ts +30 -17
  168. package/dist/schemas/workspace-specification/index.d.ts.map +1 -1
  169. package/dist/schemas/workspace.d.ts +233 -130
  170. package/dist/schemas/workspace.d.ts.map +1 -1
  171. package/dist/schemas/workspace.js +8 -6
  172. package/dist/schemas/workspace.js.map +2 -2
  173. package/dist/server.d.ts +1 -1
  174. package/dist/workspace-plugin.d.ts +3 -0
  175. package/dist/workspace-plugin.d.ts.map +1 -1
  176. package/package.json +8 -7
  177. package/dist/helpers/debounce.d.ts +0 -28
  178. package/dist/helpers/debounce.d.ts.map +0 -1
  179. package/dist/helpers/debounce.js +0 -31
  180. package/dist/helpers/debounce.js.map +0 -7
  181. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.d.ts +0 -13
  182. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.d.ts.map +0 -1
  183. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.js +0 -9
  184. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.js.map +0 -7
  185. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.d.ts +0 -32
  186. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.d.ts.map +0 -1
  187. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.js +0 -13
  188. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.js.map +0 -7
@@ -1,26 +1,119 @@
1
- const serverMutators = (target) => {
2
- const addServer = (server) => {
3
- if (!target) {
4
- return false;
1
+ import { findVariables } from "@scalar/helpers/regex/find-variables";
2
+ import { coerceValue } from "../schemas/typebox-coerce.js";
3
+ import { ServerObjectSchema } from "../schemas/v3.1/strict/openapi-document.js";
4
+ const addServer = (document) => {
5
+ if (!document) {
6
+ return void 0;
7
+ }
8
+ const parsed = coerceValue(ServerObjectSchema, {});
9
+ if (!document.servers) {
10
+ document.servers = [];
11
+ }
12
+ document.servers.push(parsed);
13
+ return parsed;
14
+ };
15
+ const getVariablePositions = (url, variables) => {
16
+ const positions = {};
17
+ for (const varName of variables) {
18
+ const position = url.indexOf(`{${varName}}`);
19
+ if (position !== -1) {
20
+ positions[varName] = position;
21
+ }
22
+ }
23
+ return positions;
24
+ };
25
+ const syncVariablesForUrlChange = (newUrl, oldUrl, existingVariables) => {
26
+ const oldVariables = findVariables(oldUrl, { includePath: true, includeEnv: false }).filter(
27
+ (v) => v !== void 0
28
+ );
29
+ const newVariables = findVariables(newUrl, { includePath: true, includeEnv: false }).filter(
30
+ (v) => v !== void 0
31
+ );
32
+ const oldPositions = getVariablePositions(oldUrl, oldVariables);
33
+ const newPositions = getVariablePositions(newUrl, newVariables);
34
+ const usedOldVariables = /* @__PURE__ */ new Set();
35
+ const syncedVariables = {};
36
+ for (const newVar of newVariables) {
37
+ if (existingVariables[newVar]) {
38
+ syncedVariables[newVar] = existingVariables[newVar];
39
+ usedOldVariables.add(newVar);
40
+ continue;
41
+ }
42
+ const newVarPosition = newPositions[newVar];
43
+ const oldVarAtPosition = oldVariables.find(
44
+ (oldVar) => oldPositions[oldVar] === newVarPosition && !usedOldVariables.has(oldVar)
45
+ );
46
+ if (oldVarAtPosition && existingVariables[oldVarAtPosition]) {
47
+ syncedVariables[newVar] = existingVariables[oldVarAtPosition];
48
+ usedOldVariables.add(oldVarAtPosition);
49
+ continue;
5
50
  }
6
- target.push(server);
7
- return true;
8
- };
9
- const deleteServer = (url) => {
10
- if (!target) {
11
- return false;
51
+ syncedVariables[newVar] = { default: "" };
52
+ }
53
+ return syncedVariables;
54
+ };
55
+ const updateServer = (document, { index, server }) => {
56
+ const oldServer = document?.servers?.[index];
57
+ if (!oldServer) {
58
+ console.error("Server not found at index:", index);
59
+ return void 0;
60
+ }
61
+ const oldUrl = oldServer.url;
62
+ const updatedServer = coerceValue(ServerObjectSchema, { ...oldServer, ...server });
63
+ const hasUrlChanged = oldUrl && oldUrl !== updatedServer.url;
64
+ if (hasUrlChanged) {
65
+ const existingVariables = updatedServer.variables ?? {};
66
+ updatedServer.variables = syncVariablesForUrlChange(updatedServer.url, oldUrl, existingVariables);
67
+ if (document["x-scalar-selected-server"] === oldUrl) {
68
+ document["x-scalar-selected-server"] = updatedServer.url;
12
69
  }
13
- const newTarget = [...target.filter((it) => it.url !== url)];
14
- target.splice(0, target.length);
15
- target.push(...newTarget);
16
- return true;
17
- };
18
- return {
19
- addServer,
20
- deleteServer
21
- };
70
+ }
71
+ if (!document.servers) {
72
+ document.servers = [updatedServer];
73
+ } else {
74
+ document.servers[index] = updatedServer;
75
+ }
76
+ return updatedServer;
77
+ };
78
+ const deleteServer = (document, { index }) => {
79
+ if (!document?.servers) {
80
+ return;
81
+ }
82
+ const url = document.servers[index]?.url;
83
+ document.servers.splice(index, 1);
84
+ if (document["x-scalar-selected-server"] === url) {
85
+ document["x-scalar-selected-server"] = document.servers[0]?.url ?? void 0;
86
+ }
87
+ };
88
+ const updateServerVariables = (document, { index, key, value }) => {
89
+ const variable = document?.servers?.[index]?.variables?.[key];
90
+ if (!variable) {
91
+ console.error("Variable not found", key, index);
92
+ return;
93
+ }
94
+ variable.default = value;
95
+ const url = document?.servers?.[index]?.url;
96
+ if (!url) {
97
+ console.error("URL not found", index);
98
+ return;
99
+ }
100
+ return variable;
101
+ };
102
+ const updateSelectedServer = (document, { url }) => {
103
+ if (!document) {
104
+ return;
105
+ }
106
+ if (!document.servers?.some((server) => server.url === url)) {
107
+ return;
108
+ }
109
+ document["x-scalar-selected-server"] = document["x-scalar-selected-server"] === url ? void 0 : url;
110
+ return document["x-scalar-selected-server"];
22
111
  };
23
112
  export {
24
- serverMutators
113
+ addServer,
114
+ deleteServer,
115
+ updateSelectedServer,
116
+ updateServer,
117
+ updateServerVariables
25
118
  };
26
119
  //# sourceMappingURL=server.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/server.ts"],
4
- "sourcesContent": ["import type { ServerObject } from '@/schemas/v3.1/strict/openapi-document'\n\n/**\n * Provides mutator functions for managing an array of OpenAPI ServerObject entries.\n *\n * @param target - The array of ServerObject to mutate. If not provided, mutators will be no-ops.\n * @returns An object with addServer and deleteServer methods.\n */\nexport const serverMutators = (target?: ServerObject[]) => {\n /**\n * Adds a new ServerObject to the target array.\n * @param server - The ServerObject to add.\n * @returns true if the server was added, false if target is undefined.\n */\n const addServer = (server: ServerObject): boolean => {\n if (!target) {\n return false\n }\n target.push(server)\n return true\n }\n\n /**\n * Deletes a ServerObject at the specified index from the target array.\n * @param index - The index of the server to delete.\n * @returns true if the server was deleted, false if target is undefined.\n */\n const deleteServer = (url: string): boolean => {\n if (!target) {\n return false\n }\n const newTarget = [...target.filter((it) => it.url !== url)]\n target.splice(0, target.length)\n target.push(...newTarget)\n return true\n }\n\n return {\n addServer,\n deleteServer,\n }\n}\n"],
5
- "mappings": "AAQO,MAAM,iBAAiB,CAAC,WAA4B;AAMzD,QAAM,YAAY,CAAC,WAAkC;AACnD,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM;AAClB,WAAO;AAAA,EACT;AAOA,QAAM,eAAe,CAAC,QAAyB;AAC7C,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,UAAM,YAAY,CAAC,GAAG,OAAO,OAAO,CAAC,OAAO,GAAG,QAAQ,GAAG,CAAC;AAC3D,WAAO,OAAO,GAAG,OAAO,MAAM;AAC9B,WAAO,KAAK,GAAG,SAAS;AACxB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;",
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": "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",
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
  }
@@ -14,6 +14,8 @@ export declare const traverseDocument: (documentName: string, document: OpenApiD
14
14
  id: string;
15
15
  type: "document";
16
16
  title: string;
17
+ name: string;
17
18
  children: TraversedEntry[];
19
+ icon: string | undefined;
18
20
  };
19
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;;;;;CA6F/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,11 +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
- title: documentName,
80
- children: entries
92
+ title: document.info.title,
93
+ name: documentName,
94
+ children: entries,
95
+ icon: document["x-scalar-icon"]
81
96
  };
82
97
  };
83
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: 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;AAAA,IACP,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,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/navigation/helpers/traverse-paths.ts"],
4
- "sourcesContent": ["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer'\n\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport { traverseOperationExamples } from '@/navigation/helpers/traverse-examples'\nimport type { TagsMap, TraverseSpecOptions } from '@/navigation/types'\nimport { XScalarStabilityValues } from '@/schemas/extensions/operation/x-scalar-stability'\nimport type { ParentTag, TraversedExample, TraversedOperation } from '@/schemas/navigation'\nimport type { OpenApiDocument, OperationObject } from '@/schemas/v3.1/strict/openapi-document'\n\nimport { getTag } from './get-tag'\n\nexport const isDeprecatedOperation = (operation: OperationObject) => {\n return operation.deprecated || operation['x-scalar-stability'] === XScalarStabilityValues.Deprecated\n}\n\n/**\n * Creates a traversed operation entry from an OpenAPI operation object.\n *\n * @param ref - JSON pointer reference to the operation in the OpenAPI document\n * @param operation - The OpenAPI operation object\n * @param method - HTTP method of the operation\n * @param path - API path of the operation, defaults to 'Unknown'\n * @param tag - Tag object associated with the operation\n * @param entitiesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns A traversed operation entry with ID, title, path, method and reference\n */\nconst createOperationEntry = ({\n ref,\n operation,\n method,\n path,\n generateId,\n parentId,\n parentTag,\n}: {\n ref: string\n operation: OperationObject\n method: HttpMethod\n path: string\n parentTag: ParentTag\n generateId: TraverseSpecOptions['generateId']\n parentId: string\n}): TraversedOperation => {\n const id = generateId({\n type: 'operation',\n operation,\n parentTag,\n method: method,\n path: path,\n parentId: parentId,\n })\n const title = operation.summary?.trim() ? operation.summary : path\n\n const isDeprecated = isDeprecatedOperation(operation)\n\n const examples: TraversedExample[] = traverseOperationExamples(operation).map((example) => ({\n type: 'example',\n id: generateId({\n type: 'example',\n parentId: id,\n name: example,\n }),\n title: example,\n name: example,\n }))\n\n const entry = {\n id,\n title,\n path,\n method,\n ref,\n type: 'operation',\n isDeprecated,\n children: examples.length ? examples : undefined,\n } satisfies TraversedOperation\n\n return entry\n}\n\n/**\n * Traverses the paths in an OpenAPI document to build a map of operations organized by tags.\n *\n * This function processes each path and its operations to:\n * - Filter out internal operations (marked with x-internal) and operations to ignore (marked with x-scalar-ignore)\n * - Group operations by their tags\n * - Create a default tag group for untagged operations\n * - Generate unique references and IDs for each operation\n *\n * TODO: filter out internal and scalar-ignore tags\n *\n * @param content - The OpenAPI document to traverse\n * @param tagsDict - Dictionary mapping tag names to their OpenAPI tag objects\n * @param entitiesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns Map of tag names to arrays of traversed operations\n */\nexport const traversePaths = ({\n document,\n tagsMap,\n generateId,\n documentId,\n}: {\n document: OpenApiDocument\n /** Map of tags and their entries */\n tagsMap: TagsMap\n /** Function used to generate unique IDs for operations */\n generateId: TraverseSpecOptions['generateId']\n /** Document ID */\n documentId: string\n}) => {\n // Traverse paths\n Object.entries(document.paths ?? {}).forEach(([path, pathItemObject]) => {\n const pathKeys = objectKeys(pathItemObject ?? {}).filter((key) => isHttpMethod(key))\n\n pathKeys.forEach((method) => {\n const _operation = pathItemObject?.[method]\n const operation = getResolvedRef(_operation)\n if (!operation) {\n return\n }\n\n // Skip if the operation is internal or scalar-ignore\n if (operation['x-internal'] || operation['x-scalar-ignore'] || !isHttpMethod(method)) {\n return\n }\n\n const ref = `#/paths/${escapeJsonPointer(path)}/${method}`\n\n // Traverse tags\n if (operation.tags?.length) {\n operation.tags.forEach((tagName: string) => {\n const { tag, id: tagId } = getTag({\n tagsMap,\n name: tagName,\n documentId,\n generateId,\n })\n tagsMap.get(tagName)?.entries.push(\n createOperationEntry({\n ref,\n operation,\n method,\n path,\n parentTag: { tag, id: tagId },\n generateId,\n parentId: tagId,\n }),\n )\n })\n }\n // Add to default tag\n else {\n const { tag, id: tagId } = getTag({\n tagsMap,\n name: 'default',\n documentId,\n generateId,\n })\n tagsMap.get('default')?.entries.push(\n createOperationEntry({\n ref,\n operation,\n method,\n path,\n parentTag: { tag, id: tagId },\n generateId,\n parentId: tagId,\n }),\n )\n }\n })\n })\n}\n"],
5
- "mappings": "AACA,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAElC,SAAS,sBAAsB;AAC/B,SAAS,iCAAiC;AAE1C,SAAS,8BAA8B;AAIvC,SAAS,cAAc;AAEhB,MAAM,wBAAwB,CAAC,cAA+B;AACnE,SAAO,UAAU,cAAc,UAAU,oBAAoB,MAAM,uBAAuB;AAC5F;AAcA,MAAM,uBAAuB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQ0B;AACxB,QAAM,KAAK,WAAW;AAAA,IACpB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,UAAU,SAAS,KAAK,IAAI,UAAU,UAAU;AAE9D,QAAM,eAAe,sBAAsB,SAAS;AAEpD,QAAM,WAA+B,0BAA0B,SAAS,EAAE,IAAI,CAAC,aAAa;AAAA,IAC1F,MAAM;AAAA,IACN,IAAI,WAAW;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,IACD,OAAO;AAAA,IACP,MAAM;AAAA,EACR,EAAE;AAEF,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,UAAU,SAAS,SAAS,WAAW;AAAA,EACzC;AAEA,SAAO;AACT;AAmBO,MAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQM;AAEJ,SAAO,QAAQ,SAAS,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,cAAc,MAAM;AACvE,UAAM,WAAW,WAAW,kBAAkB,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,aAAa,GAAG,CAAC;AAEnF,aAAS,QAAQ,CAAC,WAAW;AAC3B,YAAM,aAAa,iBAAiB,MAAM;AAC1C,YAAM,YAAY,eAAe,UAAU;AAC3C,UAAI,CAAC,WAAW;AACd;AAAA,MACF;AAGA,UAAI,UAAU,YAAY,KAAK,UAAU,iBAAiB,KAAK,CAAC,aAAa,MAAM,GAAG;AACpF;AAAA,MACF;AAEA,YAAM,MAAM,WAAW,kBAAkB,IAAI,CAAC,IAAI,MAAM;AAGxD,UAAI,UAAU,MAAM,QAAQ;AAC1B,kBAAU,KAAK,QAAQ,CAAC,YAAoB;AAC1C,gBAAM,EAAE,KAAK,IAAI,MAAM,IAAI,OAAO;AAAA,YAChC;AAAA,YACA,MAAM;AAAA,YACN;AAAA,YACA;AAAA,UACF,CAAC;AACD,kBAAQ,IAAI,OAAO,GAAG,QAAQ;AAAA,YAC5B,qBAAqB;AAAA,cACnB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW,EAAE,KAAK,IAAI,MAAM;AAAA,cAC5B;AAAA,cACA,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH,OAEK;AACH,cAAM,EAAE,KAAK,IAAI,MAAM,IAAI,OAAO;AAAA,UAChC;AAAA,UACA,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACF,CAAC;AACD,gBAAQ,IAAI,SAAS,GAAG,QAAQ;AAAA,UAC9B,qBAAqB;AAAA,YACnB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW,EAAE,KAAK,IAAI,MAAM;AAAA,YAC5B;AAAA,YACA,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;",
4
+ "sourcesContent": ["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer'\n\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport { traverseOperationExamples } from '@/navigation/helpers/traverse-examples'\nimport type { TagsMap, TraverseSpecOptions } from '@/navigation/types'\nimport { XScalarStabilityValues } from '@/schemas/extensions/operation/x-scalar-stability'\nimport type { ParentTag, TraversedExample, TraversedOperation } from '@/schemas/navigation'\nimport type { OpenApiDocument, OperationObject } from '@/schemas/v3.1/strict/openapi-document'\n\nimport { getTag } from './get-tag'\n\nexport const isDeprecatedOperation = (operation: OperationObject) => {\n return operation.deprecated || operation['x-scalar-stability'] === XScalarStabilityValues.Deprecated\n}\n\n/**\n * Creates a traversed operation entry from an OpenAPI operation object.\n *\n * @param ref - JSON pointer reference to the operation in the OpenAPI document\n * @param operation - The OpenAPI operation object\n * @param method - HTTP method of the operation\n * @param path - API path of the operation, defaults to 'Unknown'\n * @param tag - Tag object associated with the operation\n * @param entitiesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns A traversed operation entry with ID, title, path, method and reference\n */\nconst createOperationEntry = ({\n ref,\n operation,\n method,\n path,\n generateId,\n parentId,\n parentTag,\n}: {\n ref: string\n operation: OperationObject\n method: HttpMethod\n path: string\n parentTag?: ParentTag\n generateId: TraverseSpecOptions['generateId']\n parentId: string\n}): TraversedOperation => {\n const id = generateId({\n type: 'operation',\n operation,\n parentTag,\n method: method,\n path: path,\n parentId: parentId,\n })\n const title = operation.summary?.trim() ? operation.summary : path\n\n const isDeprecated = isDeprecatedOperation(operation)\n\n const examples: TraversedExample[] = traverseOperationExamples(operation).map((example) => ({\n type: 'example',\n id: generateId({\n type: 'example',\n parentId: id,\n name: example,\n }),\n title: example,\n name: example,\n }))\n\n const entry = {\n id,\n title,\n path,\n method,\n ref,\n type: 'operation',\n isDeprecated,\n children: examples.length ? examples : undefined,\n } satisfies TraversedOperation\n\n return entry\n}\n\n/**\n * Traverses the paths in an OpenAPI document to build a map of operations organized by tags.\n *\n * This function processes each path and its operations to:\n * - Filter out internal operations (marked with x-internal) and operations to ignore (marked with x-scalar-ignore)\n * - Group operations by their tags\n * - Collect operations without tags to be added at the document level\n * - Generate unique references and IDs for each operation\n *\n * TODO: filter out internal and scalar-ignore tags\n *\n * @param content - The OpenAPI document to traverse\n * @param tagsDict - Dictionary mapping tag names to their OpenAPI tag objects\n * @param entitiesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns Object containing the tagsMap and an array of untagged operations\n */\nexport const traversePaths = ({\n document,\n tagsMap,\n generateId,\n documentId,\n}: {\n document: OpenApiDocument\n /** Map of tags and their entries */\n tagsMap: TagsMap\n /** Function used to generate unique IDs for operations */\n generateId: TraverseSpecOptions['generateId']\n /** Document ID */\n documentId: string\n}): { untaggedOperations: TraversedOperation[] } => {\n const untaggedOperations: TraversedOperation[] = []\n\n // Traverse paths\n Object.entries(document.paths ?? {}).forEach(([path, pathItemObject]) => {\n const pathKeys = objectKeys(pathItemObject ?? {}).filter((key) => isHttpMethod(key))\n\n pathKeys.forEach((method) => {\n const _operation = pathItemObject?.[method]\n const operation = getResolvedRef(_operation)\n if (!operation) {\n return\n }\n\n // Skip if the operation is internal or scalar-ignore\n if (operation['x-internal'] || operation['x-scalar-ignore'] || !isHttpMethod(method)) {\n return\n }\n\n const ref = `#/paths/${escapeJsonPointer(path)}/${method}`\n\n // Traverse tags\n if (operation.tags?.length) {\n operation.tags.forEach((tagName: string) => {\n const { tag, id: tagId } = getTag({\n tagsMap,\n name: tagName,\n documentId,\n generateId,\n })\n tagsMap.get(tagName)?.entries.push(\n createOperationEntry({\n ref,\n operation,\n method,\n path,\n parentTag: { tag, id: tagId },\n generateId,\n parentId: tagId,\n }),\n )\n })\n } else {\n // Collect operations without tags (no parentTag)\n untaggedOperations.push(\n createOperationEntry({\n ref,\n operation,\n method,\n path,\n generateId,\n parentId: documentId,\n }),\n )\n }\n })\n })\n\n return { untaggedOperations }\n}\n"],
5
+ "mappings": "AACA,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAElC,SAAS,sBAAsB;AAC/B,SAAS,iCAAiC;AAE1C,SAAS,8BAA8B;AAIvC,SAAS,cAAc;AAEhB,MAAM,wBAAwB,CAAC,cAA+B;AACnE,SAAO,UAAU,cAAc,UAAU,oBAAoB,MAAM,uBAAuB;AAC5F;AAcA,MAAM,uBAAuB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQ0B;AACxB,QAAM,KAAK,WAAW;AAAA,IACpB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,UAAU,SAAS,KAAK,IAAI,UAAU,UAAU;AAE9D,QAAM,eAAe,sBAAsB,SAAS;AAEpD,QAAM,WAA+B,0BAA0B,SAAS,EAAE,IAAI,CAAC,aAAa;AAAA,IAC1F,MAAM;AAAA,IACN,IAAI,WAAW;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,IACD,OAAO;AAAA,IACP,MAAM;AAAA,EACR,EAAE;AAEF,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,UAAU,SAAS,SAAS,WAAW;AAAA,EACzC;AAEA,SAAO;AACT;AAmBO,MAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQoD;AAClD,QAAM,qBAA2C,CAAC;AAGlD,SAAO,QAAQ,SAAS,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,cAAc,MAAM;AACvE,UAAM,WAAW,WAAW,kBAAkB,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,aAAa,GAAG,CAAC;AAEnF,aAAS,QAAQ,CAAC,WAAW;AAC3B,YAAM,aAAa,iBAAiB,MAAM;AAC1C,YAAM,YAAY,eAAe,UAAU;AAC3C,UAAI,CAAC,WAAW;AACd;AAAA,MACF;AAGA,UAAI,UAAU,YAAY,KAAK,UAAU,iBAAiB,KAAK,CAAC,aAAa,MAAM,GAAG;AACpF;AAAA,MACF;AAEA,YAAM,MAAM,WAAW,kBAAkB,IAAI,CAAC,IAAI,MAAM;AAGxD,UAAI,UAAU,MAAM,QAAQ;AAC1B,kBAAU,KAAK,QAAQ,CAAC,YAAoB;AAC1C,gBAAM,EAAE,KAAK,IAAI,MAAM,IAAI,OAAO;AAAA,YAChC;AAAA,YACA,MAAM;AAAA,YACN;AAAA,YACA;AAAA,UACF,CAAC;AACD,kBAAQ,IAAI,OAAO,GAAG,QAAQ;AAAA,YAC5B,qBAAqB;AAAA,cACnB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW,EAAE,KAAK,IAAI,MAAM;AAAA,cAC5B;AAAA,cACA,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AAEL,2BAAmB;AAAA,UACjB,qBAAqB;AAAA,YACnB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO,EAAE,mBAAmB;AAC9B;",
6
6
  "names": []
7
7
  }
@@ -9,7 +9,6 @@ type Options = Pick<TraverseSpecOptions, 'tagsSorter' | 'operationsSorter' | 'ge
9
9
  * - Handle tag groups if specified via x-tagGroups
10
10
  * - Sort tags and their operations according to provided sorters
11
11
  * - Create navigation entries for each tag or tag group
12
- * - Flatten default tag entries if it's the only tag present
13
12
  */
14
13
  export declare const traverseTags: ({ document, tagsMap, documentId, options: { generateId, tagsSorter, operationsSorter }, }: {
15
14
  document: OpenApiDocument;
@@ -1 +1 @@
1
- {"version":3,"file":"traverse-tags.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-tags.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,sBAAsB,CAAA;AACxE,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,wCAAwC,CAAA;AAIxF,KAAK,OAAO,GAAG,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,kBAAkB,GAAG,YAAY,CAAC,CAAA;AAkK1F;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAI,2FAK1B;IACD,QAAQ,EAAE,eAAe,CAAA;IACzB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,KAAG,cAAc,EAuCjB,CAAA"}
1
+ {"version":3,"file":"traverse-tags.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-tags.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,sBAAsB,CAAA;AACxE,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,wCAAwC,CAAA;AAIxF,KAAK,OAAO,GAAG,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,kBAAkB,GAAG,YAAY,CAAC,CAAA;AA6K1F;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,2FAK1B;IACD,QAAQ,EAAE,eAAe,CAAA;IACzB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,KAAG,cAAc,EAyCjB,CAAA"}