@scalar/workspace-store 0.35.1 → 0.35.2
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.
- package/CHANGELOG.md +25 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +2 -2
- package/dist/mutators/auth.d.ts.map +1 -1
- package/dist/mutators/auth.js +13 -5
- package/dist/mutators/auth.js.map +2 -2
- package/dist/plugins/bundler/helpers.d.ts.map +1 -1
- package/dist/plugins/bundler/helpers.js +2 -2
- package/dist/plugins/bundler/helpers.js.map +2 -2
- package/dist/plugins/bundler/index.d.ts.map +1 -1
- package/dist/plugins/bundler/index.js +7 -0
- package/dist/plugins/bundler/index.js.map +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +17 -2
- package/dist/server.js.map +2 -2
- package/package.json +7 -7
- package/dist/helpers/json-path-utils.d.ts +0 -23
- package/dist/helpers/json-path-utils.d.ts.map +0 -1
- package/dist/helpers/json-path-utils.js +0 -16
- package/dist/helpers/json-path-utils.js.map +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @scalar/workspace-store
|
|
2
2
|
|
|
3
|
+
## 0.35.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#8310](https://github.com/scalar/scalar/pull/8310): refactor: move helpers to the helpers package to share primitive helpers
|
|
8
|
+
- [#8294](https://github.com/scalar/scalar/pull/8294): default createAnySecurityScheme to false and fix index clamp issue
|
|
9
|
+
- [#8287](https://github.com/scalar/scalar/pull/8287): consider path-level parameters in syncPathParameters instead of creating bare synthetic ones
|
|
10
|
+
|
|
11
|
+
#### Updated Dependencies
|
|
12
|
+
|
|
13
|
+
- **@scalar/helpers@0.2.17**
|
|
14
|
+
- [#8310](https://github.com/scalar/scalar/pull/8310): refactor: move helpers to the helpers package to share primitive helpers
|
|
15
|
+
|
|
16
|
+
- **@scalar/openapi-upgrader@0.1.10**
|
|
17
|
+
- [#8272](https://github.com/scalar/scalar/pull/8272): feat: migrate swagger 2.0 response examples
|
|
18
|
+
|
|
19
|
+
- **@scalar/json-magic@0.11.6**
|
|
20
|
+
- [#8310](https://github.com/scalar/scalar/pull/8310): fix: properly parse json pointers
|
|
21
|
+
|
|
22
|
+
- **@scalar/object-utils@1.2.31**
|
|
23
|
+
|
|
24
|
+
- **@scalar/types@0.6.9**
|
|
25
|
+
|
|
26
|
+
- **@scalar/snippetz@0.6.18**
|
|
27
|
+
|
|
3
28
|
## 0.35.1
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getValueAtPath } from "@scalar/helpers/object/get-value-at-path";
|
|
1
2
|
import { isObject } from "@scalar/helpers/object/is-object";
|
|
2
3
|
import { preventPollution } from "@scalar/helpers/object/prevent-pollution";
|
|
3
4
|
import { generateHash } from "@scalar/helpers/string/generate-hash";
|
|
@@ -17,7 +18,6 @@ import { deepClone } from "./helpers/deep-clone.js";
|
|
|
17
18
|
import { createDetectChangesProxy } from "./helpers/detect-changes-proxy.js";
|
|
18
19
|
import { safeAssign } from "./helpers/general.js";
|
|
19
20
|
import { getFetch } from "./helpers/get-fetch.js";
|
|
20
|
-
import { getValueByPath } from "./helpers/json-path-utils.js";
|
|
21
21
|
import { mergeObjects } from "./helpers/merge-object.js";
|
|
22
22
|
import { createOverridesProxy } from "./helpers/overrides-proxy.js";
|
|
23
23
|
import { unpackProxyObject } from "./helpers/unpack-proxy.js";
|
|
@@ -456,7 +456,7 @@ const createWorkspaceStore = (workspaceProps) => {
|
|
|
456
456
|
},
|
|
457
457
|
resolve: (path) => {
|
|
458
458
|
const activeDocument = workspace.activeDocument;
|
|
459
|
-
const target =
|
|
459
|
+
const target = getValueAtPath(activeDocument, path);
|
|
460
460
|
if (!isObject(target)) {
|
|
461
461
|
console.error(
|
|
462
462
|
`Invalid path provided for resolution. Path: [${path.join(", ")}]. Found value of type: ${typeof target}. Expected an object.`
|
package/dist/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client.ts"],
|
|
4
|
-
"sourcesContent": ["import { isObject } from '@scalar/helpers/object/is-object'\nimport { preventPollution } from '@scalar/helpers/object/prevent-pollution'\nimport { generateHash } from '@scalar/helpers/string/generate-hash'\nimport { measureAsync, measureSync } from '@scalar/helpers/testing/measure'\nimport { type LoaderPlugin, bundle } from '@scalar/json-magic/bundle'\nimport { fetchUrls } from '@scalar/json-magic/bundle/plugins/browser'\nimport { type Difference, apply, diff, merge } from '@scalar/json-magic/diff'\nimport { createMagicProxy, getRaw } from '@scalar/json-magic/magic-proxy'\nimport { upgrade } from '@scalar/openapi-upgrader'\nimport type { Record } from '@scalar/typebox'\nimport { Value } from '@scalar/typebox/value'\nimport type { PartialDeep } from 'type-fest'\nimport { reactive } from 'vue'\nimport YAML from 'yaml'\n\nimport { type AuthStore, createAuthStore } from '@/entities/auth'\nimport { type HistoryStore, createHistoryStore } from '@/entities/history'\nimport { applySelectiveUpdates } from '@/helpers/apply-selective-updates'\nimport { deepClone } from '@/helpers/deep-clone'\nimport { createDetectChangesProxy } from '@/helpers/detect-changes-proxy'\nimport { type UnknownObject, safeAssign } from '@/helpers/general'\nimport { getFetch } from '@/helpers/get-fetch'\nimport { getValueByPath } from '@/helpers/json-path-utils'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { createOverridesProxy } from '@/helpers/overrides-proxy'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport { createNavigation } from '@/navigation'\nimport type { NavigationOptions } from '@/navigation/get-navigation-options'\nimport {\n externalValueResolver,\n loadingStatus,\n normalizeAuthSchemes,\n normalizeRefs,\n refsEverywhere,\n restoreOriginalRefs,\n syncPathParameters,\n} from '@/plugins/bundler'\nimport { extensions } from '@/schemas/extensions'\nimport type { InMemoryWorkspace } from '@/schemas/inmemory-workspace'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n OpenAPIDocumentSchema as OpenAPIDocumentSchemaStrict,\n type OpenApiDocument,\n} from '@/schemas/v3.1/strict/openapi-document'\nimport type {\n DocumentMetaExtensions,\n Workspace,\n WorkspaceDocumentMeta,\n WorkspaceExtensions,\n WorkspaceMeta,\n} from '@/schemas/workspace'\nimport type { WorkspaceSpecification } from '@/schemas/workspace-specification'\nimport type { WorkspacePlugin, WorkspaceStateChangeEvent } from '@/workspace-plugin'\n\ntype ExtraDocumentConfigurations = Record<\n string,\n {\n fetch: WorkspaceDocumentMetaInput['fetch']\n }\n>\n\n/**\n * Input type for workspace document metadata and configuration.\n * This type defines the required and optional fields for initializing a document in the workspace.\n */\ntype WorkspaceDocumentMetaInput = {\n /** Optional metadata about the document like title, description, etc */\n meta?: WorkspaceDocumentMeta\n /** Required unique identifier for the document */\n name: string\n /** Overrides for the document */\n overrides?: PartialDeep<OpenApiDocument>\n /** Optional custom fetch implementation to use when retrieving the document. By default the global fetch implementation will be used */\n fetch?: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response>\n}\n\n/**\n * Represents a document that is loaded from a URL.\n * This type extends WorkspaceDocumentMetaInput to include URL-specific properties.\n */\nexport type UrlDoc = {\n /** URL to fetch the OpenAPI document from */\n url: string\n} & WorkspaceDocumentMetaInput\n\n/**\n * Represents a document that is loaded from a URL.\n * This type extends WorkspaceDocumentMetaInput to include URL-specific properties.\n */\nexport type FileDoc = {\n /** Path to the local file to read the OpenAPI document from */\n path: string\n} & WorkspaceDocumentMetaInput\n\n/** Represents a document that is provided directly as an object rather than loaded from a URL */\nexport type ObjectDoc = {\n /** The OpenAPI document object containing the API specification */\n document: Record<string, unknown>\n} & WorkspaceDocumentMetaInput\n\n/**\n * Union type representing the possible input formats for a workspace document:\n * - UrlDoc: Document loaded from a URL with optional fetch configuration\n * - ObjectDoc: Direct document object with metadata\n */\nexport type WorkspaceDocumentInput = UrlDoc | ObjectDoc | FileDoc\n\n/**\n * Resolves a workspace document from various input sources (URL, local file, or direct document object).\n *\n * @param workspaceDocument - The document input to resolve, which can be:\n * - A URL to fetch the document from\n * - A direct document object\n * @returns A promise that resolves to an object containing:\n * - ok: boolean indicating if the resolution was successful\n * - data: The resolved document data\n *\n * @example\n * // Resolve from URL\n * const urlDoc = await loadDocument({ name: 'api', url: 'https://api.example.com/openapi.json' })\n *\n * // Resolve direct document\n * const directDoc = await loadDocument({\n * name: 'inline',\n * document: { openapi: '3.0.0', paths: {} }\n * })\n */\nfunction loadDocument(\n workspaceDocument: WorkspaceDocumentInput & {\n /** A file loader plugin for resolving local file references (for non browser environments) */\n fileLoader?: LoaderPlugin\n },\n): ReturnType<LoaderPlugin['exec']> {\n if ('url' in workspaceDocument) {\n return fetchUrls({ fetch: workspaceDocument.fetch }).exec(workspaceDocument.url)\n }\n\n if ('path' in workspaceDocument) {\n const loader = workspaceDocument.fileLoader\n if (!loader) {\n console.error('No loader provided for loading files')\n return Promise.resolve({\n ok: false,\n })\n }\n return loader.exec(workspaceDocument.path)\n }\n\n return Promise.resolve({\n ok: true,\n data: workspaceDocument.document,\n // string version of the raw document for hashing purposes\n raw: JSON.stringify(workspaceDocument.document),\n })\n}\n\n/**\n * Returns the base source of a workspace document if it was loaded from a URL or file.\n * If the document was loaded from a file, returns the path to the file.\n * If the document was provided directly as an object, returns undefined.\n * Which can be used to resolve relative references in the document.\n *\n * @param input - The workspace document input (either UrlDoc or ObjectDoc)\n * @returns The URL string if present, otherwise undefined\n */\nconst getDocumentSource = (input: WorkspaceDocumentInput) => {\n if ('url' in input) {\n return input.url\n }\n if ('path' in input) {\n return input.path\n }\n return undefined\n}\n\n/**\n * Configuration object for initializing a workspace store.\n * Defines the initial state and documents for the workspace.\n */\ntype WorkspaceProps = {\n /** Optional metadata for the workspace including theme, active document, etc */\n meta?: WorkspaceMeta\n /** Fetch function for retrieving documents */\n fetch?: WorkspaceDocumentInput['fetch']\n /** A list of all registered plugins for the current workspace */\n plugins?: WorkspacePlugin[]\n /** A file loader plugin for resolving local file references (for non browser environments) */\n fileLoader?: LoaderPlugin\n}\n\n/**\n * Type definition for the workspace store return object.\n * This explicit type is needed to avoid TypeScript inference limits.\n *\n * @see https://github.com/microsoft/TypeScript/issues/43817#issuecomment-827746462\n */\nexport type WorkspaceStore = {\n /**\n * The history store for the workspace\n */\n readonly history: HistoryStore\n /**\n * The auth store for the workspace\n */\n readonly auth: AuthStore\n /**\n * Returns the reactive workspace object with an additional activeDocument getter\n */\n readonly workspace: Workspace\n /**\n * Updates a specific metadata field in the workspace\n * @param key - The metadata field to update\n * @param value - The new value for the field\n * @example\n * // Update the workspace title\n * update('x-scalar-active-document', 'document-name')\n */\n update<K extends keyof WorkspaceMeta | keyof WorkspaceExtensions>(\n key: K,\n value: (WorkspaceMeta & WorkspaceExtensions)[K],\n ): void\n /**\n * Updates a specific metadata field for a given document in the workspace.\n * @param name - The document to update. Use 'active' for the currently active document, or provide a specific document name.\n * @param key - The metadata field to update, as defined in WorkspaceDocumentMeta.\n * @param value - The new value for the selected metadata field.\n * @returns true if the update was successful, false otherwise.\n * @example\n * // Update the auth metadata for the active document\n * updateDocument('active', 'x-scalar-active-auth', 'Bearer')\n * // Update the auth metadata for a specific document\n * updateDocument('document-name', 'x-scalar-active-auth', 'Bearer')\n */\n updateDocument<K extends keyof DocumentMetaExtensions>(\n name: 'active' | (string & {}),\n key: K,\n value: DocumentMetaExtensions[K],\n ): boolean\n /**\n * Replaces the content of a specific document in the workspace with the provided input.\n * This method computes the difference between the current document and the new input,\n * then applies only the necessary changes in place. The updates are applied atomically,\n * ensuring the document is updated in a single operation.\n *\n * @param documentName - The name of the document to update.\n * @param input - The new content to apply to the document (as a plain object).\n * @example\n * // Replace the content of the 'api' document with new data\n * store.replaceDocument('api', {\n * openapi: '3.1.0',\n * info: { title: 'Updated API', version: '1.0.1' },\n * paths: {},\n * })\n */\n replaceDocument(documentName: string, input: Record<string, unknown>): Promise<void>\n /**\n * Resolves a reference in the active document by following the provided path and resolving any external $ref references.\n * This method traverses the document structure following the given path and resolves any $ref references it encounters.\n * During resolution, it sets a loading status and updates the reference with the resolved content.\n *\n * @param path - Array of strings representing the path to the reference (e.g. ['paths', '/users', 'get', 'responses', '200'])\n * @throws Error if the path is invalid or empty\n * @example\n * // Resolve a reference in the active document\n * resolve(['paths', '/users', 'get', 'responses', '200'])\n */\n resolve(path: string[]): Promise<unknown>\n /**\n * Adds a new document to the workspace\n * @param document - The document content to add. This should be a valid OpenAPI/Swagger document or other supported format\n * @param meta - Metadata for the document, including its name and other properties defined in WorkspaceDocumentMeta\n * @example\n * // Add a new OpenAPI document to the workspace\n * store.addDocument({\n * name: 'name',\n * document: {\n * openapi: '3.0.0',\n * info: { title: 'title' },\n * },\n * meta: {\n * 'x-scalar-active-auth': 'Bearer',\n * 'x-scalar-selected-server': 'production'\n * }\n * })\n */\n addDocument(input: WorkspaceDocumentInput, navigationOptions?: NavigationOptions): Promise<boolean>\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This method removes the document from the workspace along with all related data including:\n * - The document itself from the workspace documents map\n * - Original document data\n * - Intermediate document data (saved local versions)\n * - Document-specific configuration\n * - Document overrides\n * - Extra document configurations\n *\n * If the deleted document was the active document, the active document is automatically\n * reset to the first remaining document in the workspace, or undefined if no documents remain.\n *\n * The deletion is automatically tracked by the workspace change detection system,\n * and appropriate events will be fired to notify registered plugins.\n *\n * @param documentName - The name of the document to delete\n * @returns void\n *\n * @example\n * // Delete the document named 'api'\n * store.deleteDocument('api')\n *\n * @example\n * // Delete multiple documents\n * ['api', 'petstore'].forEach(name => store.deleteDocument(name))\n */\n deleteDocument(documentName: string): void\n /**\n * Exports the specified document in the requested format.\n *\n * This method serializes the most recently saved local version of the document (from the intermediateDocuments map)\n * to either JSON or YAML. The exported document reflects the last locally saved state, including any edits\n * that have been saved but not yet synced to a remote registry. Runtime/in-memory changes that have not been saved\n * will not be included.\n *\n * @param documentName - The name of the document to export.\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The document as a string in the requested format, or undefined if the document does not exist.\n *\n * @example\n * // Export a document as JSON\n * const jsonString = store.exportDocument('api', 'json')\n *\n * // Export a document as YAML\n * const yamlString = store.exportDocument('api', 'yaml')\n */\n exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Exports the currently active document in the requested format.\n *\n * This is a convenience method that exports the active document (determined by the workspace's\n * activeDocument extension) without requiring the caller to specify the document name.\n * The exported document reflects the last locally saved state, including any edits that have\n * been saved but not yet synced to a remote registry.\n *\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The active document as a string in the requested format, or undefined if no active document exists.\n *\n * @example\n * // Export the active document as JSON\n * const jsonString = store.exportActiveDocument('json')\n *\n * // Export the active document as YAML\n * const yamlString = store.exportActiveDocument('yaml')\n */\n exportActiveDocument(format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Saves the current state of the specified document to the intermediate documents map.\n *\n * This function captures the latest (reactive) state of the document from the workspace and\n * applies its changes to the corresponding entry in the `intermediateDocuments` map.\n * The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n * which may include edits not yet synced to the remote registry.\n *\n * The update is performed in-place. A deep clone of the current document\n * state is used to avoid mutating the reactive object directly.\n *\n * @param documentName - The name of the document to save.\n * @returns An array of diffs that were excluded from being applied (such as changes to ignored keys),\n * or undefined if the document does not exist or cannot be updated.\n *\n * @example\n * // Save the current state of the document named 'api'\n * const excludedDiffs = store.saveDocument('api')\n */\n saveDocument(documentName: string): Promise<unknown[] | undefined>\n /**\n * Builds the sidebar for the specified document.\n *\n * @param documentName - The name of the document to build the sidebar for\n * @returns boolean indicating if the sidebar was built successfully\n */\n buildSidebar: (documentName: string) => boolean\n /**\n * Restores the specified document to its last locally saved state.\n *\n * This method updates the current reactive document (in the workspace) with the contents of the\n * corresponding intermediate document (from the `intermediateDocuments` map), effectively discarding\n * any unsaved in-memory changes and reverting to the last saved version.\n * Vue reactivity is preserved by updating the existing reactive object in place.\n *\n * **Warning:** This operation will discard all unsaved (in-memory) changes to the specified document.\n *\n * @param documentName - The name of the document to restore.\n * @returns void\n *\n * @example\n * // Restore the document named 'api' to its last saved state\n * store.revertDocumentChanges('api')\n */\n revertDocumentChanges(documentName: string): Promise<void>\n /**\n * Commits the specified document.\n *\n * This method is intended to finalize and persist the current state of the document,\n * potentially syncing it with a remote registry or marking it as the latest committed version.\n *\n * @param documentName - The name of the document to commit.\n * @remarks\n * The actual commit logic is not implemented yet.\n */\n commitDocument(documentName: string): void\n /**\n * Exports the complete current workspace state as a plain JavaScript object.\n *\n * The returned object includes all workspace documents (with Vue reactivity removed), workspace metadata,\n * document configurations, and both the original and intermediate document maps. This object can be\n * serialized (e.g., with JSON.stringify) and later imported to fully restore the workspace\u2014including\n * all documents, their configurations, metadata, and historical states.\n *\n * @returns An `InMemoryWorkspace` object representing the entire workspace state,\n * suitable for persistence, backup, or sharing.\n */\n exportWorkspace(): InMemoryWorkspace\n /**\n * Imports a workspace from a serialized JSON string.\n *\n * This method parses the input string using the InMemoryWorkspaceSchema,\n * then updates the current workspace state, including documents, metadata,\n * and configuration, with the imported values.\n *\n * @param input - The serialized workspace JSON string to import.\n */\n loadWorkspace(input: InMemoryWorkspace): void\n /**\n * Imports a workspace from a WorkspaceSpecification object.\n *\n * This method assigns workspace metadata and adds all documents defined in the specification.\n * Each document is added using its $ref and optional overrides.\n *\n * @example\n * ```ts\n * await store.importWorkspaceFromSpecification({\n * documents: {\n * api: { $ref: '/specs/api.yaml' },\n * petstore: { $ref: '/specs/petstore.yaml' }\n * },\n * overrides: {\n * api: { config: { features: { showModels: true } } }\n * },\n * info: { title: 'My Workspace' },\n * workspace: 'v1',\n * \"x-scalar-color-mode\": true\n * })\n * ```\n *\n * @param specification - The workspace specification to import.\n */\n importWorkspaceFromSpecification(specification: WorkspaceSpecification): Promise<boolean[]>\n /**\n * Rebases a document in the workspace by refetching its origin and merging with local edits.\n *\n * This method fetches the latest version of the document (optionally with custom fetch/config),\n * calculates changes relative to the original and locally edited versions,\n * and attempts to update the workspace document while preserving user edits.\n * If automatic resolution isn't possible due to conflicts, returns a conflict list for the caller to resolve.\n * If `resolvedConflicts` are provided (e.g., after user intervention), applies them to complete the rebase.\n *\n * @param input Object specifying which document to rebase\n * @returns If there are unresolved conflicts, resolves to an object containing the list of conflicts and a method to apply user-resolved conflicts; otherwise resolves to void.\n *\n * @example\n * // Rebase a document and handle conflicts interactively\n * const result = await store.rebaseDocument({ name: 'api', fetch: customFetch });\n * if (result && result.ok) {\n * // Present conflicts to the user and collect resolutions...\n * await result.applyChanges(userResolvedConflicts);\n * }\n */\n rebaseDocument: (input: WorkspaceDocumentInput) => Promise<\n | {\n ok: false\n type: 'CORRUPTED_STATE' | 'FETCH_FAILED' | 'NO_CHANGES_DETECTED'\n message: string\n }\n | {\n ok: true\n conflicts: ReturnType<typeof merge>['conflicts']\n applyChanges: (resolvedConflicts: Difference<unknown>[]) => Promise<void>\n }\n >\n}\n\n/**\n * Creates a reactive workspace store that manages documents and their metadata.\n * The store provides functionality for accessing, updating, and resolving document references.\n *\n * @param workspaceProps - Configuration object for the workspace\n * @param workspaceProps.meta - Optional metadata for the workspace\n * @param workspaceProps.documents - Optional record of documents to initialize the workspace with\n * Documents that require asynchronous loading must be added using `1` after the store is created\n * this allows atomic awaiting and does not block page load for the store initialization\n * @returns An object containing methods and getters for managing the workspace\n */\nexport const createWorkspaceStore = (workspaceProps?: WorkspaceProps): WorkspaceStore => {\n /**\n * Holds additional configuration options for each document in the workspace.\n *\n * This can include settings that can not be persisted between sessions (not JSON serializable)\n */\n const extraDocumentConfigurations: ExtraDocumentConfigurations = {}\n\n /**\n * Notifies all workspace plugins of a workspace state change event.\n *\n * This function iterates through all registered plugins (if any) and invokes\n * their onWorkspaceStateChanges hook with the given event object.\n *\n * @param event - The workspace state change event to broadcast to plugins\n */\n const fireWorkspaceChange = (event: WorkspaceStateChangeEvent) => {\n workspaceProps?.plugins?.forEach((plugin) => plugin.hooks?.onWorkspaceStateChanges?.(event))\n }\n\n /**\n * An object containing the reactive workspace state.\n *\n * Every change to the workspace, is tracked and broadcast to all registered plugins.\n * allowing for change tracking.\n *\n * NOTE:\n * The detect changes proxy is applied separately beacause the vue reactitvity proxy have to be the outer most proxy.\n * If the order is reversed, Vue cannot properly track mutations, leading to lost reactivity and bugs.\n * By wrapping the contents with the detect changes proxy first, and then passing the result to Vue's `reactive`,\n * we ensure that Vue manages its reactivity as expected and our change detection hooks\n * are also triggered reliably.\n * Do not reverse this order\u203C\uFE0F\n */\n const workspace = reactive<Workspace>(\n createDetectChangesProxy(\n {\n ...workspaceProps?.meta,\n documents: {},\n /**\n * Returns the currently active document from the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The active document or undefined if no document is found\n */\n get activeDocument(): NonNullable<Workspace['activeDocument']> | undefined {\n return workspace.documents[getActiveDocumentName()]\n },\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n /** Document changes */\n if (type === 'documents') {\n // We are overriding the while documents object, ignore. This should not happen\n if (path.length < 2) {\n console.log('[WARN]: Overriding entire documents object is not supported')\n return\n }\n\n const documentName = path[1] as string\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Active document changes */\n if (type === 'activeDocument') {\n const documentName = getActiveDocumentName()\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n // Active document changed\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Workspace meta changes */\n const { activeDocument: _a, documents: _d, ...meta } = workspace\n const event = {\n type: 'meta',\n value: unpackProxyObject(meta, { depth: 1 }),\n } satisfies WorkspaceStateChangeEvent\n\n fireWorkspaceChange(event)\n return\n },\n },\n },\n ),\n )\n\n /**\n * An object containing all the workspace state, wrapped in a detect changes proxy.\n *\n * Every change to the workspace state (documents, configs, metadata, etc.) can be detected here,\n * allowing for change tracking.\n */\n const { originalDocuments, intermediateDocuments, overrides } = createDetectChangesProxy(\n {\n /**\n * Holds the original, unmodified documents as they were initially loaded into the workspace.\n * These documents are stored in their raw form\u2014prior to any reactive wrapping, dereferencing, or bundling.\n * This map preserves the pristine structure of each document, using deep clones to ensure that\n * subsequent mutations in the workspace do not affect the originals.\n * The originals are retained so that we can restore, compare, or sync with the remote registry as needed.\n */\n originalDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores the intermediate state of documents after local edits but before syncing with the remote registry.\n *\n * This map acts as a local \"saved\" version of the document, reflecting the user's changes after they hit \"save\".\n * The `originalDocuments` map, by contrast, always mirrors the document as it exists in the remote registry.\n *\n * Use this map to stage local changes that are ready to be propagated back to the remote registry.\n * This separation allows us to distinguish between:\n * - The last known remote version (`originalDocuments`)\n * - The latest locally saved version (`intermediateDocuments`)\n * - The current in-memory (possibly unsaved) workspace document (`workspace.documents`)\n */\n intermediateDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores per-document overrides for OpenAPI documents.\n * This object is used to override specific fields of a document\n * when you cannot (or should not) modify the source document directly.\n * For example, this enables UI-driven or temporary changes to be applied\n * on top of the original document, without mutating the source.\n * The key is the document name, and the value is a deep partial\n * OpenAPI document representing the overridden fields.\n */\n overrides: {} as InMemoryWorkspace['overrides'],\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n if (!type) {\n return\n }\n\n if (path.length < 2) {\n return\n }\n\n const documentName = path[1] as string\n if (type === 'originalDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(originalDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'intermediateDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(intermediateDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'overrides') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(overrides[documentName] ?? {}),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n },\n },\n },\n )\n\n /**\n * This store is used to track the history of requests and responses for documents and operations.\n */\n const history = createHistoryStore({\n hooks: {\n onHistoryChange: (documentName) => {\n fireWorkspaceChange({\n type: 'history',\n documentName,\n value: history.export()[documentName] ?? {},\n } satisfies WorkspaceStateChangeEvent)\n },\n },\n })\n\n /**\n * The auth store for the workspace\n */\n const auth = createAuthStore({\n hooks: {\n onAuthChange: (documentName) => {\n fireWorkspaceChange({\n type: 'auth',\n documentName,\n value: auth.export()[documentName] ?? {\n secrets: {},\n selected: { document: { selectedIndex: 0, selectedSchemes: [] }, path: {} },\n },\n } satisfies WorkspaceStateChangeEvent)\n },\n },\n })\n\n /**\n * Returns the name of the currently active document in the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The name of the active document or an empty string if no document is found\n */\n function getActiveDocumentName() {\n return workspace[extensions.workspace.activeDocument] ?? Object.keys(workspace.documents)[0] ?? ''\n }\n\n function exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean) {\n const intermediateDocument = intermediateDocuments[documentName]\n\n if (!intermediateDocument) {\n return\n }\n\n if (format === 'json') {\n return minify ? JSON.stringify(intermediateDocument) : JSON.stringify(intermediateDocument, null, 2)\n }\n\n return YAML.stringify(intermediateDocument)\n }\n\n // Save the current state of the specified document to the intermediate documents map.\n // This function captures the latest (reactive) state of the document from the workspace and\n // applies its changes to the corresponding entry in the `intermediateDocuments` map.\n // The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n // which may include edits not yet synced to the remote registry.\n async function saveDocument(documentName: string) {\n const intermediateDocument = intermediateDocuments[documentName]\n const workspaceDocument = workspace.documents[documentName]\n\n if (!workspaceDocument) {\n return\n }\n\n // Obtain the raw state of the current document to ensure accurate diffing\n const activeDocumentRaw = unpackProxyObject(workspaceDocument)\n\n // If either the intermediate or updated document is missing, do nothing\n if (!intermediateDocument || !activeDocumentRaw) {\n console.warn('Failed to save document, intermediate document and/or active document is missing')\n return\n }\n\n // Traverse the document and convert refs back to the original shape\n const updatedWithOriginalRefs = await bundle(deepClone(activeDocumentRaw), {\n plugins: [restoreOriginalRefs()],\n treeShake: false,\n urlMap: true,\n })\n\n // Apply changes from the current document to the intermediate document in place\n const excludedDiffs = applySelectiveUpdates(intermediateDocument, updatedWithOriginalRefs as UnknownObject)\n\n // Mark the document as not dirty since we are saving it\n workspaceDocument['x-scalar-is-dirty'] = false\n\n return excludedDiffs\n }\n\n // Add a document to the store synchronously from an in-memory OpenAPI document\n async function addInMemoryDocument(\n input: ObjectDoc & { initialize?: boolean; documentSource?: string; documentHash: string },\n navigationOptions?: NavigationOptions,\n ) {\n const { name, meta } = input\n const clonedRawInputDocument = measureSync('deepClone', () => deepClone(input.document))\n\n measureSync('initialize', () => {\n if (input.initialize !== false) {\n // Store the original document in the originalDocuments map\n // This is used to track the original state of the document as it was loaded into the workspace\n originalDocuments[name] = deepClone(clonedRawInputDocument)\n\n // Store the intermediate document state for local edits\n // This is used to track the last saved state of the document\n // It allows us to differentiate between the original document and the latest saved version\n // This is important for local edits that are not yet synced with the remote registry\n // The intermediate document is used to store the latest saved state of the document\n // This allows us to track changes and revert to the last saved state if needed\n intermediateDocuments[name] = deepClone(clonedRawInputDocument)\n // Store the overrides for this document, or an empty object if none are provided\n overrides[name] = input.overrides ?? {}\n // Store extra document configurations that can not be persisted\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n }\n })\n\n const inputDocument = measureSync('upgrade', () => upgrade(deepClone(clonedRawInputDocument), '3.1'))\n\n const strictDocument: UnknownObject = createMagicProxy(\n {\n ...inputDocument,\n ...meta,\n 'x-original-oas-version': originalDocuments[name]?.openapi ?? originalDocuments[name]?.swagger,\n 'x-scalar-original-document-hash': input.documentHash,\n 'x-scalar-original-source-url': input.documentSource,\n },\n { showInternal: true },\n )\n\n // If the document navigation is not already present, bundle the entire document to resolve all references.\n // This typically applies when the document is not preprocessed by the server and needs local reference resolution.\n // We need to bundle document first before we validate, so we can also validate the external references\n if (strictDocument[extensions.document.navigation] === undefined) {\n const loaders = [\n fetchUrls({\n fetch: extraDocumentConfigurations[name]?.fetch ?? workspaceProps?.fetch,\n }),\n ]\n\n // If a file loader plugin is provided, use it to resolve local file references\n // This is useful for non browser environments\n if (workspaceProps?.fileLoader) {\n loaders.push(workspaceProps.fileLoader)\n }\n\n await measureAsync(\n 'bundle',\n async () =>\n await bundle(getRaw(strictDocument), {\n treeShake: false,\n plugins: [\n ...loaders,\n normalizeRefs(),\n externalValueResolver(),\n refsEverywhere(),\n normalizeAuthSchemes(),\n syncPathParameters(),\n ],\n urlMap: true,\n origin: input.documentSource, // use the document origin (if provided) as the base URL for resolution\n }),\n )\n\n // We coerce the values only when the document is not preprocessed by the server-side-store\n const coerced = measureSync('coerceValue', () =>\n coerceValue(OpenAPIDocumentSchemaStrict, deepClone(strictDocument)),\n )\n measureSync('mergeObjects', () => mergeObjects(strictDocument, coerced))\n }\n\n const isValid = Value.Check(OpenAPIDocumentSchemaStrict, strictDocument)\n\n if (!isValid) {\n const validationErrors = Array.from(Value.Errors(OpenAPIDocumentSchemaStrict, strictDocument))\n\n console.warn('document validation errors: ')\n console.warn(\n validationErrors.map((error) => ({\n message: error.message,\n path: error.path,\n schema: error.schema,\n value: error.value,\n })),\n )\n }\n\n // Skip navigation generation if the document already has a server-side generated navigation structure\n if (strictDocument[extensions.document.navigation] === undefined) {\n const navigation = createNavigation(name, strictDocument as OpenApiDocument, navigationOptions)\n strictDocument[extensions.document.navigation] = navigation\n }\n\n // Create a proxied document with magic proxy and apply any overrides, then store it in the workspace documents map\n // We create a new proxy here in order to hide internal properties after validation and processing\n // This ensures that the workspace document only exposes the intended OpenAPI properties and extensions\n workspace.documents[name] = createOverridesProxy(createMagicProxy(getRaw(strictDocument)) as OpenApiDocument, {\n overrides: unpackProxyObject(overrides[name]),\n })\n }\n\n // Asynchronously adds a new document to the workspace by loading and validating the input.\n // If loading fails, a placeholder error document is added instead.\n async function addDocument(input: WorkspaceDocumentInput, navigationOptions?: NavigationOptions) {\n const { name, meta } = input\n\n /** Ensure we use the active proxy to fetch documents unless we have a custom fetch override */\n const fetch = getFetch({\n fetch: input.fetch ?? workspaceProps?.fetch,\n proxyUrl: workspace['x-scalar-active-proxy'] ?? undefined,\n })\n\n const resolve = await measureAsync(\n 'loadDocument',\n async () => await loadDocument({ ...input, fetch, fileLoader: workspaceProps?.fileLoader }),\n )\n\n // Log the time taken to add a document\n return await measureAsync('addDocument', async () => {\n if (!resolve.ok) {\n console.error(`Failed to fetch document '${name}': request was not successful`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n if (!isObject(resolve.data)) {\n console.error(`Failed to load document '${name}': response data is not a valid object`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n await addInMemoryDocument(\n {\n ...input,\n document: resolve.data,\n documentSource: getDocumentSource(input),\n documentHash: generateHash(resolve.raw),\n },\n navigationOptions,\n )\n\n return true\n })\n }\n\n /**\n * Builds (or updates) the navigation sidebar for the specified document.\n *\n * This method generates the sidebar navigation structure for a workspace document,\n * and attaches it to the document's metadata under the navigation extension key.\n * The document is unpacked to avoid assigning proxy objects as direct property references.\n *\n * - Only the top-level object is proxied; all child objects should be unproxied.\n * - This approach enables safe unpacking of the proxy object without recursively traversing the full object tree.\n *\n * @param documentName - The name/key of the document whose sidebar should be built.\n * @returns {boolean} True if the sidebar was built successfully, false if the document does not exist.\n */\n const buildSidebar = (documentName: string): boolean => {\n const document = workspace.documents[documentName]\n\n if (!document) {\n // Log and exit if the document does not exist in the workspace\n console.error(`Document '${documentName}' does not exist in the workspace.`)\n return false\n }\n\n // Generate the navigation structure for the sidebar.\n const navigation = createNavigation(documentName, document)\n\n // Set the computed navigation structure on the document metadata.\n document[extensions.document.navigation] = navigation\n\n return true\n }\n\n // Cache to track visited nodes during reference resolution to prevent bundling the same subtree multiple times\n // This is needed because we are doing partial bundle operations\n const visitedNodesCache = new Set()\n\n return {\n get workspace() {\n return workspace\n },\n get history() {\n return history\n },\n get auth() {\n return auth\n },\n update(key, value) {\n preventPollution(key)\n Object.assign(workspace, { [key]: value })\n },\n updateDocument<K extends keyof DocumentMetaExtensions>(\n name: 'active' | (string & {}),\n key: K,\n value: DocumentMetaExtensions[K],\n ) {\n const currentDocument = workspace.documents[name === 'active' ? getActiveDocumentName() : name]\n\n if (!currentDocument) {\n return false\n }\n\n preventPollution(key)\n Object.assign(currentDocument, { [key]: value })\n return true\n },\n async replaceDocument(documentName: string, input: Record<string, unknown>) {\n const currentDocument = workspace.documents[documentName]\n\n if (!currentDocument) {\n return console.error(`Document '${documentName}' does not exist in the workspace.`)\n }\n\n // Replace the whole document\n await addInMemoryDocument({\n name: documentName,\n document: input,\n // Preserve the current metadata\n documentSource: currentDocument['x-scalar-original-source-url'],\n documentHash: currentDocument['x-scalar-original-document-hash'],\n meta: {\n 'x-scalar-active-auth': currentDocument['x-scalar-active-auth'],\n 'x-scalar-selected-server': currentDocument['x-scalar-selected-server'],\n },\n initialize: false,\n })\n },\n resolve: (path) => {\n const activeDocument = workspace.activeDocument\n\n const target = getValueByPath(activeDocument, path)\n\n if (!isObject(target)) {\n console.error(\n `Invalid path provided for resolution. Path: [${path.join(', ')}]. Found value of type: ${typeof target}. Expected an object.`,\n )\n return Promise.resolve()\n }\n\n // Bundle the target document with the active document as root, resolving any external references\n // and tracking resolution status through hooks\n return bundle(target, {\n root: activeDocument,\n treeShake: false,\n plugins: [fetchUrls(), loadingStatus(), externalValueResolver()],\n urlMap: true,\n visitedNodes: visitedNodesCache,\n })\n },\n addDocument,\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This function removes the document and all related data structures.\n * If the deleted document was active, it automatically selects the first remaining document.\n */\n deleteDocument: (documentName: string): void => {\n // Check if the document exists before attempting deletion\n if (!workspace.documents[documentName]) {\n return\n }\n\n // Delete the document from the workspace (this will trigger change detection events)\n delete workspace.documents[documentName]\n\n // Clean up all associated data structures\n delete originalDocuments[documentName]\n delete intermediateDocuments[documentName]\n delete overrides[documentName]\n delete extraDocumentConfigurations[documentName]\n history.clearDocumentHistory(documentName)\n auth.clearDocumentAuth(documentName)\n\n // Get remaining documents before deletion to properly set the active document\n const remainingDocuments = Object.keys(workspace.documents)\n const wasActiveDocument = workspace['x-scalar-active-document'] === documentName\n\n // Reset the active document to the first remaining one if the deleted document was the active one\n if (wasActiveDocument) {\n workspace['x-scalar-active-document'] = remainingDocuments[0] ?? undefined\n }\n\n // Fire the deleteDocument event\n fireWorkspaceChange({\n type: 'deleteDocument',\n documentName,\n })\n },\n exportDocument,\n exportActiveDocument: (format, minify) => exportDocument(getActiveDocumentName(), format, minify),\n buildSidebar,\n saveDocument,\n async revertDocumentChanges(documentName: string) {\n const workspaceDocument = workspace.documents[documentName]\n const intermediate = intermediateDocuments[documentName]\n\n if (!workspaceDocument || !intermediate) {\n return\n }\n\n await addInMemoryDocument({\n name: documentName,\n document: intermediate,\n documentSource: workspaceDocument['x-scalar-original-source-url'],\n documentHash: workspaceDocument['x-scalar-original-document-hash'],\n initialize: false,\n })\n },\n commitDocument(documentName: string) {\n // TODO: Implement commit logic\n console.warn(`Commit operation for document '${documentName}' is not implemented yet.`)\n },\n exportWorkspace() {\n const { activeDocument: _, documents, ...meta } = unpackProxyObject(workspace)\n return {\n documents: {\n ...Object.fromEntries(\n Object.entries(documents).map(([name, doc]) => [\n name,\n // Get the raw document without any proxies\n unpackProxyObject(doc),\n ]),\n ),\n },\n meta: unpackProxyObject(meta) ?? {},\n originalDocuments: unpackProxyObject(originalDocuments),\n intermediateDocuments: unpackProxyObject(intermediateDocuments),\n overrides: unpackProxyObject(overrides),\n history: history.export(),\n auth: auth.export(),\n } satisfies InMemoryWorkspace\n },\n loadWorkspace(input: InMemoryWorkspace) {\n safeAssign(\n workspace.documents,\n Object.fromEntries(\n Object.entries(input.documents).map(([name, doc]) => [\n name,\n createOverridesProxy(createMagicProxy(doc), {\n overrides: input.overrides[name],\n }),\n ]),\n ),\n )\n\n safeAssign(originalDocuments, input.originalDocuments)\n safeAssign(intermediateDocuments, input.intermediateDocuments)\n safeAssign(overrides, input.overrides)\n safeAssign(workspace, input.meta)\n history.load(input.history)\n auth.load(input.auth)\n },\n importWorkspaceFromSpecification: (specification: WorkspaceSpecification) => {\n const { documents, overrides, info: _info, workspace: _workspaceVersion, ...meta } = specification\n\n // Assign workspace metadata\n safeAssign(workspace, meta)\n\n // Add workspace documents\n return Promise.all(\n Object.entries(documents ?? {}).map(([name, doc]) =>\n addDocument({ url: doc.$ref, name, overrides: overrides?.[name] }),\n ),\n )\n },\n rebaseDocument: async (input: WorkspaceDocumentInput) => {\n const { name } = input\n\n // ---- Get the current documents\n const originalDocument = unpackProxyObject(originalDocuments[name], { depth: 1 })\n const intermediateDocument = unpackProxyObject(intermediateDocuments[name], { depth: 1 })\n // raw version without any proxies\n const activeDocument = workspace.documents[name]\n ? unpackProxyObject(workspace.documents[name], { depth: 1 })\n : undefined\n\n if (!originalDocument || !intermediateDocument || !activeDocument) {\n // If any required document state is missing, do nothing\n return {\n ok: false,\n type: 'CORRUPTED_STATE' as const,\n message: `Cannot rebase document '${name}': missing original, intermediate, or active document state`,\n }\n }\n\n // ---- Resolve input document\n const resolve = await measureAsync(\n 'loadDocument',\n async () =>\n await loadDocument({\n ...input,\n fetch: input.fetch ?? workspaceProps?.fetch,\n fileLoader: workspaceProps?.fileLoader,\n }),\n )\n\n if (!resolve.ok || !isObject(resolve.data)) {\n return {\n ok: false,\n type: 'FETCH_FAILED' as const,\n message: `Failed to fetch document '${name}': request was not successful or returned invalid data`,\n }\n }\n\n // Compare document hashes to see if the document has changed\n // When the hashes match, we can skip the rebase process\n const newHash = generateHash(resolve.raw)\n if (activeDocument['x-scalar-original-document-hash'] === newHash) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}': document hash matches the active document`,\n }\n }\n\n const newDocumentOrigin = resolve.data\n\n // ---- Override the configurations and metadata\n overrides[name] = input.overrides ?? {}\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n\n // ---- Get the new intermediate document\n const changelogAA = diff(originalDocument, newDocumentOrigin)\n\n // When there are no changes, we can return early since we don't need to do anything\n // This is not supposed to happen due to the hash check above, but just in case\n if (changelogAA.length === 0) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}' after fetching the latest version.`,\n }\n }\n\n const changelogAB = diff(originalDocument, intermediateDocument)\n\n const changesA = merge(changelogAA, changelogAB)\n\n return {\n ok: true,\n conflicts: changesA.conflicts,\n applyChanges: async (resolvedConflicts: Difference<unknown>[]) => {\n const changesetA = changesA.diffs.concat(resolvedConflicts)\n\n // Apply the changes to the original document to get the new intermediate\n const newIntermediateDocument = apply(deepClone(originalDocument), changesetA)\n intermediateDocuments[name] = newIntermediateDocument\n\n // Update the original document\n originalDocuments[name] = newDocumentOrigin\n\n // ---- Get the new active document\n const changelogBA = diff(intermediateDocument, newIntermediateDocument)\n const changelogBB = diff(intermediateDocument, activeDocument)\n\n const changesB = merge(changelogBA, changelogBB)\n\n // Auto-conflict resolution: pick only the changes from the first changeset\n // TODO: In the future, implement smarter conflict resolution if needed\n const changesetB = changesB.diffs.concat(changesB.conflicts.flatMap((it) => it[0]))\n\n const newActiveDocument = coerceValue(\n OpenAPIDocumentSchemaStrict,\n apply(deepClone(newIntermediateDocument), changesetB),\n )\n\n // add the new active document to the workspace but don't re-initialize\n await addInMemoryDocument({\n ...input,\n document: {\n ...newActiveDocument,\n // force regeneration of navigation\n // when we are rebasing, we want to ensure that the navigation is always up to date\n [extensions.document.navigation]: undefined,\n },\n documentSource: getDocumentSource(input),\n // Update the original document hash\n documentHash: generateHash(resolve.raw),\n initialize: false,\n })\n },\n }\n },\n }\n}\n\n// biome-ignore lint/performance/noBarrelFile: It's a package entry point\nexport { generateClientMutators } from '@/mutators'\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport { isObject } from '@scalar/helpers/object/is-object'\nimport { preventPollution } from '@scalar/helpers/object/prevent-pollution'\nimport { generateHash } from '@scalar/helpers/string/generate-hash'\nimport { measureAsync, measureSync } from '@scalar/helpers/testing/measure'\nimport { type LoaderPlugin, bundle } from '@scalar/json-magic/bundle'\nimport { fetchUrls } from '@scalar/json-magic/bundle/plugins/browser'\nimport { type Difference, apply, diff, merge } from '@scalar/json-magic/diff'\nimport { createMagicProxy, getRaw } from '@scalar/json-magic/magic-proxy'\nimport { upgrade } from '@scalar/openapi-upgrader'\nimport type { Record } from '@scalar/typebox'\nimport { Value } from '@scalar/typebox/value'\nimport type { PartialDeep } from 'type-fest'\nimport { reactive } from 'vue'\nimport YAML from 'yaml'\n\nimport { type AuthStore, createAuthStore } from '@/entities/auth'\nimport { type HistoryStore, createHistoryStore } from '@/entities/history'\nimport { applySelectiveUpdates } from '@/helpers/apply-selective-updates'\nimport { deepClone } from '@/helpers/deep-clone'\nimport { createDetectChangesProxy } from '@/helpers/detect-changes-proxy'\nimport { type UnknownObject, safeAssign } from '@/helpers/general'\nimport { getFetch } from '@/helpers/get-fetch'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { createOverridesProxy } from '@/helpers/overrides-proxy'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport { createNavigation } from '@/navigation'\nimport type { NavigationOptions } from '@/navigation/get-navigation-options'\nimport {\n externalValueResolver,\n loadingStatus,\n normalizeAuthSchemes,\n normalizeRefs,\n refsEverywhere,\n restoreOriginalRefs,\n syncPathParameters,\n} from '@/plugins/bundler'\nimport { extensions } from '@/schemas/extensions'\nimport type { InMemoryWorkspace } from '@/schemas/inmemory-workspace'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n OpenAPIDocumentSchema as OpenAPIDocumentSchemaStrict,\n type OpenApiDocument,\n} from '@/schemas/v3.1/strict/openapi-document'\nimport type {\n DocumentMetaExtensions,\n Workspace,\n WorkspaceDocumentMeta,\n WorkspaceExtensions,\n WorkspaceMeta,\n} from '@/schemas/workspace'\nimport type { WorkspaceSpecification } from '@/schemas/workspace-specification'\nimport type { WorkspacePlugin, WorkspaceStateChangeEvent } from '@/workspace-plugin'\n\ntype ExtraDocumentConfigurations = Record<\n string,\n {\n fetch: WorkspaceDocumentMetaInput['fetch']\n }\n>\n\n/**\n * Input type for workspace document metadata and configuration.\n * This type defines the required and optional fields for initializing a document in the workspace.\n */\ntype WorkspaceDocumentMetaInput = {\n /** Optional metadata about the document like title, description, etc */\n meta?: WorkspaceDocumentMeta\n /** Required unique identifier for the document */\n name: string\n /** Overrides for the document */\n overrides?: PartialDeep<OpenApiDocument>\n /** Optional custom fetch implementation to use when retrieving the document. By default the global fetch implementation will be used */\n fetch?: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response>\n}\n\n/**\n * Represents a document that is loaded from a URL.\n * This type extends WorkspaceDocumentMetaInput to include URL-specific properties.\n */\nexport type UrlDoc = {\n /** URL to fetch the OpenAPI document from */\n url: string\n} & WorkspaceDocumentMetaInput\n\n/**\n * Represents a document that is loaded from a URL.\n * This type extends WorkspaceDocumentMetaInput to include URL-specific properties.\n */\nexport type FileDoc = {\n /** Path to the local file to read the OpenAPI document from */\n path: string\n} & WorkspaceDocumentMetaInput\n\n/** Represents a document that is provided directly as an object rather than loaded from a URL */\nexport type ObjectDoc = {\n /** The OpenAPI document object containing the API specification */\n document: Record<string, unknown>\n} & WorkspaceDocumentMetaInput\n\n/**\n * Union type representing the possible input formats for a workspace document:\n * - UrlDoc: Document loaded from a URL with optional fetch configuration\n * - ObjectDoc: Direct document object with metadata\n */\nexport type WorkspaceDocumentInput = UrlDoc | ObjectDoc | FileDoc\n\n/**\n * Resolves a workspace document from various input sources (URL, local file, or direct document object).\n *\n * @param workspaceDocument - The document input to resolve, which can be:\n * - A URL to fetch the document from\n * - A direct document object\n * @returns A promise that resolves to an object containing:\n * - ok: boolean indicating if the resolution was successful\n * - data: The resolved document data\n *\n * @example\n * // Resolve from URL\n * const urlDoc = await loadDocument({ name: 'api', url: 'https://api.example.com/openapi.json' })\n *\n * // Resolve direct document\n * const directDoc = await loadDocument({\n * name: 'inline',\n * document: { openapi: '3.0.0', paths: {} }\n * })\n */\nfunction loadDocument(\n workspaceDocument: WorkspaceDocumentInput & {\n /** A file loader plugin for resolving local file references (for non browser environments) */\n fileLoader?: LoaderPlugin\n },\n): ReturnType<LoaderPlugin['exec']> {\n if ('url' in workspaceDocument) {\n return fetchUrls({ fetch: workspaceDocument.fetch }).exec(workspaceDocument.url)\n }\n\n if ('path' in workspaceDocument) {\n const loader = workspaceDocument.fileLoader\n if (!loader) {\n console.error('No loader provided for loading files')\n return Promise.resolve({\n ok: false,\n })\n }\n return loader.exec(workspaceDocument.path)\n }\n\n return Promise.resolve({\n ok: true,\n data: workspaceDocument.document,\n // string version of the raw document for hashing purposes\n raw: JSON.stringify(workspaceDocument.document),\n })\n}\n\n/**\n * Returns the base source of a workspace document if it was loaded from a URL or file.\n * If the document was loaded from a file, returns the path to the file.\n * If the document was provided directly as an object, returns undefined.\n * Which can be used to resolve relative references in the document.\n *\n * @param input - The workspace document input (either UrlDoc or ObjectDoc)\n * @returns The URL string if present, otherwise undefined\n */\nconst getDocumentSource = (input: WorkspaceDocumentInput) => {\n if ('url' in input) {\n return input.url\n }\n if ('path' in input) {\n return input.path\n }\n return undefined\n}\n\n/**\n * Configuration object for initializing a workspace store.\n * Defines the initial state and documents for the workspace.\n */\ntype WorkspaceProps = {\n /** Optional metadata for the workspace including theme, active document, etc */\n meta?: WorkspaceMeta\n /** Fetch function for retrieving documents */\n fetch?: WorkspaceDocumentInput['fetch']\n /** A list of all registered plugins for the current workspace */\n plugins?: WorkspacePlugin[]\n /** A file loader plugin for resolving local file references (for non browser environments) */\n fileLoader?: LoaderPlugin\n}\n\n/**\n * Type definition for the workspace store return object.\n * This explicit type is needed to avoid TypeScript inference limits.\n *\n * @see https://github.com/microsoft/TypeScript/issues/43817#issuecomment-827746462\n */\nexport type WorkspaceStore = {\n /**\n * The history store for the workspace\n */\n readonly history: HistoryStore\n /**\n * The auth store for the workspace\n */\n readonly auth: AuthStore\n /**\n * Returns the reactive workspace object with an additional activeDocument getter\n */\n readonly workspace: Workspace\n /**\n * Updates a specific metadata field in the workspace\n * @param key - The metadata field to update\n * @param value - The new value for the field\n * @example\n * // Update the workspace title\n * update('x-scalar-active-document', 'document-name')\n */\n update<K extends keyof WorkspaceMeta | keyof WorkspaceExtensions>(\n key: K,\n value: (WorkspaceMeta & WorkspaceExtensions)[K],\n ): void\n /**\n * Updates a specific metadata field for a given document in the workspace.\n * @param name - The document to update. Use 'active' for the currently active document, or provide a specific document name.\n * @param key - The metadata field to update, as defined in WorkspaceDocumentMeta.\n * @param value - The new value for the selected metadata field.\n * @returns true if the update was successful, false otherwise.\n * @example\n * // Update the auth metadata for the active document\n * updateDocument('active', 'x-scalar-active-auth', 'Bearer')\n * // Update the auth metadata for a specific document\n * updateDocument('document-name', 'x-scalar-active-auth', 'Bearer')\n */\n updateDocument<K extends keyof DocumentMetaExtensions>(\n name: 'active' | (string & {}),\n key: K,\n value: DocumentMetaExtensions[K],\n ): boolean\n /**\n * Replaces the content of a specific document in the workspace with the provided input.\n * This method computes the difference between the current document and the new input,\n * then applies only the necessary changes in place. The updates are applied atomically,\n * ensuring the document is updated in a single operation.\n *\n * @param documentName - The name of the document to update.\n * @param input - The new content to apply to the document (as a plain object).\n * @example\n * // Replace the content of the 'api' document with new data\n * store.replaceDocument('api', {\n * openapi: '3.1.0',\n * info: { title: 'Updated API', version: '1.0.1' },\n * paths: {},\n * })\n */\n replaceDocument(documentName: string, input: Record<string, unknown>): Promise<void>\n /**\n * Resolves a reference in the active document by following the provided path and resolving any external $ref references.\n * This method traverses the document structure following the given path and resolves any $ref references it encounters.\n * During resolution, it sets a loading status and updates the reference with the resolved content.\n *\n * @param path - Array of strings representing the path to the reference (e.g. ['paths', '/users', 'get', 'responses', '200'])\n * @throws Error if the path is invalid or empty\n * @example\n * // Resolve a reference in the active document\n * resolve(['paths', '/users', 'get', 'responses', '200'])\n */\n resolve(path: string[]): Promise<unknown>\n /**\n * Adds a new document to the workspace\n * @param document - The document content to add. This should be a valid OpenAPI/Swagger document or other supported format\n * @param meta - Metadata for the document, including its name and other properties defined in WorkspaceDocumentMeta\n * @example\n * // Add a new OpenAPI document to the workspace\n * store.addDocument({\n * name: 'name',\n * document: {\n * openapi: '3.0.0',\n * info: { title: 'title' },\n * },\n * meta: {\n * 'x-scalar-active-auth': 'Bearer',\n * 'x-scalar-selected-server': 'production'\n * }\n * })\n */\n addDocument(input: WorkspaceDocumentInput, navigationOptions?: NavigationOptions): Promise<boolean>\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This method removes the document from the workspace along with all related data including:\n * - The document itself from the workspace documents map\n * - Original document data\n * - Intermediate document data (saved local versions)\n * - Document-specific configuration\n * - Document overrides\n * - Extra document configurations\n *\n * If the deleted document was the active document, the active document is automatically\n * reset to the first remaining document in the workspace, or undefined if no documents remain.\n *\n * The deletion is automatically tracked by the workspace change detection system,\n * and appropriate events will be fired to notify registered plugins.\n *\n * @param documentName - The name of the document to delete\n * @returns void\n *\n * @example\n * // Delete the document named 'api'\n * store.deleteDocument('api')\n *\n * @example\n * // Delete multiple documents\n * ['api', 'petstore'].forEach(name => store.deleteDocument(name))\n */\n deleteDocument(documentName: string): void\n /**\n * Exports the specified document in the requested format.\n *\n * This method serializes the most recently saved local version of the document (from the intermediateDocuments map)\n * to either JSON or YAML. The exported document reflects the last locally saved state, including any edits\n * that have been saved but not yet synced to a remote registry. Runtime/in-memory changes that have not been saved\n * will not be included.\n *\n * @param documentName - The name of the document to export.\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The document as a string in the requested format, or undefined if the document does not exist.\n *\n * @example\n * // Export a document as JSON\n * const jsonString = store.exportDocument('api', 'json')\n *\n * // Export a document as YAML\n * const yamlString = store.exportDocument('api', 'yaml')\n */\n exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Exports the currently active document in the requested format.\n *\n * This is a convenience method that exports the active document (determined by the workspace's\n * activeDocument extension) without requiring the caller to specify the document name.\n * The exported document reflects the last locally saved state, including any edits that have\n * been saved but not yet synced to a remote registry.\n *\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The active document as a string in the requested format, or undefined if no active document exists.\n *\n * @example\n * // Export the active document as JSON\n * const jsonString = store.exportActiveDocument('json')\n *\n * // Export the active document as YAML\n * const yamlString = store.exportActiveDocument('yaml')\n */\n exportActiveDocument(format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Saves the current state of the specified document to the intermediate documents map.\n *\n * This function captures the latest (reactive) state of the document from the workspace and\n * applies its changes to the corresponding entry in the `intermediateDocuments` map.\n * The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n * which may include edits not yet synced to the remote registry.\n *\n * The update is performed in-place. A deep clone of the current document\n * state is used to avoid mutating the reactive object directly.\n *\n * @param documentName - The name of the document to save.\n * @returns An array of diffs that were excluded from being applied (such as changes to ignored keys),\n * or undefined if the document does not exist or cannot be updated.\n *\n * @example\n * // Save the current state of the document named 'api'\n * const excludedDiffs = store.saveDocument('api')\n */\n saveDocument(documentName: string): Promise<unknown[] | undefined>\n /**\n * Builds the sidebar for the specified document.\n *\n * @param documentName - The name of the document to build the sidebar for\n * @returns boolean indicating if the sidebar was built successfully\n */\n buildSidebar: (documentName: string) => boolean\n /**\n * Restores the specified document to its last locally saved state.\n *\n * This method updates the current reactive document (in the workspace) with the contents of the\n * corresponding intermediate document (from the `intermediateDocuments` map), effectively discarding\n * any unsaved in-memory changes and reverting to the last saved version.\n * Vue reactivity is preserved by updating the existing reactive object in place.\n *\n * **Warning:** This operation will discard all unsaved (in-memory) changes to the specified document.\n *\n * @param documentName - The name of the document to restore.\n * @returns void\n *\n * @example\n * // Restore the document named 'api' to its last saved state\n * store.revertDocumentChanges('api')\n */\n revertDocumentChanges(documentName: string): Promise<void>\n /**\n * Commits the specified document.\n *\n * This method is intended to finalize and persist the current state of the document,\n * potentially syncing it with a remote registry or marking it as the latest committed version.\n *\n * @param documentName - The name of the document to commit.\n * @remarks\n * The actual commit logic is not implemented yet.\n */\n commitDocument(documentName: string): void\n /**\n * Exports the complete current workspace state as a plain JavaScript object.\n *\n * The returned object includes all workspace documents (with Vue reactivity removed), workspace metadata,\n * document configurations, and both the original and intermediate document maps. This object can be\n * serialized (e.g., with JSON.stringify) and later imported to fully restore the workspace\u2014including\n * all documents, their configurations, metadata, and historical states.\n *\n * @returns An `InMemoryWorkspace` object representing the entire workspace state,\n * suitable for persistence, backup, or sharing.\n */\n exportWorkspace(): InMemoryWorkspace\n /**\n * Imports a workspace from a serialized JSON string.\n *\n * This method parses the input string using the InMemoryWorkspaceSchema,\n * then updates the current workspace state, including documents, metadata,\n * and configuration, with the imported values.\n *\n * @param input - The serialized workspace JSON string to import.\n */\n loadWorkspace(input: InMemoryWorkspace): void\n /**\n * Imports a workspace from a WorkspaceSpecification object.\n *\n * This method assigns workspace metadata and adds all documents defined in the specification.\n * Each document is added using its $ref and optional overrides.\n *\n * @example\n * ```ts\n * await store.importWorkspaceFromSpecification({\n * documents: {\n * api: { $ref: '/specs/api.yaml' },\n * petstore: { $ref: '/specs/petstore.yaml' }\n * },\n * overrides: {\n * api: { config: { features: { showModels: true } } }\n * },\n * info: { title: 'My Workspace' },\n * workspace: 'v1',\n * \"x-scalar-color-mode\": true\n * })\n * ```\n *\n * @param specification - The workspace specification to import.\n */\n importWorkspaceFromSpecification(specification: WorkspaceSpecification): Promise<boolean[]>\n /**\n * Rebases a document in the workspace by refetching its origin and merging with local edits.\n *\n * This method fetches the latest version of the document (optionally with custom fetch/config),\n * calculates changes relative to the original and locally edited versions,\n * and attempts to update the workspace document while preserving user edits.\n * If automatic resolution isn't possible due to conflicts, returns a conflict list for the caller to resolve.\n * If `resolvedConflicts` are provided (e.g., after user intervention), applies them to complete the rebase.\n *\n * @param input Object specifying which document to rebase\n * @returns If there are unresolved conflicts, resolves to an object containing the list of conflicts and a method to apply user-resolved conflicts; otherwise resolves to void.\n *\n * @example\n * // Rebase a document and handle conflicts interactively\n * const result = await store.rebaseDocument({ name: 'api', fetch: customFetch });\n * if (result && result.ok) {\n * // Present conflicts to the user and collect resolutions...\n * await result.applyChanges(userResolvedConflicts);\n * }\n */\n rebaseDocument: (input: WorkspaceDocumentInput) => Promise<\n | {\n ok: false\n type: 'CORRUPTED_STATE' | 'FETCH_FAILED' | 'NO_CHANGES_DETECTED'\n message: string\n }\n | {\n ok: true\n conflicts: ReturnType<typeof merge>['conflicts']\n applyChanges: (resolvedConflicts: Difference<unknown>[]) => Promise<void>\n }\n >\n}\n\n/**\n * Creates a reactive workspace store that manages documents and their metadata.\n * The store provides functionality for accessing, updating, and resolving document references.\n *\n * @param workspaceProps - Configuration object for the workspace\n * @param workspaceProps.meta - Optional metadata for the workspace\n * @param workspaceProps.documents - Optional record of documents to initialize the workspace with\n * Documents that require asynchronous loading must be added using `1` after the store is created\n * this allows atomic awaiting and does not block page load for the store initialization\n * @returns An object containing methods and getters for managing the workspace\n */\nexport const createWorkspaceStore = (workspaceProps?: WorkspaceProps): WorkspaceStore => {\n /**\n * Holds additional configuration options for each document in the workspace.\n *\n * This can include settings that can not be persisted between sessions (not JSON serializable)\n */\n const extraDocumentConfigurations: ExtraDocumentConfigurations = {}\n\n /**\n * Notifies all workspace plugins of a workspace state change event.\n *\n * This function iterates through all registered plugins (if any) and invokes\n * their onWorkspaceStateChanges hook with the given event object.\n *\n * @param event - The workspace state change event to broadcast to plugins\n */\n const fireWorkspaceChange = (event: WorkspaceStateChangeEvent) => {\n workspaceProps?.plugins?.forEach((plugin) => plugin.hooks?.onWorkspaceStateChanges?.(event))\n }\n\n /**\n * An object containing the reactive workspace state.\n *\n * Every change to the workspace, is tracked and broadcast to all registered plugins.\n * allowing for change tracking.\n *\n * NOTE:\n * The detect changes proxy is applied separately beacause the vue reactitvity proxy have to be the outer most proxy.\n * If the order is reversed, Vue cannot properly track mutations, leading to lost reactivity and bugs.\n * By wrapping the contents with the detect changes proxy first, and then passing the result to Vue's `reactive`,\n * we ensure that Vue manages its reactivity as expected and our change detection hooks\n * are also triggered reliably.\n * Do not reverse this order\u203C\uFE0F\n */\n const workspace = reactive<Workspace>(\n createDetectChangesProxy(\n {\n ...workspaceProps?.meta,\n documents: {},\n /**\n * Returns the currently active document from the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The active document or undefined if no document is found\n */\n get activeDocument(): NonNullable<Workspace['activeDocument']> | undefined {\n return workspace.documents[getActiveDocumentName()]\n },\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n /** Document changes */\n if (type === 'documents') {\n // We are overriding the while documents object, ignore. This should not happen\n if (path.length < 2) {\n console.log('[WARN]: Overriding entire documents object is not supported')\n return\n }\n\n const documentName = path[1] as string\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Active document changes */\n if (type === 'activeDocument') {\n const documentName = getActiveDocumentName()\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n // Active document changed\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Workspace meta changes */\n const { activeDocument: _a, documents: _d, ...meta } = workspace\n const event = {\n type: 'meta',\n value: unpackProxyObject(meta, { depth: 1 }),\n } satisfies WorkspaceStateChangeEvent\n\n fireWorkspaceChange(event)\n return\n },\n },\n },\n ),\n )\n\n /**\n * An object containing all the workspace state, wrapped in a detect changes proxy.\n *\n * Every change to the workspace state (documents, configs, metadata, etc.) can be detected here,\n * allowing for change tracking.\n */\n const { originalDocuments, intermediateDocuments, overrides } = createDetectChangesProxy(\n {\n /**\n * Holds the original, unmodified documents as they were initially loaded into the workspace.\n * These documents are stored in their raw form\u2014prior to any reactive wrapping, dereferencing, or bundling.\n * This map preserves the pristine structure of each document, using deep clones to ensure that\n * subsequent mutations in the workspace do not affect the originals.\n * The originals are retained so that we can restore, compare, or sync with the remote registry as needed.\n */\n originalDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores the intermediate state of documents after local edits but before syncing with the remote registry.\n *\n * This map acts as a local \"saved\" version of the document, reflecting the user's changes after they hit \"save\".\n * The `originalDocuments` map, by contrast, always mirrors the document as it exists in the remote registry.\n *\n * Use this map to stage local changes that are ready to be propagated back to the remote registry.\n * This separation allows us to distinguish between:\n * - The last known remote version (`originalDocuments`)\n * - The latest locally saved version (`intermediateDocuments`)\n * - The current in-memory (possibly unsaved) workspace document (`workspace.documents`)\n */\n intermediateDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores per-document overrides for OpenAPI documents.\n * This object is used to override specific fields of a document\n * when you cannot (or should not) modify the source document directly.\n * For example, this enables UI-driven or temporary changes to be applied\n * on top of the original document, without mutating the source.\n * The key is the document name, and the value is a deep partial\n * OpenAPI document representing the overridden fields.\n */\n overrides: {} as InMemoryWorkspace['overrides'],\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n if (!type) {\n return\n }\n\n if (path.length < 2) {\n return\n }\n\n const documentName = path[1] as string\n if (type === 'originalDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(originalDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'intermediateDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(intermediateDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'overrides') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(overrides[documentName] ?? {}),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n },\n },\n },\n )\n\n /**\n * This store is used to track the history of requests and responses for documents and operations.\n */\n const history = createHistoryStore({\n hooks: {\n onHistoryChange: (documentName) => {\n fireWorkspaceChange({\n type: 'history',\n documentName,\n value: history.export()[documentName] ?? {},\n } satisfies WorkspaceStateChangeEvent)\n },\n },\n })\n\n /**\n * The auth store for the workspace\n */\n const auth = createAuthStore({\n hooks: {\n onAuthChange: (documentName) => {\n fireWorkspaceChange({\n type: 'auth',\n documentName,\n value: auth.export()[documentName] ?? {\n secrets: {},\n selected: { document: { selectedIndex: 0, selectedSchemes: [] }, path: {} },\n },\n } satisfies WorkspaceStateChangeEvent)\n },\n },\n })\n\n /**\n * Returns the name of the currently active document in the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The name of the active document or an empty string if no document is found\n */\n function getActiveDocumentName() {\n return workspace[extensions.workspace.activeDocument] ?? Object.keys(workspace.documents)[0] ?? ''\n }\n\n function exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean) {\n const intermediateDocument = intermediateDocuments[documentName]\n\n if (!intermediateDocument) {\n return\n }\n\n if (format === 'json') {\n return minify ? JSON.stringify(intermediateDocument) : JSON.stringify(intermediateDocument, null, 2)\n }\n\n return YAML.stringify(intermediateDocument)\n }\n\n // Save the current state of the specified document to the intermediate documents map.\n // This function captures the latest (reactive) state of the document from the workspace and\n // applies its changes to the corresponding entry in the `intermediateDocuments` map.\n // The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n // which may include edits not yet synced to the remote registry.\n async function saveDocument(documentName: string) {\n const intermediateDocument = intermediateDocuments[documentName]\n const workspaceDocument = workspace.documents[documentName]\n\n if (!workspaceDocument) {\n return\n }\n\n // Obtain the raw state of the current document to ensure accurate diffing\n const activeDocumentRaw = unpackProxyObject(workspaceDocument)\n\n // If either the intermediate or updated document is missing, do nothing\n if (!intermediateDocument || !activeDocumentRaw) {\n console.warn('Failed to save document, intermediate document and/or active document is missing')\n return\n }\n\n // Traverse the document and convert refs back to the original shape\n const updatedWithOriginalRefs = await bundle(deepClone(activeDocumentRaw), {\n plugins: [restoreOriginalRefs()],\n treeShake: false,\n urlMap: true,\n })\n\n // Apply changes from the current document to the intermediate document in place\n const excludedDiffs = applySelectiveUpdates(intermediateDocument, updatedWithOriginalRefs as UnknownObject)\n\n // Mark the document as not dirty since we are saving it\n workspaceDocument['x-scalar-is-dirty'] = false\n\n return excludedDiffs\n }\n\n // Add a document to the store synchronously from an in-memory OpenAPI document\n async function addInMemoryDocument(\n input: ObjectDoc & { initialize?: boolean; documentSource?: string; documentHash: string },\n navigationOptions?: NavigationOptions,\n ) {\n const { name, meta } = input\n const clonedRawInputDocument = measureSync('deepClone', () => deepClone(input.document))\n\n measureSync('initialize', () => {\n if (input.initialize !== false) {\n // Store the original document in the originalDocuments map\n // This is used to track the original state of the document as it was loaded into the workspace\n originalDocuments[name] = deepClone(clonedRawInputDocument)\n\n // Store the intermediate document state for local edits\n // This is used to track the last saved state of the document\n // It allows us to differentiate between the original document and the latest saved version\n // This is important for local edits that are not yet synced with the remote registry\n // The intermediate document is used to store the latest saved state of the document\n // This allows us to track changes and revert to the last saved state if needed\n intermediateDocuments[name] = deepClone(clonedRawInputDocument)\n // Store the overrides for this document, or an empty object if none are provided\n overrides[name] = input.overrides ?? {}\n // Store extra document configurations that can not be persisted\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n }\n })\n\n const inputDocument = measureSync('upgrade', () => upgrade(deepClone(clonedRawInputDocument), '3.1'))\n\n const strictDocument: UnknownObject = createMagicProxy(\n {\n ...inputDocument,\n ...meta,\n 'x-original-oas-version': originalDocuments[name]?.openapi ?? originalDocuments[name]?.swagger,\n 'x-scalar-original-document-hash': input.documentHash,\n 'x-scalar-original-source-url': input.documentSource,\n },\n { showInternal: true },\n )\n\n // If the document navigation is not already present, bundle the entire document to resolve all references.\n // This typically applies when the document is not preprocessed by the server and needs local reference resolution.\n // We need to bundle document first before we validate, so we can also validate the external references\n if (strictDocument[extensions.document.navigation] === undefined) {\n const loaders = [\n fetchUrls({\n fetch: extraDocumentConfigurations[name]?.fetch ?? workspaceProps?.fetch,\n }),\n ]\n\n // If a file loader plugin is provided, use it to resolve local file references\n // This is useful for non browser environments\n if (workspaceProps?.fileLoader) {\n loaders.push(workspaceProps.fileLoader)\n }\n\n await measureAsync(\n 'bundle',\n async () =>\n await bundle(getRaw(strictDocument), {\n treeShake: false,\n plugins: [\n ...loaders,\n normalizeRefs(),\n externalValueResolver(),\n refsEverywhere(),\n normalizeAuthSchemes(),\n syncPathParameters(),\n ],\n urlMap: true,\n origin: input.documentSource, // use the document origin (if provided) as the base URL for resolution\n }),\n )\n\n // We coerce the values only when the document is not preprocessed by the server-side-store\n const coerced = measureSync('coerceValue', () =>\n coerceValue(OpenAPIDocumentSchemaStrict, deepClone(strictDocument)),\n )\n measureSync('mergeObjects', () => mergeObjects(strictDocument, coerced))\n }\n\n const isValid = Value.Check(OpenAPIDocumentSchemaStrict, strictDocument)\n\n if (!isValid) {\n const validationErrors = Array.from(Value.Errors(OpenAPIDocumentSchemaStrict, strictDocument))\n\n console.warn('document validation errors: ')\n console.warn(\n validationErrors.map((error) => ({\n message: error.message,\n path: error.path,\n schema: error.schema,\n value: error.value,\n })),\n )\n }\n\n // Skip navigation generation if the document already has a server-side generated navigation structure\n if (strictDocument[extensions.document.navigation] === undefined) {\n const navigation = createNavigation(name, strictDocument as OpenApiDocument, navigationOptions)\n strictDocument[extensions.document.navigation] = navigation\n }\n\n // Create a proxied document with magic proxy and apply any overrides, then store it in the workspace documents map\n // We create a new proxy here in order to hide internal properties after validation and processing\n // This ensures that the workspace document only exposes the intended OpenAPI properties and extensions\n workspace.documents[name] = createOverridesProxy(createMagicProxy(getRaw(strictDocument)) as OpenApiDocument, {\n overrides: unpackProxyObject(overrides[name]),\n })\n }\n\n // Asynchronously adds a new document to the workspace by loading and validating the input.\n // If loading fails, a placeholder error document is added instead.\n async function addDocument(input: WorkspaceDocumentInput, navigationOptions?: NavigationOptions) {\n const { name, meta } = input\n\n /** Ensure we use the active proxy to fetch documents unless we have a custom fetch override */\n const fetch = getFetch({\n fetch: input.fetch ?? workspaceProps?.fetch,\n proxyUrl: workspace['x-scalar-active-proxy'] ?? undefined,\n })\n\n const resolve = await measureAsync(\n 'loadDocument',\n async () => await loadDocument({ ...input, fetch, fileLoader: workspaceProps?.fileLoader }),\n )\n\n // Log the time taken to add a document\n return await measureAsync('addDocument', async () => {\n if (!resolve.ok) {\n console.error(`Failed to fetch document '${name}': request was not successful`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n if (!isObject(resolve.data)) {\n console.error(`Failed to load document '${name}': response data is not a valid object`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n await addInMemoryDocument(\n {\n ...input,\n document: resolve.data,\n documentSource: getDocumentSource(input),\n documentHash: generateHash(resolve.raw),\n },\n navigationOptions,\n )\n\n return true\n })\n }\n\n /**\n * Builds (or updates) the navigation sidebar for the specified document.\n *\n * This method generates the sidebar navigation structure for a workspace document,\n * and attaches it to the document's metadata under the navigation extension key.\n * The document is unpacked to avoid assigning proxy objects as direct property references.\n *\n * - Only the top-level object is proxied; all child objects should be unproxied.\n * - This approach enables safe unpacking of the proxy object without recursively traversing the full object tree.\n *\n * @param documentName - The name/key of the document whose sidebar should be built.\n * @returns {boolean} True if the sidebar was built successfully, false if the document does not exist.\n */\n const buildSidebar = (documentName: string): boolean => {\n const document = workspace.documents[documentName]\n\n if (!document) {\n // Log and exit if the document does not exist in the workspace\n console.error(`Document '${documentName}' does not exist in the workspace.`)\n return false\n }\n\n // Generate the navigation structure for the sidebar.\n const navigation = createNavigation(documentName, document)\n\n // Set the computed navigation structure on the document metadata.\n document[extensions.document.navigation] = navigation\n\n return true\n }\n\n // Cache to track visited nodes during reference resolution to prevent bundling the same subtree multiple times\n // This is needed because we are doing partial bundle operations\n const visitedNodesCache = new Set()\n\n return {\n get workspace() {\n return workspace\n },\n get history() {\n return history\n },\n get auth() {\n return auth\n },\n update(key, value) {\n preventPollution(key)\n Object.assign(workspace, { [key]: value })\n },\n updateDocument<K extends keyof DocumentMetaExtensions>(\n name: 'active' | (string & {}),\n key: K,\n value: DocumentMetaExtensions[K],\n ) {\n const currentDocument = workspace.documents[name === 'active' ? getActiveDocumentName() : name]\n\n if (!currentDocument) {\n return false\n }\n\n preventPollution(key)\n Object.assign(currentDocument, { [key]: value })\n return true\n },\n async replaceDocument(documentName: string, input: Record<string, unknown>) {\n const currentDocument = workspace.documents[documentName]\n\n if (!currentDocument) {\n return console.error(`Document '${documentName}' does not exist in the workspace.`)\n }\n\n // Replace the whole document\n await addInMemoryDocument({\n name: documentName,\n document: input,\n // Preserve the current metadata\n documentSource: currentDocument['x-scalar-original-source-url'],\n documentHash: currentDocument['x-scalar-original-document-hash'],\n meta: {\n 'x-scalar-active-auth': currentDocument['x-scalar-active-auth'],\n 'x-scalar-selected-server': currentDocument['x-scalar-selected-server'],\n },\n initialize: false,\n })\n },\n resolve: (path) => {\n const activeDocument = workspace.activeDocument\n\n const target = getValueAtPath(activeDocument, path)\n\n if (!isObject(target)) {\n console.error(\n `Invalid path provided for resolution. Path: [${path.join(', ')}]. Found value of type: ${typeof target}. Expected an object.`,\n )\n return Promise.resolve()\n }\n\n // Bundle the target document with the active document as root, resolving any external references\n // and tracking resolution status through hooks\n return bundle(target, {\n root: activeDocument,\n treeShake: false,\n plugins: [fetchUrls(), loadingStatus(), externalValueResolver()],\n urlMap: true,\n visitedNodes: visitedNodesCache,\n })\n },\n addDocument,\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This function removes the document and all related data structures.\n * If the deleted document was active, it automatically selects the first remaining document.\n */\n deleteDocument: (documentName: string): void => {\n // Check if the document exists before attempting deletion\n if (!workspace.documents[documentName]) {\n return\n }\n\n // Delete the document from the workspace (this will trigger change detection events)\n delete workspace.documents[documentName]\n\n // Clean up all associated data structures\n delete originalDocuments[documentName]\n delete intermediateDocuments[documentName]\n delete overrides[documentName]\n delete extraDocumentConfigurations[documentName]\n history.clearDocumentHistory(documentName)\n auth.clearDocumentAuth(documentName)\n\n // Get remaining documents before deletion to properly set the active document\n const remainingDocuments = Object.keys(workspace.documents)\n const wasActiveDocument = workspace['x-scalar-active-document'] === documentName\n\n // Reset the active document to the first remaining one if the deleted document was the active one\n if (wasActiveDocument) {\n workspace['x-scalar-active-document'] = remainingDocuments[0] ?? undefined\n }\n\n // Fire the deleteDocument event\n fireWorkspaceChange({\n type: 'deleteDocument',\n documentName,\n })\n },\n exportDocument,\n exportActiveDocument: (format, minify) => exportDocument(getActiveDocumentName(), format, minify),\n buildSidebar,\n saveDocument,\n async revertDocumentChanges(documentName: string) {\n const workspaceDocument = workspace.documents[documentName]\n const intermediate = intermediateDocuments[documentName]\n\n if (!workspaceDocument || !intermediate) {\n return\n }\n\n await addInMemoryDocument({\n name: documentName,\n document: intermediate,\n documentSource: workspaceDocument['x-scalar-original-source-url'],\n documentHash: workspaceDocument['x-scalar-original-document-hash'],\n initialize: false,\n })\n },\n commitDocument(documentName: string) {\n // TODO: Implement commit logic\n console.warn(`Commit operation for document '${documentName}' is not implemented yet.`)\n },\n exportWorkspace() {\n const { activeDocument: _, documents, ...meta } = unpackProxyObject(workspace)\n return {\n documents: {\n ...Object.fromEntries(\n Object.entries(documents).map(([name, doc]) => [\n name,\n // Get the raw document without any proxies\n unpackProxyObject(doc),\n ]),\n ),\n },\n meta: unpackProxyObject(meta) ?? {},\n originalDocuments: unpackProxyObject(originalDocuments),\n intermediateDocuments: unpackProxyObject(intermediateDocuments),\n overrides: unpackProxyObject(overrides),\n history: history.export(),\n auth: auth.export(),\n } satisfies InMemoryWorkspace\n },\n loadWorkspace(input: InMemoryWorkspace) {\n safeAssign(\n workspace.documents,\n Object.fromEntries(\n Object.entries(input.documents).map(([name, doc]) => [\n name,\n createOverridesProxy(createMagicProxy(doc), {\n overrides: input.overrides[name],\n }),\n ]),\n ),\n )\n\n safeAssign(originalDocuments, input.originalDocuments)\n safeAssign(intermediateDocuments, input.intermediateDocuments)\n safeAssign(overrides, input.overrides)\n safeAssign(workspace, input.meta)\n history.load(input.history)\n auth.load(input.auth)\n },\n importWorkspaceFromSpecification: (specification: WorkspaceSpecification) => {\n const { documents, overrides, info: _info, workspace: _workspaceVersion, ...meta } = specification\n\n // Assign workspace metadata\n safeAssign(workspace, meta)\n\n // Add workspace documents\n return Promise.all(\n Object.entries(documents ?? {}).map(([name, doc]) =>\n addDocument({ url: doc.$ref, name, overrides: overrides?.[name] }),\n ),\n )\n },\n rebaseDocument: async (input: WorkspaceDocumentInput) => {\n const { name } = input\n\n // ---- Get the current documents\n const originalDocument = unpackProxyObject(originalDocuments[name], { depth: 1 })\n const intermediateDocument = unpackProxyObject(intermediateDocuments[name], { depth: 1 })\n // raw version without any proxies\n const activeDocument = workspace.documents[name]\n ? unpackProxyObject(workspace.documents[name], { depth: 1 })\n : undefined\n\n if (!originalDocument || !intermediateDocument || !activeDocument) {\n // If any required document state is missing, do nothing\n return {\n ok: false,\n type: 'CORRUPTED_STATE' as const,\n message: `Cannot rebase document '${name}': missing original, intermediate, or active document state`,\n }\n }\n\n // ---- Resolve input document\n const resolve = await measureAsync(\n 'loadDocument',\n async () =>\n await loadDocument({\n ...input,\n fetch: input.fetch ?? workspaceProps?.fetch,\n fileLoader: workspaceProps?.fileLoader,\n }),\n )\n\n if (!resolve.ok || !isObject(resolve.data)) {\n return {\n ok: false,\n type: 'FETCH_FAILED' as const,\n message: `Failed to fetch document '${name}': request was not successful or returned invalid data`,\n }\n }\n\n // Compare document hashes to see if the document has changed\n // When the hashes match, we can skip the rebase process\n const newHash = generateHash(resolve.raw)\n if (activeDocument['x-scalar-original-document-hash'] === newHash) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}': document hash matches the active document`,\n }\n }\n\n const newDocumentOrigin = resolve.data\n\n // ---- Override the configurations and metadata\n overrides[name] = input.overrides ?? {}\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n\n // ---- Get the new intermediate document\n const changelogAA = diff(originalDocument, newDocumentOrigin)\n\n // When there are no changes, we can return early since we don't need to do anything\n // This is not supposed to happen due to the hash check above, but just in case\n if (changelogAA.length === 0) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}' after fetching the latest version.`,\n }\n }\n\n const changelogAB = diff(originalDocument, intermediateDocument)\n\n const changesA = merge(changelogAA, changelogAB)\n\n return {\n ok: true,\n conflicts: changesA.conflicts,\n applyChanges: async (resolvedConflicts: Difference<unknown>[]) => {\n const changesetA = changesA.diffs.concat(resolvedConflicts)\n\n // Apply the changes to the original document to get the new intermediate\n const newIntermediateDocument = apply(deepClone(originalDocument), changesetA)\n intermediateDocuments[name] = newIntermediateDocument\n\n // Update the original document\n originalDocuments[name] = newDocumentOrigin\n\n // ---- Get the new active document\n const changelogBA = diff(intermediateDocument, newIntermediateDocument)\n const changelogBB = diff(intermediateDocument, activeDocument)\n\n const changesB = merge(changelogBA, changelogBB)\n\n // Auto-conflict resolution: pick only the changes from the first changeset\n // TODO: In the future, implement smarter conflict resolution if needed\n const changesetB = changesB.diffs.concat(changesB.conflicts.flatMap((it) => it[0]))\n\n const newActiveDocument = coerceValue(\n OpenAPIDocumentSchemaStrict,\n apply(deepClone(newIntermediateDocument), changesetB),\n )\n\n // add the new active document to the workspace but don't re-initialize\n await addInMemoryDocument({\n ...input,\n document: {\n ...newActiveDocument,\n // force regeneration of navigation\n // when we are rebasing, we want to ensure that the navigation is always up to date\n [extensions.document.navigation]: undefined,\n },\n documentSource: getDocumentSource(input),\n // Update the original document hash\n documentHash: generateHash(resolve.raw),\n initialize: false,\n })\n },\n }\n },\n }\n}\n\n// biome-ignore lint/performance/noBarrelFile: It's a package entry point\nexport { generateClientMutators } from '@/mutators'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["event", "overrides"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/mutators/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAM3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,6BAA6B,GACxC,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,4CAA4C,UAAU,CAAC,uCAAuC,CAAC,kBA4EhG,CAAA;AAwBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,UAAU,CAAC,6BAA6B,CAAC,+NAc7D,CAAA;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,iBAAiB,UAAU,CAAC,0BAA0B,CAAC,SAuCxD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,6CAA6C,UAAU,CAAC,6BAA6B,CAAC,SA6CvF,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,WAAW,UAAU,CAAC,6BAA6B,CAAC,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/mutators/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAM3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,6BAA6B,GACxC,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,4CAA4C,UAAU,CAAC,uCAAuC,CAAC,kBA4EhG,CAAA;AAwBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,UAAU,CAAC,6BAA6B,CAAC,+NAc7D,CAAA;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,iBAAiB,UAAU,CAAC,0BAA0B,CAAC,SAuCxD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,6CAA6C,UAAU,CAAC,6BAA6B,CAAC,SA6CvF,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,cAAc,GAAG,IAAI,EAC5B,UAAU,iBAAiB,GAAG,IAAI,EAClC,WAAW,UAAU,CAAC,6BAA6B,CAAC,SAgFrD,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,sBAGjC;IACD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAClC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CAC7B;6CAE4C,UAAU,CAAC,uCAAuC,CAAC;4CAEpD,UAAU,CAAC,sCAAsC,CAAC;oCAE1D,UAAU,CAAC,6BAA6B,CAAC;2CAElC,UAAU,CAAC,qCAAqC,CAAC;0CAElD,UAAU,CAAC,oCAAoC,CAAC;qCAErD,UAAU,CAAC,0BAA0B,CAAC;oCAEvC,UAAU,CAAC,6BAA6B,CAAC;oCAEzC,UAAU,CAAC,6BAA6B,CAAC;CAG5E,CAAA"}
|
package/dist/mutators/auth.js
CHANGED
|
@@ -176,13 +176,19 @@ const deleteSecurityScheme = (store, document, { names }) => {
|
|
|
176
176
|
names.forEach((name) => {
|
|
177
177
|
delete target[name];
|
|
178
178
|
});
|
|
179
|
-
const
|
|
179
|
+
const clampIndex = (index, length) => {
|
|
180
|
+
return Math.max(0, Math.min(index, length - 1));
|
|
181
|
+
};
|
|
182
|
+
const filterSecuritySchemes = (_schemes) => {
|
|
183
|
+
const schemes = unpackProxyObject(_schemes, { depth: 1 }) ?? [];
|
|
180
184
|
return schemes.filter((scheme) => !names.some((name) => Object.keys(scheme).includes(name)));
|
|
181
185
|
};
|
|
182
186
|
const documentSelectedSecurity = store?.auth.getAuthSelectedSchemas({ type: "document", documentName });
|
|
183
187
|
if (documentSelectedSecurity) {
|
|
184
|
-
documentSelectedSecurity.selectedSchemes = filterSecuritySchemes(
|
|
185
|
-
|
|
188
|
+
documentSelectedSecurity.selectedSchemes = filterSecuritySchemes(documentSelectedSecurity.selectedSchemes);
|
|
189
|
+
documentSelectedSecurity.selectedIndex = clampIndex(
|
|
190
|
+
documentSelectedSecurity.selectedIndex,
|
|
191
|
+
documentSelectedSecurity.selectedSchemes.length
|
|
186
192
|
);
|
|
187
193
|
}
|
|
188
194
|
if (document["security"]) {
|
|
@@ -204,8 +210,10 @@ const deleteSecurityScheme = (store, document, { names }) => {
|
|
|
204
210
|
method
|
|
205
211
|
});
|
|
206
212
|
if (operationSelectedSecurity) {
|
|
207
|
-
operationSelectedSecurity.selectedSchemes = filterSecuritySchemes(
|
|
208
|
-
|
|
213
|
+
operationSelectedSecurity.selectedSchemes = filterSecuritySchemes(operationSelectedSecurity.selectedSchemes);
|
|
214
|
+
operationSelectedSecurity.selectedIndex = clampIndex(
|
|
215
|
+
operationSelectedSecurity.selectedIndex,
|
|
216
|
+
operationSelectedSecurity.selectedSchemes.length
|
|
209
217
|
);
|
|
210
218
|
}
|
|
211
219
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/mutators/auth.ts"],
|
|
4
|
-
"sourcesContent": ["import type { WorkspaceStore } from '@/client'\nimport type { AuthEvents } from '@/events/definitions/auth'\nimport { generateUniqueValue } from '@/helpers/generate-unique-value'\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport { isNonOptionalSecurityRequirement } from '@/helpers/is-non-optional-security-requirement'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport type { WorkspaceDocument } from '@/schemas'\nimport type { SecurityRequirementObject } from '@/schemas/v3.1/strict/security-requirement'\nimport type { OAuth2Object } from '@/schemas/v3.1/strict/security-scheme'\n\n/**\n * Updates the selected security schemes for either the entire document or a specific operation.\n * - Adds newly created security schemes (if any) to the workspace document's components.\n * - Ensures that each new scheme name is unique within the document by using `generateUniqueValue`.\n * - Updates the `x-scalar-selected-security` property on the target (document or operation) to reflect the new set of selected security schemes.\n * - Corrects and maintains the selected index so it points to a valid security scheme.\n *\n * @param document - The workspace OpenAPI document to mutate (can be null, in which case nothing happens)\n * @param selectedSecuritySchemes - The current list of selected security scheme objects\n * @param create - Array of new schemes to create, each with a name and a scheme definition\n * @param meta - Location to update: whole document or a specific operation (`{ type: 'document' }` or `{ type: 'operation', path, method }`)\n *\n * Example usage:\n * ```\n * updateSelectedSecuritySchemes({\n * document,\n * selectedSecuritySchemes: [{ bearerAuth: [] }],\n * create: [\n * { name: 'ApiKeyAuth', scheme: { type: 'apiKey', in: 'header', name: 'X-API-Key' } }\n * ],\n * meta: { type: 'document' }\n * })\n * ```\n */\nexport const updateSelectedSecuritySchemes = async (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { selectedRequirements, newSchemes, meta }: AuthEvents['auth:update:selected-security-schemes'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // Helper to get the target (whole document or a specific operation)\n const getTarget = () => {\n if (meta.type === 'document') {\n return store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n }\n\n return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n }\n\n const createdSecurityRequirements = await Promise.all(\n newSchemes.map(async (newScheme) => {\n const uniqueSchemeName = await generateUniqueValue({\n defaultValue: newScheme.name,\n validation: (value) => !document.components?.securitySchemes?.[value],\n maxRetries: 100,\n })\n\n if (!uniqueSchemeName) {\n return\n }\n\n // Ensure components and securitySchemes exist\n if (!document.components) {\n document.components = {}\n }\n if (!document.components.securitySchemes) {\n document.components.securitySchemes = {}\n }\n\n // Add the new security scheme definition\n document.components.securitySchemes[uniqueSchemeName] = newScheme.scheme\n\n // Return an OpenAPI Security Requirement Object for this new scheme (empty scope array)\n return {\n [uniqueSchemeName]: [],\n }\n }),\n )\n\n // Create any new security schemes required, ensuring unique names for the components\n const createdSchemes = createdSecurityRequirements.filter(Boolean) as SecurityRequirementObject[]\n\n const target = getTarget()\n\n const newSelectedSecuritySchemes = [...selectedRequirements, ...createdSchemes]\n\n const getSelectedIndex = () => {\n if (!target?.selectedIndex) {\n return 0\n }\n\n if (target.selectedIndex >= newSelectedSecuritySchemes.length) {\n return newSelectedSecuritySchemes.length - 1\n }\n\n return target.selectedIndex\n }\n\n // if (payload. === 'document') {\n if (meta.type === 'document') {\n return store?.auth.setAuthSelectedSchemas(\n { type: 'document', documentName },\n { selectedIndex: getSelectedIndex(), selectedSchemes: newSelectedSecuritySchemes },\n )\n }\n return store?.auth.setAuthSelectedSchemas(\n { type: 'operation', documentName, path: meta.path, method: meta.method },\n { selectedIndex: getSelectedIndex(), selectedSchemes: newSelectedSecuritySchemes },\n )\n}\n\n/**\n * Clears the selected security schemes from the workspace store for a document or operation.\n * This function will remove any selection state related to security (auth) for either the entire document\n * or for a specific operation if meta.type is 'operation'.\n * If the document name cannot be determined, nothing happens.\n */\nconst clearSelectedSecuritySchemes = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { meta }: AuthEvents['auth:clear:selected-security-schemes'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n if (meta.type === 'document') {\n return store?.auth.clearAuthSelectedSchemas({ type: 'document', documentName })\n }\n return store?.auth.clearAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n}\n\n/**\n * Updates a security scheme in the OpenAPI document's components object.\n * Handles updates for HTTP, API Key, and OAuth2 types, saving secret information and configuration for UI-auth flows.\n *\n * @param document - The OpenAPI workspace document (can be null)\n * @param data - The update information, including type and payload\n * @param name - The name of the security scheme in document.components.securitySchemes\n *\n * Example usage:\n *\n * updateSecurityScheme({\n * document,\n * data: {\n * type: 'http',\n * payload: {\n * username: 'user123',\n * password: 'pw123',\n * token: 'tokenval'\n * }\n * },\n * name: 'MyHttpAuth',\n * })\n */\nexport const updateSecurityScheme = (\n document: WorkspaceDocument | null,\n { payload, name }: AuthEvents['auth:update:security-scheme'],\n) => {\n const target = getResolvedRef(document?.components?.securitySchemes?.[name])\n if (!target) {\n console.error(`Security scheme ${name} not found`)\n return\n }\n\n // Handle HTTP (basic, bearer, etc.)\n if (target.type === payload.type) {\n mergeObjects(target, payload)\n }\n\n return target\n}\n\nconst updateSecuritySchemeSecrets = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { payload, name, overwrite = false }: AuthEvents['auth:update:security-scheme-secrets'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // If we want to remove properties then we should set replace to true\n if (overwrite) {\n store?.auth.setAuthSecrets(documentName, name, payload)\n return\n }\n\n const auth = store?.auth.getAuthSecrets(documentName, name)\n const result = mergeObjects(\n unpackProxyObject(auth, { depth: 1 }) ?? {},\n payload,\n ) as AuthEvents['auth:update:security-scheme-secrets']['payload']\n store?.auth.setAuthSecrets(documentName, name, result)\n}\n\nconst clearSecuritySchemeSecrets = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { name }: AuthEvents['auth:clear:security-scheme-secrets'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n store?.auth.clearAuthSecrets(documentName, name)\n}\n\n/**\n * Sets the selected authentication tab (scheme) index for the given OpenAPI document or operation.\n * - When on the document level, updates the 'selectedIndex' on the document's x-scalar-selected-security extension.\n * - When on an operation (endpoint) level, updates the 'selectedIndex' for that operation's x-scalar-selected-security.\n *\n * Also initializes the x-scalar-selected-security extension if it does not exist.\n *\n * @param document The OpenAPI document object (may be null)\n * @param index The index to set as selected\n * @param meta Context where the selection applies ('document' or specific operation)\n *\n * @example\n * // Document-level tab selection\n * updateSelectedAuthTab({\n * document,\n * index: 1,\n * meta: { type: 'document' }\n * });\n *\n * // Operation-level tab selection (e.g., GET /pets)\n * updateSelectedAuthTab({\n * document,\n * index: 0,\n * meta: { type: 'operation', path: '/pets', method: 'get' }\n * });\n */\nexport const updateSelectedAuthTab = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { index, meta }: AuthEvents['auth:update:active-index'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // Ensure the path/method exists in the document\n if (meta.type === 'operation' && document?.paths?.[meta.path]?.[meta.method] === undefined) {\n return\n }\n\n // Determine the target object for setting the auth tab index:\n // - Document/root level\n // - Operation/endpoint level (if meta specifies operation)\n const getTarget = () => {\n if (meta.type === 'document') {\n return store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n }\n return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n }\n\n const target = getTarget()\n\n if (!target) {\n if (meta.type === 'document') {\n return store?.auth.setAuthSelectedSchemas(\n { type: 'document', documentName },\n { selectedIndex: index, selectedSchemes: [] },\n )\n }\n return store?.auth.setAuthSelectedSchemas(\n { type: 'operation', documentName, path: meta.path, method: meta.method },\n { selectedIndex: index, selectedSchemes: [] },\n )\n }\n\n // Set the selected index\n target.selectedIndex = index\n}\n\n/**\n * Updates the scopes for a specific security requirement in the selected security schemes of\n * a document or operation. Also allow to add a new scope to the scheme.\n *\n * @param document - The OpenAPI WorkspaceDocument to update.\n * @param id - An array of scheme names that uniquely identifies the target security requirement.\n * For example: ['OAuth', 'ApiKeyAuth']\n * @param name - The security scheme name to update scopes for (e.g., 'OAuth').\n * @param scopes - The new list of scopes to set. For example: ['read:pets', 'write:pets']\n * @param newScopePayload - The payload to add a new scope with\n * @param meta - The context specifying whether the update is at the document-level or operation-level.\n *\n * Example usage:\n * ```ts\n * // Suppose your document (or operation) x-scalar-selected-security looks like:\n * // \"x-scalar-selected-security\": {\n * // selectedIndex: 0,\n * // selectedSchemes: [\n * // { \"OAuth\": [\"read:pets\"] },\n * // { \"ApiKeyAuth\": [] }\n * // ]\n * // }\n *\n * updateSelectedScopes({\n * document,\n * id: [\"OAuth\"], // identifies the scheme object: { \"OAuth\": [...] }\n * name: \"OAuth\", // scheme name to update within this security requirement\n * scopes: [\"write:pets\"], // new scopes array\n * meta: { type: \"document\" }\n * })\n * // After, the first scheme becomes: { \"OAuth\": [\"write:pets\"] }\n * ```\n */\nexport const updateSelectedScopes = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { id, name, scopes, newScopePayload, meta }: AuthEvents['auth:update:selected-scopes'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // Determine the target object (document or the operation)\n const getTarget = () => {\n if (meta.type === 'document') {\n return store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n }\n return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n }\n\n const target = getTarget()\n if (!target) {\n return\n }\n\n // Find the security requirement that matches the given id (scheme key names)\n // For example: if id = [\"OAuth\"], matches { OAuth: [...] }\n const scheme = target.selectedSchemes.find((scheme) => JSON.stringify(Object.keys(scheme)) === JSON.stringify(id))\n\n // If the scheme is optional, do nothing as it cannot have scopes\n if (!isNonOptionalSecurityRequirement(scheme)) {\n return\n }\n\n // If we have a new scope payload, add it to the scheme\n if (newScopePayload) {\n const securityScheme = getResolvedRef(document.components?.securitySchemes?.[name])\n const flow = (securityScheme as OAuth2Object)?.flows?.[newScopePayload?.flowType]\n if (!flow) {\n return\n }\n flow.scopes ||= {}\n\n flow.scopes[newScopePayload.name] = newScopePayload.description\n scheme[name] = [...scopes, newScopePayload.name]\n return\n }\n\n // Set the scopes array for the named security scheme within the found security requirement\n scheme[name] = scopes\n}\n\n/**\n * Deletes one or more security schemes from an OpenAPI WorkspaceDocument,\n * and removes all references to those schemes from selected security, document-level security,\n * and operation-level security/selected security (e.g., on paths).\n *\n * Example usage:\n *\n * ```ts\n * deleteSecurityScheme({\n * document, // The OpenAPI document to update\n * names: ['ApiKeyAuth', 'BearerAuth'], // The names of security schemes you want to delete\n * });\n * ```\n *\n * After running this function:\n * - The named security schemes are removed from the components.securitySchemes section.\n * - All document-level and operation-level security entries referencing those schemes are removed.\n * - Any extended x-scalar-selected-security references to those schemes are also removed.\n */\nexport const deleteSecurityScheme = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { names }: AuthEvents['auth:delete:security-scheme'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n // Early exit if there is no document to modify\n return\n }\n\n // Get the mutable reference to securitySchemes in components (may be a proxy/resolved reference)\n const target = getResolvedRef(document.components?.securitySchemes)\n\n if (!target) {\n // If there are no security schemes to delete from, return early\n return\n }\n\n // Remove each named security scheme from the components.securitySchemes object\n names.forEach((name) => {\n delete target[name]\n })\n\n // Function to remove any security requirement objects that reference given scheme names.\n const filterSecuritySchemes = (schemes: SecurityRequirementObject[]) => {\n // Remove schemes whose key is included in the `names` to be deleted.\n return schemes.filter((scheme) => !names.some((name) => Object.keys(scheme).includes(name)))\n }\n\n const documentSelectedSecurity = store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n\n // -- Remove from document-level `x-scalar-selected-security` extension, if present\n if (documentSelectedSecurity) {\n documentSelectedSecurity.selectedSchemes = filterSecuritySchemes(\n unpackProxyObject(documentSelectedSecurity.selectedSchemes, { depth: 1 }) ?? [],\n )\n }\n\n // -- Remove from document-level `security` property, if present\n if (document['security']) {\n document['security'] = filterSecuritySchemes(document['security'])\n }\n\n // -- For each path and operation, remove deleted security schemes from operation-level security and custom extension\n Object.entries(document.paths ?? {}).forEach(([path, pathItemObject]) => {\n Object.entries(pathItemObject).forEach(([method, operation]) => {\n if (typeof operation !== 'object') {\n // Ignore operations that are not objects (could be undefined)\n return\n }\n\n // Get mutable reference for the operation (could resolve $ref proxies)\n const resolvedOperation = getResolvedRef(operation)\n\n // Remove from operation-level security array\n if ('security' in resolvedOperation && resolvedOperation['security']) {\n resolvedOperation['security'] = filterSecuritySchemes(resolvedOperation['security'])\n }\n\n // // Remove from operation-level x-scalar-selected-security array\n const operationSelectedSecurity = store?.auth.getAuthSelectedSchemas({\n type: 'operation',\n documentName,\n path,\n method,\n })\n if (operationSelectedSecurity) {\n operationSelectedSecurity.selectedSchemes = filterSecuritySchemes(\n unpackProxyObject(operationSelectedSecurity.selectedSchemes, { depth: 1 }) ?? [],\n )\n }\n })\n })\n}\n\nexport const authMutatorsFactory = ({\n document,\n store,\n}: {\n document: WorkspaceDocument | null\n store: WorkspaceStore | null\n}) => {\n return {\n updateSelectedSecuritySchemes: (payload: AuthEvents['auth:update:selected-security-schemes']) =>\n updateSelectedSecuritySchemes(store, document, payload),\n clearSelectedSecuritySchemes: (payload: AuthEvents['auth:clear:selected-security-schemes']) =>\n clearSelectedSecuritySchemes(store, document, payload),\n updateSecurityScheme: (payload: AuthEvents['auth:update:security-scheme']) =>\n updateSecurityScheme(document, payload),\n updateSecuritySchemeSecrets: (payload: AuthEvents['auth:update:security-scheme-secrets']) =>\n updateSecuritySchemeSecrets(store, document, payload),\n clearSecuritySchemeSecrets: (payload: AuthEvents['auth:clear:security-scheme-secrets']) =>\n clearSecuritySchemeSecrets(store, document, payload),\n updateSelectedAuthTab: (payload: AuthEvents['auth:update:active-index']) =>\n updateSelectedAuthTab(store, document, payload),\n updateSelectedScopes: (payload: AuthEvents['auth:update:selected-scopes']) =>\n updateSelectedScopes(store, document, payload),\n deleteSecurityScheme: (payload: AuthEvents['auth:delete:security-scheme']) =>\n deleteSecurityScheme(store, document, payload),\n }\n}\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,2BAA2B;AACpC,SAAS,sBAAsB;AAC/B,SAAS,wCAAwC;AACjD,SAAS,oBAAoB;AAC7B,SAAS,yBAAyB;AA6B3B,MAAM,gCAAgC,OAC3C,OACA,UACA,EAAE,sBAAsB,YAAY,KAAK,MACtC;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAGA,QAAM,YAAY,MAAM;AACtB,QAAI,KAAK,SAAS,YAAY;AAC5B,aAAO,OAAO,KAAK,uBAAuB,EAAE,MAAM,YAAY,aAAa,CAAC;AAAA,IAC9E;AAEA,WAAO,OAAO,KAAK,uBAAuB,EAAE,MAAM,aAAa,cAAc,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO,CAAC;AAAA,EACrH;AAEA,QAAM,8BAA8B,MAAM,QAAQ;AAAA,IAChD,WAAW,IAAI,OAAO,cAAc;AAClC,YAAM,mBAAmB,MAAM,oBAAoB;AAAA,QACjD,cAAc,UAAU;AAAA,QACxB,YAAY,CAAC,UAAU,CAAC,SAAS,YAAY,kBAAkB,KAAK;AAAA,QACpE,YAAY;AAAA,MACd,CAAC;AAED,UAAI,CAAC,kBAAkB;AACrB;AAAA,MACF;AAGA,UAAI,CAAC,SAAS,YAAY;AACxB,iBAAS,aAAa,CAAC;AAAA,MACzB;AACA,UAAI,CAAC,SAAS,WAAW,iBAAiB;AACxC,iBAAS,WAAW,kBAAkB,CAAC;AAAA,MACzC;AAGA,eAAS,WAAW,gBAAgB,gBAAgB,IAAI,UAAU;AAGlE,aAAO;AAAA,QACL,CAAC,gBAAgB,GAAG,CAAC;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,iBAAiB,4BAA4B,OAAO,OAAO;AAEjE,QAAM,SAAS,UAAU;AAEzB,QAAM,6BAA6B,CAAC,GAAG,sBAAsB,GAAG,cAAc;AAE9E,QAAM,mBAAmB,MAAM;AAC7B,QAAI,CAAC,QAAQ,eAAe;AAC1B,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,iBAAiB,2BAA2B,QAAQ;AAC7D,aAAO,2BAA2B,SAAS;AAAA,IAC7C;AAEA,WAAO,OAAO;AAAA,EAChB;AAGA,MAAI,KAAK,SAAS,YAAY;AAC5B,WAAO,OAAO,KAAK;AAAA,MACjB,EAAE,MAAM,YAAY,aAAa;AAAA,MACjC,EAAE,eAAe,iBAAiB,GAAG,iBAAiB,2BAA2B;AAAA,IACnF;AAAA,EACF;AACA,SAAO,OAAO,KAAK;AAAA,IACjB,EAAE,MAAM,aAAa,cAAc,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO;AAAA,IACxE,EAAE,eAAe,iBAAiB,GAAG,iBAAiB,2BAA2B;AAAA,EACnF;AACF;AAQA,MAAM,+BAA+B,CACnC,OACA,UACA,EAAE,KAAK,MACJ;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,YAAY;AAC5B,WAAO,OAAO,KAAK,yBAAyB,EAAE,MAAM,YAAY,aAAa,CAAC;AAAA,EAChF;AACA,SAAO,OAAO,KAAK,yBAAyB,EAAE,MAAM,aAAa,cAAc,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO,CAAC;AACvH;AAyBO,MAAM,uBAAuB,CAClC,UACA,EAAE,SAAS,KAAK,MACb;AACH,QAAM,SAAS,eAAe,UAAU,YAAY,kBAAkB,IAAI,CAAC;AAC3E,MAAI,CAAC,QAAQ;AACX,YAAQ,MAAM,mBAAmB,IAAI,YAAY;AACjD;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,QAAQ,MAAM;AAChC,iBAAa,QAAQ,OAAO;AAAA,EAC9B;AAEA,SAAO;AACT;AAEA,MAAM,8BAA8B,CAClC,OACA,UACA,EAAE,SAAS,MAAM,YAAY,MAAM,MAChC;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAGA,MAAI,WAAW;AACb,WAAO,KAAK,eAAe,cAAc,MAAM,OAAO;AACtD;AAAA,EACF;AAEA,QAAM,OAAO,OAAO,KAAK,eAAe,cAAc,IAAI;AAC1D,QAAM,SAAS;AAAA,IACb,kBAAkB,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC;AAAA,IAC1C;AAAA,EACF;AACA,SAAO,KAAK,eAAe,cAAc,MAAM,MAAM;AACvD;AAEA,MAAM,6BAA6B,CACjC,OACA,UACA,EAAE,KAAK,MACJ;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAEA,SAAO,KAAK,iBAAiB,cAAc,IAAI;AACjD;AA4BO,MAAM,wBAAwB,CACnC,OACA,UACA,EAAE,OAAO,KAAK,MACX;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAGA,MAAI,KAAK,SAAS,eAAe,UAAU,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,MAAM,QAAW;AAC1F;AAAA,EACF;AAKA,QAAM,YAAY,MAAM;AACtB,QAAI,KAAK,SAAS,YAAY;AAC5B,aAAO,OAAO,KAAK,uBAAuB,EAAE,MAAM,YAAY,aAAa,CAAC;AAAA,IAC9E;AACA,WAAO,OAAO,KAAK,uBAAuB,EAAE,MAAM,aAAa,cAAc,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO,CAAC;AAAA,EACrH;AAEA,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,QAAQ;AACX,QAAI,KAAK,SAAS,YAAY;AAC5B,aAAO,OAAO,KAAK;AAAA,QACjB,EAAE,MAAM,YAAY,aAAa;AAAA,QACjC,EAAE,eAAe,OAAO,iBAAiB,CAAC,EAAE;AAAA,MAC9C;AAAA,IACF;AACA,WAAO,OAAO,KAAK;AAAA,MACjB,EAAE,MAAM,aAAa,cAAc,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO;AAAA,MACxE,EAAE,eAAe,OAAO,iBAAiB,CAAC,EAAE;AAAA,IAC9C;AAAA,EACF;AAGA,SAAO,gBAAgB;AACzB;AAmCO,MAAM,uBAAuB,CAClC,OACA,UACA,EAAE,IAAI,MAAM,QAAQ,iBAAiB,KAAK,MACvC;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAGA,QAAM,YAAY,MAAM;AACtB,QAAI,KAAK,SAAS,YAAY;AAC5B,aAAO,OAAO,KAAK,uBAAuB,EAAE,MAAM,YAAY,aAAa,CAAC;AAAA,IAC9E;AACA,WAAO,OAAO,KAAK,uBAAuB,EAAE,MAAM,aAAa,cAAc,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO,CAAC;AAAA,EACrH;AAEA,QAAM,SAAS,UAAU;AACzB,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAIA,QAAM,SAAS,OAAO,gBAAgB,KAAK,CAACA,YAAW,KAAK,UAAU,OAAO,KAAKA,OAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;AAGjH,MAAI,CAAC,iCAAiC,MAAM,GAAG;AAC7C;AAAA,EACF;AAGA,MAAI,iBAAiB;AACnB,UAAM,iBAAiB,eAAe,SAAS,YAAY,kBAAkB,IAAI,CAAC;AAClF,UAAM,OAAQ,gBAAiC,QAAQ,iBAAiB,QAAQ;AAChF,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AACA,SAAK,WAAW,CAAC;AAEjB,SAAK,OAAO,gBAAgB,IAAI,IAAI,gBAAgB;AACpD,WAAO,IAAI,IAAI,CAAC,GAAG,QAAQ,gBAAgB,IAAI;AAC/C;AAAA,EACF;AAGA,SAAO,IAAI,IAAI;AACjB;AAqBO,MAAM,uBAAuB,CAClC,OACA,UACA,EAAE,MAAM,MACL;AACH,QAAM,eAAe,WAAW,qBAAqB,GAAG;AACxD,MAAI,CAAC,cAAc;AAEjB;AAAA,EACF;AAGA,QAAM,SAAS,eAAe,SAAS,YAAY,eAAe;AAElE,MAAI,CAAC,QAAQ;AAEX;AAAA,EACF;AAGA,QAAM,QAAQ,CAAC,SAAS;AACtB,WAAO,OAAO,IAAI;AAAA,EACpB,CAAC;
|
|
4
|
+
"sourcesContent": ["import type { WorkspaceStore } from '@/client'\nimport type { AuthEvents } from '@/events/definitions/auth'\nimport { generateUniqueValue } from '@/helpers/generate-unique-value'\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport { isNonOptionalSecurityRequirement } from '@/helpers/is-non-optional-security-requirement'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport type { WorkspaceDocument } from '@/schemas'\nimport type { SecurityRequirementObject } from '@/schemas/v3.1/strict/security-requirement'\nimport type { OAuth2Object } from '@/schemas/v3.1/strict/security-scheme'\n\n/**\n * Updates the selected security schemes for either the entire document or a specific operation.\n * - Adds newly created security schemes (if any) to the workspace document's components.\n * - Ensures that each new scheme name is unique within the document by using `generateUniqueValue`.\n * - Updates the `x-scalar-selected-security` property on the target (document or operation) to reflect the new set of selected security schemes.\n * - Corrects and maintains the selected index so it points to a valid security scheme.\n *\n * @param document - The workspace OpenAPI document to mutate (can be null, in which case nothing happens)\n * @param selectedSecuritySchemes - The current list of selected security scheme objects\n * @param create - Array of new schemes to create, each with a name and a scheme definition\n * @param meta - Location to update: whole document or a specific operation (`{ type: 'document' }` or `{ type: 'operation', path, method }`)\n *\n * Example usage:\n * ```\n * updateSelectedSecuritySchemes({\n * document,\n * selectedSecuritySchemes: [{ bearerAuth: [] }],\n * create: [\n * { name: 'ApiKeyAuth', scheme: { type: 'apiKey', in: 'header', name: 'X-API-Key' } }\n * ],\n * meta: { type: 'document' }\n * })\n * ```\n */\nexport const updateSelectedSecuritySchemes = async (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { selectedRequirements, newSchemes, meta }: AuthEvents['auth:update:selected-security-schemes'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // Helper to get the target (whole document or a specific operation)\n const getTarget = () => {\n if (meta.type === 'document') {\n return store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n }\n\n return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n }\n\n const createdSecurityRequirements = await Promise.all(\n newSchemes.map(async (newScheme) => {\n const uniqueSchemeName = await generateUniqueValue({\n defaultValue: newScheme.name,\n validation: (value) => !document.components?.securitySchemes?.[value],\n maxRetries: 100,\n })\n\n if (!uniqueSchemeName) {\n return\n }\n\n // Ensure components and securitySchemes exist\n if (!document.components) {\n document.components = {}\n }\n if (!document.components.securitySchemes) {\n document.components.securitySchemes = {}\n }\n\n // Add the new security scheme definition\n document.components.securitySchemes[uniqueSchemeName] = newScheme.scheme\n\n // Return an OpenAPI Security Requirement Object for this new scheme (empty scope array)\n return {\n [uniqueSchemeName]: [],\n }\n }),\n )\n\n // Create any new security schemes required, ensuring unique names for the components\n const createdSchemes = createdSecurityRequirements.filter(Boolean) as SecurityRequirementObject[]\n\n const target = getTarget()\n\n const newSelectedSecuritySchemes = [...selectedRequirements, ...createdSchemes]\n\n const getSelectedIndex = () => {\n if (!target?.selectedIndex) {\n return 0\n }\n\n if (target.selectedIndex >= newSelectedSecuritySchemes.length) {\n return newSelectedSecuritySchemes.length - 1\n }\n\n return target.selectedIndex\n }\n\n // if (payload. === 'document') {\n if (meta.type === 'document') {\n return store?.auth.setAuthSelectedSchemas(\n { type: 'document', documentName },\n { selectedIndex: getSelectedIndex(), selectedSchemes: newSelectedSecuritySchemes },\n )\n }\n return store?.auth.setAuthSelectedSchemas(\n { type: 'operation', documentName, path: meta.path, method: meta.method },\n { selectedIndex: getSelectedIndex(), selectedSchemes: newSelectedSecuritySchemes },\n )\n}\n\n/**\n * Clears the selected security schemes from the workspace store for a document or operation.\n * This function will remove any selection state related to security (auth) for either the entire document\n * or for a specific operation if meta.type is 'operation'.\n * If the document name cannot be determined, nothing happens.\n */\nconst clearSelectedSecuritySchemes = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { meta }: AuthEvents['auth:clear:selected-security-schemes'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n if (meta.type === 'document') {\n return store?.auth.clearAuthSelectedSchemas({ type: 'document', documentName })\n }\n return store?.auth.clearAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n}\n\n/**\n * Updates a security scheme in the OpenAPI document's components object.\n * Handles updates for HTTP, API Key, and OAuth2 types, saving secret information and configuration for UI-auth flows.\n *\n * @param document - The OpenAPI workspace document (can be null)\n * @param data - The update information, including type and payload\n * @param name - The name of the security scheme in document.components.securitySchemes\n *\n * Example usage:\n *\n * updateSecurityScheme({\n * document,\n * data: {\n * type: 'http',\n * payload: {\n * username: 'user123',\n * password: 'pw123',\n * token: 'tokenval'\n * }\n * },\n * name: 'MyHttpAuth',\n * })\n */\nexport const updateSecurityScheme = (\n document: WorkspaceDocument | null,\n { payload, name }: AuthEvents['auth:update:security-scheme'],\n) => {\n const target = getResolvedRef(document?.components?.securitySchemes?.[name])\n if (!target) {\n console.error(`Security scheme ${name} not found`)\n return\n }\n\n // Handle HTTP (basic, bearer, etc.)\n if (target.type === payload.type) {\n mergeObjects(target, payload)\n }\n\n return target\n}\n\nconst updateSecuritySchemeSecrets = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { payload, name, overwrite = false }: AuthEvents['auth:update:security-scheme-secrets'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // If we want to remove properties then we should set replace to true\n if (overwrite) {\n store?.auth.setAuthSecrets(documentName, name, payload)\n return\n }\n\n const auth = store?.auth.getAuthSecrets(documentName, name)\n const result = mergeObjects(\n unpackProxyObject(auth, { depth: 1 }) ?? {},\n payload,\n ) as AuthEvents['auth:update:security-scheme-secrets']['payload']\n store?.auth.setAuthSecrets(documentName, name, result)\n}\n\nconst clearSecuritySchemeSecrets = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { name }: AuthEvents['auth:clear:security-scheme-secrets'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n store?.auth.clearAuthSecrets(documentName, name)\n}\n\n/**\n * Sets the selected authentication tab (scheme) index for the given OpenAPI document or operation.\n * - When on the document level, updates the 'selectedIndex' on the document's x-scalar-selected-security extension.\n * - When on an operation (endpoint) level, updates the 'selectedIndex' for that operation's x-scalar-selected-security.\n *\n * Also initializes the x-scalar-selected-security extension if it does not exist.\n *\n * @param document The OpenAPI document object (may be null)\n * @param index The index to set as selected\n * @param meta Context where the selection applies ('document' or specific operation)\n *\n * @example\n * // Document-level tab selection\n * updateSelectedAuthTab({\n * document,\n * index: 1,\n * meta: { type: 'document' }\n * });\n *\n * // Operation-level tab selection (e.g., GET /pets)\n * updateSelectedAuthTab({\n * document,\n * index: 0,\n * meta: { type: 'operation', path: '/pets', method: 'get' }\n * });\n */\nexport const updateSelectedAuthTab = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { index, meta }: AuthEvents['auth:update:active-index'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // Ensure the path/method exists in the document\n if (meta.type === 'operation' && document?.paths?.[meta.path]?.[meta.method] === undefined) {\n return\n }\n\n // Determine the target object for setting the auth tab index:\n // - Document/root level\n // - Operation/endpoint level (if meta specifies operation)\n const getTarget = () => {\n if (meta.type === 'document') {\n return store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n }\n return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n }\n\n const target = getTarget()\n\n if (!target) {\n if (meta.type === 'document') {\n return store?.auth.setAuthSelectedSchemas(\n { type: 'document', documentName },\n { selectedIndex: index, selectedSchemes: [] },\n )\n }\n return store?.auth.setAuthSelectedSchemas(\n { type: 'operation', documentName, path: meta.path, method: meta.method },\n { selectedIndex: index, selectedSchemes: [] },\n )\n }\n\n // Set the selected index\n target.selectedIndex = index\n}\n\n/**\n * Updates the scopes for a specific security requirement in the selected security schemes of\n * a document or operation. Also allow to add a new scope to the scheme.\n *\n * @param document - The OpenAPI WorkspaceDocument to update.\n * @param id - An array of scheme names that uniquely identifies the target security requirement.\n * For example: ['OAuth', 'ApiKeyAuth']\n * @param name - The security scheme name to update scopes for (e.g., 'OAuth').\n * @param scopes - The new list of scopes to set. For example: ['read:pets', 'write:pets']\n * @param newScopePayload - The payload to add a new scope with\n * @param meta - The context specifying whether the update is at the document-level or operation-level.\n *\n * Example usage:\n * ```ts\n * // Suppose your document (or operation) x-scalar-selected-security looks like:\n * // \"x-scalar-selected-security\": {\n * // selectedIndex: 0,\n * // selectedSchemes: [\n * // { \"OAuth\": [\"read:pets\"] },\n * // { \"ApiKeyAuth\": [] }\n * // ]\n * // }\n *\n * updateSelectedScopes({\n * document,\n * id: [\"OAuth\"], // identifies the scheme object: { \"OAuth\": [...] }\n * name: \"OAuth\", // scheme name to update within this security requirement\n * scopes: [\"write:pets\"], // new scopes array\n * meta: { type: \"document\" }\n * })\n * // After, the first scheme becomes: { \"OAuth\": [\"write:pets\"] }\n * ```\n */\nexport const updateSelectedScopes = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { id, name, scopes, newScopePayload, meta }: AuthEvents['auth:update:selected-scopes'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n return\n }\n\n // Determine the target object (document or the operation)\n const getTarget = () => {\n if (meta.type === 'document') {\n return store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n }\n return store?.auth.getAuthSelectedSchemas({ type: 'operation', documentName, path: meta.path, method: meta.method })\n }\n\n const target = getTarget()\n if (!target) {\n return\n }\n\n // Find the security requirement that matches the given id (scheme key names)\n // For example: if id = [\"OAuth\"], matches { OAuth: [...] }\n const scheme = target.selectedSchemes.find((scheme) => JSON.stringify(Object.keys(scheme)) === JSON.stringify(id))\n\n // If the scheme is optional, do nothing as it cannot have scopes\n if (!isNonOptionalSecurityRequirement(scheme)) {\n return\n }\n\n // If we have a new scope payload, add it to the scheme\n if (newScopePayload) {\n const securityScheme = getResolvedRef(document.components?.securitySchemes?.[name])\n const flow = (securityScheme as OAuth2Object)?.flows?.[newScopePayload?.flowType]\n if (!flow) {\n return\n }\n flow.scopes ||= {}\n\n flow.scopes[newScopePayload.name] = newScopePayload.description\n scheme[name] = [...scopes, newScopePayload.name]\n return\n }\n\n // Set the scopes array for the named security scheme within the found security requirement\n scheme[name] = scopes\n}\n\n/**\n * Deletes one or more security schemes from an OpenAPI WorkspaceDocument,\n * and removes all references to those schemes from selected security, document-level security,\n * and operation-level security/selected security (e.g., on paths).\n *\n * Example usage:\n *\n * ```ts\n * deleteSecurityScheme({\n * document, // The OpenAPI document to update\n * names: ['ApiKeyAuth', 'BearerAuth'], // The names of security schemes you want to delete\n * });\n * ```\n *\n * After running this function:\n * - The named security schemes are removed from the components.securitySchemes section.\n * - All document-level and operation-level security entries referencing those schemes are removed.\n * - Any extended x-scalar-selected-security references to those schemes are also removed.\n */\nexport const deleteSecurityScheme = (\n store: WorkspaceStore | null,\n document: WorkspaceDocument | null,\n { names }: AuthEvents['auth:delete:security-scheme'],\n) => {\n const documentName = document?.['x-scalar-navigation']?.name\n if (!documentName) {\n // Early exit if there is no document to modify\n return\n }\n\n // Get the mutable reference to securitySchemes in components (may be a proxy/resolved reference)\n const target = getResolvedRef(document.components?.securitySchemes)\n\n if (!target) {\n // If there are no security schemes to delete from, return early\n return\n }\n\n // Remove each named security scheme from the components.securitySchemes object\n names.forEach((name) => {\n delete target[name]\n })\n\n const clampIndex = (index: number, length: number) => {\n return Math.max(0, Math.min(index, length - 1))\n }\n\n // Function to remove any security requirement objects that reference given scheme names.\n const filterSecuritySchemes = (_schemes: SecurityRequirementObject[]) => {\n const schemes = unpackProxyObject(_schemes, { depth: 1 }) ?? []\n // Remove schemes whose key is included in the `names` to be deleted.\n return schemes.filter((scheme) => !names.some((name) => Object.keys(scheme).includes(name)))\n }\n\n const documentSelectedSecurity = store?.auth.getAuthSelectedSchemas({ type: 'document', documentName })\n\n // -- Remove from document-level `x-scalar-selected-security` extension, if present\n if (documentSelectedSecurity) {\n documentSelectedSecurity.selectedSchemes = filterSecuritySchemes(documentSelectedSecurity.selectedSchemes)\n documentSelectedSecurity.selectedIndex = clampIndex(\n documentSelectedSecurity.selectedIndex,\n documentSelectedSecurity.selectedSchemes.length,\n )\n }\n\n // -- Remove from document-level `security` property, if present\n if (document['security']) {\n document['security'] = filterSecuritySchemes(document['security'])\n }\n\n // -- For each path and operation, remove deleted security schemes from operation-level security and custom extension\n Object.entries(document.paths ?? {}).forEach(([path, pathItemObject]) => {\n Object.entries(pathItemObject).forEach(([method, operation]) => {\n if (typeof operation !== 'object') {\n // Ignore operations that are not objects (could be undefined)\n return\n }\n\n // Get mutable reference for the operation (could resolve $ref proxies)\n const resolvedOperation = getResolvedRef(operation)\n\n // Remove from operation-level security array\n if ('security' in resolvedOperation && resolvedOperation['security']) {\n resolvedOperation['security'] = filterSecuritySchemes(resolvedOperation['security'])\n }\n\n // // Remove from operation-level x-scalar-selected-security array\n const operationSelectedSecurity = store?.auth.getAuthSelectedSchemas({\n type: 'operation',\n documentName,\n path,\n method,\n })\n if (operationSelectedSecurity) {\n operationSelectedSecurity.selectedSchemes = filterSecuritySchemes(operationSelectedSecurity.selectedSchemes)\n operationSelectedSecurity.selectedIndex = clampIndex(\n operationSelectedSecurity.selectedIndex,\n operationSelectedSecurity.selectedSchemes.length,\n )\n }\n })\n })\n}\n\nexport const authMutatorsFactory = ({\n document,\n store,\n}: {\n document: WorkspaceDocument | null\n store: WorkspaceStore | null\n}) => {\n return {\n updateSelectedSecuritySchemes: (payload: AuthEvents['auth:update:selected-security-schemes']) =>\n updateSelectedSecuritySchemes(store, document, payload),\n clearSelectedSecuritySchemes: (payload: AuthEvents['auth:clear:selected-security-schemes']) =>\n clearSelectedSecuritySchemes(store, document, payload),\n updateSecurityScheme: (payload: AuthEvents['auth:update:security-scheme']) =>\n updateSecurityScheme(document, payload),\n updateSecuritySchemeSecrets: (payload: AuthEvents['auth:update:security-scheme-secrets']) =>\n updateSecuritySchemeSecrets(store, document, payload),\n clearSecuritySchemeSecrets: (payload: AuthEvents['auth:clear:security-scheme-secrets']) =>\n clearSecuritySchemeSecrets(store, document, payload),\n updateSelectedAuthTab: (payload: AuthEvents['auth:update:active-index']) =>\n updateSelectedAuthTab(store, document, payload),\n updateSelectedScopes: (payload: AuthEvents['auth:update:selected-scopes']) =>\n updateSelectedScopes(store, document, payload),\n deleteSecurityScheme: (payload: AuthEvents['auth:delete:security-scheme']) =>\n deleteSecurityScheme(store, document, payload),\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["scheme"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,OAAO,EAAE,SAAS;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,KAAG,OAapF,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { getValueAtPath } from "@scalar/helpers/object/get-value-at-path";
|
|
1
2
|
import { getSegmentsFromPath } from "@scalar/json-magic/helpers/get-segments-from-path";
|
|
2
|
-
import { getValueByPath } from "../../helpers/json-path-utils.js";
|
|
3
3
|
const getResolvedRef = (node, context) => {
|
|
4
4
|
if (node && typeof node === "object" && "$ref" in node && typeof node["$ref"] === "string" && node["$ref"].startsWith("#")) {
|
|
5
5
|
const segments = getSegmentsFromPath(node["$ref"].slice(1));
|
|
6
|
-
return getResolvedRef(
|
|
6
|
+
return getResolvedRef(getValueAtPath(context.rootNode, segments), context);
|
|
7
7
|
}
|
|
8
8
|
return node;
|
|
9
9
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/bundler/helpers.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport { getSegmentsFromPath } from '@scalar/json-magic/helpers/get-segments-from-path'\n\nimport type { UnknownObject } from '@/helpers/general'\n\n/**\n * Recursively resolves the value behind a $ref pointer within the current document tree.\n * For example, given a node with { $ref: '#/some/path' }, this will locate and return\n * the referenced node, following the $ref chain if necessary.\n *\n * @param node - The node that may be a $ref object. If not, returns the node as is.\n * @returns The resolved node if a $ref chain exists, otherwise the original node.\n */\nexport const getResolvedRef = (node: unknown, context: { rootNode: UnknownObject }): unknown => {\n if (\n node &&\n typeof node === 'object' &&\n '$ref' in node &&\n typeof node['$ref'] === 'string' &&\n node['$ref'].startsWith('#')\n ) {\n const segments = getSegmentsFromPath(node['$ref'].slice(1))\n return getResolvedRef(getValueAtPath(context.rootNode, segments), context)\n }\n // If this node isn't a $ref, return it as the resolved value\n return node\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AAY7B,MAAM,iBAAiB,CAAC,MAAe,YAAkD;AAC9F,MACE,QACA,OAAO,SAAS,YAChB,UAAU,QACV,OAAO,KAAK,MAAM,MAAM,YACxB,KAAK,MAAM,EAAE,WAAW,GAAG,GAC3B;AACA,UAAM,WAAW,oBAAoB,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC;AAC1D,WAAO,eAAe,eAAe,QAAQ,UAAU,QAAQ,GAAG,OAAO;AAAA,EAC3E;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAMhE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAahC,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,QAAO,eA+BxC,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAAO,eAwCjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,QAAO,eAuBtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB,QAAO,eAuBvC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAmBhC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAMhE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAahC,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,QAAO,eA+BxC,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAAO,eAwCjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,QAAO,eAuBtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB,QAAO,eAuBvC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAmBhC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAO,eAyErC,CAAA"}
|
|
@@ -147,6 +147,13 @@ const syncPathParameters = () => {
|
|
|
147
147
|
other: []
|
|
148
148
|
}
|
|
149
149
|
);
|
|
150
|
+
const pathItemParameters = "parameters" in node && Array.isArray(node.parameters) ? node.parameters : [];
|
|
151
|
+
for (const param of pathItemParameters) {
|
|
152
|
+
const resolved = getResolvedRef(param, context);
|
|
153
|
+
if (isObject(resolved) && resolved.in === "path" && !pathParameters.find((p) => p.name === resolved.name)) {
|
|
154
|
+
pathParameters.push(resolved);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
150
157
|
const syncedParameters = syncParametersForPathChange(pathString, pathString, pathParameters);
|
|
151
158
|
const result = [...syncedParameters, ...restParameters];
|
|
152
159
|
if (result.length > 0) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/bundler/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * This file contains a collection of plugins used for the bundler.\n * Plugins defined here can extend or modify the behavior of the bundling process,\n * such as adding lifecycle hooks or custom processing logic.\n */\n\nimport { HTTP_METHODS } from '@scalar/helpers/http/http-methods'\nimport { isObject } from '@scalar/helpers/object/is-object'\nimport type { LifecyclePlugin } from '@scalar/json-magic/bundle'\n\nimport { isLocalRef } from '@/helpers/general'\nimport { syncParametersForPathChange } from '@/mutators/operation/helpers/sync-path-parameters'\nimport { getResolvedRef } from '@/plugins/bundler/helpers'\n\n/**\n * A lifecycle plugin that adds a `$status` property to nodes during resolution.\n * - Sets `$status` to 'loading' when resolution starts.\n * - Sets `$status` to 'error' if resolution fails.\n * - Removes `$status` when resolution succeeds.\n */\nexport const loadingStatus = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onResolveStart: (node) => {\n node['$status'] = 'loading'\n },\n onResolveError: (node) => {\n node['$status'] = 'error'\n },\n onResolveSuccess: (node) => {\n delete node['$status']\n },\n }\n}\n\n/**\n * Lifecycle plugin to resolve and embed external content referenced by an 'externalValue' property in a node.\n *\n * When a node contains an 'externalValue' property (as a string), this plugin will:\n * - Fetch the external resource (such as a URL or file) using the fetchUrls plugin.\n * - If the fetch is successful, assign the fetched data to the node's 'value' property.\n *\n * This is useful for inlining external content (like examples or schemas) into the OpenAPI document during bundling.\n *\n * @param node - The node being processed, which may contain an 'externalValue' property.\n */\nexport const externalValueResolver = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onAfterNodeProcess: async (node, context) => {\n const externalValue = node['externalValue']\n const cache = context.resolutionCache\n\n // Only process if 'externalValue' is a string\n if (typeof externalValue !== 'string') {\n return\n }\n\n const loader = context.loaders.find((it) => it.validate(externalValue))\n\n // We can not process the external value\n if (!loader) {\n return\n }\n\n if (!cache.has(externalValue)) {\n cache.set(externalValue, loader.exec(externalValue))\n }\n\n const result = await cache.get(externalValue)\n\n // If fetch is successful, assign the data to the node's 'value' property\n if (result?.ok) {\n node['value'] = result.data\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to resolve $ref on any object, including non-standard locations like the info object.\n *\n * This plugin will:\n * - Detect if a node contains a $ref property (as a string).\n * - If the node is under the 'info' path, attempt to resolve the reference using fetchUrls.\n * - Replace the node's properties with the resolved data if successful.\n *\n * Note: This currently only supports refs on the 'info' object and does not handle primitive types.\n */\nexport const refsEverywhere = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: async (node, context) => {\n const { path, resolutionCache, parentNode } = context\n const ref = node['$ref']\n\n // Only process nodes that have a $ref property as a string\n if (typeof ref !== 'string') {\n return\n }\n\n // Can not resolve top level refs\n if (!parentNode || !path.length) {\n return\n }\n\n const loader = context.loaders.find((it) => it.validate(ref))\n\n // Can not load the external ref\n if (!loader) {\n return\n }\n\n // Support resolving $ref on the info object\n if (path[0] === 'info') {\n // Use the cache to avoid duplicate fetches\n if (!resolutionCache.has(ref)) {\n resolutionCache.set(ref, loader.exec(ref))\n }\n\n const result = await resolutionCache.get(ref)\n\n if (result?.ok) {\n // Replace the ref with the resolved data\n parentNode[path.at(-1)!] = result.data\n }\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to restore original $ref values after processing.\n *\n * This plugin is intended to be used as a \"lifecycle\" plugin in the bundling process.\n * It operates in the `onAfterNodeProcess` hook, and its main purpose is to restore\n * the original $ref values for external references that may have been replaced or\n * rewritten during the bundling process.\n *\n * How it works:\n * - For each node processed, if the node contains a $ref property (as a string),\n * and the root document contains an \"x-ext-urls\" mapping object,\n * the plugin will attempt to restore the original $ref value.\n * - The \"x-ext-urls\" object is expected to be a mapping from the rewritten $ref\n * (e.g., a hashed or compressed reference) back to the original external URL or path.\n * - If a mapping exists for the current $ref, the plugin replaces the $ref value\n * with the original value from the mapping. If no mapping exists (e.g., for local refs),\n * the $ref value is left unchanged.\n *\n * This is useful for scenarios where you want to present or export the bundled document\n * with the original external $ref values, rather than the internal or rewritten ones.\n *\n * @returns {LifecyclePlugin} The plugin object for use in the bundler.\n */\nexport const restoreOriginalRefs = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: (node, context) => {\n const ref = node['$ref']\n const root = context.rootNode\n const extUrls = root['x-ext-urls']\n\n // Only process if $ref is a string and x-ext-urls is a valid object\n if (typeof ref !== 'string' || typeof extUrls !== 'object' || extUrls === null || !isLocalRef(ref)) {\n return\n }\n\n // Working with local refs\n\n const segments = ref.split('/')\n const key = segments.at(-1) ?? ''\n\n // Replace the $ref with the original version from the mapping,\n // or keep the current version if there is no mapping (e.g., for local refs)\n node['$ref'] = (extUrls as Record<string, string>)[key] ?? ref\n },\n }\n}\n\n/**\n * Lifecycle plugin to normalize the `scheme` property in securitySchemes to lowercase.\n *\n * Our typebox schemas require the `scheme` property to be a lowercase string.\n * This plugin ensures that any `scheme` field under `components.securitySchemes` is normalized to lowercase, fixing\n * potential user input errors such as \"Bearer\" or \"BASIC\".\n *\n * Example:\n * ```yaml\n * Before normalization:\n * components:\n * securitySchemes:\n * bearerAuth:\n * type: http\n * scheme: Bearer\n * ```\n * After normalization:\n * ```yaml\n * components:\n * securitySchemes:\n * bearerAuth:\n * type: http\n * scheme: bearer\n * ```\n */\nexport const normalizeAuthSchemes = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onAfterNodeProcess: (node, context) => {\n const { path } = context\n\n // Check if we're at components.securitySchemes.{schemeName}\n if (path.length === 3 && path[0] === 'components' && path[1] === 'securitySchemes') {\n const targetNode = getResolvedRef(node, context)\n\n // If the scheme exists and is a string, normalize to lowercase if not already\n if (\n typeof targetNode === 'object' &&\n targetNode !== null &&\n 'scheme' in targetNode &&\n typeof targetNode['scheme'] === 'string' &&\n targetNode['scheme'].toLowerCase() !== targetNode['scheme']\n ) {\n targetNode['scheme'] = targetNode['scheme'].toLowerCase()\n }\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to normalize $ref nodes:\n * Ensures that for any non-schema object containing a $ref, only $ref,\n * summary, description, and $status properties are preserved.\n * This keeps $ref references clean and predictable for downstream consumers.\n */\nexport const normalizeRefs = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: (node, context) => {\n const { path } = context\n\n // If the node is a $ref and we are not on the schema object, we need to normalize the $ref\n if (typeof node['$ref'] === 'string' && !(path[0] === 'components' && path[1] === 'schemas')) {\n // Remove any other properties from the node and only keep the '$ref', 'summary', 'description' and '$status'\n const keepProperties = new Set(['$ref', 'summary', 'description', '$status'])\n\n Object.keys(node).forEach((key) => {\n if (!keepProperties.has(key)) {\n delete node[key]\n }\n })\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to sync path parameters for all operations under a path item.\n *\n * When processing a path item (e.g., '/users/{id}'), this plugin will:\n * - Extract path variables from the path string\n * - For each HTTP method operation (get, post, put, delete, etc.)\n * - Sync the operation's parameters to match the path variables\n * - Preserve existing parameter configurations when possible\n *\n * This ensures that path parameters are always in sync with the path string,\n * even after bundling or other transformations.\n */\nexport const syncPathParameters = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: (node, context) => {\n const { path } = context\n\n // Only process path items (e.g., paths -> /users/{id} -> operations)\n if (path.length !== 2 || path[0] !== 'paths' || typeof path[1] !== 'string') {\n return\n }\n\n const pathString = path[1]\n\n // Sync parameters for each operation method\n for (const method of HTTP_METHODS) {\n const operation = getResolvedRef(node[method], context)\n\n if (!isObject(operation)) {\n continue\n }\n\n const existingParameters =\n 'parameters' in operation && Array.isArray(operation.parameters) ? operation.parameters : []\n\n const { path: pathParameters, other: restParameters } = existingParameters.reduce<{\n path: any[]\n other: any[]\n }>(\n (acc, param) => {\n const resolved = getResolvedRef(param, context)\n\n if (!isObject(resolved)) {\n return acc\n }\n\n if (resolved.in === 'path') {\n acc.path.push(resolved)\n return acc\n }\n acc.other.push(param)\n return acc\n },\n {\n path: [],\n other: [],\n },\n )\n\n // Sync path parameters using the same path for old and new\n // This ensures parameters match the current path string\n const syncedParameters = syncParametersForPathChange(pathString, pathString, pathParameters)\n\n const result = [...syncedParameters, ...restParameters]\n\n if (result.length > 0) {\n operation.parameters = result\n }\n }\n },\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * This file contains a collection of plugins used for the bundler.\n * Plugins defined here can extend or modify the behavior of the bundling process,\n * such as adding lifecycle hooks or custom processing logic.\n */\n\nimport { HTTP_METHODS } from '@scalar/helpers/http/http-methods'\nimport { isObject } from '@scalar/helpers/object/is-object'\nimport type { LifecyclePlugin } from '@scalar/json-magic/bundle'\n\nimport { isLocalRef } from '@/helpers/general'\nimport { syncParametersForPathChange } from '@/mutators/operation/helpers/sync-path-parameters'\nimport { getResolvedRef } from '@/plugins/bundler/helpers'\n\n/**\n * A lifecycle plugin that adds a `$status` property to nodes during resolution.\n * - Sets `$status` to 'loading' when resolution starts.\n * - Sets `$status` to 'error' if resolution fails.\n * - Removes `$status` when resolution succeeds.\n */\nexport const loadingStatus = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onResolveStart: (node) => {\n node['$status'] = 'loading'\n },\n onResolveError: (node) => {\n node['$status'] = 'error'\n },\n onResolveSuccess: (node) => {\n delete node['$status']\n },\n }\n}\n\n/**\n * Lifecycle plugin to resolve and embed external content referenced by an 'externalValue' property in a node.\n *\n * When a node contains an 'externalValue' property (as a string), this plugin will:\n * - Fetch the external resource (such as a URL or file) using the fetchUrls plugin.\n * - If the fetch is successful, assign the fetched data to the node's 'value' property.\n *\n * This is useful for inlining external content (like examples or schemas) into the OpenAPI document during bundling.\n *\n * @param node - The node being processed, which may contain an 'externalValue' property.\n */\nexport const externalValueResolver = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onAfterNodeProcess: async (node, context) => {\n const externalValue = node['externalValue']\n const cache = context.resolutionCache\n\n // Only process if 'externalValue' is a string\n if (typeof externalValue !== 'string') {\n return\n }\n\n const loader = context.loaders.find((it) => it.validate(externalValue))\n\n // We can not process the external value\n if (!loader) {\n return\n }\n\n if (!cache.has(externalValue)) {\n cache.set(externalValue, loader.exec(externalValue))\n }\n\n const result = await cache.get(externalValue)\n\n // If fetch is successful, assign the data to the node's 'value' property\n if (result?.ok) {\n node['value'] = result.data\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to resolve $ref on any object, including non-standard locations like the info object.\n *\n * This plugin will:\n * - Detect if a node contains a $ref property (as a string).\n * - If the node is under the 'info' path, attempt to resolve the reference using fetchUrls.\n * - Replace the node's properties with the resolved data if successful.\n *\n * Note: This currently only supports refs on the 'info' object and does not handle primitive types.\n */\nexport const refsEverywhere = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: async (node, context) => {\n const { path, resolutionCache, parentNode } = context\n const ref = node['$ref']\n\n // Only process nodes that have a $ref property as a string\n if (typeof ref !== 'string') {\n return\n }\n\n // Can not resolve top level refs\n if (!parentNode || !path.length) {\n return\n }\n\n const loader = context.loaders.find((it) => it.validate(ref))\n\n // Can not load the external ref\n if (!loader) {\n return\n }\n\n // Support resolving $ref on the info object\n if (path[0] === 'info') {\n // Use the cache to avoid duplicate fetches\n if (!resolutionCache.has(ref)) {\n resolutionCache.set(ref, loader.exec(ref))\n }\n\n const result = await resolutionCache.get(ref)\n\n if (result?.ok) {\n // Replace the ref with the resolved data\n parentNode[path.at(-1)!] = result.data\n }\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to restore original $ref values after processing.\n *\n * This plugin is intended to be used as a \"lifecycle\" plugin in the bundling process.\n * It operates in the `onAfterNodeProcess` hook, and its main purpose is to restore\n * the original $ref values for external references that may have been replaced or\n * rewritten during the bundling process.\n *\n * How it works:\n * - For each node processed, if the node contains a $ref property (as a string),\n * and the root document contains an \"x-ext-urls\" mapping object,\n * the plugin will attempt to restore the original $ref value.\n * - The \"x-ext-urls\" object is expected to be a mapping from the rewritten $ref\n * (e.g., a hashed or compressed reference) back to the original external URL or path.\n * - If a mapping exists for the current $ref, the plugin replaces the $ref value\n * with the original value from the mapping. If no mapping exists (e.g., for local refs),\n * the $ref value is left unchanged.\n *\n * This is useful for scenarios where you want to present or export the bundled document\n * with the original external $ref values, rather than the internal or rewritten ones.\n *\n * @returns {LifecyclePlugin} The plugin object for use in the bundler.\n */\nexport const restoreOriginalRefs = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: (node, context) => {\n const ref = node['$ref']\n const root = context.rootNode\n const extUrls = root['x-ext-urls']\n\n // Only process if $ref is a string and x-ext-urls is a valid object\n if (typeof ref !== 'string' || typeof extUrls !== 'object' || extUrls === null || !isLocalRef(ref)) {\n return\n }\n\n // Working with local refs\n\n const segments = ref.split('/')\n const key = segments.at(-1) ?? ''\n\n // Replace the $ref with the original version from the mapping,\n // or keep the current version if there is no mapping (e.g., for local refs)\n node['$ref'] = (extUrls as Record<string, string>)[key] ?? ref\n },\n }\n}\n\n/**\n * Lifecycle plugin to normalize the `scheme` property in securitySchemes to lowercase.\n *\n * Our typebox schemas require the `scheme` property to be a lowercase string.\n * This plugin ensures that any `scheme` field under `components.securitySchemes` is normalized to lowercase, fixing\n * potential user input errors such as \"Bearer\" or \"BASIC\".\n *\n * Example:\n * ```yaml\n * Before normalization:\n * components:\n * securitySchemes:\n * bearerAuth:\n * type: http\n * scheme: Bearer\n * ```\n * After normalization:\n * ```yaml\n * components:\n * securitySchemes:\n * bearerAuth:\n * type: http\n * scheme: bearer\n * ```\n */\nexport const normalizeAuthSchemes = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onAfterNodeProcess: (node, context) => {\n const { path } = context\n\n // Check if we're at components.securitySchemes.{schemeName}\n if (path.length === 3 && path[0] === 'components' && path[1] === 'securitySchemes') {\n const targetNode = getResolvedRef(node, context)\n\n // If the scheme exists and is a string, normalize to lowercase if not already\n if (\n typeof targetNode === 'object' &&\n targetNode !== null &&\n 'scheme' in targetNode &&\n typeof targetNode['scheme'] === 'string' &&\n targetNode['scheme'].toLowerCase() !== targetNode['scheme']\n ) {\n targetNode['scheme'] = targetNode['scheme'].toLowerCase()\n }\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to normalize $ref nodes:\n * Ensures that for any non-schema object containing a $ref, only $ref,\n * summary, description, and $status properties are preserved.\n * This keeps $ref references clean and predictable for downstream consumers.\n */\nexport const normalizeRefs = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: (node, context) => {\n const { path } = context\n\n // If the node is a $ref and we are not on the schema object, we need to normalize the $ref\n if (typeof node['$ref'] === 'string' && !(path[0] === 'components' && path[1] === 'schemas')) {\n // Remove any other properties from the node and only keep the '$ref', 'summary', 'description' and '$status'\n const keepProperties = new Set(['$ref', 'summary', 'description', '$status'])\n\n Object.keys(node).forEach((key) => {\n if (!keepProperties.has(key)) {\n delete node[key]\n }\n })\n }\n },\n }\n}\n\n/**\n * Lifecycle plugin to sync path parameters for all operations under a path item.\n *\n * When processing a path item (e.g., '/users/{id}'), this plugin will:\n * - Extract path variables from the path string\n * - For each HTTP method operation (get, post, put, delete, etc.)\n * - Sync the operation's parameters to match the path variables\n * - Preserve existing parameter configurations when possible\n *\n * This ensures that path parameters are always in sync with the path string,\n * even after bundling or other transformations.\n */\nexport const syncPathParameters = (): LifecyclePlugin => {\n return {\n type: 'lifecycle',\n onBeforeNodeProcess: (node, context) => {\n const { path } = context\n\n // Only process path items (e.g., paths -> /users/{id} -> operations)\n if (path.length !== 2 || path[0] !== 'paths' || typeof path[1] !== 'string') {\n return\n }\n\n const pathString = path[1]\n\n // Sync parameters for each operation method\n for (const method of HTTP_METHODS) {\n const operation = getResolvedRef(node[method], context)\n\n if (!isObject(operation)) {\n continue\n }\n\n const existingParameters =\n 'parameters' in operation && Array.isArray(operation.parameters) ? operation.parameters : []\n\n const { path: pathParameters, other: restParameters } = existingParameters.reduce<{\n path: any[]\n other: any[]\n }>(\n (acc, param) => {\n const resolved = getResolvedRef(param, context)\n\n if (!isObject(resolved)) {\n return acc\n }\n\n if (resolved.in === 'path') {\n acc.path.push(resolved)\n return acc\n }\n acc.other.push(param)\n return acc\n },\n {\n path: [],\n other: [],\n },\n )\n\n // Include path-item level path parameters as fallbacks for any that the operation does not declare.\n // Without this, syncParametersForPathChange would create bare `{ name, in: 'path' }` params,\n // losing description, schema, required, etc. from the path-item definition.\n const pathItemParameters = 'parameters' in node && Array.isArray(node.parameters) ? node.parameters : []\n\n for (const param of pathItemParameters) {\n const resolved = getResolvedRef(param, context)\n\n if (isObject(resolved) && resolved.in === 'path' && !pathParameters.find((p) => p.name === resolved.name)) {\n pathParameters.push(resolved)\n }\n }\n\n // Sync path parameters using the same path for old and new\n // This ensures parameters match the current path string\n const syncedParameters = syncParametersForPathChange(pathString, pathString, pathParameters)\n\n const result = [...syncedParameters, ...restParameters]\n\n if (result.length > 0) {\n operation.parameters = result\n }\n }\n },\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import { cwd } from "node:process";
|
|
3
|
+
import { parseJsonPointerSegments } from "@scalar/helpers/json/parse-json-pointer-segments";
|
|
4
|
+
import { getValueAtPath } from "@scalar/helpers/object/get-value-at-path";
|
|
3
5
|
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
4
6
|
import { escapeJsonPointer } from "@scalar/json-magic/helpers/escape-json-pointer";
|
|
5
7
|
import { upgrade } from "@scalar/openapi-upgrader";
|
|
@@ -10,7 +12,6 @@ import { coerceValue } from "./schemas/typebox-coerce.js";
|
|
|
10
12
|
import {
|
|
11
13
|
OpenAPIDocumentSchema
|
|
12
14
|
} from "./schemas/v3.1/strict/openapi-document.js";
|
|
13
|
-
import { getValueByPath, parseJsonPointer } from "./helpers/json-path-utils.js";
|
|
14
15
|
const DEFAULT_ASSETS_FOLDER = "assets";
|
|
15
16
|
const WORKSPACE_FILE_NAME = "scalar-workspace.json";
|
|
16
17
|
const httpMethods = /* @__PURE__ */ new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
@@ -202,7 +203,21 @@ async function createServerWorkspaceStore(workspaceProps) {
|
|
|
202
203
|
* @returns The chunk data if found, undefined otherwise
|
|
203
204
|
*/
|
|
204
205
|
get: (pointer) => {
|
|
205
|
-
|
|
206
|
+
const pointerPath = (() => {
|
|
207
|
+
if (pointer.startsWith("#")) {
|
|
208
|
+
return pointer.slice(1);
|
|
209
|
+
}
|
|
210
|
+
if (pointer.startsWith("/")) {
|
|
211
|
+
return pointer;
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
return new URL(pointer).pathname;
|
|
215
|
+
} catch {
|
|
216
|
+
return pointer;
|
|
217
|
+
}
|
|
218
|
+
})();
|
|
219
|
+
const path = parseJsonPointerSegments(pointerPath).map(escapeJsonPointer);
|
|
220
|
+
return getValueAtPath(assets, path);
|
|
206
221
|
},
|
|
207
222
|
/**
|
|
208
223
|
* Adds a new document to the workspace asynchronously.
|
package/dist/server.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/server.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'node:fs/promises'\nimport { cwd } from 'node:process'\n\nimport type { LoaderPlugin } from '@scalar/json-magic/bundle'\nimport { fetchUrls, readFiles } from '@scalar/json-magic/bundle/plugins/node'\nimport { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer'\nimport { upgrade } from '@scalar/openapi-upgrader'\n\nimport { keyOf } from '@/helpers/general'\nimport { createNavigation } from '@/navigation'\nimport type { NavigationOptions } from '@/navigation/get-navigation-options'\nimport { extensions } from '@/schemas/extensions'\nimport type { TraversedDocument } from '@/schemas/navigation'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n type ComponentsObject,\n OpenAPIDocumentSchema,\n type OpenApiDocument,\n type OperationObject,\n type PathsObject,\n} from '@/schemas/v3.1/strict/openapi-document'\n\nimport { getValueByPath, parseJsonPointer } from './helpers/json-path-utils'\nimport type { WorkspaceDocumentMeta, WorkspaceMeta } from './schemas/workspace'\n\nconst DEFAULT_ASSETS_FOLDER = 'assets'\nexport const WORKSPACE_FILE_NAME = 'scalar-workspace.json'\n\ntype WorkspaceDocumentMetaInput = {\n name: string\n meta?: WorkspaceDocumentMeta\n}\n\ntype UrlDoc = { url: string } & WorkspaceDocumentMetaInput\ntype FileDoc = { path: string } & WorkspaceDocumentMetaInput\ntype ObjectDoc = { document: Record<string, unknown> } & WorkspaceDocumentMetaInput\n\ntype WorkspaceDocumentInput = UrlDoc | ObjectDoc | FileDoc\n\ntype CreateServerWorkspaceStoreBase = {\n documents: WorkspaceDocumentInput[]\n meta?: WorkspaceMeta\n navigationOptions?: NavigationOptions\n}\ntype CreateServerWorkspaceStore =\n | ({\n directory?: string\n mode: 'static'\n } & CreateServerWorkspaceStoreBase)\n | ({\n baseUrl: string\n mode: 'ssr'\n } & CreateServerWorkspaceStoreBase)\n\nconst httpMethods = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'])\n\n/**\n * Filters an OpenAPI PathsObject to only include standard HTTP methods.\n * Removes any vendor extensions or other non-HTTP properties.\n *\n * @param paths - The OpenAPI PathsObject to filter\n * @returns A new PathsObject containing only standard HTTP methods\n *\n * @example\n * Input: {\n * \"/users\": {\n * \"get\": {...},\n * \"x-custom\": {...},\n * \"post\": {...}\n * }\n * }\n * Output: {\n * \"/users\": {\n * \"get\": {...},\n * \"post\": {...}\n * }\n * }\n */\nexport function filterHttpMethodsOnly(paths: PathsObject): Record<string, Record<string, OperationObject>> {\n const result: Record<string, Record<string, OperationObject>> = {}\n\n // Todo: skip extension properties\n for (const [path, methods] of Object.entries(paths)) {\n if (!methods) {\n continue\n }\n\n const filteredMethods: Record<string, any> = {}\n\n for (const [method, operation] of Object.entries(methods)) {\n if (httpMethods.has(method.toLowerCase())) {\n filteredMethods[method] = operation\n }\n }\n\n if (Object.keys(filteredMethods).length > 0) {\n result[path] = filteredMethods\n }\n }\n\n return result\n}\n\n/**\n * Escapes path keys in an OpenAPI PathsObject to be JSON Pointer compatible.\n * This is necessary because OpenAPI paths can contain characters that need to be escaped\n * when used as JSON Pointer references (like '/' and '~').\n *\n * @example\n * Input: { \"/users/{id}\": { ... } }\n * Output: { \"/users~1{id}\": { ... } }\n */\nexport function escapePaths(\n paths: Record<string, Record<string, OperationObject>>,\n): Record<string, Record<string, OperationObject>> {\n const result: Record<string, Record<string, OperationObject>> = {}\n\n Object.keys(paths).forEach((path) => {\n if (paths[path]) {\n result[escapeJsonPointer(path)] = paths[path]\n }\n })\n\n return result\n}\n\n/**\n * Externalizes components by turning them into refs.\n */\nexport function externalizeComponentReferences(\n document: OpenApiDocument,\n meta: { mode: 'ssr'; name: string; baseUrl: string } | { mode: 'static'; name: string; directory: string },\n) {\n const result: Record<string, any> = {}\n\n if (!document.components) {\n return result\n }\n\n Object.entries(document.components).forEach(([type, component]) => {\n if (!component || typeof component !== 'object') {\n return\n }\n\n result[type] = {}\n Object.keys(component).forEach((name) => {\n const ref =\n meta.mode === 'ssr'\n ? `${meta.baseUrl}/${meta.name}/components/${type}/${name}#`\n : `./chunks/${meta.name}/components/${type}/${name}.json#`\n\n result[type][name] = { '$ref': ref, $global: true }\n })\n })\n\n return result\n}\n\n/**\n * Externalizes paths operations by turning them into refs.\n */\nexport function externalizePathReferences(\n document: OpenApiDocument,\n meta: { mode: 'ssr'; name: string; baseUrl: string } | { mode: 'static'; name: string; directory: string },\n) {\n const result: Record<string, any> = {}\n\n if (!document.paths) {\n return result\n }\n\n Object.entries(document.paths).forEach(([path, pathItem]) => {\n if (!pathItem || typeof pathItem !== 'object') {\n return\n }\n\n const pathItemRecord = pathItem as Record<string, unknown>\n\n result[path] = {}\n\n const escapedPath = escapeJsonPointer(path)\n\n keyOf(pathItemRecord).forEach((type) => {\n if (httpMethods.has(type)) {\n const ref =\n meta.mode === 'ssr'\n ? `${meta.baseUrl}/${meta.name}/operations/${escapedPath}/${type}#`\n : `./chunks/${meta.name}/operations/${escapedPath}/${type}.json#`\n\n result[path][type] = { '$ref': ref, $global: true }\n } else {\n result[path][type] = pathItemRecord[type]\n }\n })\n })\n\n return result\n}\n\n/**\n * Resolves a workspace document from various input sources (URL, local file, or direct document object).\n *\n * @param workspaceDocument - The document input to resolve, which can be:\n * - A URL to fetch the document from\n * - A local file path to read the document from\n * - A direct document object\n * @returns A promise that resolves to an object containing:\n * - ok: boolean indicating if the resolution was successful\n * - data: The resolved document data\n *\n * @example\n * // Resolve from URL\n * const urlDoc = await loadDocument({ name: 'api', url: 'https://api.example.com/openapi.json' })\n *\n * // Resolve direct document\n * const directDoc = await loadDocument({\n * name: 'inline',\n * document: { openapi: '3.0.0', paths: {} }\n * })\n */\nfunction loadDocument(workspaceDocument: WorkspaceDocumentInput): ReturnType<LoaderPlugin['exec']> {\n if ('url' in workspaceDocument) {\n return fetchUrls().exec(workspaceDocument.url)\n }\n\n if ('path' in workspaceDocument) {\n return readFiles().exec(workspaceDocument.path)\n }\n\n return Promise.resolve({\n ok: true,\n data: workspaceDocument.document,\n raw: JSON.stringify(workspaceDocument.document),\n })\n}\n\n/**\n * Create server state workspace store\n */\nexport async function createServerWorkspaceStore(workspaceProps: CreateServerWorkspaceStore) {\n /**\n * Base workspace document containing essential metadata and document references.\n *\n * This workspace document provides the minimal information needed for initial rendering.\n * All components and path operations are replaced with references to enable lazy loading.\n *\n * In SSR mode, references point to API endpoints.\n * In static mode, references point to filesystem chunks.\n */\n const workspace = {\n ...workspaceProps.meta,\n documents: {} as Record<string, OpenApiDocument & { [extensions.document.navigation]: TraversedDocument }>,\n }\n\n /**\n * A map of document chunks that can be loaded asynchronously by the client.\n * Each document is split into components and operations to enable lazy loading.\n * The keys are document names and values contain the components and operations\n * for that document.\n */\n const assets = {} as Record<\n string,\n { components?: ComponentsObject; operations?: Record<string, Record<string, OperationObject>> }\n >\n\n /**\n * Adds a new document to the workspace.\n *\n * This function processes an OpenAPI document by:\n * 1. Converting it to OpenAPI 3.1 format if needed\n * 2. Separating it into reusable components and path operations\n * 3. Externalizing references based on the workspace mode (SSR or static)\n * 4. Adding the processed document to the workspace with its metadata\n *\n * The resulting document contains minimal information with externalized references\n * that will be resolved on-demand through the workspace's get() method.\n *\n * @param document - The OpenAPI document to process and add\n * @param meta - Document metadata containing the required name and optional settings\n */\n const addDocumentSync = (document: Record<string, unknown>, meta: { name: string } & WorkspaceDocumentMeta) => {\n const { name, ...documentMeta } = meta\n\n const documentV3 = coerceValue(OpenAPIDocumentSchema, upgrade(document, '3.1'))\n\n // add the assets\n assets[meta.name] = {\n components: documentV3.components,\n operations: documentV3.paths && escapePaths(filterHttpMethodsOnly(documentV3.paths)),\n }\n\n const options =\n workspaceProps.mode === 'ssr'\n ? { mode: workspaceProps.mode, name, baseUrl: workspaceProps.baseUrl }\n : { mode: workspaceProps.mode, name, directory: workspaceProps.directory ?? DEFAULT_ASSETS_FOLDER }\n\n const components = externalizeComponentReferences(documentV3, options)\n const paths = externalizePathReferences(documentV3, options)\n\n // Build the sidebar entries\n const navigation = createNavigation(name, documentV3, workspaceProps.navigationOptions)\n\n // The document is now a minimal version with externalized references to components and operations.\n // These references will be resolved asynchronously when needed through the workspace's get() method.\n workspace.documents[meta.name] = {\n ...documentMeta,\n ...documentV3,\n components,\n paths,\n [extensions.document.navigation]: navigation,\n }\n }\n\n /**\n * Adds a new document to the workspace asynchronously.\n *\n * This function:\n * 1. Loads the document using the provided input\n * 2. Checks if the document loaded successfully\n * 3. If successful, adds the document to the workspace using addDocumentSync\n *\n * @param input - The document input containing the document source and metadata\n */\n const addDocument = async (input: WorkspaceDocumentInput) => {\n const document = await loadDocument(input)\n\n if (!document.ok) {\n console.warn(`Failed to load document \"${input.name}`)\n return\n }\n\n addDocumentSync(document.data as Record<string, unknown>, { name: input.name, ...input.meta })\n }\n\n // Load and process all initial documents in parallel\n await Promise.all(workspaceProps.documents.map((document) => addDocument(document)))\n\n return {\n /**\n * Generates workspace chunks by writing components and operations to the filesystem.\n *\n * This method is only available in static mode. It creates a directory structure containing:\n * - A workspace file with metadata and document references\n * - Component chunks split by type (schemas, parameters, etc)\n * - Operation chunks split by path and HTTP method\n *\n * The generated workspace references will be relative file paths pointing to these chunks.\n *\n * @throws {Error} If called when mode is not 'static'\n */\n generateWorkspaceChunks: async () => {\n if (workspaceProps.mode !== 'static') {\n throw 'Mode has to be set to `static` to generate filesystem workspace chunks'\n }\n\n // Write the workspace document\n const basePath = `${cwd()}/${workspaceProps.directory ?? DEFAULT_ASSETS_FOLDER}`\n await fs.mkdir(basePath, { recursive: true })\n\n // Write the workspace contents on the file system\n await fs.writeFile(`${basePath}/${WORKSPACE_FILE_NAME}`, JSON.stringify(workspace))\n\n // Write the chunks\n for (const [name, { components, operations }] of Object.entries(assets)) {\n // Write the components chunks\n if (components) {\n for (const [type, component] of Object.entries(components as Record<string, Record<string, unknown>>)) {\n const componentPath = `${basePath}/chunks/${name}/components/${type}`\n await fs.mkdir(componentPath, { recursive: true })\n\n for (const [key, value] of Object.entries(component)) {\n await fs.writeFile(`${componentPath}/${key}.json`, JSON.stringify(value))\n }\n }\n }\n\n // Write the operations chunks\n if (operations) {\n for (const [path, methods] of Object.entries(operations)) {\n const operationPath = `${basePath}/chunks/${name}/operations/${path}`\n await fs.mkdir(operationPath, { recursive: true })\n\n for (const [method, operation] of Object.entries(methods)) {\n await fs.writeFile(`${operationPath}/${method}.json`, JSON.stringify(operation))\n }\n }\n }\n }\n },\n /**\n * Returns the workspace document containing metadata and all sparse documents.\n *\n * The workspace document includes:\n * - Global workspace metadata (theme, active document, etc)\n * - Document metadata and sparse document\n * - In SSR mode: References point to in-memory chunks\n * - In static mode: References point to filesystem chunks\n *\n * @returns The complete workspace document\n */\n getWorkspace: () => {\n return workspace\n },\n /**\n * Retrieves a chunk of data from the workspace using a JSON Pointer\n *\n * A JSON Pointer is a string that references a specific location in a JSON document.\n * Only components and operations chunks can be retrieved.\n *\n * @example\n * ```ts\n * // Get a component\n * get('#/document-name/components/schemas/User')\n *\n * // Get an operation\n * get('#/document-name/operations/pets/get')\n * ```\n *\n * @param pointer - The JSON Pointer string to locate the chunk\n * @returns The chunk data if found, undefined otherwise\n */\n get: (pointer: string) => {\n return getValueByPath(assets, parseJsonPointer(pointer))\n },\n /**\n * Adds a new document to the workspace asynchronously.\n *\n * This function:\n * 1. Loads the document using the provided input\n * 2. Checks if the document loaded successfully\n * 3. If successful, adds the document to the workspace using addDocumentSync\n *\n * @param input - The document input containing the document source and metadata\n */\n addDocument,\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,QAAQ;AACf,SAAS,WAAW;
|
|
4
|
+
"sourcesContent": ["import fs from 'node:fs/promises'\nimport { cwd } from 'node:process'\n\nimport { parseJsonPointerSegments } from '@scalar/helpers/json/parse-json-pointer-segments'\nimport { getValueAtPath } from '@scalar/helpers/object/get-value-at-path'\nimport type { LoaderPlugin } from '@scalar/json-magic/bundle'\nimport { fetchUrls, readFiles } from '@scalar/json-magic/bundle/plugins/node'\nimport { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer'\nimport { upgrade } from '@scalar/openapi-upgrader'\n\nimport { keyOf } from '@/helpers/general'\nimport { createNavigation } from '@/navigation'\nimport type { NavigationOptions } from '@/navigation/get-navigation-options'\nimport { extensions } from '@/schemas/extensions'\nimport type { TraversedDocument } from '@/schemas/navigation'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n type ComponentsObject,\n OpenAPIDocumentSchema,\n type OpenApiDocument,\n type OperationObject,\n type PathsObject,\n} from '@/schemas/v3.1/strict/openapi-document'\n\nimport type { WorkspaceDocumentMeta, WorkspaceMeta } from './schemas/workspace'\n\nconst DEFAULT_ASSETS_FOLDER = 'assets'\nexport const WORKSPACE_FILE_NAME = 'scalar-workspace.json'\n\ntype WorkspaceDocumentMetaInput = {\n name: string\n meta?: WorkspaceDocumentMeta\n}\n\ntype UrlDoc = { url: string } & WorkspaceDocumentMetaInput\ntype FileDoc = { path: string } & WorkspaceDocumentMetaInput\ntype ObjectDoc = { document: Record<string, unknown> } & WorkspaceDocumentMetaInput\n\ntype WorkspaceDocumentInput = UrlDoc | ObjectDoc | FileDoc\n\ntype CreateServerWorkspaceStoreBase = {\n documents: WorkspaceDocumentInput[]\n meta?: WorkspaceMeta\n navigationOptions?: NavigationOptions\n}\ntype CreateServerWorkspaceStore =\n | ({\n directory?: string\n mode: 'static'\n } & CreateServerWorkspaceStoreBase)\n | ({\n baseUrl: string\n mode: 'ssr'\n } & CreateServerWorkspaceStoreBase)\n\nconst httpMethods = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'])\n\n/**\n * Filters an OpenAPI PathsObject to only include standard HTTP methods.\n * Removes any vendor extensions or other non-HTTP properties.\n *\n * @param paths - The OpenAPI PathsObject to filter\n * @returns A new PathsObject containing only standard HTTP methods\n *\n * @example\n * Input: {\n * \"/users\": {\n * \"get\": {...},\n * \"x-custom\": {...},\n * \"post\": {...}\n * }\n * }\n * Output: {\n * \"/users\": {\n * \"get\": {...},\n * \"post\": {...}\n * }\n * }\n */\nexport function filterHttpMethodsOnly(paths: PathsObject): Record<string, Record<string, OperationObject>> {\n const result: Record<string, Record<string, OperationObject>> = {}\n\n // Todo: skip extension properties\n for (const [path, methods] of Object.entries(paths)) {\n if (!methods) {\n continue\n }\n\n const filteredMethods: Record<string, any> = {}\n\n for (const [method, operation] of Object.entries(methods)) {\n if (httpMethods.has(method.toLowerCase())) {\n filteredMethods[method] = operation\n }\n }\n\n if (Object.keys(filteredMethods).length > 0) {\n result[path] = filteredMethods\n }\n }\n\n return result\n}\n\n/**\n * Escapes path keys in an OpenAPI PathsObject to be JSON Pointer compatible.\n * This is necessary because OpenAPI paths can contain characters that need to be escaped\n * when used as JSON Pointer references (like '/' and '~').\n *\n * @example\n * Input: { \"/users/{id}\": { ... } }\n * Output: { \"/users~1{id}\": { ... } }\n */\nexport function escapePaths(\n paths: Record<string, Record<string, OperationObject>>,\n): Record<string, Record<string, OperationObject>> {\n const result: Record<string, Record<string, OperationObject>> = {}\n\n Object.keys(paths).forEach((path) => {\n if (paths[path]) {\n result[escapeJsonPointer(path)] = paths[path]\n }\n })\n\n return result\n}\n\n/**\n * Externalizes components by turning them into refs.\n */\nexport function externalizeComponentReferences(\n document: OpenApiDocument,\n meta: { mode: 'ssr'; name: string; baseUrl: string } | { mode: 'static'; name: string; directory: string },\n) {\n const result: Record<string, any> = {}\n\n if (!document.components) {\n return result\n }\n\n Object.entries(document.components).forEach(([type, component]) => {\n if (!component || typeof component !== 'object') {\n return\n }\n\n result[type] = {}\n Object.keys(component).forEach((name) => {\n const ref =\n meta.mode === 'ssr'\n ? `${meta.baseUrl}/${meta.name}/components/${type}/${name}#`\n : `./chunks/${meta.name}/components/${type}/${name}.json#`\n\n result[type][name] = { '$ref': ref, $global: true }\n })\n })\n\n return result\n}\n\n/**\n * Externalizes paths operations by turning them into refs.\n */\nexport function externalizePathReferences(\n document: OpenApiDocument,\n meta: { mode: 'ssr'; name: string; baseUrl: string } | { mode: 'static'; name: string; directory: string },\n) {\n const result: Record<string, any> = {}\n\n if (!document.paths) {\n return result\n }\n\n Object.entries(document.paths).forEach(([path, pathItem]) => {\n if (!pathItem || typeof pathItem !== 'object') {\n return\n }\n\n const pathItemRecord = pathItem as Record<string, unknown>\n\n result[path] = {}\n\n const escapedPath = escapeJsonPointer(path)\n\n keyOf(pathItemRecord).forEach((type) => {\n if (httpMethods.has(type)) {\n const ref =\n meta.mode === 'ssr'\n ? `${meta.baseUrl}/${meta.name}/operations/${escapedPath}/${type}#`\n : `./chunks/${meta.name}/operations/${escapedPath}/${type}.json#`\n\n result[path][type] = { '$ref': ref, $global: true }\n } else {\n result[path][type] = pathItemRecord[type]\n }\n })\n })\n\n return result\n}\n\n/**\n * Resolves a workspace document from various input sources (URL, local file, or direct document object).\n *\n * @param workspaceDocument - The document input to resolve, which can be:\n * - A URL to fetch the document from\n * - A local file path to read the document from\n * - A direct document object\n * @returns A promise that resolves to an object containing:\n * - ok: boolean indicating if the resolution was successful\n * - data: The resolved document data\n *\n * @example\n * // Resolve from URL\n * const urlDoc = await loadDocument({ name: 'api', url: 'https://api.example.com/openapi.json' })\n *\n * // Resolve direct document\n * const directDoc = await loadDocument({\n * name: 'inline',\n * document: { openapi: '3.0.0', paths: {} }\n * })\n */\nfunction loadDocument(workspaceDocument: WorkspaceDocumentInput): ReturnType<LoaderPlugin['exec']> {\n if ('url' in workspaceDocument) {\n return fetchUrls().exec(workspaceDocument.url)\n }\n\n if ('path' in workspaceDocument) {\n return readFiles().exec(workspaceDocument.path)\n }\n\n return Promise.resolve({\n ok: true,\n data: workspaceDocument.document,\n raw: JSON.stringify(workspaceDocument.document),\n })\n}\n\n/**\n * Create server state workspace store\n */\nexport async function createServerWorkspaceStore(workspaceProps: CreateServerWorkspaceStore) {\n /**\n * Base workspace document containing essential metadata and document references.\n *\n * This workspace document provides the minimal information needed for initial rendering.\n * All components and path operations are replaced with references to enable lazy loading.\n *\n * In SSR mode, references point to API endpoints.\n * In static mode, references point to filesystem chunks.\n */\n const workspace = {\n ...workspaceProps.meta,\n documents: {} as Record<string, OpenApiDocument & { [extensions.document.navigation]: TraversedDocument }>,\n }\n\n /**\n * A map of document chunks that can be loaded asynchronously by the client.\n * Each document is split into components and operations to enable lazy loading.\n * The keys are document names and values contain the components and operations\n * for that document.\n */\n const assets = {} as Record<\n string,\n { components?: ComponentsObject; operations?: Record<string, Record<string, OperationObject>> }\n >\n\n /**\n * Adds a new document to the workspace.\n *\n * This function processes an OpenAPI document by:\n * 1. Converting it to OpenAPI 3.1 format if needed\n * 2. Separating it into reusable components and path operations\n * 3. Externalizing references based on the workspace mode (SSR or static)\n * 4. Adding the processed document to the workspace with its metadata\n *\n * The resulting document contains minimal information with externalized references\n * that will be resolved on-demand through the workspace's get() method.\n *\n * @param document - The OpenAPI document to process and add\n * @param meta - Document metadata containing the required name and optional settings\n */\n const addDocumentSync = (document: Record<string, unknown>, meta: { name: string } & WorkspaceDocumentMeta) => {\n const { name, ...documentMeta } = meta\n\n const documentV3 = coerceValue(OpenAPIDocumentSchema, upgrade(document, '3.1'))\n\n // add the assets\n assets[meta.name] = {\n components: documentV3.components,\n operations: documentV3.paths && escapePaths(filterHttpMethodsOnly(documentV3.paths)),\n }\n\n const options =\n workspaceProps.mode === 'ssr'\n ? { mode: workspaceProps.mode, name, baseUrl: workspaceProps.baseUrl }\n : { mode: workspaceProps.mode, name, directory: workspaceProps.directory ?? DEFAULT_ASSETS_FOLDER }\n\n const components = externalizeComponentReferences(documentV3, options)\n const paths = externalizePathReferences(documentV3, options)\n\n // Build the sidebar entries\n const navigation = createNavigation(name, documentV3, workspaceProps.navigationOptions)\n\n // The document is now a minimal version with externalized references to components and operations.\n // These references will be resolved asynchronously when needed through the workspace's get() method.\n workspace.documents[meta.name] = {\n ...documentMeta,\n ...documentV3,\n components,\n paths,\n [extensions.document.navigation]: navigation,\n }\n }\n\n /**\n * Adds a new document to the workspace asynchronously.\n *\n * This function:\n * 1. Loads the document using the provided input\n * 2. Checks if the document loaded successfully\n * 3. If successful, adds the document to the workspace using addDocumentSync\n *\n * @param input - The document input containing the document source and metadata\n */\n const addDocument = async (input: WorkspaceDocumentInput) => {\n const document = await loadDocument(input)\n\n if (!document.ok) {\n console.warn(`Failed to load document \"${input.name}`)\n return\n }\n\n addDocumentSync(document.data as Record<string, unknown>, { name: input.name, ...input.meta })\n }\n\n // Load and process all initial documents in parallel\n await Promise.all(workspaceProps.documents.map((document) => addDocument(document)))\n\n return {\n /**\n * Generates workspace chunks by writing components and operations to the filesystem.\n *\n * This method is only available in static mode. It creates a directory structure containing:\n * - A workspace file with metadata and document references\n * - Component chunks split by type (schemas, parameters, etc)\n * - Operation chunks split by path and HTTP method\n *\n * The generated workspace references will be relative file paths pointing to these chunks.\n *\n * @throws {Error} If called when mode is not 'static'\n */\n generateWorkspaceChunks: async () => {\n if (workspaceProps.mode !== 'static') {\n throw 'Mode has to be set to `static` to generate filesystem workspace chunks'\n }\n\n // Write the workspace document\n const basePath = `${cwd()}/${workspaceProps.directory ?? DEFAULT_ASSETS_FOLDER}`\n await fs.mkdir(basePath, { recursive: true })\n\n // Write the workspace contents on the file system\n await fs.writeFile(`${basePath}/${WORKSPACE_FILE_NAME}`, JSON.stringify(workspace))\n\n // Write the chunks\n for (const [name, { components, operations }] of Object.entries(assets)) {\n // Write the components chunks\n if (components) {\n for (const [type, component] of Object.entries(components as Record<string, Record<string, unknown>>)) {\n const componentPath = `${basePath}/chunks/${name}/components/${type}`\n await fs.mkdir(componentPath, { recursive: true })\n\n for (const [key, value] of Object.entries(component)) {\n await fs.writeFile(`${componentPath}/${key}.json`, JSON.stringify(value))\n }\n }\n }\n\n // Write the operations chunks\n if (operations) {\n for (const [path, methods] of Object.entries(operations)) {\n const operationPath = `${basePath}/chunks/${name}/operations/${path}`\n await fs.mkdir(operationPath, { recursive: true })\n\n for (const [method, operation] of Object.entries(methods)) {\n await fs.writeFile(`${operationPath}/${method}.json`, JSON.stringify(operation))\n }\n }\n }\n }\n },\n /**\n * Returns the workspace document containing metadata and all sparse documents.\n *\n * The workspace document includes:\n * - Global workspace metadata (theme, active document, etc)\n * - Document metadata and sparse document\n * - In SSR mode: References point to in-memory chunks\n * - In static mode: References point to filesystem chunks\n *\n * @returns The complete workspace document\n */\n getWorkspace: () => {\n return workspace\n },\n /**\n * Retrieves a chunk of data from the workspace using a JSON Pointer\n *\n * A JSON Pointer is a string that references a specific location in a JSON document.\n * Only components and operations chunks can be retrieved.\n *\n * @example\n * ```ts\n * // Get a component\n * get('#/document-name/components/schemas/User')\n *\n * // Get an operation\n * get('#/document-name/operations/pets/get')\n * ```\n *\n * @param pointer - The JSON Pointer string to locate the chunk\n * @returns The chunk data if found, undefined otherwise\n */\n get: (pointer: string) => {\n const pointerPath = (() => {\n if (pointer.startsWith('#')) {\n return pointer.slice(1)\n }\n\n if (pointer.startsWith('/')) {\n return pointer\n }\n\n try {\n return new URL(pointer).pathname\n } catch {\n return pointer\n }\n })()\n\n // Keep the path segments escaped cuz we store them on the filesystem as escaped sequences\n const path = parseJsonPointerSegments(pointerPath).map(escapeJsonPointer)\n return getValueAtPath(assets, path)\n },\n /**\n * Adds a new document to the workspace asynchronously.\n *\n * This function:\n * 1. Loads the document using the provided input\n * 2. Checks if the document loaded successfully\n * 3. If successful, adds the document to the workspace using addDocumentSync\n *\n * @param input - The document input containing the document source and metadata\n */\n addDocument,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"openapi",
|
|
17
17
|
"scalar"
|
|
18
18
|
],
|
|
19
|
-
"version": "0.35.
|
|
19
|
+
"version": "0.35.2",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
@@ -139,12 +139,12 @@
|
|
|
139
139
|
"vue": "^3.5.26",
|
|
140
140
|
"yaml": "^2.8.0",
|
|
141
141
|
"@scalar/code-highlight": "0.2.4",
|
|
142
|
-
"@scalar/helpers": "0.2.
|
|
143
|
-
"@scalar/
|
|
144
|
-
"@scalar/
|
|
145
|
-
"@scalar/
|
|
146
|
-
"@scalar/
|
|
147
|
-
"@scalar/
|
|
142
|
+
"@scalar/helpers": "0.2.17",
|
|
143
|
+
"@scalar/object-utils": "1.2.31",
|
|
144
|
+
"@scalar/json-magic": "0.11.6",
|
|
145
|
+
"@scalar/types": "0.6.9",
|
|
146
|
+
"@scalar/openapi-upgrader": "0.1.10",
|
|
147
|
+
"@scalar/snippetz": "0.6.18"
|
|
148
148
|
},
|
|
149
149
|
"devDependencies": {
|
|
150
150
|
"@google-cloud/storage": "7.16.0",
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parses a JSON Pointer string into an array of path segments
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```ts
|
|
6
|
-
* parseJsonPointer('#/components/schemas/User')
|
|
7
|
-
*
|
|
8
|
-
* ['components', 'schemas', 'User']
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
export declare function parseJsonPointer(pointer: string): string[];
|
|
12
|
-
/**
|
|
13
|
-
* Retrieves a nested value from the source document using a path array
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* getValueByPath(document, ['components', 'schemas', 'User'])
|
|
18
|
-
*
|
|
19
|
-
* { id: '123', name: 'John Doe' }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare function getValueByPath<R = unknown>(obj: any, pointer: string[]): R;
|
|
23
|
-
//# sourceMappingURL=json-path-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"json-path-utils.d.ts","sourceRoot":"","sources":["../../src/helpers/json-path-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,CAO1E"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
function parseJsonPointer(pointer) {
|
|
2
|
-
return pointer.split("/").filter((segment, index) => (index !== 0 || segment !== "#") && segment);
|
|
3
|
-
}
|
|
4
|
-
function getValueByPath(obj, pointer) {
|
|
5
|
-
return pointer.reduce((acc, part) => {
|
|
6
|
-
if (acc === void 0 || acc === null) {
|
|
7
|
-
return void 0;
|
|
8
|
-
}
|
|
9
|
-
return acc[part];
|
|
10
|
-
}, obj);
|
|
11
|
-
}
|
|
12
|
-
export {
|
|
13
|
-
getValueByPath,
|
|
14
|
-
parseJsonPointer
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=json-path-utils.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/json-path-utils.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Parses a JSON Pointer string into an array of path segments\n *\n * @example\n * ```ts\n * parseJsonPointer('#/components/schemas/User')\n *\n * ['components', 'schemas', 'User']\n * ```\n */\nexport function parseJsonPointer(pointer: string): string[] {\n return (\n pointer\n // Split on '/'\n .split('/')\n // Remove the leading '#' if present\n .filter((segment, index) => (index !== 0 || segment !== '#') && segment)\n )\n}\n\n/**\n * Retrieves a nested value from the source document using a path array\n *\n * @example\n * ```ts\n * getValueByPath(document, ['components', 'schemas', 'User'])\n *\n * { id: '123', name: 'John Doe' }\n * ```\n */\nexport function getValueByPath<R = unknown>(obj: any, pointer: string[]): R {\n return pointer.reduce((acc, part) => {\n if (acc === undefined || acc === null) {\n return undefined\n }\n return acc[part]\n }, obj)\n}\n"],
|
|
5
|
-
"mappings": "AAUO,SAAS,iBAAiB,SAA2B;AAC1D,SACE,QAEG,MAAM,GAAG,EAET,OAAO,CAAC,SAAS,WAAW,UAAU,KAAK,YAAY,QAAQ,OAAO;AAE7E;AAYO,SAAS,eAA4B,KAAU,SAAsB;AAC1E,SAAO,QAAQ,OAAO,CAAC,KAAK,SAAS;AACnC,QAAI,QAAQ,UAAa,QAAQ,MAAM;AACrC,aAAO;AAAA,IACT;AACA,WAAO,IAAI,IAAI;AAAA,EACjB,GAAG,GAAG;AACR;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|