@scalar/workspace-store 0.49.3 → 0.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/client.d.ts +2 -3
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +58 -25
  5. package/dist/entities/auth/schema.d.ts +25 -5
  6. package/dist/entities/auth/schema.d.ts.map +1 -1
  7. package/dist/events/bus.d.ts +70 -0
  8. package/dist/events/bus.d.ts.map +1 -1
  9. package/dist/events/bus.js +48 -11
  10. package/dist/events/definitions/analytics.d.ts +0 -12
  11. package/dist/events/definitions/analytics.d.ts.map +1 -1
  12. package/dist/events/definitions/auth.d.ts +44 -6
  13. package/dist/events/definitions/auth.d.ts.map +1 -1
  14. package/dist/events/definitions/index.d.ts +3 -2
  15. package/dist/events/definitions/index.d.ts.map +1 -1
  16. package/dist/events/definitions/log.d.ts +18 -0
  17. package/dist/events/definitions/log.d.ts.map +1 -0
  18. package/dist/events/definitions/log.js +1 -0
  19. package/dist/events/definitions/operation.d.ts +1 -1
  20. package/dist/events/definitions/operation.d.ts.map +1 -1
  21. package/dist/events/definitions/ui.d.ts +18 -1
  22. package/dist/events/definitions/ui.d.ts.map +1 -1
  23. package/dist/events/index.d.ts +1 -1
  24. package/dist/events/index.d.ts.map +1 -1
  25. package/dist/helpers/get-resolved-ref.d.ts +6 -0
  26. package/dist/helpers/get-resolved-ref.d.ts.map +1 -1
  27. package/dist/helpers/get-resolved-ref.js +9 -0
  28. package/dist/helpers/is-hidden.d.ts +8 -0
  29. package/dist/helpers/is-hidden.d.ts.map +1 -0
  30. package/dist/helpers/is-hidden.js +5 -0
  31. package/dist/helpers/merge-object.d.ts +1 -1
  32. package/dist/helpers/merge-object.d.ts.map +1 -1
  33. package/dist/mutators/auth.d.ts +22 -3
  34. package/dist/mutators/auth.d.ts.map +1 -1
  35. package/dist/mutators/auth.js +213 -37
  36. package/dist/mutators/cookie.d.ts.map +1 -1
  37. package/dist/mutators/cookie.js +3 -2
  38. package/dist/mutators/document.d.ts.map +1 -1
  39. package/dist/mutators/document.js +5 -4
  40. package/dist/mutators/environment.d.ts.map +1 -1
  41. package/dist/mutators/environment.js +12 -5
  42. package/dist/mutators/index.d.ts +4 -0
  43. package/dist/mutators/index.d.ts.map +1 -1
  44. package/dist/mutators/operation/body.d.ts.map +1 -1
  45. package/dist/mutators/operation/body.js +6 -2
  46. package/dist/mutators/operation/extensions.d.ts.map +1 -1
  47. package/dist/mutators/operation/extensions.js +5 -1
  48. package/dist/mutators/operation/history.d.ts.map +1 -1
  49. package/dist/mutators/operation/history.js +7 -3
  50. package/dist/mutators/operation/operation.d.ts.map +1 -1
  51. package/dist/mutators/operation/operation.js +15 -10
  52. package/dist/mutators/operation/parameters.d.ts.map +1 -1
  53. package/dist/mutators/operation/parameters.js +12 -5
  54. package/dist/mutators/server.d.ts.map +1 -1
  55. package/dist/mutators/server.js +2 -1
  56. package/dist/mutators/tag.d.ts.map +1 -1
  57. package/dist/mutators/tag.js +9 -4
  58. package/dist/navigation/get-navigation-options.d.ts +1 -1
  59. package/dist/navigation/get-navigation-options.d.ts.map +1 -1
  60. package/dist/navigation/get-navigation-options.js +1 -0
  61. package/dist/navigation/helpers/get-openapi-object.d.ts.map +1 -1
  62. package/dist/navigation/helpers/get-openapi-object.js +5 -0
  63. package/dist/navigation/helpers/traverse-document.d.ts.map +1 -1
  64. package/dist/navigation/helpers/traverse-document.js +8 -2
  65. package/dist/navigation/helpers/traverse-paths.d.ts +4 -2
  66. package/dist/navigation/helpers/traverse-paths.d.ts.map +1 -1
  67. package/dist/navigation/helpers/traverse-paths.js +9 -6
  68. package/dist/navigation/helpers/traverse-schemas.d.ts.map +1 -1
  69. package/dist/navigation/helpers/traverse-schemas.js +9 -4
  70. package/dist/navigation/helpers/traverse-tags.d.ts.map +1 -1
  71. package/dist/navigation/helpers/traverse-tags.js +2 -1
  72. package/dist/navigation/helpers/traverse-webhooks.d.ts.map +1 -1
  73. package/dist/navigation/helpers/traverse-webhooks.js +4 -3
  74. package/dist/navigation/helpers/update-order-ids.d.ts.map +1 -1
  75. package/dist/navigation/helpers/update-order-ids.js +4 -1
  76. package/dist/navigation/types.d.ts +4 -0
  77. package/dist/navigation/types.d.ts.map +1 -1
  78. package/dist/persistence/index.d.ts +123 -80
  79. package/dist/persistence/index.d.ts.map +1 -1
  80. package/dist/persistence/index.js +233 -167
  81. package/dist/persistence/migrations/v2-team-to-local.d.ts +22 -5
  82. package/dist/persistence/migrations/v2-team-to-local.d.ts.map +1 -1
  83. package/dist/persistence/migrations/v2-team-to-local.js +195 -137
  84. package/dist/request-example/builder/body/build-request-body.d.ts.map +1 -1
  85. package/dist/request-example/builder/body/build-request-body.js +66 -2
  86. package/dist/request-example/builder/build-request.d.ts +24 -3
  87. package/dist/request-example/builder/build-request.d.ts.map +1 -1
  88. package/dist/request-example/builder/build-request.js +89 -18
  89. package/dist/request-example/builder/index.d.ts +2 -1
  90. package/dist/request-example/builder/index.d.ts.map +1 -1
  91. package/dist/request-example/builder/index.js +2 -1
  92. package/dist/request-example/builder/request-factory.d.ts.map +1 -1
  93. package/dist/request-example/builder/request-factory.js +5 -8
  94. package/dist/request-example/builder/resolve-request-factory-url.d.ts +18 -1
  95. package/dist/request-example/builder/resolve-request-factory-url.d.ts.map +1 -1
  96. package/dist/request-example/builder/resolve-request-factory-url.js +29 -4
  97. package/dist/request-example/context/environment.d.ts.map +1 -1
  98. package/dist/request-example/context/environment.js +2 -1
  99. package/dist/request-example/context/get-request-example-context.d.ts.map +1 -1
  100. package/dist/request-example/context/get-request-example-context.js +7 -0
  101. package/dist/request-example/context/headers.d.ts +28 -13
  102. package/dist/request-example/context/headers.d.ts.map +1 -1
  103. package/dist/request-example/context/headers.js +84 -19
  104. package/dist/request-example/context/index.d.ts +1 -0
  105. package/dist/request-example/context/index.d.ts.map +1 -1
  106. package/dist/request-example/context/index.js +1 -0
  107. package/dist/request-example/context/security/get-selected-security.d.ts.map +1 -1
  108. package/dist/request-example/context/security/get-selected-security.js +3 -6
  109. package/dist/request-example/context/servers.d.ts.map +1 -1
  110. package/dist/request-example/context/servers.js +3 -3
  111. package/dist/request-example/index.d.ts +3 -3
  112. package/dist/request-example/index.d.ts.map +1 -1
  113. package/dist/request-example/index.js +2 -2
  114. package/dist/resolve.d.ts.map +1 -1
  115. package/dist/resolve.js +1 -8
  116. package/dist/schemas/extensions/document/x-scalar-environments.d.ts +6 -6
  117. package/dist/schemas/extensions/document/x-scalar-original-source-url.d.ts +15 -0
  118. package/dist/schemas/extensions/document/x-scalar-original-source-url.d.ts.map +1 -0
  119. package/dist/schemas/extensions/document/x-scalar-original-source-url.js +16 -0
  120. package/dist/schemas/extensions/operation/x-badge.d.ts +2 -2
  121. package/dist/schemas/extensions/operation/x-scalar-stability.d.ts +1 -1
  122. package/dist/schemas/extensions/schema/x-enum-descriptions.d.ts +2 -2
  123. package/dist/schemas/extensions/security/x-scalar-credentials-location.d.ts +1 -1
  124. package/dist/schemas/extensions/security/x-use-pkce.d.ts +1 -1
  125. package/dist/schemas/extensions/workspace/x-scalar-active-proxy.d.ts +1 -1
  126. package/dist/schemas/inmemory-workspace.d.ts +3 -4631
  127. package/dist/schemas/inmemory-workspace.d.ts.map +1 -1
  128. package/dist/schemas/inmemory-workspace.js +1 -15
  129. package/dist/schemas/reference-config/index.d.ts +6 -2
  130. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  131. package/dist/schemas/reference-config/settings.d.ts +5 -1
  132. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  133. package/dist/schemas/type-guards.d.ts +24 -0
  134. package/dist/schemas/type-guards.d.ts.map +1 -0
  135. package/dist/schemas/type-guards.js +30 -0
  136. package/dist/schemas/v3.1/openapi/index.d.ts +4 -3
  137. package/dist/schemas/v3.1/openapi/index.d.ts.map +1 -1
  138. package/dist/schemas/v3.1/openapi/index.js +2 -3
  139. package/dist/schemas/v3.1/strict/encoding.d.ts +12 -0
  140. package/dist/schemas/v3.1/strict/encoding.d.ts.map +1 -1
  141. package/dist/schemas/v3.1/strict/encoding.js +11 -0
  142. package/dist/schemas/v3.1/strict/openapi-document.d.ts +179 -39
  143. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  144. package/dist/schemas/v3.1/strict/openapi-document.js +2 -2
  145. package/dist/schemas/workspace-specification/index.d.ts +1 -1
  146. package/dist/schemas/workspace.d.ts +4 -4377
  147. package/dist/schemas/workspace.d.ts.map +1 -1
  148. package/dist/schemas/workspace.js +0 -8
  149. package/dist/schemas.d.ts +2 -1
  150. package/dist/schemas.d.ts.map +1 -1
  151. package/dist/schemas.js +1 -1
  152. package/package.json +8 -7
@@ -3,6 +3,8 @@ import { getResolvedRef } from '../helpers/get-resolved-ref.js';
3
3
  import { isNonOptionalSecurityRequirement } from '../helpers/is-non-optional-security-requirement.js';
4
4
  import { mergeObjects } from '../helpers/merge-object.js';
5
5
  import { unpackProxyObject } from '../helpers/unpack-proxy.js';
6
+ import { getSelectedSecurity } from '../request-example/context/security/get-selected-security.js';
7
+ import { isOpenApiDocument } from '../schemas/type-guards.js';
6
8
  /**
7
9
  * Updates the selected security schemes for either the entire document or a specific operation.
8
10
  * - Adds newly created security schemes (if any) to the workspace document's components.
@@ -28,7 +30,10 @@ import { unpackProxyObject } from '../helpers/unpack-proxy.js';
28
30
  * ```
29
31
  */
30
32
  export const updateSelectedSecuritySchemes = async (store, document, { selectedRequirements, newSchemes, meta }) => {
31
- const documentName = document?.['x-scalar-navigation']?.name;
33
+ if (!isOpenApiDocument(document)) {
34
+ return;
35
+ }
36
+ const documentName = document['x-scalar-navigation']?.name;
32
37
  if (!documentName) {
33
38
  return;
34
39
  }
@@ -88,7 +93,10 @@ export const updateSelectedSecuritySchemes = async (store, document, { selectedR
88
93
  * If the document name cannot be determined, nothing happens.
89
94
  */
90
95
  const clearSelectedSecuritySchemes = (store, document, { meta }) => {
91
- const documentName = document?.['x-scalar-navigation']?.name;
96
+ if (!isOpenApiDocument(document)) {
97
+ return;
98
+ }
99
+ const documentName = document['x-scalar-navigation']?.name;
92
100
  if (!documentName) {
93
101
  return;
94
102
  }
@@ -121,7 +129,10 @@ const clearSelectedSecuritySchemes = (store, document, { meta }) => {
121
129
  * })
122
130
  */
123
131
  export const updateSecurityScheme = (document, { payload, name }) => {
124
- const target = getResolvedRef(document?.components?.securitySchemes?.[name]);
132
+ if (!isOpenApiDocument(document)) {
133
+ return;
134
+ }
135
+ const target = getResolvedRef(document.components?.securitySchemes?.[name]);
125
136
  if (!target) {
126
137
  console.error(`Security scheme ${name} not found`);
127
138
  return;
@@ -133,7 +144,10 @@ export const updateSecurityScheme = (document, { payload, name }) => {
133
144
  return target;
134
145
  };
135
146
  const updateSecuritySchemeSecrets = (store, document, { payload, name, overwrite = false }) => {
136
- const documentName = document?.['x-scalar-navigation']?.name;
147
+ if (!isOpenApiDocument(document)) {
148
+ return;
149
+ }
150
+ const documentName = document['x-scalar-navigation']?.name;
137
151
  if (!documentName) {
138
152
  return;
139
153
  }
@@ -147,7 +161,10 @@ const updateSecuritySchemeSecrets = (store, document, { payload, name, overwrite
147
161
  store?.auth.setAuthSecrets(documentName, name, result);
148
162
  };
149
163
  const clearSecuritySchemeSecrets = (store, document, { name }) => {
150
- const documentName = document?.['x-scalar-navigation']?.name;
164
+ if (!isOpenApiDocument(document)) {
165
+ return;
166
+ }
167
+ const documentName = document['x-scalar-navigation']?.name;
151
168
  if (!documentName) {
152
169
  return;
153
170
  }
@@ -180,12 +197,15 @@ const clearSecuritySchemeSecrets = (store, document, { name }) => {
180
197
  * });
181
198
  */
182
199
  export const updateSelectedAuthTab = (store, document, { index, meta }) => {
183
- const documentName = document?.['x-scalar-navigation']?.name;
200
+ if (!isOpenApiDocument(document)) {
201
+ return;
202
+ }
203
+ const documentName = document['x-scalar-navigation']?.name;
184
204
  if (!documentName) {
185
205
  return;
186
206
  }
187
207
  // Ensure the path/method exists in the document
188
- if (meta.type === 'operation' && document?.paths?.[meta.path]?.[meta.method] === undefined) {
208
+ if (meta.type === 'operation' && document.paths?.[meta.path]?.[meta.method] === undefined) {
189
209
  return;
190
210
  }
191
211
  // Determine the target object for setting the auth tab index:
@@ -204,19 +224,33 @@ export const updateSelectedAuthTab = (store, document, { index, meta }) => {
204
224
  }
205
225
  return store?.auth.setAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method }, { selectedIndex: index, selectedSchemes: [] });
206
226
  }
207
- // Set the selected index
208
- target.selectedIndex = index;
227
+ store?.auth.setAuthSelectedSchemas(meta.type === 'document'
228
+ ? { type: 'document', documentName }
229
+ : { type: 'operation', documentName, path: meta.path, method: meta.method }, {
230
+ selectedIndex: index,
231
+ selectedSchemes: unpackProxyObject(target.selectedSchemes, { depth: null }) ?? [],
232
+ });
233
+ };
234
+ /**
235
+ * Returns whether `id` lists the same scheme names as `requirement` (OpenAPI security requirement keys),
236
+ * ignoring key order. UI payloads use `Object.keys(selectedSecuritySchemas)` which follows insertion order;
237
+ * stored copies may serialize with a different order.
238
+ */
239
+ const securityRequirementIdsMatch = (requirement, id) => {
240
+ const sortedRequirementKeys = [...Object.keys(requirement)].sort((a, b) => a.localeCompare(b));
241
+ const sortedId = [...id].sort((a, b) => a.localeCompare(b));
242
+ return JSON.stringify(sortedRequirementKeys) === JSON.stringify(sortedId);
209
243
  };
210
244
  /**
211
245
  * Updates the scopes for a specific security requirement in the selected security schemes of
212
- * a document or operation. Also allow to add a new scope to the scheme.
246
+ * a document or operation. This mutator only touches selection state; managing the scope
247
+ * definitions on the OAuth flow is handled by `upsertScope` and `deleteScope`.
213
248
  *
214
249
  * @param document - The OpenAPI WorkspaceDocument to update.
215
250
  * @param id - An array of scheme names that uniquely identifies the target security requirement.
216
251
  * For example: ['OAuth', 'ApiKeyAuth']
217
252
  * @param name - The security scheme name to update scopes for (e.g., 'OAuth').
218
253
  * @param scopes - The new list of scopes to set. For example: ['read:pets', 'write:pets']
219
- * @param newScopePayload - The payload to add a new scope with
220
254
  * @param meta - The context specifying whether the update is at the document-level or operation-level.
221
255
  *
222
256
  * Example usage:
@@ -240,8 +274,11 @@ export const updateSelectedAuthTab = (store, document, { index, meta }) => {
240
274
  * // After, the first scheme becomes: { "OAuth": ["write:pets"] }
241
275
  * ```
242
276
  */
243
- export const updateSelectedScopes = (store, document, { id, name, scopes, newScopePayload, meta }) => {
244
- const documentName = document?.['x-scalar-navigation']?.name;
277
+ export const updateSelectedScopes = (store, document, { id, name, scopes, meta }) => {
278
+ if (!isOpenApiDocument(document)) {
279
+ return;
280
+ }
281
+ const documentName = document['x-scalar-navigation']?.name;
245
282
  if (!documentName) {
246
283
  return;
247
284
  }
@@ -252,31 +289,160 @@ export const updateSelectedScopes = (store, document, { id, name, scopes, newSco
252
289
  }
253
290
  return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method });
254
291
  };
255
- const target = getTarget();
256
- if (!target) {
292
+ // Resolve the target lazily: only build a fallback selection when the store has none.
293
+ //
294
+ // We pass `[]` for security requirements because a `preferredSecurityScheme` is always
295
+ // supplied (derived from `id`), which makes `getSelectedSecurity` build the requirement
296
+ // from that scheme alone and never read the requirements array.
297
+ const target = getTarget() ??
298
+ getSelectedSecurity(undefined, undefined, [], (document.components?.securitySchemes ?? {}), id.length === 1 ? id[0] : id);
299
+ const nextSelectedSchemes = unpackProxyObject(target.selectedSchemes, { depth: 1 }) ?? [];
300
+ // Match the security requirement by scheme key names (order-insensitive: Object.keys order
301
+ // can differ between the store copy and the UI payload for the same requirement object).
302
+ const nextScheme = nextSelectedSchemes.find((candidate) => securityRequirementIdsMatch(candidate, id));
303
+ if (!isNonOptionalSecurityRequirement(nextScheme)) {
304
+ return;
305
+ }
306
+ nextScheme[name] = scopes;
307
+ store?.auth.setAuthSelectedSchemas(meta.type === 'document'
308
+ ? { type: 'document', documentName }
309
+ : { type: 'operation', documentName, path: meta.path, method: meta.method }, { selectedIndex: target.selectedIndex, selectedSchemes: nextSelectedSchemes });
310
+ };
311
+ /**
312
+ * Resolves the OAuth flow on a security scheme by name + flow type.
313
+ * Returns `null` when the scheme or flow cannot be found, or the scheme is not an OAuth2 / OpenID Connect scheme.
314
+ */
315
+ const resolveOAuthFlow = (document, name, flowType) => {
316
+ if (!isOpenApiDocument(document)) {
317
+ return null;
318
+ }
319
+ const securityScheme = getResolvedRef(document.components?.securitySchemes?.[name]);
320
+ if (!securityScheme) {
321
+ return null;
322
+ }
323
+ if (securityScheme.type !== 'oauth2' && securityScheme.type !== 'openIdConnect') {
324
+ return null;
325
+ }
326
+ return securityScheme.flows?.[flowType] ?? null;
327
+ };
328
+ /**
329
+ * Walks every selection container that lives under a document (the document-level
330
+ * `x-scalar-selected-security` plus the equivalent on every path / method) and invokes
331
+ * `transform` on a plain copy of `selectedSchemes`, then writes back through
332
+ * `setAuthSelectedSchemas` so persistence hooks run.
333
+ */
334
+ const walkSelectedSchemes = (store, document, transform) => {
335
+ if (!isOpenApiDocument(document) || !store) {
336
+ return;
337
+ }
338
+ const documentName = document['x-scalar-navigation']?.name;
339
+ if (!documentName) {
340
+ return;
341
+ }
342
+ const apply = (payload) => {
343
+ const target = store.auth.getAuthSelectedSchemas(payload);
344
+ if (!target) {
345
+ return;
346
+ }
347
+ const nextSchemes = unpackProxyObject(target.selectedSchemes, { depth: 1 }) ?? [];
348
+ transform(nextSchemes);
349
+ store.auth.setAuthSelectedSchemas(payload, {
350
+ selectedIndex: target.selectedIndex,
351
+ selectedSchemes: nextSchemes,
352
+ });
353
+ };
354
+ apply({ type: 'document', documentName });
355
+ Object.entries(document.paths ?? {}).forEach(([path, pathItemObject]) => {
356
+ Object.entries(pathItemObject).forEach(([method, operation]) => {
357
+ if (typeof operation !== 'object') {
358
+ return;
359
+ }
360
+ apply({ type: 'operation', documentName, path, method });
361
+ });
362
+ });
363
+ };
364
+ /**
365
+ * Adds a new scope to an OAuth flow, or renames / updates the description of an existing one.
366
+ *
367
+ * When `oldScope` differs from `scope`, this mutator also rewrites every selection entry
368
+ * that references the matching security scheme so consumers do not need a follow-up
369
+ * `auth:update:selected-scopes`.
370
+ *
371
+ * When `enable` is true, the resulting `scope` is additionally appended to every selection
372
+ * requirement that already references this security scheme, enabling an "add and select"
373
+ * flow without a separate selection mutation.
374
+ */
375
+ export const upsertScope = (store, document, { name, flowType, scope, description, oldScope, enable }) => {
376
+ if (!isOpenApiDocument(document)) {
257
377
  return;
258
378
  }
259
- // Find the security requirement that matches the given id (scheme key names)
260
- // For example: if id = ["OAuth"], matches { OAuth: [...] }
261
- const scheme = target.selectedSchemes.find((scheme) => JSON.stringify(Object.keys(scheme)) === JSON.stringify(id));
262
- // If the scheme is optional, do nothing as it cannot have scopes
263
- if (!isNonOptionalSecurityRequirement(scheme)) {
379
+ const flow = resolveOAuthFlow(document, name, flowType);
380
+ if (!flow) {
264
381
  return;
265
382
  }
266
- // If we have a new scope payload, add it to the scheme
267
- if (newScopePayload) {
268
- const securityScheme = getResolvedRef(document.components?.securitySchemes?.[name]);
269
- const flow = securityScheme?.flows?.[newScopePayload?.flowType];
270
- if (!flow) {
383
+ flow.scopes ||= {};
384
+ const isRename = Boolean(oldScope) && oldScope !== scope;
385
+ // Rename: drop the previous key so iteration order stays predictable.
386
+ if (isRename) {
387
+ if (!(oldScope in flow.scopes)) {
271
388
  return;
272
389
  }
273
- flow.scopes ||= {};
274
- flow.scopes[newScopePayload.name] = newScopePayload.description;
275
- scheme[name] = [...scopes, newScopePayload.name];
390
+ delete flow.scopes[oldScope];
391
+ }
392
+ flow.scopes[scope] = description;
393
+ if (!isRename && !enable) {
394
+ return;
395
+ }
396
+ // Mirror the rename and/or apply `enable` across selection entries that reference this scheme.
397
+ walkSelectedSchemes(store, document, (selectedSchemes) => {
398
+ selectedSchemes.forEach((requirement) => {
399
+ if (!isNonOptionalSecurityRequirement(requirement)) {
400
+ return;
401
+ }
402
+ const scopes = requirement[name];
403
+ if (!Array.isArray(scopes)) {
404
+ return;
405
+ }
406
+ let nextScopes = scopes;
407
+ // Rewrite the old key in place when this requirement had the renamed scope selected.
408
+ if (isRename && nextScopes.includes(oldScope)) {
409
+ nextScopes = nextScopes.map((current) => (current === oldScope ? scope : current));
410
+ }
411
+ // Append the resulting scope when the caller asked for "add and select".
412
+ if (enable && !nextScopes.includes(scope)) {
413
+ nextScopes = [...nextScopes, scope];
414
+ }
415
+ if (nextScopes !== scopes) {
416
+ requirement[name] = nextScopes;
417
+ }
418
+ });
419
+ });
420
+ };
421
+ /**
422
+ * Removes a scope from an OAuth flow and strips it from any selection state that references
423
+ * the matching security scheme.
424
+ */
425
+ export const deleteScope = (store, document, { name, flowType, scope }) => {
426
+ if (!isOpenApiDocument(document)) {
276
427
  return;
277
428
  }
278
- // Set the scopes array for the named security scheme within the found security requirement
279
- scheme[name] = scopes;
429
+ const flow = resolveOAuthFlow(document, name, flowType);
430
+ if (!flow?.scopes) {
431
+ return;
432
+ }
433
+ delete flow.scopes[scope];
434
+ walkSelectedSchemes(store, document, (selectedSchemes) => {
435
+ selectedSchemes.forEach((requirement) => {
436
+ if (!isNonOptionalSecurityRequirement(requirement)) {
437
+ return;
438
+ }
439
+ const scopes = requirement[name];
440
+ if (!Array.isArray(scopes) || !scopes.includes(scope)) {
441
+ return;
442
+ }
443
+ requirement[name] = scopes.filter((current) => current !== scope);
444
+ });
445
+ });
280
446
  };
281
447
  /**
282
448
  * Deletes one or more security schemes from an OpenAPI WorkspaceDocument,
@@ -298,11 +464,14 @@ export const updateSelectedScopes = (store, document, { id, name, scopes, newSco
298
464
  * - Any extended x-scalar-selected-security references to those schemes are also removed.
299
465
  */
300
466
  export const deleteSecurityScheme = (store, document, { names }) => {
301
- const documentName = document?.['x-scalar-navigation']?.name;
302
- if (!documentName) {
467
+ if (!isOpenApiDocument(document)) {
303
468
  // Early exit if there is no document to modify
304
469
  return;
305
470
  }
471
+ const documentName = document['x-scalar-navigation']?.name;
472
+ if (!documentName) {
473
+ return;
474
+ }
306
475
  // Get the mutable reference to securitySchemes in components (may be a proxy/resolved reference)
307
476
  const target = getResolvedRef(document.components?.securitySchemes);
308
477
  if (!target) {
@@ -325,8 +494,11 @@ export const deleteSecurityScheme = (store, document, { names }) => {
325
494
  const documentSelectedSecurity = store?.auth.getAuthSelectedSchemas({ type: 'document', documentName });
326
495
  // -- Remove from document-level `x-scalar-selected-security` extension, if present
327
496
  if (documentSelectedSecurity) {
328
- documentSelectedSecurity.selectedSchemes = filterSecuritySchemes(documentSelectedSecurity.selectedSchemes);
329
- documentSelectedSecurity.selectedIndex = clampIndex(documentSelectedSecurity.selectedIndex, documentSelectedSecurity.selectedSchemes.length);
497
+ const filtered = filterSecuritySchemes(documentSelectedSecurity.selectedSchemes);
498
+ store?.auth.setAuthSelectedSchemas({ type: 'document', documentName }, {
499
+ selectedIndex: clampIndex(documentSelectedSecurity.selectedIndex, filtered.length),
500
+ selectedSchemes: filtered,
501
+ });
330
502
  }
331
503
  // -- Remove from document-level `security` property, if present
332
504
  if (document['security']) {
@@ -345,7 +517,6 @@ export const deleteSecurityScheme = (store, document, { names }) => {
345
517
  if ('security' in resolvedOperation && resolvedOperation['security']) {
346
518
  resolvedOperation['security'] = filterSecuritySchemes(resolvedOperation['security']);
347
519
  }
348
- // // Remove from operation-level x-scalar-selected-security array
349
520
  const operationSelectedSecurity = store?.auth.getAuthSelectedSchemas({
350
521
  type: 'operation',
351
522
  documentName,
@@ -353,8 +524,11 @@ export const deleteSecurityScheme = (store, document, { names }) => {
353
524
  method,
354
525
  });
355
526
  if (operationSelectedSecurity) {
356
- operationSelectedSecurity.selectedSchemes = filterSecuritySchemes(operationSelectedSecurity.selectedSchemes);
357
- operationSelectedSecurity.selectedIndex = clampIndex(operationSelectedSecurity.selectedIndex, operationSelectedSecurity.selectedSchemes.length);
527
+ const filtered = filterSecuritySchemes(operationSelectedSecurity.selectedSchemes);
528
+ store?.auth.setAuthSelectedSchemas({ type: 'operation', documentName, path, method }, {
529
+ selectedIndex: clampIndex(operationSelectedSecurity.selectedIndex, filtered.length),
530
+ selectedSchemes: filtered,
531
+ });
358
532
  }
359
533
  });
360
534
  });
@@ -368,6 +542,8 @@ export const authMutatorsFactory = ({ document, store, }) => {
368
542
  clearSecuritySchemeSecrets: (payload) => clearSecuritySchemeSecrets(store, document, payload),
369
543
  updateSelectedAuthTab: (payload) => updateSelectedAuthTab(store, document, payload),
370
544
  updateSelectedScopes: (payload) => updateSelectedScopes(store, document, payload),
545
+ upsertScope: (payload) => upsertScope(store, document, payload),
546
+ deleteScope: (payload) => deleteScope(store, document, payload),
371
547
  deleteSecurityScheme: (payload) => deleteSecurityScheme(store, document, payload),
372
548
  };
373
549
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/mutators/cookie.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,+CAA+C,CAAA;AAGvG,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;AAElF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GACvB,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,oBAAoB,KAAK,CAAC,sBAAsB,CAAC,KAChD,aAAa,GAAG,SA8BlB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,WAAW,KAAK,CAAC,sBAAsB,CAAC,KACvC,OAWF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,gBAAgB;IAAE,UAAU,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAA;CAAE;4BAE9E,KAAK,CAAC,sBAAsB,CAAC;4BAC7B,KAAK,CAAC,sBAAsB,CAAC;CAExD,CAAA"}
1
+ {"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/mutators/cookie.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,+CAA+C,CAAA;AAIvG,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;AAElF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GACvB,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,oBAAoB,KAAK,CAAC,sBAAsB,CAAC,KAChD,aAAa,GAAG,SA8BlB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,WAAW,KAAK,CAAC,sBAAsB,CAAC,KACvC,OAWF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,gBAAgB;IAAE,UAAU,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAA;CAAE;4BAE9E,KAAK,CAAC,sBAAsB,CAAC;4BAC7B,KAAK,CAAC,sBAAsB,CAAC;CAExD,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { xScalarCookieSchema } from '../schemas/extensions/general/x-scalar-cookies.js';
2
+ import { isAsyncApiDocument } from '../schemas/type-guards.js';
2
3
  import { coerceValue } from '../schemas/typebox-coerce.js';
3
4
  /**
4
5
  * Adds OR updates a cookie to the document or workspace.
@@ -11,7 +12,7 @@ import { coerceValue } from '../schemas/typebox-coerce.js';
11
12
  * @returns the parsed cookie that was added or updated or undefined if the collection is not found
12
13
  */
13
14
  export const upsertCookie = (collection, { payload, index }) => {
14
- if (!collection) {
15
+ if (!collection || isAsyncApiDocument(collection)) {
15
16
  return;
16
17
  }
17
18
  if (!collection['x-scalar-cookies']) {
@@ -46,7 +47,7 @@ export const upsertCookie = (collection, { payload, index }) => {
46
47
  * @returns true if the cookie was deleted, false otherwise
47
48
  */
48
49
  export const deleteCookie = (collection, { index }) => {
49
- if (!collection || !collection['x-scalar-cookies']) {
50
+ if (!collection || isAsyncApiDocument(collection) || !collection['x-scalar-cookies']) {
50
51
  return false;
51
52
  }
52
53
  if (index < 0 || index >= collection['x-scalar-cookies'].length) {
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/mutators/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,cAAc,CAAC,2BAA2B,CAAC,SAMrD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,WAAW,OAAO,SAOrF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,cAAc,CAAC,sBAAsB,CAAC,SAchD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,MAAM,MAAM,SASlF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,GAAG,IAAI,EAC5B,SAAS,cAAc,CAAC,gCAAgC,CAAC,kBA8B1D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,cAAc,GAAG,IAAI,EAAE,SAAS,cAAc,CAAC,0BAA0B,CAAC,SAM/G,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,sBAGrC;IACD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAClC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CAC7B;uCAEsC,cAAc,CAAC,2BAA2B,CAAC;kCAEhD,cAAc,CAAC,sBAAsB,CAAC;+BACzC,cAAc,CAAC,4BAA4B,CAAC;kCACzC,cAAc,CAAC,sBAAsB,CAAC;mCACrC,cAAc,CAAC,gCAAgC,CAAC;8BAErD,cAAc,CAAC,0BAA0B,CAAC;CAEvE,CAAA"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/mutators/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAGlD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,cAAc,CAAC,2BAA2B,CAAC,SAMrD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,WAAW,OAAO,SAOrF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,cAAc,CAAC,sBAAsB,CAAC,SAchD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,MAAM,MAAM,SASlF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,GAAG,IAAI,EAC5B,SAAS,cAAc,CAAC,gCAAgC,CAAC,kBA8B1D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,cAAc,GAAG,IAAI,EAAE,SAAS,cAAc,CAAC,0BAA0B,CAAC,SAM/G,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,sBAGrC;IACD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAClC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CAC7B;uCAEsC,cAAc,CAAC,2BAA2B,CAAC;kCAEhD,cAAc,CAAC,sBAAsB,CAAC;+BACzC,cAAc,CAAC,4BAA4B,CAAC;kCACzC,cAAc,CAAC,sBAAsB,CAAC;mCACrC,cAAc,CAAC,gCAAgC,CAAC;8BAErD,cAAc,CAAC,0BAA0B,CAAC;CAEvE,CAAA"}
@@ -1,10 +1,11 @@
1
1
  import { mergeObjects } from '../helpers/merge-object.js';
2
+ import { isOpenApiDocument } from '../schemas/type-guards.js';
2
3
  /**
3
4
  * Updates extension fields on the document (e.g. x-pre-request, x-post-response).
4
5
  * Merges the payload into the document root.
5
6
  */
6
7
  export const updateDocumentExtension = (document, payload) => {
7
- if (!document) {
8
+ if (!isOpenApiDocument(document)) {
8
9
  return;
9
10
  }
10
11
  mergeObjects(document, payload);
@@ -18,7 +19,7 @@ export const updateDocumentExtension = (document, payload) => {
18
19
  * If document is null, does nothing.
19
20
  */
20
21
  export const updateWatchMode = (document, watchMode) => {
21
- if (!document) {
22
+ if (!isOpenApiDocument(document)) {
22
23
  return;
23
24
  }
24
25
  // Set (or unset) the x-scalar-watch-mode property on the document
@@ -35,7 +36,7 @@ export const updateWatchMode = (document, watchMode) => {
35
36
  * If document is null, does nothing.
36
37
  */
37
38
  export const updateDocumentInfo = (document, payload) => {
38
- if (!document) {
39
+ if (!isOpenApiDocument(document)) {
39
40
  return;
40
41
  }
41
42
  // Merge the given payload into the document's info object
@@ -53,7 +54,7 @@ export const updateDocumentInfo = (document, payload) => {
53
54
  * Does not perform a sidebar rebuild for performance benefit
54
55
  */
55
56
  export const updateDocumentIcon = (document, icon) => {
56
- if (!document || !document['x-scalar-navigation']) {
57
+ if (!isOpenApiDocument(document) || !document['x-scalar-navigation']) {
57
58
  return;
58
59
  }
59
60
  // Update the document icon
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/mutators/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAGxB,MAAM,qDAAqD,CAAA;AAG5D,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;AAE5F;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,kDAAkD,KAAK,CAAC,gCAAgC,CAAC,KACxF,kBAAkB,GAAG,SAoCvB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,qBAAqB,KAAK,CAAC,gCAAgC,CAAC,SAQ7D,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,sCAAsC,KAAK,CAAC,yCAAyC,CAAC,KACrF,aAAa,GAAG,SA0BlB,CAAA;AAED,eAAO,MAAM,yBAAyB,GACpC,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,4BAA4B,KAAK,CAAC,yCAAyC,CAAC,SAO7E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,4BAGxC;IACD,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAA;CACjD;iCAEgC,KAAK,CAAC,gCAAgC,CAAC;iCAEvC,KAAK,CAAC,gCAAgC,CAAC;yCAE/B,KAAK,CAAC,yCAAyC,CAAC;yCAEhD,KAAK,CAAC,yCAAyC,CAAC;CAGxF,CAAA"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/mutators/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAGxB,MAAM,qDAAqD,CAAA;AAI5D,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;AAE5F;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,kDAAkD,KAAK,CAAC,gCAAgC,CAAC,KACxF,kBAAkB,GAAG,SAoCvB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,qBAAqB,KAAK,CAAC,gCAAgC,CAAC,SAQ7D,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,sCAAsC,KAAK,CAAC,yCAAyC,CAAC,KACrF,aAAa,GAAG,SA6BlB,CAAA;AAED,eAAO,MAAM,yBAAyB,GACpC,YAAY,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAChD,4BAA4B,KAAK,CAAC,yCAAyC,CAAC,SAU7E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,4BAGxC;IACD,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAA;CACjD;iCAEgC,KAAK,CAAC,gCAAgC,CAAC;iCAEvC,KAAK,CAAC,gCAAgC,CAAC;yCAE/B,KAAK,CAAC,yCAAyC,CAAC;yCAEhD,KAAK,CAAC,yCAAyC,CAAC;CAGxF,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { unpackProxyObject } from '../helpers/unpack-proxy.js';
2
2
  import { xScalarEnvVarSchema, xScalarEnvironmentSchema, } from '../schemas/extensions/document/x-scalar-environments.js';
3
+ import { isAsyncApiDocument } from '../schemas/type-guards.js';
3
4
  import { coerceValue } from '../schemas/typebox-coerce.js';
4
5
  /**
5
6
  * Adds OR updates an environment to the document or workspace.
@@ -13,7 +14,7 @@ import { coerceValue } from '../schemas/typebox-coerce.js';
13
14
  */
14
15
  export const upsertEnvironment = (workspace, collection, { environmentName, payload, oldEnvironmentName }) => {
15
16
  /** Discriminating between document and workspace */
16
- if (!collection || !workspace) {
17
+ if (!collection || !workspace || isAsyncApiDocument(collection)) {
17
18
  return;
18
19
  }
19
20
  if (!collection['x-scalar-environments']) {
@@ -49,7 +50,7 @@ export const upsertEnvironment = (workspace, collection, { environmentName, payl
49
50
  * @param environmentName - The name of the environment to delete.
50
51
  */
51
52
  export const deleteEnvironment = (workspace, collection, { environmentName }) => {
52
- if (!collection || !workspace) {
53
+ if (!collection || !workspace || isAsyncApiDocument(collection)) {
53
54
  return;
54
55
  }
55
56
  // Trigegr the change event for the active environment
@@ -65,8 +66,11 @@ export const deleteEnvironment = (workspace, collection, { environmentName }) =>
65
66
  * @returns the parsed variable that was added or updated or undefined if the collection is not found
66
67
  */
67
68
  export const upsertEnvironmentVariable = (collection, { environmentName, variable, index }) => {
69
+ if (!collection || isAsyncApiDocument(collection)) {
70
+ return;
71
+ }
68
72
  // The environment should exist by now if we are upserting a variable
69
- if (!collection?.['x-scalar-environments']?.[environmentName]) {
73
+ if (!collection['x-scalar-environments']?.[environmentName]) {
70
74
  console.error('Environment not found', environmentName);
71
75
  return;
72
76
  }
@@ -88,11 +92,14 @@ export const upsertEnvironmentVariable = (collection, { environmentName, variabl
88
92
  return parsed;
89
93
  };
90
94
  export const deleteEnvironmentVariable = (collection, { environmentName, index }) => {
91
- if (!collection?.['x-scalar-environments']?.[environmentName]) {
95
+ if (!collection || isAsyncApiDocument(collection)) {
96
+ return;
97
+ }
98
+ if (!collection['x-scalar-environments']?.[environmentName]) {
92
99
  console.error('Environment not found', environmentName);
93
100
  return;
94
101
  }
95
- collection['x-scalar-environments']?.[environmentName]?.variables?.splice(index, 1);
102
+ collection['x-scalar-environments'][environmentName]?.variables?.splice(index, 1);
96
103
  };
97
104
  export const environmentMutatorsFactory = ({ workspace, collection, }) => {
98
105
  return {
@@ -70,6 +70,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
70
70
  clearSecuritySchemeSecrets: (payload: import("../events/definitions/auth.js").AuthEvents["auth:clear:security-scheme-secrets"]) => void;
71
71
  updateSelectedAuthTab: (payload: import("../events/definitions/auth.js").AuthEvents["auth:update:active-index"]) => void;
72
72
  updateSelectedScopes: (payload: import("../events/definitions/auth.js").AuthEvents["auth:update:selected-scopes"]) => void;
73
+ upsertScope: (payload: import("../events/definitions/auth.js").AuthEvents["auth:upsert:scopes"]) => void;
74
+ deleteScope: (payload: import("../events/definitions/auth.js").AuthEvents["auth:delete:scopes"]) => void;
73
75
  deleteSecurityScheme: (payload: import("../events/definitions/auth.js").AuthEvents["auth:delete:security-scheme"]) => void;
74
76
  };
75
77
  cookie: {
@@ -157,6 +159,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
157
159
  clearSecuritySchemeSecrets: (payload: import("../events/definitions/auth.js").AuthEvents["auth:clear:security-scheme-secrets"]) => void;
158
160
  updateSelectedAuthTab: (payload: import("../events/definitions/auth.js").AuthEvents["auth:update:active-index"]) => void;
159
161
  updateSelectedScopes: (payload: import("../events/definitions/auth.js").AuthEvents["auth:update:selected-scopes"]) => void;
162
+ upsertScope: (payload: import("../events/definitions/auth.js").AuthEvents["auth:upsert:scopes"]) => void;
163
+ deleteScope: (payload: import("../events/definitions/auth.js").AuthEvents["auth:delete:scopes"]) => void;
160
164
  deleteSecurityScheme: (payload: import("../events/definitions/auth.js").AuthEvents["auth:delete:security-scheme"]) => void;
161
165
  };
162
166
  cookie: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mutators/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAa9C;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAqC/D;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEH;;;;OAIG;gBACS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAErB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mutators/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAa9C;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAqC/D;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEH;;;;OAIG;gBACS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAErB"}
@@ -1 +1 @@
1
- {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAGrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAgClD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GAChD,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,0CAA0C,CAAC,SAwB/E,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,GAC5C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,oCAAoC,CAAC,SAStF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,GAC9C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,wCAAwC,CAAC,SAS1F,CAAA"}
1
+ {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAGrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAoClD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GAChD,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,0CAA0C,CAAC,SAwB/E,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,GAC5C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,oCAAoC,CAAC,SAStF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,GAC9C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,wCAAwC,CAAC,SAS1F,CAAA"}
@@ -1,8 +1,12 @@
1
1
  import { getResolvedRef } from '../../helpers/get-resolved-ref.js';
2
2
  import { unpackProxyObject } from '../../helpers/unpack-proxy.js';
3
+ import { isOpenApiDocument } from '../../schemas/type-guards.js';
3
4
  /** Ensure the json that we need exists up to the example object in the request body */
4
5
  const findOrCreateRequestBodyExample = (document, contentType, meta) => {
5
- const operation = getResolvedRef(document?.paths?.[meta.path]?.[meta.method]);
6
+ if (!isOpenApiDocument(document)) {
7
+ return null;
8
+ }
9
+ const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method]);
6
10
  if (!operation) {
7
11
  return null;
8
12
  }
@@ -36,7 +40,7 @@ const findOrCreateRequestBodyExample = (document, contentType, meta) => {
36
40
  * ```
37
41
  */
38
42
  export const updateOperationRequestBodyContentType = (document, { meta, payload }) => {
39
- if (!document) {
43
+ if (!isOpenApiDocument(document)) {
40
44
  return;
41
45
  }
42
46
  const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method]);
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,4BAA4B,CAAC,SAQjE,CAAA"}
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAGlD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,4BAA4B,CAAC,SAWjE,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { getResolvedRef } from '../../helpers/get-resolved-ref.js';
2
2
  import { mergeObjects } from '../../helpers/merge-object.js';
3
+ import { isOpenApiDocument } from '../../schemas/type-guards.js';
3
4
  /**
4
5
  * Updates an extension of the operation
5
6
  *
@@ -13,7 +14,10 @@ import { mergeObjects } from '../../helpers/merge-object.js';
13
14
  * ```
14
15
  */
15
16
  export const updateOperationExtension = (document, { meta, payload }) => {
16
- const operation = getResolvedRef(document?.paths?.[meta.path]?.[meta.method]);
17
+ if (!isOpenApiDocument(document)) {
18
+ return;
19
+ }
20
+ const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method]);
17
21
  if (!operation) {
18
22
  return;
19
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAErE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAOlD,eAAO,MAAM,oBAAoB,GAC/B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,WAAW,CAAC,2BAA2B,CAAC,kBAyC5D,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,2BAA2B,eAAe,CAAC,0BAA0B,CAAC,SA4BvE,CAAA"}
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAErE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAQlD,eAAO,MAAM,oBAAoB,GAC/B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,WAAW,CAAC,2BAA2B,CAAC,kBA4C5D,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,2BAA2B,eAAe,CAAC,0BAA0B,CAAC,SA4BvE,CAAA"}
@@ -1,11 +1,15 @@
1
1
  import { getResolvedRef } from '../../helpers/get-resolved-ref.js';
2
+ import { isOpenApiDocument } from '../../schemas/type-guards.js';
2
3
  import { isContentTypeParameterObject } from '../../schemas/v3.1/strict/type-guards.js';
3
4
  import { fetchRequestToHar } from './helpers/fetch-request-to-har.js';
4
5
  import { fetchResponseToHar } from './helpers/fetch-response-to-har.js';
5
6
  import { harToOperation } from './helpers/har-to-operation.js';
6
7
  export const addResponseToHistory = async (store, document, { payload, meta }) => {
7
- const documentName = document?.['x-scalar-navigation']?.name;
8
- if (!document || !documentName || !payload) {
8
+ if (!isOpenApiDocument(document)) {
9
+ return;
10
+ }
11
+ const documentName = document['x-scalar-navigation']?.name;
12
+ if (!documentName || !payload) {
9
13
  return;
10
14
  }
11
15
  const operation = getResolvedRef(document.paths?.[meta.path]?.[meta.method]);
@@ -40,7 +44,7 @@ export const addResponseToHistory = async (store, document, { payload, meta }) =
40
44
  });
41
45
  };
42
46
  export const reloadOperationHistory = (store, document, { meta, index, callback }) => {
43
- if (!document) {
47
+ if (!isOpenApiDocument(document)) {
44
48
  console.error('Document not found', meta.path, meta.method);
45
49
  return;
46
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"operation.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/operation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAOrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAC1B,gBAAgB,cAAc,GAAG,IAAI,EACrC,SAAS,eAAe,CAAC,4BAA4B,CAAC,KACrD,MAAM,GAAG,SA0DX,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,uBAAuB,CAAC,SAsB5D,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yBAAyB,GACpC,UAAU,iBAAiB,GAAG,IAAI,EAClC,OAAO,cAAc,GAAG,IAAI,EAC5B,mEAAmE,eAAe,CAAC,6BAA6B,CAAC,KAChH,IAgGF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,cAAc,GAAG,IAAI,EAChC,wBAAwB,eAAe,CAAC,4BAA4B,CAAC,SAgBtE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GACtC,WAAW,cAAc,GAAG,IAAI,EAChC,uDAAuD,eAAe,CAAC,gCAAgC,CAAC,SAuBzG,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GACjC,WAAW,cAAc,GAAG,IAAI,EAChC,sDAAsD,eAAe,CAAC,0BAA0B,CAAC,SAiDlG,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GACjC,WAAW,cAAc,GAAG,IAAI,EAChC,+DAA+D,eAAe,CAAC,0BAA0B,CAAC,SAuE3G,CAAA"}
1
+ {"version":3,"file":"operation.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/operation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAOrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAGlD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAC1B,gBAAgB,cAAc,GAAG,IAAI,EACrC,SAAS,eAAe,CAAC,4BAA4B,CAAC,KACrD,MAAM,GAAG,SA0DX,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,uBAAuB,CAAC,SAsB5D,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yBAAyB,GACpC,UAAU,iBAAiB,GAAG,IAAI,EAClC,OAAO,cAAc,GAAG,IAAI,EAC5B,mEAAmE,eAAe,CAAC,6BAA6B,CAAC,KAChH,IAqGF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,cAAc,GAAG,IAAI,EAChC,wBAAwB,eAAe,CAAC,4BAA4B,CAAC,SAgBtE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GACtC,WAAW,cAAc,GAAG,IAAI,EAChC,uDAAuD,eAAe,CAAC,gCAAgC,CAAC,SAuBzG,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GACjC,WAAW,cAAc,GAAG,IAAI,EAChC,sDAAsD,eAAe,CAAC,0BAA0B,CAAC,SAiDlG,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GACjC,WAAW,cAAc,GAAG,IAAI,EAChC,+DAA+D,eAAe,CAAC,0BAA0B,CAAC,SAuE3G,CAAA"}