@scalar/workspace-store 0.20.0 → 0.22.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 (260) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +2 -2
  3. package/dist/client.d.ts +54 -6
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +66 -29
  6. package/dist/client.js.map +2 -2
  7. package/dist/events/bus.d.ts +14 -2
  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 +2 -1
  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 +19 -2
  18. package/dist/events/definitions/document.d.ts.map +1 -1
  19. package/dist/events/definitions/index.d.ts +6 -1
  20. package/dist/events/definitions/index.d.ts.map +1 -1
  21. package/dist/events/definitions/operation.d.ts +20 -14
  22. package/dist/events/definitions/operation.d.ts.map +1 -1
  23. package/dist/events/definitions/server.d.ts +2 -2
  24. package/dist/events/definitions/server.d.ts.map +1 -1
  25. package/dist/events/definitions/tabs.d.ts +55 -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/tag.d.ts +15 -0
  30. package/dist/events/definitions/tag.d.ts.map +1 -0
  31. package/dist/events/definitions/tag.js +1 -0
  32. package/dist/events/definitions/tag.js.map +7 -0
  33. package/dist/events/definitions/ui.d.ts +131 -39
  34. package/dist/events/definitions/ui.d.ts.map +1 -1
  35. package/dist/events/definitions/workspace.d.ts +18 -0
  36. package/dist/events/definitions/workspace.d.ts.map +1 -0
  37. package/dist/events/definitions/workspace.js +1 -0
  38. package/dist/events/definitions/workspace.js.map +7 -0
  39. package/dist/events/index.d.ts +1 -1
  40. package/dist/events/index.d.ts.map +1 -1
  41. package/dist/events/index.js.map +2 -2
  42. package/dist/helpers/generate-unique-value.d.ts +19 -6
  43. package/dist/helpers/generate-unique-value.d.ts.map +1 -1
  44. package/dist/helpers/generate-unique-value.js +12 -7
  45. package/dist/helpers/generate-unique-value.js.map +2 -2
  46. package/dist/helpers/unpack-proxy.d.ts +14 -1
  47. package/dist/helpers/unpack-proxy.d.ts.map +1 -1
  48. package/dist/helpers/unpack-proxy.js +51 -1
  49. package/dist/helpers/unpack-proxy.js.map +3 -3
  50. package/dist/mutators/auth.d.ts +7 -2
  51. package/dist/mutators/auth.d.ts.map +1 -1
  52. package/dist/mutators/auth.js +24 -21
  53. package/dist/mutators/auth.js.map +2 -2
  54. package/dist/mutators/cookie.d.ts +21 -13
  55. package/dist/mutators/cookie.d.ts.map +1 -1
  56. package/dist/mutators/cookie.js +34 -26
  57. package/dist/mutators/cookie.js.map +3 -3
  58. package/dist/mutators/document.d.ts +12 -2
  59. package/dist/mutators/document.d.ts.map +1 -1
  60. package/dist/mutators/document.js +42 -3
  61. package/dist/mutators/document.js.map +2 -2
  62. package/dist/mutators/index.d.ts +30 -20
  63. package/dist/mutators/index.d.ts.map +1 -1
  64. package/dist/mutators/index.js +38 -9
  65. package/dist/mutators/index.js.map +2 -2
  66. package/dist/mutators/operation.d.ts +49 -108
  67. package/dist/mutators/operation.d.ts.map +1 -1
  68. package/dist/mutators/operation.js +198 -94
  69. package/dist/mutators/operation.js.map +2 -2
  70. package/dist/mutators/request.d.ts +2 -1
  71. package/dist/mutators/request.d.ts.map +1 -1
  72. package/dist/mutators/request.js.map +1 -1
  73. package/dist/mutators/server.d.ts +1 -1
  74. package/dist/mutators/server.d.ts.map +1 -1
  75. package/dist/mutators/server.js +6 -5
  76. package/dist/mutators/server.js.map +2 -2
  77. package/dist/mutators/tabs.d.ts +44 -0
  78. package/dist/mutators/tabs.d.ts.map +1 -0
  79. package/dist/mutators/tabs.js +133 -0
  80. package/dist/mutators/tabs.js.map +7 -0
  81. package/dist/mutators/tag.d.ts +12 -0
  82. package/dist/mutators/tag.d.ts.map +1 -0
  83. package/dist/mutators/tag.js +19 -0
  84. package/dist/mutators/tag.js.map +7 -0
  85. package/dist/mutators/workspace.d.ts +6 -0
  86. package/dist/mutators/workspace.d.ts.map +1 -0
  87. package/dist/mutators/workspace.js +24 -0
  88. package/dist/mutators/workspace.js.map +7 -0
  89. package/dist/navigation/get-navigation-options.d.ts.map +1 -1
  90. package/dist/navigation/get-navigation-options.js +4 -4
  91. package/dist/navigation/get-navigation-options.js.map +2 -2
  92. package/dist/navigation/helpers/get-openapi-object.d.ts +35 -0
  93. package/dist/navigation/helpers/get-openapi-object.d.ts.map +1 -0
  94. package/dist/navigation/helpers/get-openapi-object.js +31 -0
  95. package/dist/navigation/helpers/get-openapi-object.js.map +7 -0
  96. package/dist/navigation/helpers/get-operation-entries.d.ts +24 -0
  97. package/dist/navigation/helpers/get-operation-entries.d.ts.map +1 -0
  98. package/dist/navigation/helpers/get-operation-entries.js +33 -0
  99. package/dist/navigation/helpers/get-operation-entries.js.map +7 -0
  100. package/dist/navigation/helpers/get-parent-entry.d.ts +15 -0
  101. package/dist/navigation/helpers/get-parent-entry.d.ts.map +1 -0
  102. package/dist/navigation/helpers/get-parent-entry.js +13 -0
  103. package/dist/navigation/helpers/get-parent-entry.js.map +7 -0
  104. package/dist/navigation/helpers/traverse-description.d.ts +0 -1
  105. package/dist/navigation/helpers/traverse-description.d.ts.map +1 -1
  106. package/dist/navigation/helpers/traverse-description.js +0 -1
  107. package/dist/navigation/helpers/traverse-description.js.map +2 -2
  108. package/dist/navigation/helpers/traverse-document.d.ts +1 -0
  109. package/dist/navigation/helpers/traverse-document.d.ts.map +1 -1
  110. package/dist/navigation/helpers/traverse-document.js +16 -2
  111. package/dist/navigation/helpers/traverse-document.js.map +2 -2
  112. package/dist/navigation/helpers/traverse-examples.js +2 -2
  113. package/dist/navigation/helpers/traverse-examples.js.map +2 -2
  114. package/dist/navigation/helpers/traverse-paths.d.ts +6 -3
  115. package/dist/navigation/helpers/traverse-paths.d.ts.map +1 -1
  116. package/dist/navigation/helpers/traverse-paths.js +5 -10
  117. package/dist/navigation/helpers/traverse-paths.js.map +2 -2
  118. package/dist/navigation/helpers/traverse-tags.d.ts +0 -1
  119. package/dist/navigation/helpers/traverse-tags.d.ts.map +1 -1
  120. package/dist/navigation/helpers/traverse-tags.js +57 -49
  121. package/dist/navigation/helpers/traverse-tags.js.map +3 -3
  122. package/dist/navigation/helpers/utils.d.ts +2 -1
  123. package/dist/navigation/helpers/utils.d.ts.map +1 -1
  124. package/dist/navigation/helpers/utils.js.map +1 -1
  125. package/dist/navigation/index.d.ts +2 -1
  126. package/dist/navigation/index.d.ts.map +1 -1
  127. package/dist/navigation/index.js +5 -3
  128. package/dist/navigation/index.js.map +2 -2
  129. package/dist/persistence/index.d.ts +6 -0
  130. package/dist/persistence/index.d.ts.map +1 -1
  131. package/dist/persistence/index.js +18 -0
  132. package/dist/persistence/index.js.map +2 -2
  133. package/dist/persistence/indexdb.d.ts +1 -0
  134. package/dist/persistence/indexdb.d.ts.map +1 -1
  135. package/dist/persistence/indexdb.js +6 -1
  136. package/dist/persistence/indexdb.js.map +2 -2
  137. package/dist/plugins/client/persistence.d.ts.map +1 -1
  138. package/dist/plugins/client/persistence.js +6 -0
  139. package/dist/plugins/client/persistence.js.map +2 -2
  140. package/dist/schemas/extensions/document/x-scalar-environments.d.ts +1 -0
  141. package/dist/schemas/extensions/document/x-scalar-environments.d.ts.map +1 -1
  142. package/dist/schemas/extensions/document/x-scalar-environments.js.map +2 -2
  143. package/dist/schemas/extensions/document/x-scalar-set-operation-security.d.ts +13 -0
  144. package/dist/schemas/extensions/document/x-scalar-set-operation-security.d.ts.map +1 -0
  145. package/dist/schemas/extensions/document/x-scalar-set-operation-security.js +8 -0
  146. package/dist/schemas/extensions/document/x-scalar-set-operation-security.js.map +7 -0
  147. package/dist/schemas/extensions/general/x-scalar-cookies.d.ts +36 -0
  148. package/dist/schemas/extensions/general/x-scalar-cookies.d.ts.map +1 -0
  149. package/dist/schemas/extensions/general/x-scalar-cookies.js +15 -0
  150. package/dist/schemas/extensions/general/x-scalar-cookies.js.map +7 -0
  151. package/dist/schemas/extensions/general/x-scalar-order.d.ts +12 -0
  152. package/dist/schemas/extensions/general/x-scalar-order.d.ts.map +1 -0
  153. package/dist/schemas/extensions/general/x-scalar-order.js +8 -0
  154. package/dist/schemas/extensions/general/x-scalar-order.js.map +7 -0
  155. package/dist/schemas/extensions/operation/index.d.ts +4 -1
  156. package/dist/schemas/extensions/operation/index.d.ts.map +1 -1
  157. package/dist/schemas/extensions/operation/index.js +22 -0
  158. package/dist/schemas/extensions/operation/index.js.map +3 -3
  159. package/dist/schemas/extensions/operation/x-code-samples.d.ts +0 -5
  160. package/dist/schemas/extensions/operation/x-code-samples.d.ts.map +1 -1
  161. package/dist/schemas/extensions/operation/x-code-samples.js +0 -1
  162. package/dist/schemas/extensions/operation/x-code-samples.js.map +2 -2
  163. package/dist/schemas/extensions/operation/x-post-response.d.ts +0 -18
  164. package/dist/schemas/extensions/operation/x-post-response.d.ts.map +1 -1
  165. package/dist/schemas/extensions/operation/x-post-response.js.map +1 -1
  166. package/dist/schemas/extensions/tag/x-tag-groups.d.ts +8 -14
  167. package/dist/schemas/extensions/tag/x-tag-groups.d.ts.map +1 -1
  168. package/dist/schemas/extensions/tag/x-tag-groups.js +15 -11
  169. package/dist/schemas/extensions/tag/x-tag-groups.js.map +2 -2
  170. package/dist/schemas/extensions/workspace/index.d.ts +4 -0
  171. package/dist/schemas/extensions/workspace/index.d.ts.map +1 -0
  172. package/dist/schemas/extensions/workspace/index.js +15 -0
  173. package/dist/schemas/extensions/workspace/index.js.map +7 -0
  174. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts +18 -0
  175. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts.map +1 -0
  176. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.js +8 -0
  177. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.js.map +7 -0
  178. package/dist/schemas/extensions/workspace/x-scalar-tabs.d.ts +36 -0
  179. package/dist/schemas/extensions/workspace/x-scalar-tabs.d.ts.map +1 -0
  180. package/dist/schemas/extensions/workspace/x-scalar-tabs.js +16 -0
  181. package/dist/schemas/extensions/workspace/x-scalar-tabs.js.map +7 -0
  182. package/dist/schemas/extensions.d.ts +1 -1
  183. package/dist/schemas/extensions.js +1 -1
  184. package/dist/schemas/extensions.js.map +2 -2
  185. package/dist/schemas/inmemory-workspace.d.ts +46 -33
  186. package/dist/schemas/inmemory-workspace.d.ts.map +1 -1
  187. package/dist/schemas/navigation.d.ts +12 -1
  188. package/dist/schemas/navigation.d.ts.map +1 -1
  189. package/dist/schemas/navigation.js +2 -1
  190. package/dist/schemas/navigation.js.map +2 -2
  191. package/dist/schemas/reference-config/index.d.ts +22 -16
  192. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  193. package/dist/schemas/reference-config/settings.d.ts +22 -16
  194. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  195. package/dist/schemas/reference-config/settings.js +2 -0
  196. package/dist/schemas/reference-config/settings.js.map +2 -2
  197. package/dist/schemas/v3.1/strict/header.d.ts +0 -45
  198. package/dist/schemas/v3.1/strict/header.d.ts.map +1 -1
  199. package/dist/schemas/v3.1/strict/header.js +1 -3
  200. package/dist/schemas/v3.1/strict/header.js.map +2 -2
  201. package/dist/schemas/v3.1/strict/oauth-flow.d.ts +0 -99
  202. package/dist/schemas/v3.1/strict/oauth-flow.d.ts.map +1 -1
  203. package/dist/schemas/v3.1/strict/oauth-flow.js +0 -7
  204. package/dist/schemas/v3.1/strict/oauth-flow.js.map +2 -2
  205. package/dist/schemas/v3.1/strict/openapi-document.d.ts +756 -552
  206. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  207. package/dist/schemas/v3.1/strict/openapi-document.js +10 -11
  208. package/dist/schemas/v3.1/strict/openapi-document.js.map +2 -2
  209. package/dist/schemas/v3.1/strict/operation.d.ts +1 -5
  210. package/dist/schemas/v3.1/strict/operation.d.ts.map +1 -1
  211. package/dist/schemas/v3.1/strict/operation.js +1 -5
  212. package/dist/schemas/v3.1/strict/operation.js.map +2 -2
  213. package/dist/schemas/v3.1/strict/parameter.d.ts +1 -101
  214. package/dist/schemas/v3.1/strict/parameter.d.ts.map +1 -1
  215. package/dist/schemas/v3.1/strict/parameter.js +1 -4
  216. package/dist/schemas/v3.1/strict/parameter.js.map +2 -2
  217. package/dist/schemas/v3.1/strict/ref-definitions.d.ts +0 -1
  218. package/dist/schemas/v3.1/strict/ref-definitions.d.ts.map +1 -1
  219. package/dist/schemas/v3.1/strict/ref-definitions.js +0 -2
  220. package/dist/schemas/v3.1/strict/ref-definitions.js.map +2 -2
  221. package/dist/schemas/v3.1/strict/schema.d.ts +28 -11
  222. package/dist/schemas/v3.1/strict/schema.d.ts.map +1 -1
  223. package/dist/schemas/v3.1/strict/schema.js +2 -2
  224. package/dist/schemas/v3.1/strict/schema.js.map +2 -2
  225. package/dist/schemas/v3.1/strict/security-scheme.d.ts +1 -54
  226. package/dist/schemas/v3.1/strict/security-scheme.d.ts.map +1 -1
  227. package/dist/schemas/v3.1/strict/security-scheme.js +0 -5
  228. package/dist/schemas/v3.1/strict/security-scheme.js.map +2 -2
  229. package/dist/schemas/v3.1/strict/tag.d.ts +4 -1
  230. package/dist/schemas/v3.1/strict/tag.d.ts.map +1 -1
  231. package/dist/schemas/v3.1/strict/tag.js +3 -1
  232. package/dist/schemas/v3.1/strict/tag.js.map +2 -2
  233. package/dist/schemas/v3.1/strict/type-guards.d.ts +6 -0
  234. package/dist/schemas/v3.1/strict/type-guards.d.ts.map +1 -1
  235. package/dist/schemas/v3.1/strict/type-guards.js +4 -0
  236. package/dist/schemas/v3.1/strict/type-guards.js.map +2 -2
  237. package/dist/schemas/workspace-specification/config.d.ts +22 -16
  238. package/dist/schemas/workspace-specification/config.d.ts.map +1 -1
  239. package/dist/schemas/workspace-specification/index.d.ts +23 -17
  240. package/dist/schemas/workspace-specification/index.d.ts.map +1 -1
  241. package/dist/schemas/workspace.d.ts +204 -130
  242. package/dist/schemas/workspace.d.ts.map +1 -1
  243. package/dist/schemas/workspace.js +18 -11
  244. package/dist/schemas/workspace.js.map +2 -2
  245. package/dist/server.d.ts +1 -1
  246. package/dist/workspace-plugin.d.ts +3 -0
  247. package/dist/workspace-plugin.d.ts.map +1 -1
  248. package/package.json +50 -35
  249. package/dist/schemas/extensions/document/x-scalar-document-security.d.ts +0 -13
  250. package/dist/schemas/extensions/document/x-scalar-document-security.d.ts.map +0 -1
  251. package/dist/schemas/extensions/document/x-scalar-document-security.js +0 -8
  252. package/dist/schemas/extensions/document/x-scalar-document-security.js.map +0 -7
  253. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.d.ts +0 -13
  254. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.d.ts.map +0 -1
  255. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.js +0 -9
  256. package/dist/schemas/extensions/operation/x-scalar-operation-identifiers.js.map +0 -7
  257. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.d.ts +0 -32
  258. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.d.ts.map +0 -1
  259. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.js +0 -13
  260. package/dist/schemas/v3.1/strict/client-config-extensions/x-scalar-client-config-cookies.js.map +0 -7
@@ -1,9 +1,99 @@
1
+ import { isHttpMethod } from "@scalar/helpers/http/is-http-method";
2
+ import { preventPollution } from "@scalar/helpers/object/prevent-pollution";
3
+ import { findVariables } from "@scalar/helpers/regex/find-variables";
1
4
  import { getResolvedRef } from "../helpers/get-resolved-ref.js";
2
- const updateOperationSummary = ({
3
- document,
4
- meta,
5
- payload: { summary }
6
- }) => {
5
+ import { unpackProxyObject } from "../helpers/unpack-proxy.js";
6
+ import { getOpenapiObject } from "../navigation/index.js";
7
+ import { getNavigationOptions } from "../navigation/get-navigation-options.js";
8
+ import { canHaveOrder } from "../navigation/helpers/get-openapi-object.js";
9
+ import { getOperationEntries } from "../navigation/helpers/get-operation-entries.js";
10
+ import { isContentTypeParameterObject } from "../schemas/v3.1/strict/type-guards.js";
11
+ const getParameterPositions = (path, parameters) => {
12
+ const positions = {};
13
+ for (const paramName of parameters) {
14
+ const position = path.indexOf(`{${paramName}}`);
15
+ if (position !== -1) {
16
+ positions[paramName] = position;
17
+ }
18
+ }
19
+ return positions;
20
+ };
21
+ const syncParametersForPathChange = (newPath, oldPath, existingParameters) => {
22
+ const oldPathParams = findVariables(oldPath, { includePath: true, includeEnv: false }).filter(
23
+ (v) => v !== void 0
24
+ );
25
+ const newPathParams = findVariables(newPath, { includePath: true, includeEnv: false }).filter(
26
+ (v) => v !== void 0
27
+ );
28
+ const oldPositions = getParameterPositions(oldPath, oldPathParams);
29
+ const newPositions = getParameterPositions(newPath, newPathParams);
30
+ const pathParameters = [];
31
+ const nonPathParameters = [];
32
+ for (const param of existingParameters) {
33
+ const resolved = getResolvedRef(param);
34
+ if (resolved?.in === "path") {
35
+ pathParameters.push(param);
36
+ } else {
37
+ nonPathParameters.push(param);
38
+ }
39
+ }
40
+ const existingPathParamsByName = /* @__PURE__ */ new Map();
41
+ for (const param of pathParameters) {
42
+ const resolved = getResolvedRef(param);
43
+ if (resolved?.name) {
44
+ existingPathParamsByName.set(resolved.name, param);
45
+ }
46
+ }
47
+ const usedOldParams = /* @__PURE__ */ new Set();
48
+ const syncedPathParameters = [];
49
+ for (const newParamName of newPathParams) {
50
+ if (existingPathParamsByName.has(newParamName)) {
51
+ syncedPathParameters.push(existingPathParamsByName.get(newParamName));
52
+ usedOldParams.add(newParamName);
53
+ continue;
54
+ }
55
+ const newParamPosition = newPositions[newParamName];
56
+ const oldParamAtPosition = oldPathParams.find(
57
+ (oldParam) => oldPositions[oldParam] === newParamPosition && !usedOldParams.has(oldParam)
58
+ );
59
+ if (oldParamAtPosition && existingPathParamsByName.has(oldParamAtPosition)) {
60
+ const oldParam = existingPathParamsByName.get(oldParamAtPosition);
61
+ const resolved = getResolvedRef(oldParam);
62
+ if (resolved) {
63
+ resolved.name = newParamName;
64
+ syncedPathParameters.push(oldParam);
65
+ usedOldParams.add(oldParamAtPosition);
66
+ continue;
67
+ }
68
+ }
69
+ syncedPathParameters.push({
70
+ name: newParamName,
71
+ in: "path"
72
+ });
73
+ }
74
+ return [...syncedPathParameters, ...nonPathParameters];
75
+ };
76
+ const createOperation = (workspaceStore, payload) => {
77
+ const document = workspaceStore?.workspace.documents[payload.documentName];
78
+ if (!document) {
79
+ payload.callback?.(false);
80
+ return void 0;
81
+ }
82
+ const { path, method, operation } = payload;
83
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
84
+ if (!document.paths) {
85
+ document.paths = {};
86
+ }
87
+ if (!document.paths[normalizedPath]) {
88
+ document.paths[normalizedPath] = {};
89
+ }
90
+ preventPollution(normalizedPath);
91
+ preventPollution(method);
92
+ document.paths[normalizedPath][method] = operation;
93
+ payload.callback?.(true);
94
+ return normalizedPath;
95
+ };
96
+ const updateOperationSummary = (document, { meta, payload: { summary } }) => {
7
97
  if (!document) {
8
98
  return;
9
99
  }
@@ -13,25 +103,62 @@ const updateOperationSummary = ({
13
103
  }
14
104
  operation.summary = summary;
15
105
  };
16
- const updateOperationMethodDraft = ({
17
- document,
18
- meta,
19
- payload: { method }
20
- }) => {
21
- if (!document) {
106
+ const updateOperationMethod = (document, store, { meta, payload: { method } }, callback) => {
107
+ if (meta.method === method || !isHttpMethod(method)) {
108
+ return;
109
+ }
110
+ const documentName = document?.["x-scalar-navigation"]?.name;
111
+ if (!document?.["x-scalar-navigation"] || !documentName || !store) {
112
+ console.error("Document or workspace not found", { document });
22
113
  return;
23
114
  }
24
115
  const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method]);
25
116
  if (!operation) {
117
+ console.error("Operation not found", { meta, document });
26
118
  return;
27
119
  }
28
- operation["x-scalar-method"] = method;
120
+ const documentConfig = store?.getDocumentConfiguration(documentName);
121
+ const { generateId } = getNavigationOptions(documentName, documentConfig);
122
+ const operationsMap = getOperationEntries(document["x-scalar-navigation"]);
123
+ const entries = operationsMap.get(`${meta.path}|${meta.method}`);
124
+ entries?.forEach((entry) => {
125
+ if (!canHaveOrder(entry.parent)) {
126
+ return;
127
+ }
128
+ const parentOpenAPIObject = getOpenapiObject({ store, entry: entry.parent });
129
+ if (!parentOpenAPIObject || !("x-scalar-order" in parentOpenAPIObject)) {
130
+ return;
131
+ }
132
+ const order = parentOpenAPIObject["x-scalar-order"];
133
+ const index = order?.indexOf(entry.id);
134
+ if (!Array.isArray(order) || typeof index !== "number" || index < 0) {
135
+ return;
136
+ }
137
+ const parentTag = entry.parent.type === "tag" && "name" in parentOpenAPIObject ? { tag: parentOpenAPIObject, id: entry.parent.id } : void 0;
138
+ order[index] = generateId({
139
+ type: "operation",
140
+ path: meta.path,
141
+ method,
142
+ operation,
143
+ parentId: entry.parent.id,
144
+ parentTag
145
+ });
146
+ });
147
+ preventPollution(meta.path);
148
+ const pathItems = document.paths?.[meta.path];
149
+ if (!pathItems) {
150
+ return;
151
+ }
152
+ pathItems[method] = unpackProxyObject(operation);
153
+ delete pathItems[meta.method];
154
+ if (store) {
155
+ const success = store.buildSidebar(documentName);
156
+ callback?.(success);
157
+ } else {
158
+ callback?.(true);
159
+ }
29
160
  };
30
- const updateOperationPathDraft = ({
31
- document,
32
- meta,
33
- payload: { path }
34
- }) => {
161
+ const updateOperationPath = (document, { meta, payload: { path } }) => {
35
162
  if (!document) {
36
163
  return;
37
164
  }
@@ -39,24 +166,35 @@ const updateOperationPathDraft = ({
39
166
  if (!operation) {
40
167
  return;
41
168
  }
42
- operation["x-scalar-path"] = path;
43
- const pathVariables = Array.from(path.matchAll(/{([^\/}]+)}/g), (m) => m[1]);
44
- const pathVariablesWithoutPathParameters = operation.parameters?.filter((it) => getResolvedRef(it).in !== "path");
45
- operation.parameters = [
46
- ...pathVariablesWithoutPathParameters ?? [],
47
- ...pathVariables.map((it) => ({
48
- name: it ?? "",
49
- in: "path",
50
- required: true
51
- }))
52
- ];
169
+ if (meta.path === path) {
170
+ return;
171
+ }
172
+ const oldPathParams = findVariables(meta.path, { includePath: true, includeEnv: false }).filter(
173
+ (v) => v !== void 0
174
+ );
175
+ const newPathParams = findVariables(path, { includePath: true, includeEnv: false }).filter(
176
+ (v) => v !== void 0
177
+ );
178
+ if (oldPathParams.length > 0 || newPathParams.length > 0) {
179
+ const existingParameters = operation.parameters ?? [];
180
+ operation.parameters = syncParametersForPathChange(path, meta.path, existingParameters);
181
+ }
182
+ if (!document.paths) {
183
+ document.paths = {};
184
+ }
185
+ if (!document.paths[path]) {
186
+ document.paths[path] = {};
187
+ }
188
+ document.paths[path][meta.method] = unpackProxyObject(operation);
189
+ const oldPath = document.paths[meta.path];
190
+ if (oldPath) {
191
+ delete oldPath[meta.method];
192
+ if (Object.keys(oldPath).length === 0) {
193
+ delete document.paths[meta.path];
194
+ }
195
+ }
53
196
  };
54
- const addOperationParameter = ({
55
- document,
56
- meta,
57
- payload,
58
- type
59
- }) => {
197
+ const addOperationParameter = (document, { meta, payload, type }) => {
60
198
  if (!document) {
61
199
  return;
62
200
  }
@@ -79,13 +217,7 @@ const addOperationParameter = ({
79
217
  }
80
218
  });
81
219
  };
82
- const updateOperationParameter = ({
83
- document,
84
- meta,
85
- type,
86
- payload,
87
- index
88
- }) => {
220
+ const updateOperationParameter = (document, { meta, type, payload, index }) => {
89
221
  if (!document) {
90
222
  return;
91
223
  }
@@ -99,24 +231,24 @@ const updateOperationParameter = ({
99
231
  return;
100
232
  }
101
233
  parameter.name = payload.key ?? parameter.name ?? "";
102
- if ("examples" in parameter) {
103
- if (!parameter.examples) {
104
- parameter.examples = {};
105
- }
106
- const example = getResolvedRef(parameter.examples[meta.exampleKey]);
107
- if (!example) {
108
- return;
109
- }
110
- example.value = payload.value ?? example?.value ?? "";
111
- example["x-disabled"] = payload.isEnabled === void 0 ? example["x-disabled"] : !payload.isEnabled;
234
+ if (isContentTypeParameterObject(parameter)) {
235
+ return;
236
+ }
237
+ if (!parameter.examples) {
238
+ parameter.examples = {};
239
+ }
240
+ const example = getResolvedRef(parameter.examples[meta.exampleKey]);
241
+ if (!example) {
242
+ parameter.examples[meta.exampleKey] = {
243
+ value: payload.value ?? "",
244
+ "x-disabled": payload.isEnabled === void 0 ? false : !payload.isEnabled
245
+ };
246
+ return;
112
247
  }
248
+ example.value = payload.value ?? example?.value ?? "";
249
+ example["x-disabled"] = payload.isEnabled === void 0 ? example["x-disabled"] : !payload.isEnabled;
113
250
  };
114
- const deleteOperationParameter = ({
115
- document,
116
- meta,
117
- index,
118
- type
119
- }) => {
251
+ const deleteOperationParameter = (document, { meta, index, type }) => {
120
252
  if (!document) {
121
253
  return;
122
254
  }
@@ -132,11 +264,7 @@ const deleteOperationParameter = ({
132
264
  const actualIndex = operation.parameters?.findIndex((it) => getResolvedRef(it) === parameter);
133
265
  operation.parameters?.splice(actualIndex, 1);
134
266
  };
135
- const deleteAllOperationParameters = ({
136
- document,
137
- meta,
138
- type
139
- }) => {
267
+ const deleteAllOperationParameters = (document, { meta, type }) => {
140
268
  if (!document) {
141
269
  return;
142
270
  }
@@ -146,11 +274,7 @@ const deleteAllOperationParameters = ({
146
274
  }
147
275
  operation.parameters = operation.parameters?.filter((it) => getResolvedRef(it).in !== type) ?? [];
148
276
  };
149
- const updateOperationRequestBodyContentType = ({
150
- document,
151
- meta,
152
- payload
153
- }) => {
277
+ const updateOperationRequestBodyContentType = (document, { meta, payload }) => {
154
278
  if (!document) {
155
279
  return;
156
280
  }
@@ -170,12 +294,7 @@ const updateOperationRequestBodyContentType = ({
170
294
  }
171
295
  requestBody["x-scalar-selected-content-type"][meta.exampleKey] = payload.contentType;
172
296
  };
173
- const updateOperationRequestBodyExample = ({
174
- document,
175
- meta,
176
- payload,
177
- contentType
178
- }) => {
297
+ const updateOperationRequestBodyExample = (document, { meta, payload, contentType }) => {
179
298
  if (!document) {
180
299
  return;
181
300
  }
@@ -207,12 +326,7 @@ const updateOperationRequestBodyExample = ({
207
326
  }
208
327
  example.value = payload.value;
209
328
  };
210
- const addOperationRequestBodyFormRow = ({
211
- document,
212
- meta,
213
- payload,
214
- contentType
215
- }) => {
329
+ const addOperationRequestBodyFormRow = (document, { meta, payload, contentType }) => {
216
330
  if (!document) {
217
331
  return;
218
332
  }
@@ -253,13 +367,7 @@ const addOperationRequestBodyFormRow = ({
253
367
  value: payload.value ?? ""
254
368
  });
255
369
  };
256
- const updateOperationRequestBodyFormRow = ({
257
- document,
258
- meta,
259
- index,
260
- payload,
261
- contentType
262
- }) => {
370
+ const updateOperationRequestBodyFormRow = (document, { meta, index, payload, contentType }) => {
263
371
  if (!document) {
264
372
  return;
265
373
  }
@@ -290,12 +398,7 @@ const updateOperationRequestBodyFormRow = ({
290
398
  value: payload.value === null ? void 0 : payload.value ?? example.value[index]?.value ?? ""
291
399
  };
292
400
  };
293
- const deleteOperationRequestBodyFormRow = ({
294
- document,
295
- meta,
296
- index,
297
- contentType
298
- }) => {
401
+ const deleteOperationRequestBodyFormRow = (document, { meta, index, contentType }) => {
299
402
  if (!document) {
300
403
  return;
301
404
  }
@@ -326,12 +429,13 @@ const deleteOperationRequestBodyFormRow = ({
326
429
  export {
327
430
  addOperationParameter,
328
431
  addOperationRequestBodyFormRow,
432
+ createOperation,
329
433
  deleteAllOperationParameters,
330
434
  deleteOperationParameter,
331
435
  deleteOperationRequestBodyFormRow,
332
- updateOperationMethodDraft,
436
+ updateOperationMethod,
333
437
  updateOperationParameter,
334
- updateOperationPathDraft,
438
+ updateOperationPath,
335
439
  updateOperationRequestBodyContentType,
336
440
  updateOperationRequestBodyExample,
337
441
  updateOperationRequestBodyFormRow,
@@ -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 { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { preventPollution } from '@scalar/helpers/object/prevent-pollution'\nimport { findVariables } from '@scalar/helpers/regex/find-variables'\n\nimport type { WorkspaceStore } from '@/client'\nimport type { OperationEvents } from '@/events/definitions/operation'\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport { getOpenapiObject } from '@/navigation'\nimport { getNavigationOptions } from '@/navigation/get-navigation-options'\nimport { canHaveOrder } from '@/navigation/helpers/get-openapi-object'\nimport { getOperationEntries } from '@/navigation/helpers/get-operation-entries'\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 * Creates a new operation at a specific path and method in the document.\n * Automatically normalizes the path to ensure it starts with a slash.\n *\n * Returns the normalized path if successful, undefined otherwise.\n *\n * Example:\n * ```ts\n * createOperation(\n * document,\n * 'users',\n * 'get',\n * { tags: ['Users'] },\n * )\n * ```\n */\nexport const createOperation = (\n workspaceStore: WorkspaceStore | null,\n payload: OperationEvents['operation:create:operation'],\n): string | undefined => {\n const document = workspaceStore?.workspace.documents[payload.documentName]\n if (!document) {\n payload.callback?.(false)\n return undefined\n }\n\n const { path, method, operation } = payload\n\n /** Ensure the path starts with a slash */\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n\n /** Create the operation in the document */\n if (!document.paths) {\n document.paths = {}\n }\n\n if (!document.paths[normalizedPath]) {\n document.paths[normalizedPath] = {}\n }\n\n /** Prevent pollution of the path and method */\n preventPollution(normalizedPath)\n preventPollution(method)\n\n /** Create the operation in the document */\n document.paths[normalizedPath][method] = operation\n\n payload.callback?.(true)\n return normalizedPath\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 * Updates the HTTP method of an operation and moves it to the new method slot.\n * This function:\n * 1. Moves the operation from the old method to the new method under paths\n * 2. Updates x-scalar-order to maintain the operation's position in the sidebar\n * 3. Rebuilds the sidebar to reflect the changes\n *\n * Safely no-ops if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationMethod({\n * document,\n * store,\n * meta: { method: 'get', path: '/users' },\n * payload: { method: 'post' },\n * })\n * ```\n */\nexport const updateOperationMethod = (\n document: WorkspaceDocument | null,\n store: WorkspaceStore | null,\n { meta, payload: { method } }: OperationEvents['operation:update:method'],\n callback?: (success: boolean) => void,\n) => {\n // If the method has not changed, no need to do anything\n if (meta.method === method || !isHttpMethod(method)) {\n return\n }\n\n const documentName = document?.['x-scalar-navigation']?.name\n if (!document?.['x-scalar-navigation'] || !documentName || !store) {\n console.error('Document or workspace not found', { document })\n return\n }\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 // Get the document configuration to generate IDs consistently\n // If no store is provided (e.g., in tests), use default configuration\n const documentConfig = store?.getDocumentConfiguration(documentName)\n const { generateId } = getNavigationOptions(documentName, documentConfig)\n\n /** Generate an operations map of the document */\n const operationsMap = getOperationEntries(document['x-scalar-navigation'])\n\n /** Grabs all of the current operation entries for the given path and method */\n const entries = operationsMap.get(`${meta.path}|${meta.method}`)\n\n // Loop over the entries and replace the ID in the x-scalar-order with the new ID\n entries?.forEach((entry) => {\n if (!canHaveOrder(entry.parent)) {\n return\n }\n\n // Ensure we have an x-scalar-order property\n const parentOpenAPIObject = getOpenapiObject({ store, entry: entry.parent })\n if (!parentOpenAPIObject || !('x-scalar-order' in parentOpenAPIObject)) {\n return\n }\n\n const order = parentOpenAPIObject['x-scalar-order']\n const index = order?.indexOf(entry.id)\n if (!Array.isArray(order) || typeof index !== 'number' || index < 0) {\n return\n }\n\n const parentTag =\n entry.parent.type === 'tag' && 'name' in parentOpenAPIObject\n ? { tag: parentOpenAPIObject, id: entry.parent.id }\n : undefined\n\n // Generate the new ID based on whether this is an operation or webhook\n order[index] = generateId({\n type: 'operation',\n path: meta.path,\n method: method,\n operation: operation,\n parentId: entry.parent.id,\n parentTag,\n })\n })\n\n // Prevent assigning dangerous keys to the path items object\n preventPollution(meta.path)\n\n // Now ensure we replace the actual operation in the document\n const pathItems = document.paths?.[meta.path]\n if (!pathItems) {\n return\n }\n\n pathItems[method] = unpackProxyObject(operation)\n delete pathItems[meta.method]\n\n // Rebuild the sidebar with the updated order (if store is available)\n if (store) {\n const success = store.buildSidebar(documentName)\n callback?.(success)\n } else {\n callback?.(true)\n }\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": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import type { HttpMethod } from '@scalar/helpers/http/http-methods';
2
2
  import type { OpenApiDocument } from '../schemas/v3.1/strict/openapi-document.js';
3
- export type OperationIdentifier = {
3
+ type OperationIdentifier = {
4
4
  path: string;
5
5
  method: Exclude<HttpMethod, 'head' | 'options'>;
6
6
  };
@@ -19,4 +19,5 @@ export declare const requestMutators: (document?: OpenApiDocument) => {
19
19
  }) => boolean;
20
20
  deleteRequest: ({ path, method }: OperationIdentifier) => boolean;
21
21
  };
22
+ export {};
22
23
  //# sourceMappingURL=request.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/mutators/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAE7E,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAChD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,WAAW,eAAe;4CAoBrD;QACD,MAAM,EAAE,mBAAmB,CAAA;QAC3B,WAAW,EAAE,mBAAmB,CAAA;KACjC;sCAqDwC,mBAAmB;CA0B7D,CAAA"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/mutators/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAE7E,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAChD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,WAAW,eAAe;4CAoBrD;QACD,MAAM,EAAE,mBAAmB,CAAA;QAC3B,WAAW,EAAE,mBAAmB,CAAA;KACjC;sCAqDwC,mBAAmB;CA0B7D,CAAA"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/request.ts"],
4
- "sourcesContent": ["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\n\nimport type { OpenApiDocument } from '@/schemas/v3.1/strict/openapi-document'\n\nexport type OperationIdentifier = {\n path: string\n method: Exclude<HttpMethod, 'head' | 'options'>\n}\n\n/**\n * Provides mutator functions for managing OpenAPI operations (requests) within a workspace store.\n * This module contains utilities for moving and deleting API operations while maintaining\n * document integrity and preventing conflicts.\n *\n * @param document - The OpenAPI document to operate on\n * @returns Object containing mutator functions for request operations\n */\nexport const requestMutators = (document?: OpenApiDocument) => {\n /**\n * Moves an operation from one path/method to another within the OpenAPI document.\n * This function handles the relocation of API operations while preserving their configuration\n * and preventing accidental overwrites of existing operations.\n *\n * @param source - The current location of the operation to move\n * @param destination - The target location for the operation (path and/or method)\n * @returns true if the operation was successfully moved, false otherwise\n *\n * @example\n * // Move an operation to a completely new path and method\n * moveOperation({\n * source: { path: '/old-endpoint', method: 'get' },\n * destination: { path: '/new-endpoint', method: 'post' }\n * })\n */\n const moveOperation = ({\n source,\n destination,\n }: {\n source: OperationIdentifier\n destination: OperationIdentifier\n }) => {\n if (!document || !document.paths) {\n return false\n }\n\n const pathObject = document.paths[source.path]\n\n if (!pathObject) {\n return false\n }\n\n const operation = pathObject[source.method]\n\n if (!operation) {\n return false\n }\n\n const newPath = destination.path || source.path\n const newMethod = destination.method || source.method\n\n if (document.paths[newPath]?.[newMethod]) {\n // If the new path and method already exist, we should not overwrite it.\n console.warn(`Request already exists at ${newPath} with method ${newMethod}.`)\n return false\n }\n\n // delete the request from the old location\n delete pathObject[source.method]\n\n if (!document.paths[newPath]) {\n // If the new path does not exist, create it\n document.paths[newPath] = {}\n }\n\n document.paths[newPath][newMethod] = operation\n return true\n }\n\n /**\n * Deletes an operation from the OpenAPI document at the specified path and method.\n *\n * @param path - The path of the operation to delete\n * @param method - The HTTP method of the operation to delete\n * @returns void - Returns early if document, path, or operation doesn't exist\n *\n * @example\n * // Delete a GET operation from /users endpoint\n * deleteRequest({ path: '/users', method: 'get' })\n *\n * @example\n * // Delete a POST operation from /auth/login endpoint\n * deleteRequest({ path: '/auth/login', method: 'post' })\n */\n const deleteRequest = ({ path, method }: OperationIdentifier) => {\n if (!document) {\n return false\n }\n\n const pathObject = document?.paths?.[path]\n\n if (!pathObject) {\n return false\n }\n\n const operation = pathObject[method]\n\n if (!operation) {\n return false\n }\n\n // Delete the request by slug\n delete pathObject[method]\n return true\n }\n\n return {\n moveRequest: moveOperation,\n deleteRequest,\n }\n}\n"],
4
+ "sourcesContent": ["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\n\nimport type { OpenApiDocument } from '@/schemas/v3.1/strict/openapi-document'\n\ntype OperationIdentifier = {\n path: string\n method: Exclude<HttpMethod, 'head' | 'options'>\n}\n\n/**\n * Provides mutator functions for managing OpenAPI operations (requests) within a workspace store.\n * This module contains utilities for moving and deleting API operations while maintaining\n * document integrity and preventing conflicts.\n *\n * @param document - The OpenAPI document to operate on\n * @returns Object containing mutator functions for request operations\n */\nexport const requestMutators = (document?: OpenApiDocument) => {\n /**\n * Moves an operation from one path/method to another within the OpenAPI document.\n * This function handles the relocation of API operations while preserving their configuration\n * and preventing accidental overwrites of existing operations.\n *\n * @param source - The current location of the operation to move\n * @param destination - The target location for the operation (path and/or method)\n * @returns true if the operation was successfully moved, false otherwise\n *\n * @example\n * // Move an operation to a completely new path and method\n * moveOperation({\n * source: { path: '/old-endpoint', method: 'get' },\n * destination: { path: '/new-endpoint', method: 'post' }\n * })\n */\n const moveOperation = ({\n source,\n destination,\n }: {\n source: OperationIdentifier\n destination: OperationIdentifier\n }) => {\n if (!document || !document.paths) {\n return false\n }\n\n const pathObject = document.paths[source.path]\n\n if (!pathObject) {\n return false\n }\n\n const operation = pathObject[source.method]\n\n if (!operation) {\n return false\n }\n\n const newPath = destination.path || source.path\n const newMethod = destination.method || source.method\n\n if (document.paths[newPath]?.[newMethod]) {\n // If the new path and method already exist, we should not overwrite it.\n console.warn(`Request already exists at ${newPath} with method ${newMethod}.`)\n return false\n }\n\n // delete the request from the old location\n delete pathObject[source.method]\n\n if (!document.paths[newPath]) {\n // If the new path does not exist, create it\n document.paths[newPath] = {}\n }\n\n document.paths[newPath][newMethod] = operation\n return true\n }\n\n /**\n * Deletes an operation from the OpenAPI document at the specified path and method.\n *\n * @param path - The path of the operation to delete\n * @param method - The HTTP method of the operation to delete\n * @returns void - Returns early if document, path, or operation doesn't exist\n *\n * @example\n * // Delete a GET operation from /users endpoint\n * deleteRequest({ path: '/users', method: 'get' })\n *\n * @example\n * // Delete a POST operation from /auth/login endpoint\n * deleteRequest({ path: '/auth/login', method: 'post' })\n */\n const deleteRequest = ({ path, method }: OperationIdentifier) => {\n if (!document) {\n return false\n }\n\n const pathObject = document?.paths?.[path]\n\n if (!pathObject) {\n return false\n }\n\n const operation = pathObject[method]\n\n if (!operation) {\n return false\n }\n\n // Delete the request by slug\n delete pathObject[method]\n return true\n }\n\n return {\n moveRequest: moveOperation,\n deleteRequest,\n }\n}\n"],
5
5
  "mappings": "AAiBO,MAAM,kBAAkB,CAAC,aAA+B;AAiB7D,QAAM,gBAAgB,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,EACF,MAGM;AACJ,QAAI,CAAC,YAAY,CAAC,SAAS,OAAO;AAChC,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,SAAS,MAAM,OAAO,IAAI;AAE7C,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,WAAW,OAAO,MAAM;AAE1C,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,YAAY,QAAQ,OAAO;AAC3C,UAAM,YAAY,YAAY,UAAU,OAAO;AAE/C,QAAI,SAAS,MAAM,OAAO,IAAI,SAAS,GAAG;AAExC,cAAQ,KAAK,6BAA6B,OAAO,gBAAgB,SAAS,GAAG;AAC7E,aAAO;AAAA,IACT;AAGA,WAAO,WAAW,OAAO,MAAM;AAE/B,QAAI,CAAC,SAAS,MAAM,OAAO,GAAG;AAE5B,eAAS,MAAM,OAAO,IAAI,CAAC;AAAA,IAC7B;AAEA,aAAS,MAAM,OAAO,EAAE,SAAS,IAAI;AACrC,WAAO;AAAA,EACT;AAiBA,QAAM,gBAAgB,CAAC,EAAE,MAAM,OAAO,MAA2B;AAC/D,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,UAAU,QAAQ,IAAI;AAEzC,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,WAAW,MAAM;AAEnC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAGA,WAAO,WAAW,MAAM;AACxB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,EACF;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,SAgBX,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 ? "" : url;
109
110
  return document["x-scalar-selected-server"];
110
111
  };
111
112
  export {