@scalar/workspace-store 0.23.0 → 0.24.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 (72) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +3 -2
  4. package/dist/client.js.map +2 -2
  5. package/dist/events/definitions/hooks.d.ts +25 -0
  6. package/dist/events/definitions/hooks.d.ts.map +1 -0
  7. package/dist/events/definitions/hooks.js +1 -0
  8. package/dist/events/definitions/hooks.js.map +7 -0
  9. package/dist/events/definitions/index.d.ts +2 -1
  10. package/dist/events/definitions/index.d.ts.map +1 -1
  11. package/dist/events/definitions/operation.d.ts +5 -5
  12. package/dist/events/definitions/operation.d.ts.map +1 -1
  13. package/dist/events/definitions/ui.d.ts +4 -7
  14. package/dist/events/definitions/ui.d.ts.map +1 -1
  15. package/dist/events/definitions/workspace.d.ts +5 -0
  16. package/dist/events/definitions/workspace.d.ts.map +1 -1
  17. package/dist/helpers/is-non-optional-security-requirement.d.ts +4 -0
  18. package/dist/helpers/is-non-optional-security-requirement.d.ts.map +1 -0
  19. package/dist/helpers/is-non-optional-security-requirement.js +7 -0
  20. package/dist/helpers/is-non-optional-security-requirement.js.map +7 -0
  21. package/dist/helpers/merge-object.d.ts +6 -1
  22. package/dist/helpers/merge-object.d.ts.map +1 -1
  23. package/dist/helpers/merge-object.js +4 -3
  24. package/dist/helpers/merge-object.js.map +2 -2
  25. package/dist/mutators/auth.d.ts.map +1 -1
  26. package/dist/mutators/auth.js +2 -1
  27. package/dist/mutators/auth.js.map +2 -2
  28. package/dist/mutators/index.d.ts +1 -2
  29. package/dist/mutators/index.d.ts.map +1 -1
  30. package/dist/mutators/index.js +2 -1
  31. package/dist/mutators/index.js.map +2 -2
  32. package/dist/mutators/operation.d.ts +15 -0
  33. package/dist/mutators/operation.d.ts.map +1 -1
  34. package/dist/mutators/operation.js +63 -0
  35. package/dist/mutators/operation.js.map +2 -2
  36. package/dist/mutators/tabs.js +5 -5
  37. package/dist/mutators/tabs.js.map +2 -2
  38. package/dist/mutators/workspace.d.ts +8 -0
  39. package/dist/mutators/workspace.d.ts.map +1 -1
  40. package/dist/mutators/workspace.js +7 -0
  41. package/dist/mutators/workspace.js.map +2 -2
  42. package/dist/plugins/client/index.d.ts +0 -1
  43. package/dist/plugins/client/index.d.ts.map +1 -1
  44. package/dist/plugins/client/index.js.map +2 -2
  45. package/dist/schemas/extensions/schema/x-examples.d.ts +10 -0
  46. package/dist/schemas/extensions/schema/x-examples.d.ts.map +1 -0
  47. package/dist/schemas/extensions/schema/x-examples.js +8 -0
  48. package/dist/schemas/extensions/schema/x-examples.js.map +7 -0
  49. package/dist/schemas/inmemory-workspace.d.ts +28 -4
  50. package/dist/schemas/inmemory-workspace.d.ts.map +1 -1
  51. package/dist/schemas/reference-config/index.d.ts +16 -4
  52. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  53. package/dist/schemas/reference-config/index.js.map +2 -2
  54. package/dist/schemas/reference-config/settings.d.ts +13 -1
  55. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  56. package/dist/schemas/v3.1/strict/openapi-document.d.ts +442 -34
  57. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  58. package/dist/schemas/v3.1/strict/schema.d.ts +16 -1
  59. package/dist/schemas/v3.1/strict/schema.d.ts.map +1 -1
  60. package/dist/schemas/v3.1/strict/schema.js +2 -0
  61. package/dist/schemas/v3.1/strict/schema.js.map +2 -2
  62. package/dist/schemas/v3.1/strict/security-requirement.d.ts +4 -4
  63. package/dist/schemas/v3.1/strict/security-requirement.d.ts.map +1 -1
  64. package/dist/schemas/v3.1/strict/security-requirement.js +6 -4
  65. package/dist/schemas/v3.1/strict/security-requirement.js.map +2 -2
  66. package/dist/schemas/workspace-specification/config.d.ts +14 -2
  67. package/dist/schemas/workspace-specification/config.d.ts.map +1 -1
  68. package/dist/schemas/workspace-specification/index.d.ts +15 -3
  69. package/dist/schemas/workspace-specification/index.d.ts.map +1 -1
  70. package/dist/schemas/workspace.d.ts +93 -9
  71. package/dist/schemas/workspace.d.ts.map +1 -1
  72. package/package.json +8 -8
@@ -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'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\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, getOperationEntries } from '@/navigation'\nimport { getNavigationOptions } from '@/navigation/get-navigation-options'\nimport { canHaveOrder } from '@/navigation/helpers/get-openapi-object'\nimport type { WorkspaceDocument } from '@/schemas'\nimport type { IdGenerator, TraversedOperation, TraversedWebhook, WithParent } from '@/schemas/navigation'\nimport type { OperationObject, 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 order ID of an operation in the sidebar.\n * Used when changing path or method so we do not lose the sidebar ordering\n */\nconst updateOperationOrderId = ({\n store,\n operation,\n generateId,\n method,\n path,\n entries,\n}: {\n store: WorkspaceStore\n operation: OperationObject\n generateId: IdGenerator\n method: HttpMethod\n path: string\n entries: (WithParent<TraversedOperation> | WithParent<TraversedWebhook>)[]\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,\n method,\n operation,\n parentId: entry.parent.id,\n parentTag,\n })\n })\n}\n\n/**\n * Updates the HTTP method and/or path of an operation and moves it to the new location.\n * This function:\n * 1. Moves the operation from the old method/path to the new method/path under paths\n * 2. Updates x-scalar-order to maintain the operation's position in the sidebar\n * 3. Syncs path parameters when the path changes\n *\n * Safely no-ops if nothing has changed, or if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationPathMethod({\n * document,\n * store,\n * meta: { method: 'get', path: '/users' },\n * payload: { method: 'post', path: '/api/users' },\n * })\n * ```\n */\nexport const updateOperationPathMethod = (\n document: WorkspaceDocument | null,\n store: WorkspaceStore | null,\n { meta, payload: { method, path } }: OperationEvents['operation:update:pathMethod'],\n callback: OperationEvents['operation:update:pathMethod']['callback'],\n): void => {\n const methodChanged = meta.method !== method\n const pathChanged = meta.path !== path\n\n // If nothing has changed, no need to do anything\n if (!methodChanged && !pathChanged) {\n callback('no-change')\n return\n }\n\n // Determine the final method and path\n const finalMethod = methodChanged ? method : meta.method\n const finalPath = pathChanged ? path : meta.path\n\n // Check for conflicts at the target location\n if (document?.paths?.[finalPath]?.[finalMethod]) {\n callback('conflict')\n return\n }\n\n const documentNavigation = document?.['x-scalar-navigation']\n if (!documentNavigation || !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 // Sync path parameters if the path has changed\n if (pathChanged) {\n const oldPathParams = findVariables(meta.path, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n const newPathParams = findVariables(finalPath, { 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(finalPath, meta.path, existingParameters)\n }\n }\n\n // Get the document configuration to generate IDs consistently\n const documentConfig = store.getDocumentConfiguration(documentNavigation.name)\n const { generateId } = getNavigationOptions(documentNavigation.name, documentConfig)\n\n /** Grabs all of the current operation entries for the given path and method */\n const operationEntriesMap = getOperationEntries(documentNavigation)\n const entries = operationEntriesMap.get(`${meta.path}|${meta.method}`)\n\n // Updates the order ID so we don't lose the sidebar ordering when it rebuilds\n if (entries) {\n updateOperationOrderId({ store, operation, generateId, method: finalMethod, path: finalPath, entries })\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[finalPath]) {\n document.paths[finalPath] = {}\n }\n\n // Prevent assigning dangerous keys to the path items object\n preventPollution(finalPath)\n preventPollution(meta.path)\n preventPollution(finalMethod)\n\n // Move the operation to the new location\n document.paths[finalPath][finalMethod] = unpackProxyObject(operation)\n\n // Remove the operation from the old location\n const oldPathItems = document.paths[meta.path]\n if (oldPathItems && isHttpMethod(meta.method)) {\n delete oldPathItems[meta.method]\n\n // If the old path has no more operations, remove the path entry\n if (Object.keys(oldPathItems).length === 0) {\n delete document.paths[meta.path]\n }\n }\n\n callback('success')\n}\n\n/**\n * Deletes an operation from the workspace\n *\n * Example:\n * ```ts\n * deleteOperation({\n * document,\n * meta: { method: 'get', path: '/users' },\n * })\n * ```\n */\nexport const deleteOperation = (\n workspace: WorkspaceStore | null,\n { meta, documentName }: OperationEvents['operation:delete:operation'],\n) => {\n const document = workspace?.workspace.documents[documentName]\n if (!document) {\n return\n }\n\n preventPollution(meta.path)\n preventPollution(meta.method)\n\n delete document.paths?.[meta.path]?.[meta.method]\n\n // If the path has no more operations, remove the path entry\n if (Object.keys(document.paths?.[meta.path] ?? {}).length === 0) {\n delete document.paths?.[meta.path]\n }\n}\n\n/**\n * Deletes an example with the given exampleKey from operation parameters and request body.\n *\n * - Finds the target operation within the specified document and path/method.\n * - Removes example values matching exampleKey from both parameter-level and content-level examples.\n * - Safely no-ops if the document, operation, or request body does not exist.\n */\nexport const deleteOperationExample = (\n workspace: WorkspaceStore | null,\n { meta: { path, method, exampleKey }, documentName }: OperationEvents['operation:delete:example'],\n) => {\n // Find the document in workspace based on documentName\n const document = workspace?.workspace.documents[documentName]\n if (!document) {\n return\n }\n\n // Get the operation object for the given path and method\n const operation = getResolvedRef(document.paths?.[path]?.[method])\n if (!operation) {\n return\n }\n\n // Remove the example from all operation parameters\n operation.parameters?.forEach((parameter) => {\n const resolvedParameter = getResolvedRef(parameter)\n\n // Remove from content-level examples (if parameter uses content)\n if ('content' in resolvedParameter && resolvedParameter.content) {\n Object.values(resolvedParameter.content).forEach((mediaType) => {\n delete mediaType.examples?.[exampleKey]\n })\n }\n\n // Remove from parameter-level examples\n if ('examples' in resolvedParameter && resolvedParameter.examples) {\n delete resolvedParameter.examples?.[exampleKey]\n }\n })\n\n // Remove the example from request body content types (if requestBody exists)\n const requestBody = getResolvedRef(operation.requestBody)\n if (!requestBody) {\n return\n }\n\n // For each media type, remove the example matching exampleKey\n Object.values(requestBody.content ?? {}).forEach((mediaType) => {\n delete mediaType.examples?.[exampleKey]\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', isDisabled: false },\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': Boolean(payload.isDisabled),\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', isDisabled: false },\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': Boolean(payload.isDisabled),\n }\n return\n }\n\n // Update existing example value\n example.value = payload.value ?? example?.value ?? ''\n example['x-disabled'] = Boolean(payload.isDisabled ?? example['x-disabled'])\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 // We cannot call splice on a proxy object, so we unwrap the array and filter it\n operation.parameters = unpackProxyObject(\n operation.parameters?.filter((_, i) => i !== actualIndex),\n { depth: 1 },\n )\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 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 if (!requestBody!.content[contentType]!.examples) {\n requestBody!.content[contentType]!.examples = {}\n }\n\n const examples = getResolvedRef(requestBody!.content[contentType]!.examples)\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 isDisabled: false,\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 isDisabled: false,\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 // Only set the properties that are present in the payload\n for (const key of objectKeys(payload)) {\n if (example.value[index]) {\n preventPollution(key, 'updateOperationRequestBodyFormRow')\n example.value[index][key === 'key' ? 'name' : key] = payload[key]\n }\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 // We cannot call splice on a proxy object, so we unwrap the array and filter it\n example.value = unpackProxyObject(\n example.value.filter((_, i) => i !== index),\n { depth: 1 },\n )\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 { objectKeys } from '@scalar/helpers/object/object-keys'\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, getOperationEntries } from '@/navigation'\nimport { getNavigationOptions } from '@/navigation/get-navigation-options'\nimport { canHaveOrder } from '@/navigation/helpers/get-openapi-object'\nimport type { WorkspaceDocument } from '@/schemas'\nimport type { IdGenerator, TraversedOperation, TraversedWebhook, WithParent } from '@/schemas/navigation'\nimport type { OperationObject, 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 // Make sure that we are selecting the new operation server\n const { servers } = operation\n const firstServer = unpackProxyObject(servers?.[0])\n\n // For now we only support document servers but in the future we might support operation servers\n for (const server of servers ?? []) {\n // If the server does not exist in the document, add it\n if (!document.servers?.some((s) => s.url === server.url)) {\n if (!document.servers) {\n document.servers = []\n }\n document.servers.push(unpackProxyObject(server))\n }\n }\n\n // Update the selected server to the first server of the created operation\n if (firstServer) {\n document['x-scalar-selected-server'] = firstServer.url\n }\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 order ID of an operation in the sidebar.\n * Used when changing path or method so we do not lose the sidebar ordering\n */\nconst updateOperationOrderId = ({\n store,\n operation,\n generateId,\n method,\n path,\n entries,\n}: {\n store: WorkspaceStore\n operation: OperationObject\n generateId: IdGenerator\n method: HttpMethod\n path: string\n entries: (WithParent<TraversedOperation> | WithParent<TraversedWebhook>)[]\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,\n method,\n operation,\n parentId: entry.parent.id,\n parentTag,\n })\n })\n}\n\n/**\n * Updates the HTTP method and/or path of an operation and moves it to the new location.\n * This function:\n * 1. Moves the operation from the old method/path to the new method/path under paths\n * 2. Updates x-scalar-order to maintain the operation's position in the sidebar\n * 3. Syncs path parameters when the path changes\n *\n * Safely no-ops if nothing has changed, or if the document or operation does not exist.\n *\n * Example:\n * ```ts\n * updateOperationPathMethod({\n * document,\n * store,\n * meta: { method: 'get', path: '/users' },\n * payload: { method: 'post', path: '/api/users' },\n * })\n * ```\n */\nexport const updateOperationPathMethod = (\n document: WorkspaceDocument | null,\n store: WorkspaceStore | null,\n { meta, payload: { method, path } }: OperationEvents['operation:update:pathMethod'],\n callback: OperationEvents['operation:update:pathMethod']['callback'],\n): void => {\n const methodChanged = meta.method !== method\n const pathChanged = meta.path !== path\n\n // If nothing has changed, no need to do anything\n if (!methodChanged && !pathChanged) {\n callback('no-change')\n return\n }\n\n // Determine the final method and path\n const finalMethod = methodChanged ? method : meta.method\n const finalPath = pathChanged ? path : meta.path\n\n // Check for conflicts at the target location\n if (document?.paths?.[finalPath]?.[finalMethod]) {\n callback('conflict')\n return\n }\n\n const documentNavigation = document?.['x-scalar-navigation']\n if (!documentNavigation || !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 // Sync path parameters if the path has changed\n if (pathChanged) {\n const oldPathParams = findVariables(meta.path, { includePath: true, includeEnv: false }).filter(\n (v): v is string => v !== undefined,\n )\n const newPathParams = findVariables(finalPath, { 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(finalPath, meta.path, existingParameters)\n }\n }\n\n // Get the document configuration to generate IDs consistently\n const documentConfig = store.getDocumentConfiguration(documentNavigation.name)\n const { generateId } = getNavigationOptions(documentNavigation.name, documentConfig)\n\n /** Grabs all of the current operation entries for the given path and method */\n const operationEntriesMap = getOperationEntries(documentNavigation)\n const entries = operationEntriesMap.get(`${meta.path}|${meta.method}`)\n\n // Updates the order ID so we don't lose the sidebar ordering when it rebuilds\n if (entries) {\n updateOperationOrderId({ store, operation, generateId, method: finalMethod, path: finalPath, entries })\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[finalPath]) {\n document.paths[finalPath] = {}\n }\n\n // Prevent assigning dangerous keys to the path items object\n preventPollution(finalPath)\n preventPollution(meta.path)\n preventPollution(finalMethod)\n\n // Move the operation to the new location\n document.paths[finalPath][finalMethod] = unpackProxyObject(operation)\n\n // Remove the operation from the old location\n const oldPathItems = document.paths[meta.path]\n if (oldPathItems && isHttpMethod(meta.method)) {\n delete oldPathItems[meta.method]\n\n // If the old path has no more operations, remove the path entry\n if (Object.keys(oldPathItems).length === 0) {\n delete document.paths[meta.path]\n }\n }\n\n callback('success')\n}\n\n/**\n * Deletes an operation from the workspace\n *\n * Example:\n * ```ts\n * deleteOperation({\n * document,\n * meta: { method: 'get', path: '/users' },\n * })\n * ```\n */\nexport const deleteOperation = (\n workspace: WorkspaceStore | null,\n { meta, documentName }: OperationEvents['operation:delete:operation'],\n) => {\n const document = workspace?.workspace.documents[documentName]\n if (!document) {\n return\n }\n\n preventPollution(meta.path)\n preventPollution(meta.method)\n\n delete document.paths?.[meta.path]?.[meta.method]\n\n // If the path has no more operations, remove the path entry\n if (Object.keys(document.paths?.[meta.path] ?? {}).length === 0) {\n delete document.paths?.[meta.path]\n }\n}\n\n/**\n * Deletes an example with the given exampleKey from operation parameters and request body.\n *\n * - Finds the target operation within the specified document and path/method.\n * - Removes example values matching exampleKey from both parameter-level and content-level examples.\n * - Safely no-ops if the document, operation, or request body does not exist.\n */\nexport const deleteOperationExample = (\n workspace: WorkspaceStore | null,\n { meta: { path, method, exampleKey }, documentName }: OperationEvents['operation:delete:example'],\n) => {\n // Find the document in workspace based on documentName\n const document = workspace?.workspace.documents[documentName]\n if (!document) {\n return\n }\n\n // Get the operation object for the given path and method\n const operation = getResolvedRef(document.paths?.[path]?.[method])\n if (!operation) {\n return\n }\n\n // Remove the example from all operation parameters\n operation.parameters?.forEach((parameter) => {\n const resolvedParameter = getResolvedRef(parameter)\n\n // Remove from content-level examples (if parameter uses content)\n if ('content' in resolvedParameter && resolvedParameter.content) {\n Object.values(resolvedParameter.content).forEach((mediaType) => {\n delete mediaType.examples?.[exampleKey]\n })\n }\n\n // Remove from parameter-level examples\n if ('examples' in resolvedParameter && resolvedParameter.examples) {\n delete resolvedParameter.examples?.[exampleKey]\n }\n })\n\n // Remove the example from request body content types (if requestBody exists)\n const requestBody = getResolvedRef(operation.requestBody)\n if (!requestBody) {\n return\n }\n\n // For each media type, remove the example matching exampleKey\n Object.values(requestBody.content ?? {}).forEach((mediaType) => {\n delete mediaType.examples?.[exampleKey]\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', isDisabled: false },\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': Boolean(payload.isDisabled),\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', isDisabled: false },\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': Boolean(payload.isDisabled),\n }\n return\n }\n\n // Update existing example value\n example.value = payload.value ?? example?.value ?? ''\n example['x-disabled'] = Boolean(payload.isDisabled ?? example['x-disabled'])\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 // We cannot call splice on a proxy object, so we unwrap the array and filter it\n operation.parameters = unpackProxyObject(\n operation.parameters?.filter((_, i) => i !== actualIndex),\n { depth: 1 },\n )\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 a header parameter value for a specific example key.\n * Creates the header parameter if it does not exist, otherwise updates the existing one.\n *\n * Note: This function does not handle parameters with content (ParameterWithContentObject).\n * Those cases are currently unsupported and will no-op.\n */\nexport const setHeader = ({\n operation,\n type,\n name,\n value,\n exampleKey,\n}: {\n operation: OperationObject\n type: ParameterObject['in']\n name: string\n value: string\n exampleKey: string\n}) => {\n // Initialize parameters array if it does not exist\n if (!operation.parameters) {\n operation.parameters = []\n }\n\n // Find existing header parameter (case-insensitive name match)\n const existingParameter = operation.parameters.find((param) => {\n const resolvedParam = getResolvedRef(param)\n return resolvedParam.name.toLowerCase() === name.toLowerCase() && resolvedParam.in === type\n })\n\n if (!existingParameter) {\n // Create a new header parameter with the example value\n operation.parameters.push({\n in: type,\n name,\n examples: {\n [exampleKey]: {\n value,\n },\n },\n })\n return\n }\n\n const resolvedParameter = getResolvedRef(existingParameter)\n\n // We do not handle parameters with content\n if (isContentTypeParameterObject(resolvedParameter)) {\n return\n }\n\n // Initialize examples if they do not exist\n if (!resolvedParameter.examples) {\n resolvedParameter.examples = {}\n }\n\n // Initialize the specific example if it does not exist\n if (!resolvedParameter.examples[exampleKey]) {\n resolvedParameter.examples[exampleKey] = {}\n }\n\n // Update the example value\n getResolvedRef(resolvedParameter.examples[exampleKey]).value = value\n return\n}\n\nconst SKIP_CONTENT_TYPE_HEADERS = ['other', 'none']\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 // Try to also set the content-type header in the operation parameters\n if (!SKIP_CONTENT_TYPE_HEADERS.includes(payload.contentType)) {\n setHeader({\n operation,\n name: 'Content-Type',\n type: 'header',\n exampleKey: meta.exampleKey,\n value: payload.contentType,\n })\n }\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 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 if (!requestBody!.content[contentType]!.examples) {\n requestBody!.content[contentType]!.examples = {}\n }\n\n const examples = getResolvedRef(requestBody!.content[contentType]!.examples)\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 isDisabled: false,\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 isDisabled: false,\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 // Only set the properties that are present in the payload\n for (const key of objectKeys(payload)) {\n if (example.value[index]) {\n preventPollution(key, 'updateOperationRequestBodyFormRow')\n example.value[index][key === 'key' ? 'name' : key] = payload[key]\n }\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 // We cannot call splice on a proxy object, so we unwrap the array and filter it\n example.value = unpackProxyObject(\n example.value.filter((_, i) => i !== index),\n { depth: 1 },\n )\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
  }
@@ -45,14 +45,14 @@ const closeTab = (workspace, payload) => {
45
45
  if (!hasValidTabs(workspace)) {
46
46
  return false;
47
47
  }
48
- const tabs = getUnpackedTabs(workspace);
49
48
  const index = getInputIndex();
50
- if (tabs.length <= 1) {
49
+ const filteredTabs = getUnpackedTabs(workspace).filter((_, i) => i !== index);
50
+ if (filteredTabs.length <= 0) {
51
51
  return false;
52
52
  }
53
- workspace["x-scalar-tabs"] = tabs.filter((_, i) => i !== index);
54
- if (index >= tabs.length - 1) {
55
- workspace["x-scalar-active-tab"] = tabs.length - 2;
53
+ workspace["x-scalar-tabs"] = filteredTabs;
54
+ if (index >= filteredTabs.length) {
55
+ workspace["x-scalar-active-tab"] = filteredTabs.length - 1;
56
56
  }
57
57
  return true;
58
58
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/tabs.ts"],
4
- "sourcesContent": ["import type { TabEvents } from '@/events/definitions/tabs'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport type { Workspace } from '@/schemas'\n\n/**\n * Depth level for unpacking tab proxy objects.\n * We only need shallow unpacking since tabs are a flat array.\n */\nconst TAB_UNPACK_DEPTH = 1\n\n/**\n * Helper to validate that workspace has tabs configured.\n * Returns false if workspace or tabs are not available.\n */\nconst hasValidTabs = (\n workspace: Workspace | null,\n): workspace is Workspace & { 'x-scalar-tabs': NonNullable<Workspace['x-scalar-tabs']> } => {\n return workspace !== null && workspace['x-scalar-tabs'] !== undefined\n}\n\n/**\n * Helper to get the unpacked tabs array from workspace.\n * Returns the tabs as a plain array, not a proxy.\n */\nconst getUnpackedTabs = (\n workspace: Workspace & { 'x-scalar-tabs': NonNullable<Workspace['x-scalar-tabs']> },\n): ReturnType<typeof unpackProxyObject<NonNullable<Workspace['x-scalar-tabs']>>> => {\n return unpackProxyObject(workspace['x-scalar-tabs']!, { depth: TAB_UNPACK_DEPTH })\n}\n\n/**\n * Helper to get the current active tab index.\n * Defaults to 0 if not set.\n */\nconst getActiveIndex = (workspace: Workspace): number => {\n return workspace['x-scalar-active-tab'] ?? 0\n}\n\n/**\n * Updates the tabs and active tab index in the workspace.\n * This is used for bulk updates when synchronizing state.\n */\nexport const updateTabs = (workspace: Workspace | null, payload: TabEvents['tabs:update:tabs']): void => {\n if (!workspace) {\n return\n }\n\n if (payload['x-scalar-tabs']) {\n workspace['x-scalar-tabs'] = payload['x-scalar-tabs']\n }\n\n if (payload['x-scalar-active-tab'] !== undefined) {\n workspace['x-scalar-active-tab'] = payload['x-scalar-active-tab']\n }\n}\n\n/**\n * Adds a new tab by duplicating the currently active tab.\n * This preserves the user's context when opening a new tab.\n */\nexport const addTab = (workspace: Workspace | null, _payload: TabEvents['tabs:add:tab']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n const activeIndex = getActiveIndex(workspace)\n const currentTab = tabs[activeIndex]\n\n if (!currentTab) {\n return false\n }\n\n const newTabs = [...tabs, { ...currentTab }]\n\n workspace['x-scalar-tabs'] = newTabs\n workspace['x-scalar-active-tab'] = newTabs.length - 1\n return true\n}\n\n/**\n * Closes the currently active tab.\n * Prevents closing if only one tab remains, to ensure the user always has a tab open.\n * Adjusts the active index if needed to keep it in bounds.\n */\nexport const closeTab = (workspace: Workspace | null, payload: TabEvents['tabs:close:tab']): boolean => {\n const getInputIndex = (): number => {\n if ('event' in payload) {\n return payload.event.code.startsWith('Digit') ? Number.parseInt(payload.event.key, 10) - 1 : Number.NaN\n }\n return payload.index\n }\n\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n const index = getInputIndex()\n\n if (tabs.length <= 1) {\n return false\n }\n\n workspace['x-scalar-tabs'] = tabs.filter((_, i) => i !== index)\n\n /**\n * If we closed a tab at the end, the active index needs to move back.\n * This ensures the active tab stays within bounds after removal.\n */\n if (index >= tabs.length - 1) {\n workspace['x-scalar-active-tab'] = tabs.length - 2\n }\n\n return true\n}\n\n/**\n * Closes all other tabs except the one at the given index\n */\nexport const closeOtherTabs = (workspace: Workspace | null, payload: TabEvents['tabs:close:other-tabs']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n\n if (tabs.length <= 1) {\n return false\n }\n\n workspace['x-scalar-tabs'] = tabs.filter((_, index) => index === payload.index)\n // set the active tab to the first tab since we closed all other tabs\n workspace['x-scalar-active-tab'] = 0\n return true\n}\n\n/**\n * Navigates to the previous tab in the list.\n * Does nothing if already at the first tab.\n */\nexport const navigatePreviousTab = (\n workspace: Workspace | null,\n _payload: TabEvents['tabs:navigate:previous'],\n): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const activeIndex = getActiveIndex(workspace)\n\n if (activeIndex <= 0) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = activeIndex - 1\n return true\n}\n\n/**\n * Navigates to the next tab in the list.\n * Does nothing if already at the last tab.\n */\nexport const navigateNextTab = (workspace: Workspace | null, _payload: TabEvents['tabs:navigate:next']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n const activeIndex = getActiveIndex(workspace)\n\n if (activeIndex >= tabs.length - 1) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = activeIndex + 1\n return true\n}\n\n/**\n * Focuses a specific tab based on keyboard number input (1-9).\n * Extracts the digit from the keyboard event and focuses that tab.\n * Tab numbering starts at 1 for user convenience but uses 0-based indexing internally.\n */\nexport const focusTab = (workspace: Workspace | null, payload: TabEvents['tabs:focus:tab']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const getInputIndex = (): number => {\n if ('event' in payload) {\n return payload.event.code.startsWith('Digit') ? Number.parseInt(payload.event.key, 10) - 1 : Number.NaN\n }\n return payload.index\n }\n\n const tabs = getUnpackedTabs(workspace)\n\n const newActiveIndex = getInputIndex()\n\n if (Number.isNaN(newActiveIndex) || newActiveIndex < 0 || newActiveIndex >= tabs.length) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = newActiveIndex\n return true\n}\n\n/**\n * Focuses the last tab in the list.\n * This provides a quick way to jump to the end, regardless of how many tabs exist.\n */\nexport const focusLastTab = (workspace: Workspace | null, _payload: TabEvents['tabs:focus:tab-last']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n\n if (tabs.length <= 1) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = tabs.length - 1\n return true\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { TabEvents } from '@/events/definitions/tabs'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport type { Workspace } from '@/schemas'\n\n/**\n * Depth level for unpacking tab proxy objects.\n * We only need shallow unpacking since tabs are a flat array.\n */\nconst TAB_UNPACK_DEPTH = 1\n\n/**\n * Helper to validate that workspace has tabs configured.\n * Returns false if workspace or tabs are not available.\n */\nconst hasValidTabs = (\n workspace: Workspace | null,\n): workspace is Workspace & { 'x-scalar-tabs': NonNullable<Workspace['x-scalar-tabs']> } => {\n return workspace !== null && workspace['x-scalar-tabs'] !== undefined\n}\n\n/**\n * Helper to get the unpacked tabs array from workspace.\n * Returns the tabs as a plain array, not a proxy.\n */\nconst getUnpackedTabs = (\n workspace: Workspace & { 'x-scalar-tabs': NonNullable<Workspace['x-scalar-tabs']> },\n): ReturnType<typeof unpackProxyObject<NonNullable<Workspace['x-scalar-tabs']>>> => {\n return unpackProxyObject(workspace['x-scalar-tabs']!, { depth: TAB_UNPACK_DEPTH })\n}\n\n/**\n * Helper to get the current active tab index.\n * Defaults to 0 if not set.\n */\nconst getActiveIndex = (workspace: Workspace): number => {\n return workspace['x-scalar-active-tab'] ?? 0\n}\n\n/**\n * Updates the tabs and active tab index in the workspace.\n * This is used for bulk updates when synchronizing state.\n */\nexport const updateTabs = (workspace: Workspace | null, payload: TabEvents['tabs:update:tabs']): void => {\n if (!workspace) {\n return\n }\n\n if (payload['x-scalar-tabs']) {\n workspace['x-scalar-tabs'] = payload['x-scalar-tabs']\n }\n\n if (payload['x-scalar-active-tab'] !== undefined) {\n workspace['x-scalar-active-tab'] = payload['x-scalar-active-tab']\n }\n}\n\n/**\n * Adds a new tab by duplicating the currently active tab.\n * This preserves the user's context when opening a new tab.\n */\nexport const addTab = (workspace: Workspace | null, _payload: TabEvents['tabs:add:tab']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n const activeIndex = getActiveIndex(workspace)\n const currentTab = tabs[activeIndex]\n\n if (!currentTab) {\n return false\n }\n\n const newTabs = [...tabs, { ...currentTab }]\n\n workspace['x-scalar-tabs'] = newTabs\n workspace['x-scalar-active-tab'] = newTabs.length - 1\n return true\n}\n\n/**\n * Closes the currently active tab.\n * Prevents closing if only one tab remains, to ensure the user always has a tab open.\n * Adjusts the active index if needed to keep it in bounds.\n */\nexport const closeTab = (workspace: Workspace | null, payload: TabEvents['tabs:close:tab']): boolean => {\n const getInputIndex = (): number => {\n if ('event' in payload) {\n return payload.event.code.startsWith('Digit') ? Number.parseInt(payload.event.key, 10) - 1 : Number.NaN\n }\n return payload.index\n }\n\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const index = getInputIndex()\n const filteredTabs = getUnpackedTabs(workspace).filter((_, i) => i !== index)\n\n if (filteredTabs.length <= 0) {\n return false\n }\n\n workspace['x-scalar-tabs'] = filteredTabs\n\n /**\n * If we closed a tab at the end, the active index needs to move back.\n * This ensures the active tab stays within bounds after removal.\n */\n if (index >= filteredTabs.length) {\n workspace['x-scalar-active-tab'] = filteredTabs.length - 1\n }\n\n return true\n}\n\n/**\n * Closes all other tabs except the one at the given index\n */\nexport const closeOtherTabs = (workspace: Workspace | null, payload: TabEvents['tabs:close:other-tabs']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n\n if (tabs.length <= 1) {\n return false\n }\n\n workspace['x-scalar-tabs'] = tabs.filter((_, index) => index === payload.index)\n // set the active tab to the first tab since we closed all other tabs\n workspace['x-scalar-active-tab'] = 0\n return true\n}\n\n/**\n * Navigates to the previous tab in the list.\n * Does nothing if already at the first tab.\n */\nexport const navigatePreviousTab = (\n workspace: Workspace | null,\n _payload: TabEvents['tabs:navigate:previous'],\n): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const activeIndex = getActiveIndex(workspace)\n\n if (activeIndex <= 0) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = activeIndex - 1\n return true\n}\n\n/**\n * Navigates to the next tab in the list.\n * Does nothing if already at the last tab.\n */\nexport const navigateNextTab = (workspace: Workspace | null, _payload: TabEvents['tabs:navigate:next']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n const activeIndex = getActiveIndex(workspace)\n\n if (activeIndex >= tabs.length - 1) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = activeIndex + 1\n return true\n}\n\n/**\n * Focuses a specific tab based on keyboard number input (1-9).\n * Extracts the digit from the keyboard event and focuses that tab.\n * Tab numbering starts at 1 for user convenience but uses 0-based indexing internally.\n */\nexport const focusTab = (workspace: Workspace | null, payload: TabEvents['tabs:focus:tab']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const getInputIndex = (): number => {\n if ('event' in payload) {\n return payload.event.code.startsWith('Digit') ? Number.parseInt(payload.event.key, 10) - 1 : Number.NaN\n }\n return payload.index\n }\n\n const tabs = getUnpackedTabs(workspace)\n\n const newActiveIndex = getInputIndex()\n\n if (Number.isNaN(newActiveIndex) || newActiveIndex < 0 || newActiveIndex >= tabs.length) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = newActiveIndex\n return true\n}\n\n/**\n * Focuses the last tab in the list.\n * This provides a quick way to jump to the end, regardless of how many tabs exist.\n */\nexport const focusLastTab = (workspace: Workspace | null, _payload: TabEvents['tabs:focus:tab-last']): boolean => {\n if (!hasValidTabs(workspace)) {\n return false\n }\n\n const tabs = getUnpackedTabs(workspace)\n\n if (tabs.length <= 1) {\n return false\n }\n\n workspace['x-scalar-active-tab'] = tabs.length - 1\n return true\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,4 +3,12 @@ import type { Workspace } from '../schemas.js';
3
3
  export declare const updateActiveProxy: (workspace: Workspace | null, payload: WorkspaceEvents["workspace:update:active-proxy"]) => void;
4
4
  export declare const updateColorMode: (workspace: Workspace | null, payload: WorkspaceEvents["workspace:update:color-mode"]) => void;
5
5
  export declare const updateTheme: (workspace: Workspace | null, payload: WorkspaceEvents["workspace:update:theme"]) => void;
6
+ /**
7
+ * Updates the selected http client on the workspace
8
+ *
9
+ * @param workspace - The workspace to update the selected http client in
10
+ * @param payload - The payload to update the selected client with
11
+ * @returns
12
+ */
13
+ export declare const updateSelectedClient: (workspace: Workspace | undefined, payload: WorkspaceEvents["workspace:update:selected-client"]) => void;
6
14
  //# sourceMappingURL=workspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/mutators/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,SAAS,eAAe,CAAC,+BAA+B,CAAC,SAM1D,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,WAAW,SAAS,GAAG,IAAI,EAC3B,SAAS,eAAe,CAAC,6BAA6B,CAAC,SAMxD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,WAAW,SAAS,GAAG,IAAI,EAAE,SAAS,eAAe,CAAC,wBAAwB,CAAC,SAK1G,CAAA"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/mutators/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,eAAO,MAAM,iBAAiB,GAC5B,WAAW,SAAS,GAAG,IAAI,EAC3B,SAAS,eAAe,CAAC,+BAA+B,CAAC,SAM1D,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,WAAW,SAAS,GAAG,IAAI,EAC3B,SAAS,eAAe,CAAC,6BAA6B,CAAC,SAMxD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,WAAW,SAAS,GAAG,IAAI,EAAE,SAAS,eAAe,CAAC,wBAAwB,CAAC,SAK1G,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,WAAW,SAAS,GAAG,SAAS,EAChC,SAAS,eAAe,CAAC,kCAAkC,CAAC,SAM7D,CAAA"}
@@ -16,9 +16,16 @@ const updateTheme = (workspace, payload) => {
16
16
  }
17
17
  workspace["x-scalar-theme"] = payload;
18
18
  };
19
+ const updateSelectedClient = (workspace, payload) => {
20
+ if (!workspace) {
21
+ return;
22
+ }
23
+ workspace["x-scalar-default-client"] = payload;
24
+ };
19
25
  export {
20
26
  updateActiveProxy,
21
27
  updateColorMode,
28
+ updateSelectedClient,
22
29
  updateTheme
23
30
  };
24
31
  //# sourceMappingURL=workspace.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/workspace.ts"],
4
- "sourcesContent": ["import type { WorkspaceEvents } from '@/events/definitions/workspace'\nimport type { Workspace } from '@/schemas'\n\nexport const updateActiveProxy = (\n workspace: Workspace | null,\n payload: WorkspaceEvents['workspace:update:active-proxy'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-active-proxy'] = payload ?? undefined\n}\n\nexport const updateColorMode = (\n workspace: Workspace | null,\n payload: WorkspaceEvents['workspace:update:color-mode'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-color-mode'] = payload\n}\n\nexport const updateTheme = (workspace: Workspace | null, payload: WorkspaceEvents['workspace:update:theme']) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-theme'] = payload\n}\n"],
5
- "mappings": "AAGO,MAAM,oBAAoB,CAC/B,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,uBAAuB,IAAI,WAAW;AAClD;AAEO,MAAM,kBAAkB,CAC7B,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,qBAAqB,IAAI;AACrC;AAEO,MAAM,cAAc,CAAC,WAA6B,YAAuD;AAC9G,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,gBAAgB,IAAI;AAChC;",
4
+ "sourcesContent": ["import type { WorkspaceEvents } from '@/events/definitions/workspace'\nimport type { Workspace } from '@/schemas'\n\nexport const updateActiveProxy = (\n workspace: Workspace | null,\n payload: WorkspaceEvents['workspace:update:active-proxy'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-active-proxy'] = payload ?? undefined\n}\n\nexport const updateColorMode = (\n workspace: Workspace | null,\n payload: WorkspaceEvents['workspace:update:color-mode'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-color-mode'] = payload\n}\n\nexport const updateTheme = (workspace: Workspace | null, payload: WorkspaceEvents['workspace:update:theme']) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-theme'] = payload\n}\n\n/**\n * Updates the selected http client on the workspace\n *\n * @param workspace - The workspace to update the selected http client in\n * @param payload - The payload to update the selected client with\n * @returns\n */\nexport const updateSelectedClient = (\n workspace: Workspace | undefined,\n payload: WorkspaceEvents['workspace:update:selected-client'],\n) => {\n if (!workspace) {\n return\n }\n workspace['x-scalar-default-client'] = payload\n}\n"],
5
+ "mappings": "AAGO,MAAM,oBAAoB,CAC/B,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,uBAAuB,IAAI,WAAW;AAClD;AAEO,MAAM,kBAAkB,CAC7B,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,qBAAqB,IAAI;AACrC;AAEO,MAAM,cAAc,CAAC,WAA6B,YAAuD;AAC9G,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,gBAAgB,IAAI;AAChC;AASO,MAAM,uBAAuB,CAClC,WACA,YACG;AACH,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AACA,YAAU,yBAAyB,IAAI;AACzC;",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,2 @@
1
- /** biome-ignore-all lint/performance/noBarrelFile: Plugins entry point */
2
1
  export { persistencePlugin } from './persistence.js';
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/client/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/client/index.ts"],
4
- "sourcesContent": ["/** biome-ignore-all lint/performance/noBarrelFile: Plugins entry point */\nexport { persistencePlugin } from './persistence'\n"],
5
- "mappings": "AACA,SAAS,yBAAyB;",
4
+ "sourcesContent": ["export { persistencePlugin } from './persistence'\n"],
5
+ "mappings": "AAAA,SAAS,yBAAyB;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,10 @@
1
+ export declare const XExamplesSchema: import("@scalar/typebox").TObject<{
2
+ 'x-examples': import("@scalar/typebox").TOptional<import("@scalar/typebox").TRecord<import("@scalar/typebox").TString, import("@scalar/typebox").TUnknown>>;
3
+ }>;
4
+ export type XExamples = {
5
+ /**
6
+ * This is based on one example of x-examples we have seen where it is a record of example name to example value.
7
+ */
8
+ 'x-examples'?: Record<string, unknown>;
9
+ };
10
+ //# sourceMappingURL=x-examples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-examples.d.ts","sourceRoot":"","sources":["../../../../src/schemas/extensions/schema/x-examples.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe;;EAE1B,CAAA;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { Type } from "@scalar/typebox";
2
+ const XExamplesSchema = Type.Object({
3
+ "x-examples": Type.Optional(Type.Record(Type.String(), Type.Unknown()))
4
+ });
5
+ export {
6
+ XExamplesSchema
7
+ };
8
+ //# sourceMappingURL=x-examples.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/schemas/extensions/schema/x-examples.ts"],
4
+ "sourcesContent": ["import { Type } from '@scalar/typebox'\n\nexport const XExamplesSchema = Type.Object({\n 'x-examples': Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n})\n\nexport type XExamples = {\n /**\n * This is based on one example of x-examples we have seen where it is a record of example name to example value.\n */\n 'x-examples'?: Record<string, unknown>\n}\n"],
5
+ "mappings": "AAAA,SAAS,YAAY;AAEd,MAAM,kBAAkB,KAAK,OAAO;AAAA,EACzC,cAAc,KAAK,SAAS,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;AACxE,CAAC;",
6
+ "names": []
7
+ }