@scalar/workspace-store 0.15.6 → 0.15.7

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @scalar/workspace-store
2
2
 
3
+ ## 0.15.7
4
+
5
+ ### Patch Changes
6
+
7
+ - a1f865c: refactor: use @scalar/openapi-upgrader
8
+ - dcf50ef: refactor: move escapeJsonPointer to @scalar/json-magic
9
+ - Updated dependencies [6221e4a]
10
+ - Updated dependencies [005fba9]
11
+ - Updated dependencies [fe46413]
12
+ - Updated dependencies [0aa6d26]
13
+ - Updated dependencies [2d612e4]
14
+ - Updated dependencies [dcf50ef]
15
+ - Updated dependencies [02085ef]
16
+ - @scalar/openapi-upgrader@0.1.0
17
+ - @scalar/types@0.2.16
18
+ - @scalar/json-magic@0.5.0
19
+ - @scalar/code-highlight@0.2.0
20
+ - @scalar/snippetz@0.4.10
21
+
3
22
  ## 0.15.6
4
23
 
5
24
  ### Patch Changes
package/dist/client.js CHANGED
@@ -3,7 +3,7 @@ import { bundle } from "@scalar/json-magic/bundle";
3
3
  import { fetchUrls } from "@scalar/json-magic/bundle/plugins/browser";
4
4
  import { apply, diff, merge } from "@scalar/json-magic/diff";
5
5
  import { createMagicProxy, getRaw } from "@scalar/json-magic/magic-proxy";
6
- import { upgrade } from "@scalar/openapi-parser";
6
+ import { upgrade } from "@scalar/openapi-upgrader";
7
7
  import { Value } from "@scalar/typebox/value";
8
8
  import { reactive } from "vue";
9
9
  import YAML from "yaml";
@@ -107,7 +107,7 @@ const createWorkspaceStore = (workspaceProps) => {
107
107
  async function addInMemoryDocument(input) {
108
108
  const { name, meta } = input;
109
109
  const cloned = measureSync("deepClone", () => deepClone(input.document));
110
- const inputDocument = measureSync("upgrade", () => upgrade(cloned).specification);
110
+ const inputDocument = measureSync("upgrade", () => upgrade(cloned, "3.1"));
111
111
  measureSync("initialize", () => {
112
112
  if (input.initialize !== false) {
113
113
  originalDocuments[name] = deepClone({ ...inputDocument });
@@ -337,7 +337,7 @@ const createWorkspaceStore = (workspaceProps) => {
337
337
  );
338
338
  },
339
339
  rebaseDocument: (documentName, newDocumentOrigin, resolvedConflicts) => {
340
- const newOrigin = upgrade(newDocumentOrigin).specification;
340
+ const newOrigin = upgrade(newDocumentOrigin, "3.1");
341
341
  const originalDocument = originalDocuments[documentName];
342
342
  const intermediateDocument = intermediateDocuments[documentName];
343
343
  const activeDocument = workspace.documents[documentName] ? getRaw(workspace.documents[documentName]) : void 0;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client.ts"],
4
- "sourcesContent": ["import { measureAsync, measureSync } from '@scalar/helpers/testing/measure'\nimport { 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-parser'\nimport type { Record } from '@scalar/typebox'\nimport { Value } from '@scalar/typebox/value'\nimport type { PartialDeep } from 'type-fest/source/partial-deep'\nimport type { RequiredDeep } from 'type-fest/source/required-deep'\nimport { reactive } from 'vue'\nimport YAML from 'yaml'\n\nimport { applySelectiveUpdates } from '@/helpers/apply-selective-updates'\nimport { deepClone } from '@/helpers/deep-clone'\nimport { type UnknownObject, isObject, safeAssign } from '@/helpers/general'\nimport { getValueByPath } from '@/helpers/json-path-utils'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { createOverridesProxy } from '@/helpers/overrides-proxy'\nimport { createNavigation } from '@/navigation'\nimport type { TraverseSpecOptions } from '@/navigation/types'\nimport { externalValueResolver, loadingStatus, refsEverywhere, restoreOriginalRefs } from '@/plugins'\nimport { getServersFromDocument } from '@/preprocessing/server'\nimport { extensions } from '@/schemas/extensions'\nimport { type InMemoryWorkspace, InMemoryWorkspaceSchema } from '@/schemas/inmemory-workspace'\nimport { defaultReferenceConfig } from '@/schemas/reference-config'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n OpenAPIDocumentSchema as OpenAPIDocumentSchemaStrict,\n type OpenApiDocument,\n} from '@/schemas/v3.1/strict/openapi-document'\nimport type { Workspace, WorkspaceDocumentMeta, WorkspaceMeta } from '@/schemas/workspace'\nimport type { WorkspaceSpecification } from '@/schemas/workspace-specification'\nimport type { Config } from '@/schemas/workspace-specification/config'\n\nexport type DocumentConfiguration = Config &\n PartialDeep<{\n 'x-scalar-reference-config': {\n tagSort: TraverseSpecOptions['tagsSorter']\n operationsSorter: TraverseSpecOptions['operationsSorter']\n getHeadingId: TraverseSpecOptions['getHeadingId']\n getOperationId: TraverseSpecOptions['getOperationId']\n getWebhookId: TraverseSpecOptions['getWebhookId']\n getModelId: TraverseSpecOptions['getModelId']\n getTagId: TraverseSpecOptions['getTagId']\n generateOperationSlug?: (details: {\n path: string\n operationId?: string\n method: string\n summary?: string\n }) => string\n generateHeadingSlug?: (details: { slug?: string }) => string\n generateTagSlug?: (details: { name?: string }) => string\n generateModelSlug?: (details: { name?: string }) => string\n generateWebhookSlug?: (details: { name: string; method: string }) => string\n }\n }>\n\ntype ExtraDocumentConfigurations = Record<\n string,\n {\n fetch: WorkspaceDocumentMetaInput['fetch']\n }\n>\n\nexport type ValidationError = {\n message: string\n path: string\n schema: unknown\n value: unknown\n}\n\nconst defaultConfig: RequiredDeep<Config> = {\n 'x-scalar-reference-config': defaultReferenceConfig,\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 /** Optional configuration options */\n config?: DocumentConfiguration\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/** 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\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 */\nasync function loadDocument(workspaceDocument: WorkspaceDocumentInput) {\n if ('url' in workspaceDocument) {\n return fetchUrls({ fetch: workspaceDocument.fetch }).exec(workspaceDocument.url)\n }\n\n return {\n ok: true as const,\n data: workspaceDocument.document,\n }\n}\n\n/**\n * Returns the origin (URL) of a workspace document if it was loaded from a URL.\n * If the document was provided directly as an object, returns undefined.\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 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 /** Workspace configuration */\n config?: Config\n /** Fetch function for retrieving documents */\n fetch?: WorkspaceDocumentInput['fetch']\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 * 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>(key: K, value: WorkspaceMeta[K]): void\n /**\n * Updates a specific metadata field in a document\n * @param name - The name of the document to update ('active' or a specific document name)\n * @param key - The metadata field to update\n * @param value - The new value for the field\n * @throws Error if the specified document doesn't exist\n * @example\n * // Update the auth of the active document\n * updateDocument('active', 'x-scalar-active-auth', 'Bearer')\n * // Update the auth of a specific document\n * updateDocument('document-name', 'x-scalar-active-auth', 'Bearer')\n */\n updateDocument<K extends keyof WorkspaceDocumentMeta>(\n name: 'active' | (string & {}),\n key: K,\n value: WorkspaceDocumentMeta[K],\n ): void\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-active-server': 'production'\n * }\n * })\n */\n addDocument(input: WorkspaceDocumentInput): Promise<void>\n /**\n * Returns the merged configuration for the active document.\n *\n * This getter merges configurations in the following order of precedence:\n * 1. Document-specific configuration (highest priority)\n * 2. Workspace-level configuration\n * 3. Default configuration (lowest priority)\n *\n * The active document is determined by the workspace's activeDocument extension,\n * falling back to the first document if none is specified.\n */\n readonly config: typeof defaultConfig\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'): 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'): 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 * 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 * Serializes the current workspace state to a JSON string for backup, persistence, or sharing.\n *\n * This method exports all workspace documents (removing Vue reactivity proxies), workspace metadata,\n * document configurations, and both the original and intermediate document states. The resulting JSON\n * can be imported later to fully restore the workspace to this exact state, including all documents\n * and their configurations.\n *\n * @returns A JSON string representing the complete workspace state.\n */\n exportWorkspace(): string\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: string): 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-dark-mode\": true\n * })\n * ```\n *\n * @param specification - The workspace specification to import.\n */\n importWorkspaceFromSpecification(specification: WorkspaceSpecification): Promise<void[]>\n /**\n * Rebases a document in the workspace with a new origin, resolving conflicts if provided.\n *\n * This method is used to rebase a document (e.g., after pulling remote changes) by applying the changes\n * from the new origin and merging them with local edits. If there are conflicts, they can be resolved\n * by providing a list of resolved conflicts.\n *\n * @param documentName - The name of the document to rebase.\n * @param newDocumentOrigin - The new origin document (as an object) to rebase onto.\n * @param resolvedConflicts - (Optional) An array of resolved conflicts to apply.\n * @returns If there are unresolved conflicts and no resolution is provided, returns the list of conflicts.\n *\n * @example\n * // Example: Rebase a document with a new origin and resolve conflicts\n * const conflicts = store.rebaseDocument('api', newOriginDoc)\n * if (conflicts && conflicts.length > 0) {\n * // User resolves conflicts here...\n * store.rebaseDocument('api', newOriginDoc, userResolvedConflicts)\n * }\n */\n rebaseDocument: (\n documentName: string,\n newDocumentOrigin: Record<string, unknown>,\n resolvedConflicts?: Difference<unknown>[],\n ) => void | ReturnType<typeof merge>['conflicts']\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 `addDocument` 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 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 const 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 const intermediateDocuments = {} as Record<string, UnknownObject>\n /**\n * A map of document configurations keyed by document name.\n * This stores the configuration options for each document in the workspace,\n * allowing for document-specific settings like navigation options, appearance,\n * and other reference configuration.\n */\n const documentConfigs: Record<string, Config> = {}\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 const overrides: InMemoryWorkspace['overrides'] = {}\n /**\n * Holds additional metadata for each document in the workspace.\n *\n * This metadata should be persisted together with the document itself.\n * It can include information such as user preferences, UI state, or other\n * per-document attributes that are not part of the OpenAPI document structure.\n */\n const documentMeta: InMemoryWorkspace['documentMeta'] = {}\n\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 // Create a reactive workspace object with proxied documents\n // Each document is wrapped in a proxy to enable reactive updates and reference resolution\n const workspace = reactive<Workspace>({\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 const activeDocumentKey =\n workspace[extensions.workspace.activeDocument] ?? Object.keys(workspace.documents)[0] ?? ''\n return workspace.documents[activeDocumentKey]\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') {\n const intermediateDocument = intermediateDocuments[documentName]\n\n if (!intermediateDocument) {\n return\n }\n\n if (format === 'json') {\n return JSON.stringify(intermediateDocument)\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 updatedDocument = getRaw(workspaceDocument)\n\n // If either the intermediate or updated document is missing, do nothing\n if (!intermediateDocument || !updatedDocument) {\n return\n }\n\n // Traverse the document and convert refs back to the original shape\n const updatedWithOriginalRefs = await bundle(deepClone(updatedDocument), {\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 return excludedDiffs\n }\n\n const processDocument = (input: OpenApiDocument, options: Config & { documentSource?: string }): OpenApiDocument => {\n // Get the servers from the document or the config and perform some mutations on them\n const servers = getServersFromDocument(options['x-scalar-reference-config']?.settings?.servers ?? input.servers, {\n baseServerUrl: options['x-scalar-reference-config']?.settings?.baseServerUrl,\n documentUrl: options.documentSource,\n })\n\n if (servers.length) {\n input.servers = servers.map((it) => ({ url: it.url, description: it.description, variables: it.variables }))\n }\n\n return input\n }\n\n // Add a document to the store synchronously from an in-memory OpenAPI document\n async function addInMemoryDocument(input: ObjectDoc & { initialize?: boolean; documentSource?: string }) {\n const { name, meta } = input\n const cloned = measureSync('deepClone', () => deepClone(input.document))\n const inputDocument = measureSync('upgrade', () => upgrade(cloned).specification)\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({ ...inputDocument })\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({ ...inputDocument })\n // Add the document config to the documentConfigs map\n documentConfigs[name] = input.config ?? {}\n // Store the overrides for this document, or an empty object if none are provided\n overrides[name] = input.overrides ?? {}\n // Store the document metadata for this document, setting the origin if provided\n documentMeta[name] = { documentSource: input.documentSource }\n // Store extra document configurations that can not be persisted\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n }\n })\n\n const strictDocument: UnknownObject = createMagicProxy({ ...inputDocument, ...meta }, { showInternal: true })\n\n strictDocument['x-original-oas-version'] = input.document.openapi ?? input.document.swagger\n\n if (strictDocument[extensions.document.navigation] === undefined) {\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 await measureAsync(\n 'bundle',\n async () =>\n await bundle(getRaw(strictDocument), {\n treeShake: false,\n plugins: [\n fetchUrls({\n fetch: extraDocumentConfigurations[name]?.fetch ?? workspaceProps?.fetch,\n }),\n externalValueResolver(),\n refsEverywhere(),\n ],\n urlMap: true,\n origin: documentMeta[name]?.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 measureAsync('mergeObjects', async () => 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 showModels = input.config?.['x-scalar-reference-config']?.features?.showModels\n\n strictDocument[extensions.document.navigation] = createNavigation(strictDocument as OpenApiDocument, {\n ...(input.config?.['x-scalar-reference-config'] ?? {}),\n hideModels: showModels === undefined ? undefined : !showModels,\n }).entries\n\n // Do some document processing\n processDocument(getRaw(strictDocument as OpenApiDocument), {\n ...input.config,\n documentSource: input.documentSource,\n })\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(\n createMagicProxy(getRaw(strictDocument)) as OpenApiDocument,\n input.overrides,\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) {\n const { name, meta } = input\n\n const resolve = await measureAsync(\n 'loadDocument',\n async () => await loadDocument({ ...input, fetch: input.fetch ?? workspaceProps?.fetch }),\n )\n\n // Log the time taken to add a document\n 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 }\n\n return\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 }\n\n return\n }\n\n await addInMemoryDocument({\n ...input,\n document: resolve.data,\n documentSource: getDocumentSource(input),\n })\n })\n }\n\n // Returns the effective document configuration for a given document name,\n // merging (in order of increasing priority): the default config, workspace-level config, and document-specific config.\n const getDocumentConfiguration = (name: string) => {\n return mergeObjects<typeof defaultConfig>(\n mergeObjects(defaultConfig, workspaceProps?.config ?? {}),\n documentConfigs[name] ?? {},\n )\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 update<K extends keyof WorkspaceMeta>(key: K, value: WorkspaceMeta[K]) {\n // @ts-ignore\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n throw new Error('Invalid key: cannot modify prototype')\n }\n Object.assign(workspace, { [key]: value })\n },\n updateDocument<K extends keyof WorkspaceDocumentMeta>(\n name: 'active' | (string & {}),\n key: K,\n value: WorkspaceDocumentMeta[K],\n ) {\n const currentDocument = workspace.documents[name === 'active' ? getActiveDocumentName() : name]\n\n if (!currentDocument) {\n throw 'Please select a valid document'\n }\n\n Object.assign(currentDocument, { [key]: value })\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 meta: {\n 'x-scalar-active-auth': currentDocument['x-scalar-active-auth'],\n 'x-scalar-active-server': currentDocument['x-scalar-active-server'],\n },\n initialize: false,\n })\n },\n resolve: async (path: string[]) => {\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\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 get config() {\n return getDocumentConfiguration(getActiveDocumentName())\n },\n exportDocument,\n exportActiveDocument: (format) => exportDocument(getActiveDocumentName(), format),\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 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 return JSON.stringify({\n documents: {\n ...Object.fromEntries(\n Object.entries(workspace.documents).map(([name, doc]) => [\n name,\n // Extract the raw document data for export, removing any Vue reactivity wrappers.\n // When importing, the document can be wrapped again in a magic proxy.\n getRaw(doc),\n ]),\n ),\n },\n meta: workspaceProps?.meta ?? {},\n documentConfigs,\n originalDocuments,\n intermediateDocuments,\n overrides,\n documentMeta,\n } satisfies InMemoryWorkspace)\n },\n loadWorkspace(input: string) {\n const result = coerceValue(InMemoryWorkspaceSchema, JSON.parse(input))\n\n // Assign the magic proxy to the documents\n safeAssign(\n workspace.documents,\n Object.fromEntries(\n Object.entries(result.documents).map(([name, doc]) => [\n name,\n createOverridesProxy(createMagicProxy(doc), result.overrides[name]),\n ]),\n ),\n )\n\n safeAssign(originalDocuments, result.originalDocuments)\n safeAssign(intermediateDocuments, result.intermediateDocuments)\n safeAssign(documentConfigs, result.documentConfigs)\n safeAssign(overrides, result.overrides)\n safeAssign(workspace, result.meta)\n safeAssign(documentMeta, result.documentMeta)\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: (documentName, newDocumentOrigin, resolvedConflicts) => {\n const newOrigin = upgrade(newDocumentOrigin).specification\n\n const originalDocument = originalDocuments[documentName]\n const intermediateDocument = intermediateDocuments[documentName]\n const activeDocument = workspace.documents[documentName] ? getRaw(workspace.documents[documentName]) : undefined // raw version without any overrides\n\n if (!originalDocument || !intermediateDocument || !activeDocument) {\n // If any required document state is missing, do nothing\n return console.error('[ERROR]: Specified document is missing or internal corrupted workspace state')\n }\n\n // ---- Get the new intermediate document\n const changelogAA = diff(originalDocument, newOrigin)\n const changelogAB = diff(originalDocument, intermediateDocument)\n\n const changesA = merge(changelogAA, changelogAB)\n\n if (resolvedConflicts === undefined) {\n // If there are conflicts, return the list of conflicts for user resolution\n return changesA.conflicts\n }\n\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[documentName] = newIntermediateDocument\n\n // Update the original document\n originalDocuments[documentName] = newOrigin\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 // Update the active document to the new value\n workspace.documents[documentName] = createOverridesProxy(\n createMagicProxy({ ...newActiveDocument }),\n overrides[documentName],\n )\n return\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 { measureAsync, measureSync } from '@scalar/helpers/testing/measure'\nimport { 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/source/partial-deep'\nimport type { RequiredDeep } from 'type-fest/source/required-deep'\nimport { reactive } from 'vue'\nimport YAML from 'yaml'\n\nimport { applySelectiveUpdates } from '@/helpers/apply-selective-updates'\nimport { deepClone } from '@/helpers/deep-clone'\nimport { type UnknownObject, isObject, safeAssign } from '@/helpers/general'\nimport { getValueByPath } from '@/helpers/json-path-utils'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { createOverridesProxy } from '@/helpers/overrides-proxy'\nimport { createNavigation } from '@/navigation'\nimport type { TraverseSpecOptions } from '@/navigation/types'\nimport { externalValueResolver, loadingStatus, refsEverywhere, restoreOriginalRefs } from '@/plugins'\nimport { getServersFromDocument } from '@/preprocessing/server'\nimport { extensions } from '@/schemas/extensions'\nimport { type InMemoryWorkspace, InMemoryWorkspaceSchema } from '@/schemas/inmemory-workspace'\nimport { defaultReferenceConfig } from '@/schemas/reference-config'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n OpenAPIDocumentSchema as OpenAPIDocumentSchemaStrict,\n type OpenApiDocument,\n} from '@/schemas/v3.1/strict/openapi-document'\nimport type { Workspace, WorkspaceDocumentMeta, WorkspaceMeta } from '@/schemas/workspace'\nimport type { WorkspaceSpecification } from '@/schemas/workspace-specification'\nimport type { Config } from '@/schemas/workspace-specification/config'\n\nexport type DocumentConfiguration = Config &\n PartialDeep<{\n 'x-scalar-reference-config': {\n tagSort: TraverseSpecOptions['tagsSorter']\n operationsSorter: TraverseSpecOptions['operationsSorter']\n getHeadingId: TraverseSpecOptions['getHeadingId']\n getOperationId: TraverseSpecOptions['getOperationId']\n getWebhookId: TraverseSpecOptions['getWebhookId']\n getModelId: TraverseSpecOptions['getModelId']\n getTagId: TraverseSpecOptions['getTagId']\n generateOperationSlug?: (details: {\n path: string\n operationId?: string\n method: string\n summary?: string\n }) => string\n generateHeadingSlug?: (details: { slug?: string }) => string\n generateTagSlug?: (details: { name?: string }) => string\n generateModelSlug?: (details: { name?: string }) => string\n generateWebhookSlug?: (details: { name: string; method: string }) => string\n }\n }>\n\ntype ExtraDocumentConfigurations = Record<\n string,\n {\n fetch: WorkspaceDocumentMetaInput['fetch']\n }\n>\n\nexport type ValidationError = {\n message: string\n path: string\n schema: unknown\n value: unknown\n}\n\nconst defaultConfig: RequiredDeep<Config> = {\n 'x-scalar-reference-config': defaultReferenceConfig,\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 /** Optional configuration options */\n config?: DocumentConfiguration\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/** 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\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 */\nasync function loadDocument(workspaceDocument: WorkspaceDocumentInput) {\n if ('url' in workspaceDocument) {\n return fetchUrls({ fetch: workspaceDocument.fetch }).exec(workspaceDocument.url)\n }\n\n return {\n ok: true as const,\n data: workspaceDocument.document,\n }\n}\n\n/**\n * Returns the origin (URL) of a workspace document if it was loaded from a URL.\n * If the document was provided directly as an object, returns undefined.\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 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 /** Workspace configuration */\n config?: Config\n /** Fetch function for retrieving documents */\n fetch?: WorkspaceDocumentInput['fetch']\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 * 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>(key: K, value: WorkspaceMeta[K]): void\n /**\n * Updates a specific metadata field in a document\n * @param name - The name of the document to update ('active' or a specific document name)\n * @param key - The metadata field to update\n * @param value - The new value for the field\n * @throws Error if the specified document doesn't exist\n * @example\n * // Update the auth of the active document\n * updateDocument('active', 'x-scalar-active-auth', 'Bearer')\n * // Update the auth of a specific document\n * updateDocument('document-name', 'x-scalar-active-auth', 'Bearer')\n */\n updateDocument<K extends keyof WorkspaceDocumentMeta>(\n name: 'active' | (string & {}),\n key: K,\n value: WorkspaceDocumentMeta[K],\n ): void\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-active-server': 'production'\n * }\n * })\n */\n addDocument(input: WorkspaceDocumentInput): Promise<void>\n /**\n * Returns the merged configuration for the active document.\n *\n * This getter merges configurations in the following order of precedence:\n * 1. Document-specific configuration (highest priority)\n * 2. Workspace-level configuration\n * 3. Default configuration (lowest priority)\n *\n * The active document is determined by the workspace's activeDocument extension,\n * falling back to the first document if none is specified.\n */\n readonly config: typeof defaultConfig\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'): 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'): 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 * 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 * Serializes the current workspace state to a JSON string for backup, persistence, or sharing.\n *\n * This method exports all workspace documents (removing Vue reactivity proxies), workspace metadata,\n * document configurations, and both the original and intermediate document states. The resulting JSON\n * can be imported later to fully restore the workspace to this exact state, including all documents\n * and their configurations.\n *\n * @returns A JSON string representing the complete workspace state.\n */\n exportWorkspace(): string\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: string): 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-dark-mode\": true\n * })\n * ```\n *\n * @param specification - The workspace specification to import.\n */\n importWorkspaceFromSpecification(specification: WorkspaceSpecification): Promise<void[]>\n /**\n * Rebases a document in the workspace with a new origin, resolving conflicts if provided.\n *\n * This method is used to rebase a document (e.g., after pulling remote changes) by applying the changes\n * from the new origin and merging them with local edits. If there are conflicts, they can be resolved\n * by providing a list of resolved conflicts.\n *\n * @param documentName - The name of the document to rebase.\n * @param newDocumentOrigin - The new origin document (as an object) to rebase onto.\n * @param resolvedConflicts - (Optional) An array of resolved conflicts to apply.\n * @returns If there are unresolved conflicts and no resolution is provided, returns the list of conflicts.\n *\n * @example\n * // Example: Rebase a document with a new origin and resolve conflicts\n * const conflicts = store.rebaseDocument('api', newOriginDoc)\n * if (conflicts && conflicts.length > 0) {\n * // User resolves conflicts here...\n * store.rebaseDocument('api', newOriginDoc, userResolvedConflicts)\n * }\n */\n rebaseDocument: (\n documentName: string,\n newDocumentOrigin: Record<string, unknown>,\n resolvedConflicts?: Difference<unknown>[],\n ) => void | ReturnType<typeof merge>['conflicts']\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 `addDocument` 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 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 const 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 const intermediateDocuments = {} as Record<string, UnknownObject>\n /**\n * A map of document configurations keyed by document name.\n * This stores the configuration options for each document in the workspace,\n * allowing for document-specific settings like navigation options, appearance,\n * and other reference configuration.\n */\n const documentConfigs: Record<string, Config> = {}\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 const overrides: InMemoryWorkspace['overrides'] = {}\n /**\n * Holds additional metadata for each document in the workspace.\n *\n * This metadata should be persisted together with the document itself.\n * It can include information such as user preferences, UI state, or other\n * per-document attributes that are not part of the OpenAPI document structure.\n */\n const documentMeta: InMemoryWorkspace['documentMeta'] = {}\n\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 // Create a reactive workspace object with proxied documents\n // Each document is wrapped in a proxy to enable reactive updates and reference resolution\n const workspace = reactive<Workspace>({\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 const activeDocumentKey =\n workspace[extensions.workspace.activeDocument] ?? Object.keys(workspace.documents)[0] ?? ''\n return workspace.documents[activeDocumentKey]\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') {\n const intermediateDocument = intermediateDocuments[documentName]\n\n if (!intermediateDocument) {\n return\n }\n\n if (format === 'json') {\n return JSON.stringify(intermediateDocument)\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 updatedDocument = getRaw(workspaceDocument)\n\n // If either the intermediate or updated document is missing, do nothing\n if (!intermediateDocument || !updatedDocument) {\n return\n }\n\n // Traverse the document and convert refs back to the original shape\n const updatedWithOriginalRefs = await bundle(deepClone(updatedDocument), {\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 return excludedDiffs\n }\n\n const processDocument = (input: OpenApiDocument, options: Config & { documentSource?: string }): OpenApiDocument => {\n // Get the servers from the document or the config and perform some mutations on them\n const servers = getServersFromDocument(options['x-scalar-reference-config']?.settings?.servers ?? input.servers, {\n baseServerUrl: options['x-scalar-reference-config']?.settings?.baseServerUrl,\n documentUrl: options.documentSource,\n })\n\n if (servers.length) {\n input.servers = servers.map((it) => ({ url: it.url, description: it.description, variables: it.variables }))\n }\n\n return input\n }\n\n // Add a document to the store synchronously from an in-memory OpenAPI document\n async function addInMemoryDocument(input: ObjectDoc & { initialize?: boolean; documentSource?: string }) {\n const { name, meta } = input\n const cloned = measureSync('deepClone', () => deepClone(input.document))\n const inputDocument = measureSync('upgrade', () => upgrade(cloned, '3.1'))\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({ ...inputDocument })\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({ ...inputDocument })\n // Add the document config to the documentConfigs map\n documentConfigs[name] = input.config ?? {}\n // Store the overrides for this document, or an empty object if none are provided\n overrides[name] = input.overrides ?? {}\n // Store the document metadata for this document, setting the origin if provided\n documentMeta[name] = { documentSource: input.documentSource }\n // Store extra document configurations that can not be persisted\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n }\n })\n\n const strictDocument: UnknownObject = createMagicProxy({ ...inputDocument, ...meta }, { showInternal: true })\n\n strictDocument['x-original-oas-version'] = input.document.openapi ?? input.document.swagger\n\n if (strictDocument[extensions.document.navigation] === undefined) {\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 await measureAsync(\n 'bundle',\n async () =>\n await bundle(getRaw(strictDocument), {\n treeShake: false,\n plugins: [\n fetchUrls({\n fetch: extraDocumentConfigurations[name]?.fetch ?? workspaceProps?.fetch,\n }),\n externalValueResolver(),\n refsEverywhere(),\n ],\n urlMap: true,\n origin: documentMeta[name]?.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 measureAsync('mergeObjects', async () => 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 showModels = input.config?.['x-scalar-reference-config']?.features?.showModels\n\n strictDocument[extensions.document.navigation] = createNavigation(strictDocument as OpenApiDocument, {\n ...(input.config?.['x-scalar-reference-config'] ?? {}),\n hideModels: showModels === undefined ? undefined : !showModels,\n }).entries\n\n // Do some document processing\n processDocument(getRaw(strictDocument as OpenApiDocument), {\n ...input.config,\n documentSource: input.documentSource,\n })\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(\n createMagicProxy(getRaw(strictDocument)) as OpenApiDocument,\n input.overrides,\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) {\n const { name, meta } = input\n\n const resolve = await measureAsync(\n 'loadDocument',\n async () => await loadDocument({ ...input, fetch: input.fetch ?? workspaceProps?.fetch }),\n )\n\n // Log the time taken to add a document\n 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 }\n\n return\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 }\n\n return\n }\n\n await addInMemoryDocument({\n ...input,\n document: resolve.data,\n documentSource: getDocumentSource(input),\n })\n })\n }\n\n // Returns the effective document configuration for a given document name,\n // merging (in order of increasing priority): the default config, workspace-level config, and document-specific config.\n const getDocumentConfiguration = (name: string) => {\n return mergeObjects<typeof defaultConfig>(\n mergeObjects(defaultConfig, workspaceProps?.config ?? {}),\n documentConfigs[name] ?? {},\n )\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 update<K extends keyof WorkspaceMeta>(key: K, value: WorkspaceMeta[K]) {\n // @ts-ignore\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n throw new Error('Invalid key: cannot modify prototype')\n }\n Object.assign(workspace, { [key]: value })\n },\n updateDocument<K extends keyof WorkspaceDocumentMeta>(\n name: 'active' | (string & {}),\n key: K,\n value: WorkspaceDocumentMeta[K],\n ) {\n const currentDocument = workspace.documents[name === 'active' ? getActiveDocumentName() : name]\n\n if (!currentDocument) {\n throw 'Please select a valid document'\n }\n\n Object.assign(currentDocument, { [key]: value })\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 meta: {\n 'x-scalar-active-auth': currentDocument['x-scalar-active-auth'],\n 'x-scalar-active-server': currentDocument['x-scalar-active-server'],\n },\n initialize: false,\n })\n },\n resolve: async (path: string[]) => {\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\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 get config() {\n return getDocumentConfiguration(getActiveDocumentName())\n },\n exportDocument,\n exportActiveDocument: (format) => exportDocument(getActiveDocumentName(), format),\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 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 return JSON.stringify({\n documents: {\n ...Object.fromEntries(\n Object.entries(workspace.documents).map(([name, doc]) => [\n name,\n // Extract the raw document data for export, removing any Vue reactivity wrappers.\n // When importing, the document can be wrapped again in a magic proxy.\n getRaw(doc),\n ]),\n ),\n },\n meta: workspaceProps?.meta ?? {},\n documentConfigs,\n originalDocuments,\n intermediateDocuments,\n overrides,\n documentMeta,\n } satisfies InMemoryWorkspace)\n },\n loadWorkspace(input: string) {\n const result = coerceValue(InMemoryWorkspaceSchema, JSON.parse(input))\n\n // Assign the magic proxy to the documents\n safeAssign(\n workspace.documents,\n Object.fromEntries(\n Object.entries(result.documents).map(([name, doc]) => [\n name,\n createOverridesProxy(createMagicProxy(doc), result.overrides[name]),\n ]),\n ),\n )\n\n safeAssign(originalDocuments, result.originalDocuments)\n safeAssign(intermediateDocuments, result.intermediateDocuments)\n safeAssign(documentConfigs, result.documentConfigs)\n safeAssign(overrides, result.overrides)\n safeAssign(workspace, result.meta)\n safeAssign(documentMeta, result.documentMeta)\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: (documentName, newDocumentOrigin, resolvedConflicts) => {\n const newOrigin = upgrade(newDocumentOrigin, '3.1')\n\n const originalDocument = originalDocuments[documentName]\n const intermediateDocument = intermediateDocuments[documentName]\n const activeDocument = workspace.documents[documentName] ? getRaw(workspace.documents[documentName]) : undefined // raw version without any overrides\n\n if (!originalDocument || !intermediateDocument || !activeDocument) {\n // If any required document state is missing, do nothing\n return console.error('[ERROR]: Specified document is missing or internal corrupted workspace state')\n }\n\n // ---- Get the new intermediate document\n const changelogAA = diff(originalDocument, newOrigin)\n const changelogAB = diff(originalDocument, intermediateDocument)\n\n const changesA = merge(changelogAA, changelogAB)\n\n if (resolvedConflicts === undefined) {\n // If there are conflicts, return the list of conflicts for user resolution\n return changesA.conflicts\n }\n\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[documentName] = newIntermediateDocument\n\n // Update the original document\n originalDocuments[documentName] = newOrigin\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 // Update the active document to the new value\n workspace.documents[documentName] = createOverridesProxy(\n createMagicProxy({ ...newActiveDocument }),\n overrides[documentName],\n )\n return\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": ["overrides"]
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { isHttpMethod } from "@scalar/helpers/http/is-http-method";
2
2
  import { objectKeys } from "@scalar/helpers/object/object-keys";
3
- import { escapeJsonPointer } from "@scalar/openapi-parser";
3
+ import { escapeJsonPointer } from "@scalar/json-magic/helpers/escape-json-pointer";
4
4
  import { getResolvedRef } from "../../helpers/get-resolved-ref.js";
5
5
  import { getTag } from "./get-tag.js";
6
6
  const createOperationEntry = (ref, operation, method, path = "Unknown", tag, titlesMap, getOperationId) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/navigation/helpers/traverse-paths.ts"],
4
- "sourcesContent": ["import { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { escapeJsonPointer } from '@scalar/openapi-parser'\n\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport type { TagsMap, TraverseSpecOptions } from '@/navigation/types'\nimport type { TraversedOperation } from '@/schemas/navigation'\nimport type { OpenApiDocument, OperationObject, TagObject } from '@/schemas/v3.1/strict/openapi-document'\n\nimport { getTag } from './get-tag'\n\n/**\n * Creates a traversed operation entry from an OpenAPI operation object.\n *\n * @param ref - JSON pointer reference to the operation in the OpenAPI document\n * @param operation - The OpenAPI operation object\n * @param method - HTTP method of the operation\n * @param path - API path of the operation, defaults to 'Unknown'\n * @param tag - Tag object associated with the operation\n * @param titlesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns A traversed operation entry with ID, title, path, method and reference\n */\nconst createOperationEntry = (\n ref: string,\n operation: OperationObject,\n method: string,\n path = 'Unknown',\n tag: TagObject,\n titlesMap: Map<string, string>,\n getOperationId: TraverseSpecOptions['getOperationId'],\n): TraversedOperation => {\n const id = getOperationId({ ...operation, method, path }, tag)\n const title = operation.summary?.trim() ? operation.summary : path\n\n titlesMap.set(id, title)\n\n return {\n id,\n title,\n path,\n method,\n ref,\n type: 'operation',\n }\n}\n\n/**\n * Traverses the paths in an OpenAPI document to build a map of operations organized by tags.\n *\n * This function processes each path and its operations to:\n * - Filter out internal operations (marked with x-internal) and operations to ignore (marked with x-scalar-ignore)\n * - Group operations by their tags\n * - Create a default tag group for untagged operations\n * - Generate unique references and IDs for each operation\n *\n * TODO: filter out internal and scalar-ignore tags\n *\n * @param content - The OpenAPI document to traverse\n * @param tagsDict - Dictionary mapping tag names to their OpenAPI tag objects\n * @param titlesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns Map of tag names to arrays of traversed operations\n */\nexport const traversePaths = (\n content: OpenApiDocument,\n /** Map of tags and their entries */\n tagsMap: TagsMap,\n /** Map of titles for the mobile header */\n titlesMap: Map<string, string>,\n getOperationId: TraverseSpecOptions['getOperationId'],\n) => {\n // Traverse paths\n Object.entries(content.paths ?? {}).forEach(([path, pathItemObject]) => {\n const pathKeys = objectKeys(pathItemObject ?? {}).filter((key) => isHttpMethod(key))\n\n pathKeys.forEach((method) => {\n const _operation = pathItemObject?.[method]\n const operation = getResolvedRef(_operation)\n if (!operation) {\n return\n }\n\n // Skip if the operation is internal or scalar-ignore\n if (operation['x-internal'] || operation['x-scalar-ignore'] || !isHttpMethod(method)) {\n return\n }\n\n const ref = `#/paths/${escapeJsonPointer(path)}/${method}`\n\n // Traverse tags\n if (operation.tags?.length) {\n operation.tags.forEach((tagName: string) => {\n const { tag } = getTag(tagsMap, tagName)\n tagsMap\n .get(tagName)\n ?.entries.push(createOperationEntry(ref, operation, method, path, tag, titlesMap, getOperationId))\n })\n }\n // Add to default tag\n else {\n const { tag } = getTag(tagsMap, 'default')\n tagsMap\n .get('default')\n ?.entries.push(createOperationEntry(ref, operation, method, path, tag, titlesMap, getOperationId))\n }\n })\n })\n}\n"],
4
+ "sourcesContent": ["import { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer'\n\nimport { getResolvedRef } from '@/helpers/get-resolved-ref'\nimport type { TagsMap, TraverseSpecOptions } from '@/navigation/types'\nimport type { TraversedOperation } from '@/schemas/navigation'\nimport type { OpenApiDocument, OperationObject, TagObject } from '@/schemas/v3.1/strict/openapi-document'\n\nimport { getTag } from './get-tag'\n\n/**\n * Creates a traversed operation entry from an OpenAPI operation object.\n *\n * @param ref - JSON pointer reference to the operation in the OpenAPI document\n * @param operation - The OpenAPI operation object\n * @param method - HTTP method of the operation\n * @param path - API path of the operation, defaults to 'Unknown'\n * @param tag - Tag object associated with the operation\n * @param titlesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns A traversed operation entry with ID, title, path, method and reference\n */\nconst createOperationEntry = (\n ref: string,\n operation: OperationObject,\n method: string,\n path = 'Unknown',\n tag: TagObject,\n titlesMap: Map<string, string>,\n getOperationId: TraverseSpecOptions['getOperationId'],\n): TraversedOperation => {\n const id = getOperationId({ ...operation, method, path }, tag)\n const title = operation.summary?.trim() ? operation.summary : path\n\n titlesMap.set(id, title)\n\n return {\n id,\n title,\n path,\n method,\n ref,\n type: 'operation',\n }\n}\n\n/**\n * Traverses the paths in an OpenAPI document to build a map of operations organized by tags.\n *\n * This function processes each path and its operations to:\n * - Filter out internal operations (marked with x-internal) and operations to ignore (marked with x-scalar-ignore)\n * - Group operations by their tags\n * - Create a default tag group for untagged operations\n * - Generate unique references and IDs for each operation\n *\n * TODO: filter out internal and scalar-ignore tags\n *\n * @param content - The OpenAPI document to traverse\n * @param tagsDict - Dictionary mapping tag names to their OpenAPI tag objects\n * @param titlesMap - Map to store operation IDs and titles for mobile header navigation\n * @param getOperationId - Function to generate unique IDs for operations\n * @returns Map of tag names to arrays of traversed operations\n */\nexport const traversePaths = (\n content: OpenApiDocument,\n /** Map of tags and their entries */\n tagsMap: TagsMap,\n /** Map of titles for the mobile header */\n titlesMap: Map<string, string>,\n getOperationId: TraverseSpecOptions['getOperationId'],\n) => {\n // Traverse paths\n Object.entries(content.paths ?? {}).forEach(([path, pathItemObject]) => {\n const pathKeys = objectKeys(pathItemObject ?? {}).filter((key) => isHttpMethod(key))\n\n pathKeys.forEach((method) => {\n const _operation = pathItemObject?.[method]\n const operation = getResolvedRef(_operation)\n if (!operation) {\n return\n }\n\n // Skip if the operation is internal or scalar-ignore\n if (operation['x-internal'] || operation['x-scalar-ignore'] || !isHttpMethod(method)) {\n return\n }\n\n const ref = `#/paths/${escapeJsonPointer(path)}/${method}`\n\n // Traverse tags\n if (operation.tags?.length) {\n operation.tags.forEach((tagName: string) => {\n const { tag } = getTag(tagsMap, tagName)\n tagsMap\n .get(tagName)\n ?.entries.push(createOperationEntry(ref, operation, method, path, tag, titlesMap, getOperationId))\n })\n }\n // Add to default tag\n else {\n const { tag } = getTag(tagsMap, 'default')\n tagsMap\n .get('default')\n ?.entries.push(createOperationEntry(ref, operation, method, path, tag, titlesMap, getOperationId))\n }\n })\n })\n}\n"],
5
5
  "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAElC,SAAS,sBAAsB;AAK/B,SAAS,cAAc;AAcvB,MAAM,uBAAuB,CAC3B,KACA,WACA,QACA,OAAO,WACP,KACA,WACA,mBACuB;AACvB,QAAM,KAAK,eAAe,EAAE,GAAG,WAAW,QAAQ,KAAK,GAAG,GAAG;AAC7D,QAAM,QAAQ,UAAU,SAAS,KAAK,IAAI,UAAU,UAAU;AAE9D,YAAU,IAAI,IAAI,KAAK;AAEvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAmBO,MAAM,gBAAgB,CAC3B,SAEA,SAEA,WACA,mBACG;AAEH,SAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,cAAc,MAAM;AACtE,UAAM,WAAW,WAAW,kBAAkB,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,aAAa,GAAG,CAAC;AAEnF,aAAS,QAAQ,CAAC,WAAW;AAC3B,YAAM,aAAa,iBAAiB,MAAM;AAC1C,YAAM,YAAY,eAAe,UAAU;AAC3C,UAAI,CAAC,WAAW;AACd;AAAA,MACF;AAGA,UAAI,UAAU,YAAY,KAAK,UAAU,iBAAiB,KAAK,CAAC,aAAa,MAAM,GAAG;AACpF;AAAA,MACF;AAEA,YAAM,MAAM,WAAW,kBAAkB,IAAI,CAAC,IAAI,MAAM;AAGxD,UAAI,UAAU,MAAM,QAAQ;AAC1B,kBAAU,KAAK,QAAQ,CAAC,YAAoB;AAC1C,gBAAM,EAAE,IAAI,IAAI,OAAO,SAAS,OAAO;AACvC,kBACG,IAAI,OAAO,GACV,QAAQ,KAAK,qBAAqB,KAAK,WAAW,QAAQ,MAAM,KAAK,WAAW,cAAc,CAAC;AAAA,QACrG,CAAC;AAAA,MACH,OAEK;AACH,cAAM,EAAE,IAAI,IAAI,OAAO,SAAS,SAAS;AACzC,gBACG,IAAI,SAAS,GACZ,QAAQ,KAAK,qBAAqB,KAAK,WAAW,QAAQ,MAAM,KAAK,WAAW,cAAc,CAAC;AAAA,MACrG;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import fs from "node:fs/promises";
2
2
  import { cwd } from "node:process";
3
3
  import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
4
- import { escapeJsonPointer, upgrade } from "@scalar/openapi-parser";
4
+ import { escapeJsonPointer } from "@scalar/json-magic/helpers/escape-json-pointer";
5
+ import { upgrade } from "@scalar/openapi-upgrader";
5
6
  import { keyOf } from "./helpers/general.js";
6
7
  import { createNavigation } from "./navigation/index.js";
7
8
  import { extensions } from "./schemas/extensions.js";
@@ -100,7 +101,7 @@ async function createServerWorkspaceStore(workspaceProps) {
100
101
  const assets = {};
101
102
  const addDocumentSync = (document, meta) => {
102
103
  const { name, ...documentMeta } = meta;
103
- const documentV3 = coerceValue(OpenAPIDocumentSchema, upgrade(document).specification);
104
+ const documentV3 = coerceValue(OpenAPIDocumentSchema, upgrade(document, "3.1"));
104
105
  assets[meta.name] = {
105
106
  components: documentV3.components,
106
107
  operations: documentV3.paths && escapePaths(filterHttpMethodsOnly(documentV3.paths))
@@ -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 { fetchUrls, readFiles } from '@scalar/json-magic/bundle/plugins/node'\nimport { escapeJsonPointer, upgrade } from '@scalar/openapi-parser'\n\nimport { keyOf } from '@/helpers/general'\nimport { createNavigation, type createNavigationOptions } from '@/navigation'\nimport { extensions } from '@/schemas/extensions'\nimport type { TraversedEntry } 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 config?: createNavigationOptions\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 */\nasync function loadDocument(workspaceDocument: WorkspaceDocumentInput) {\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 {\n ok: true as const,\n data: 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]: TraversedEntry[] }>,\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).specification)\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 { entries } = createNavigation(documentV3, workspaceProps.config ?? {})\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]: entries,\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(addDocument))\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": "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",
4
+ "sourcesContent": ["import fs from 'node:fs/promises'\nimport { cwd } from 'node:process'\n\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, type createNavigationOptions } from '@/navigation'\nimport { extensions } from '@/schemas/extensions'\nimport type { TraversedEntry } 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 config?: createNavigationOptions\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 */\nasync function loadDocument(workspaceDocument: WorkspaceDocumentInput) {\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 {\n ok: true as const,\n data: 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]: TraversedEntry[] }>,\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 { entries } = createNavigation(documentV3, workspaceProps.config ?? {})\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]: entries,\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(addDocument))\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": "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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.15.6",
19
+ "version": "0.15.7",
20
20
  "engines": {
21
21
  "node": ">=18"
22
22
  },
@@ -78,12 +78,12 @@
78
78
  "type-fest": "4.41.0",
79
79
  "vue": "^3.5.17",
80
80
  "yaml": "2.8.0",
81
- "@scalar/code-highlight": "0.1.9",
82
- "@scalar/json-magic": "0.4.3",
83
- "@scalar/openapi-parser": "0.20.6",
81
+ "@scalar/code-highlight": "0.2.0",
84
82
  "@scalar/helpers": "0.0.11",
85
- "@scalar/snippetz": "0.4.9",
86
- "@scalar/types": "0.2.15"
83
+ "@scalar/openapi-upgrader": "0.1.0",
84
+ "@scalar/json-magic": "0.5.0",
85
+ "@scalar/types": "0.2.16",
86
+ "@scalar/snippetz": "0.4.10"
87
87
  },
88
88
  "devDependencies": {
89
89
  "@google-cloud/storage": "7.16.0",