@scalar/workspace-store 0.27.2 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @scalar/workspace-store
2
2
 
3
+ ## 0.28.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#7823](https://github.com/scalar/scalar/pull/7823): chore: update workspace schema index to support teamUid queries and local
8
+
9
+ ## 0.28.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#7970](https://github.com/scalar/scalar/pull/7970): feat: update sidebar when docuemnt title changes
14
+
15
+ ### Patch Changes
16
+
17
+ - [#7988](https://github.com/scalar/scalar/pull/7988): feat: restore old client search
18
+ - [#7963](https://github.com/scalar/scalar/pull/7963): feat: unify is-object helpers
19
+
20
+ #### Updated Dependencies
21
+
22
+ - **@scalar/types@0.6.1**
23
+ - [#8000](https://github.com/scalar/scalar/pull/8000): fix(agent): change enabled flag to disabled
24
+ - [#7995](https://github.com/scalar/scalar/pull/7995): feat: enable/disable agent scalar
25
+
26
+ - **@scalar/json-magic@0.9.5**
27
+ - [#7963](https://github.com/scalar/scalar/pull/7963): feat: unify is-object helpers
28
+
29
+ - **@scalar/helpers@0.2.10**
30
+ - [#7963](https://github.com/scalar/scalar/pull/7963): feat: unify is-object helpers
31
+
32
+ - **@scalar/openapi-upgrader@0.1.8**
33
+
34
+ - **@scalar/snippetz@0.6.10**
35
+
36
+ - **@scalar/object-utils@1.2.24**
37
+
3
38
  ## 0.27.2
4
39
 
5
40
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { isObject } from "@scalar/helpers/object/is-object";
1
2
  import { preventPollution } from "@scalar/helpers/object/prevent-pollution";
2
3
  import { generateHash } from "@scalar/helpers/string/generate-hash";
3
4
  import { measureAsync, measureSync } from "@scalar/helpers/testing/measure";
@@ -12,7 +13,7 @@ import YAML from "yaml";
12
13
  import { applySelectiveUpdates } from "./helpers/apply-selective-updates.js";
13
14
  import { deepClone } from "./helpers/deep-clone.js";
14
15
  import { createDetectChangesProxy } from "./helpers/detect-changes-proxy.js";
15
- import { isObject, safeAssign } from "./helpers/general.js";
16
+ import { safeAssign } from "./helpers/general.js";
16
17
  import { getFetch } from "./helpers/get-fetch.js";
17
18
  import { getValueByPath } from "./helpers/json-path-utils.js";
18
19
  import { mergeObjects } from "./helpers/merge-object.js";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client.ts"],
4
- "sourcesContent": ["import { preventPollution } from '@scalar/helpers/object/prevent-pollution'\nimport { generateHash } from '@scalar/helpers/string/generate-hash'\nimport { measureAsync, measureSync } from '@scalar/helpers/testing/measure'\nimport { type LoaderPlugin, bundle } from '@scalar/json-magic/bundle'\nimport { fetchUrls } from '@scalar/json-magic/bundle/plugins/browser'\nimport { type Difference, apply, diff, merge } from '@scalar/json-magic/diff'\nimport { createMagicProxy, getRaw } from '@scalar/json-magic/magic-proxy'\nimport { upgrade } from '@scalar/openapi-upgrader'\nimport type { Record } from '@scalar/typebox'\nimport { Value } from '@scalar/typebox/value'\nimport type { PartialDeep } from 'type-fest'\nimport { reactive, toRaw } from 'vue'\nimport YAML from 'yaml'\n\nimport { applySelectiveUpdates } from '@/helpers/apply-selective-updates'\nimport { deepClone } from '@/helpers/deep-clone'\nimport { createDetectChangesProxy } from '@/helpers/detect-changes-proxy'\nimport { type UnknownObject, isObject, safeAssign } from '@/helpers/general'\nimport { getFetch } from '@/helpers/get-fetch'\nimport { getValueByPath } from '@/helpers/json-path-utils'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { createOverridesProxy, unpackOverridesProxy } from '@/helpers/overrides-proxy'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport { createNavigation } from '@/navigation'\nimport type { NavigationOptions } from '@/navigation/get-navigation-options'\nimport {\n externalValueResolver,\n loadingStatus,\n normalizeAuthSchemes,\n refsEverywhere,\n restoreOriginalRefs,\n} from '@/plugins/bundler'\nimport { extensions } from '@/schemas/extensions'\nimport type { InMemoryWorkspace } from '@/schemas/inmemory-workspace'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n OpenAPIDocumentSchema as OpenAPIDocumentSchemaStrict,\n type OpenApiDocument,\n} from '@/schemas/v3.1/strict/openapi-document'\nimport type { Workspace, WorkspaceDocumentMeta, WorkspaceExtensions, WorkspaceMeta } from '@/schemas/workspace'\nimport type { WorkspaceSpecification } from '@/schemas/workspace-specification'\nimport type { WorkspacePlugin, WorkspaceStateChangeEvent } from '@/workspace-plugin'\n\ntype ExtraDocumentConfigurations = Record<\n string,\n {\n fetch: WorkspaceDocumentMetaInput['fetch']\n }\n>\n\n/**\n * Input type for workspace document metadata and configuration.\n * This type defines the required and optional fields for initializing a document in the workspace.\n */\ntype WorkspaceDocumentMetaInput = {\n /** Optional metadata about the document like title, description, etc */\n meta?: WorkspaceDocumentMeta\n /** Required unique identifier for the document */\n name: string\n /** Overrides for the document */\n overrides?: PartialDeep<OpenApiDocument>\n /** Optional custom fetch implementation to use when retrieving the document. By default the global fetch implementation will be used */\n fetch?: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response>\n}\n\n/**\n * Represents a document that is loaded from a URL.\n * This type extends WorkspaceDocumentMetaInput to include URL-specific properties.\n */\nexport type UrlDoc = {\n /** URL to fetch the OpenAPI document from */\n url: string\n} & WorkspaceDocumentMetaInput\n\n/** 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 */\nfunction loadDocument(workspaceDocument: WorkspaceDocumentInput): ReturnType<LoaderPlugin['exec']> {\n if ('url' in workspaceDocument) {\n return fetchUrls({ fetch: workspaceDocument.fetch }).exec(workspaceDocument.url)\n }\n\n return Promise.resolve({\n ok: true,\n data: workspaceDocument.document,\n // string version of the raw document for hashing purposes\n raw: JSON.stringify(workspaceDocument.document),\n })\n}\n\n/**\n * Returns the 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 /** Fetch function for retrieving documents */\n fetch?: WorkspaceDocumentInput['fetch']\n /** A list of all registered plugins for the current workspace */\n plugins?: WorkspacePlugin[]\n /** A file loader plugin for resolving local file references (for non browser environments) */\n fileLoader?: LoaderPlugin\n}\n\n/**\n * Type definition for the workspace store return object.\n * This explicit type is needed to avoid TypeScript inference limits.\n *\n * @see https://github.com/microsoft/TypeScript/issues/43817#issuecomment-827746462\n */\nexport type WorkspaceStore = {\n /**\n * Returns the reactive workspace object with an additional activeDocument getter\n */\n readonly workspace: Workspace\n /**\n * Updates a specific metadata field in the workspace\n * @param key - The metadata field to update\n * @param value - The new value for the field\n * @example\n * // Update the workspace title\n * update('x-scalar-active-document', 'document-name')\n */\n update<K extends keyof WorkspaceMeta | keyof WorkspaceExtensions>(\n key: K,\n value: (WorkspaceMeta & WorkspaceExtensions)[K],\n ): void\n /**\n * Updates a specific metadata field 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, navigationOptions?: NavigationOptions): Promise<boolean>\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This method removes the document from the workspace along with all related data including:\n * - The document itself from the workspace documents map\n * - Original document data\n * - Intermediate document data (saved local versions)\n * - Document-specific configuration\n * - Document overrides\n * - Extra document configurations\n *\n * If the deleted document was the active document, the active document is automatically\n * reset to the first remaining document in the workspace, or undefined if no documents remain.\n *\n * The deletion is automatically tracked by the workspace change detection system,\n * and appropriate events will be fired to notify registered plugins.\n *\n * @param documentName - The name of the document to delete\n * @returns void\n *\n * @example\n * // Delete the document named 'api'\n * store.deleteDocument('api')\n *\n * @example\n * // Delete multiple documents\n * ['api', 'petstore'].forEach(name => store.deleteDocument(name))\n */\n deleteDocument(documentName: string): void\n /**\n * Exports the specified document in the requested format.\n *\n * This method serializes the most recently saved local version of the document (from the intermediateDocuments map)\n * to either JSON or YAML. The exported document reflects the last locally saved state, including any edits\n * that have been saved but not yet synced to a remote registry. Runtime/in-memory changes that have not been saved\n * will not be included.\n *\n * @param documentName - The name of the document to export.\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The document as a string in the requested format, or undefined if the document does not exist.\n *\n * @example\n * // Export a document as JSON\n * const jsonString = store.exportDocument('api', 'json')\n *\n * // Export a document as YAML\n * const yamlString = store.exportDocument('api', 'yaml')\n */\n exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Exports the currently active document in the requested format.\n *\n * This is a convenience method that exports the active document (determined by the workspace's\n * activeDocument extension) without requiring the caller to specify the document name.\n * The exported document reflects the last locally saved state, including any edits that have\n * been saved but not yet synced to a remote registry.\n *\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The active document as a string in the requested format, or undefined if no active document exists.\n *\n * @example\n * // Export the active document as JSON\n * const jsonString = store.exportActiveDocument('json')\n *\n * // Export the active document as YAML\n * const yamlString = store.exportActiveDocument('yaml')\n */\n exportActiveDocument(format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Saves the current state of the specified document to the intermediate documents map.\n *\n * This function captures the latest (reactive) state of the document from the workspace and\n * applies its changes to the corresponding entry in the `intermediateDocuments` map.\n * The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n * which may include edits not yet synced to the remote registry.\n *\n * The update is performed in-place. A deep clone of the current document\n * state is used to avoid mutating the reactive object directly.\n *\n * @param documentName - The name of the document to save.\n * @returns An array of diffs that were excluded from being applied (such as changes to ignored keys),\n * or undefined if the document does not exist or cannot be updated.\n *\n * @example\n * // Save the current state of the document named 'api'\n * const excludedDiffs = store.saveDocument('api')\n */\n saveDocument(documentName: string): Promise<unknown[] | undefined>\n /**\n * Builds the sidebar for the specified document.\n *\n * @param documentName - The name of the document to build the sidebar for\n * @returns boolean indicating if the sidebar was built successfully\n */\n buildSidebar: (documentName: string) => boolean\n /**\n * Restores the specified document to its last locally saved state.\n *\n * This method updates the current reactive document (in the workspace) with the contents of the\n * corresponding intermediate document (from the `intermediateDocuments` map), effectively discarding\n * any unsaved in-memory changes and reverting to the last saved version.\n * Vue reactivity is preserved by updating the existing reactive object in place.\n *\n * **Warning:** This operation will discard all unsaved (in-memory) changes to the specified document.\n *\n * @param documentName - The name of the document to restore.\n * @returns void\n *\n * @example\n * // Restore the document named 'api' to its last saved state\n * store.revertDocumentChanges('api')\n */\n revertDocumentChanges(documentName: string): Promise<void>\n /**\n * Commits the specified document.\n *\n * This method is intended to finalize and persist the current state of the document,\n * potentially syncing it with a remote registry or marking it as the latest committed version.\n *\n * @param documentName - The name of the document to commit.\n * @remarks\n * The actual commit logic is not implemented yet.\n */\n commitDocument(documentName: string): void\n /**\n * Exports the complete current workspace state as a plain JavaScript object.\n *\n * The returned object includes all workspace documents (with Vue reactivity removed), workspace metadata,\n * document configurations, and both the original and intermediate document maps. This object can be\n * serialized (e.g., with JSON.stringify) and later imported to fully restore the workspace\u2014including\n * all documents, their configurations, metadata, and historical states.\n *\n * @returns An `InMemoryWorkspace` object representing the entire workspace state,\n * suitable for persistence, backup, or sharing.\n */\n exportWorkspace(): InMemoryWorkspace\n /**\n * Imports a workspace from a serialized JSON string.\n *\n * This method parses the input string using the InMemoryWorkspaceSchema,\n * then updates the current workspace state, including documents, metadata,\n * and configuration, with the imported values.\n *\n * @param input - The serialized workspace JSON string to import.\n */\n loadWorkspace(input: InMemoryWorkspace): void\n /**\n * Imports a workspace from a WorkspaceSpecification object.\n *\n * This method assigns workspace metadata and adds all documents defined in the specification.\n * Each document is added using its $ref and optional overrides.\n *\n * @example\n * ```ts\n * await store.importWorkspaceFromSpecification({\n * documents: {\n * api: { $ref: '/specs/api.yaml' },\n * petstore: { $ref: '/specs/petstore.yaml' }\n * },\n * overrides: {\n * api: { config: { features: { showModels: true } } }\n * },\n * info: { title: 'My Workspace' },\n * workspace: 'v1',\n * \"x-scalar-color-mode\": true\n * })\n * ```\n *\n * @param specification - The workspace specification to import.\n */\n importWorkspaceFromSpecification(specification: WorkspaceSpecification): Promise<boolean[]>\n /**\n * Rebases a document in the workspace by refetching its origin and merging with local edits.\n *\n * This method fetches the latest version of the document (optionally with custom fetch/config),\n * calculates changes relative to the original and locally edited versions,\n * and attempts to update the workspace document while preserving user edits.\n * If automatic resolution isn't possible due to conflicts, returns a conflict list for the caller to resolve.\n * If `resolvedConflicts` are provided (e.g., after user intervention), applies them to complete the rebase.\n *\n * @param input Object specifying which document to rebase\n * @returns If there are unresolved conflicts, resolves to an object containing the list of conflicts and a method to apply user-resolved conflicts; otherwise resolves to void.\n *\n * @example\n * // Rebase a document and handle conflicts interactively\n * const result = await store.rebaseDocument({ name: 'api', fetch: customFetch });\n * if (result && result.ok) {\n * // Present conflicts to the user and collect resolutions...\n * await result.applyChanges(userResolvedConflicts);\n * }\n */\n rebaseDocument: (input: WorkspaceDocumentInput) => Promise<\n | { ok: false; type: 'CORRUPTED_STATE' | 'FETCH_FAILED' | 'NO_CHANGES_DETECTED'; message: string }\n | {\n ok: true\n conflicts: ReturnType<typeof merge>['conflicts']\n applyChanges: (resolvedConflicts: Difference<unknown>[]) => Promise<void>\n }\n >\n}\n\n/**\n * Creates a reactive workspace store that manages documents and their metadata.\n * The store provides functionality for accessing, updating, and resolving document references.\n *\n * @param workspaceProps - Configuration object for the workspace\n * @param workspaceProps.meta - Optional metadata for the workspace\n * @param workspaceProps.documents - Optional record of documents to initialize the workspace with\n * Documents that require asynchronous loading must be added using `1` after the store is created\n * this allows atomic awaiting and does not block page load for the store initialization\n * @returns An object containing methods and getters for managing the workspace\n */\nexport const createWorkspaceStore = (workspaceProps?: WorkspaceProps): WorkspaceStore => {\n /**\n * Holds additional configuration options for each document in the workspace.\n *\n * This can include settings that can not be persisted between sessions (not JSON serializable)\n */\n const extraDocumentConfigurations: ExtraDocumentConfigurations = {}\n\n /**\n * Notifies all workspace plugins of a workspace state change event.\n *\n * This function iterates through all registered plugins (if any) and invokes\n * their onWorkspaceStateChanges hook with the given event object.\n *\n * @param event - The workspace state change event to broadcast to plugins\n */\n const fireWorkspaceChange = (event: WorkspaceStateChangeEvent) => {\n workspaceProps?.plugins?.forEach((plugin) => plugin.hooks?.onWorkspaceStateChanges?.(event))\n }\n\n /**\n * An object containing the reactive workspace state.\n *\n * Every change to the workspace, is tracked and broadcast to all registered plugins.\n * allowing for change tracking.\n *\n * NOTE:\n * The detect changes proxy is applied separately beacause the vue reactitvity proxy have to be the outer most proxy.\n * If the order is reversed, Vue cannot properly track mutations, leading to lost reactivity and bugs.\n * By wrapping the contents with the detect changes proxy first, and then passing the result to Vue's `reactive`,\n * we ensure that Vue manages its reactivity as expected and our change detection hooks\n * are also triggered reliably.\n * Do not reverse this order\u203C\uFE0F\n */\n const workspace = reactive<Workspace>(\n createDetectChangesProxy(\n {\n ...workspaceProps?.meta,\n documents: {},\n /**\n * Returns the currently active document from the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The active document or undefined if no document is found\n */\n get activeDocument(): NonNullable<Workspace['activeDocument']> | undefined {\n return workspace.documents[getActiveDocumentName()]\n },\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n /** Document changes */\n if (type === 'documents') {\n // We are overriding the while documents object, ignore. This should not happen\n if (path.length < 2) {\n console.log('[WARN]: Overriding entire documents object is not supported')\n return\n }\n\n const documentName = path[1] as string\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Active document changes */\n if (type === 'activeDocument') {\n const documentName = getActiveDocumentName()\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n // Active document changed\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Workspace meta changes */\n const { activeDocument: _a, documents: _d, ...meta } = workspace\n const event = {\n type: 'meta',\n value: unpackProxyObject(meta, { depth: 1 }),\n } satisfies WorkspaceStateChangeEvent\n\n fireWorkspaceChange(event)\n return\n },\n },\n },\n ),\n )\n\n /**\n * An object containing all the workspace state, wrapped in a detect changes proxy.\n *\n * Every change to the workspace state (documents, configs, metadata, etc.) can be detected here,\n * allowing for change tracking.\n */\n const { originalDocuments, intermediateDocuments, overrides } = createDetectChangesProxy(\n {\n /**\n * Holds the original, unmodified documents as they were initially loaded into the workspace.\n * These documents are stored in their raw form\u2014prior to any reactive wrapping, dereferencing, or bundling.\n * This map preserves the pristine structure of each document, using deep clones to ensure that\n * subsequent mutations in the workspace do not affect the originals.\n * The originals are retained so that we can restore, compare, or sync with the remote registry as needed.\n */\n originalDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores the intermediate state of documents after local edits but before syncing with the remote registry.\n *\n * This map acts as a local \"saved\" version of the document, reflecting the user's changes after they hit \"save\".\n * The `originalDocuments` map, by contrast, always mirrors the document as it exists in the remote registry.\n *\n * Use this map to stage local changes that are ready to be propagated back to the remote registry.\n * This separation allows us to distinguish between:\n * - The last known remote version (`originalDocuments`)\n * - The latest locally saved version (`intermediateDocuments`)\n * - The current in-memory (possibly unsaved) workspace document (`workspace.documents`)\n */\n intermediateDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores per-document overrides for OpenAPI documents.\n * This object is used to override specific fields of a document\n * when you cannot (or should not) modify the source document directly.\n * For example, this enables UI-driven or temporary changes to be applied\n * on top of the original document, without mutating the source.\n * The key is the document name, and the value is a deep partial\n * OpenAPI document representing the overridden fields.\n */\n overrides: {} as InMemoryWorkspace['overrides'],\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n if (!type) {\n return\n }\n\n if (path.length < 2) {\n return\n }\n\n const documentName = path[1] as string\n if (type === 'originalDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(originalDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'intermediateDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(intermediateDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'overrides') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(overrides[documentName] ?? {}),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n },\n },\n },\n )\n\n /**\n * Returns the name of the currently active document in the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The name of the active document or an empty string if no document is found\n */\n function getActiveDocumentName() {\n return workspace[extensions.workspace.activeDocument] ?? Object.keys(workspace.documents)[0] ?? ''\n }\n\n function exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean) {\n const intermediateDocument = intermediateDocuments[documentName]\n\n if (!intermediateDocument) {\n return\n }\n\n if (format === 'json') {\n return minify ? JSON.stringify(intermediateDocument) : JSON.stringify(intermediateDocument, null, 2)\n }\n\n return YAML.stringify(intermediateDocument)\n }\n\n // Save the current state of the specified document to the intermediate documents map.\n // This function captures the latest (reactive) state of the document from the workspace and\n // applies its changes to the corresponding entry in the `intermediateDocuments` map.\n // The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n // which may include edits not yet synced to the remote registry.\n async function saveDocument(documentName: string) {\n const intermediateDocument = intermediateDocuments[documentName]\n const workspaceDocument = workspace.documents[documentName]\n\n if (!workspaceDocument) {\n return\n }\n\n // Obtain the raw state of the current document to ensure accurate diffing\n const activeDocumentRaw = unpackProxyObject(workspaceDocument)\n\n // If either the intermediate or updated document is missing, do nothing\n if (!intermediateDocument || !activeDocumentRaw) {\n console.warn('Failed to save document, intermediate document and/or active document is missing')\n return\n }\n\n // Traverse the document and convert refs back to the original shape\n const updatedWithOriginalRefs = await bundle(deepClone(activeDocumentRaw), {\n plugins: [restoreOriginalRefs()],\n treeShake: false,\n urlMap: true,\n })\n\n // Apply changes from the current document to the intermediate document in place\n const excludedDiffs = applySelectiveUpdates(intermediateDocument, updatedWithOriginalRefs as UnknownObject)\n\n // Mark the document as not dirty since we are saving it\n workspaceDocument['x-scalar-is-dirty'] = false\n\n return excludedDiffs\n }\n\n // Add a document to the store synchronously from an in-memory OpenAPI document\n async function addInMemoryDocument(\n input: ObjectDoc & { initialize?: boolean; documentSource?: string; documentHash: string },\n navigationOptions?: NavigationOptions,\n ) {\n const { name, meta } = input\n const clonedRawInputDocument = measureSync('deepClone', () => deepClone(input.document))\n\n measureSync('initialize', () => {\n if (input.initialize !== false) {\n // Store the original document in the originalDocuments map\n // This is used to track the original state of the document as it was loaded into the workspace\n originalDocuments[name] = deepClone(clonedRawInputDocument)\n\n // Store the intermediate document state for local edits\n // This is used to track the last saved state of the document\n // It allows us to differentiate between the original document and the latest saved version\n // This is important for local edits that are not yet synced with the remote registry\n // The intermediate document is used to store the latest saved state of the document\n // This allows us to track changes and revert to the last saved state if needed\n intermediateDocuments[name] = deepClone(clonedRawInputDocument)\n // Store the overrides for this document, or an empty object if none are provided\n overrides[name] = input.overrides ?? {}\n // Store extra document configurations that can not be persisted\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n }\n })\n\n const inputDocument = measureSync('upgrade', () => upgrade(deepClone(clonedRawInputDocument), '3.1'))\n\n const strictDocument: UnknownObject = createMagicProxy(\n {\n ...inputDocument,\n ...meta,\n 'x-original-oas-version': originalDocuments[name]?.openapi ?? originalDocuments[name]?.swagger,\n 'x-scalar-original-document-hash': input.documentHash,\n 'x-scalar-original-source-url': input.documentSource,\n },\n { showInternal: true },\n )\n\n // If the document navigation is not already present, bundle the entire document to resolve all references.\n // This typically applies when the document is not preprocessed by the server and needs local reference resolution.\n // We need to bundle document first before we validate, so we can also validate the external references\n if (strictDocument[extensions.document.navigation] === undefined) {\n const loaders = [\n fetchUrls({\n fetch: extraDocumentConfigurations[name]?.fetch ?? workspaceProps?.fetch,\n }),\n ]\n\n // If a file loader plugin is provided, use it to resolve local file references\n // This is useful for non browser environments\n if (workspaceProps?.fileLoader) {\n loaders.push(workspaceProps.fileLoader)\n }\n\n await measureAsync(\n 'bundle',\n async () =>\n await bundle(getRaw(strictDocument), {\n treeShake: false,\n plugins: [...loaders, externalValueResolver(), refsEverywhere(), normalizeAuthSchemes()],\n urlMap: true,\n origin: input.documentSource, // use the document origin (if provided) as the base URL for resolution\n }),\n )\n\n // We coerce the values only when the document is not preprocessed by the server-side-store\n const coerced = measureSync('coerceValue', () =>\n coerceValue(OpenAPIDocumentSchemaStrict, deepClone(strictDocument)),\n )\n measureSync('mergeObjects', () => mergeObjects(strictDocument, coerced))\n }\n\n const isValid = Value.Check(OpenAPIDocumentSchemaStrict, strictDocument)\n\n if (!isValid) {\n const validationErrors = Array.from(Value.Errors(OpenAPIDocumentSchemaStrict, strictDocument))\n\n console.warn('document validation errors: ')\n console.warn(\n validationErrors.map((error) => ({\n message: error.message,\n path: error.path,\n schema: error.schema,\n value: error.value,\n })),\n )\n }\n\n // Skip navigation generation if the document already has a server-side generated navigation structure\n if (strictDocument[extensions.document.navigation] === undefined) {\n const navigation = createNavigation(name, strictDocument as OpenApiDocument, navigationOptions)\n strictDocument[extensions.document.navigation] = navigation\n }\n\n // Create a proxied document with magic proxy and apply any overrides, then store it in the workspace documents map\n // We create a new proxy here in order to hide internal properties after validation and processing\n // This ensures that the workspace document only exposes the intended OpenAPI properties and extensions\n workspace.documents[name] = createOverridesProxy(createMagicProxy(getRaw(strictDocument)) as OpenApiDocument, {\n overrides: unpackProxyObject(overrides[name]),\n })\n }\n\n // Asynchronously adds a new document to the workspace by loading and validating the input.\n // If loading fails, a placeholder error document is added instead.\n async function addDocument(input: WorkspaceDocumentInput, navigationOptions?: NavigationOptions) {\n const { name, meta } = input\n\n /** Ensure we use the active proxy to fetch documents unless we have a custom fetch override */\n const fetch = getFetch({\n fetch: input.fetch ?? workspaceProps?.fetch,\n proxyUrl: workspace['x-scalar-active-proxy'],\n })\n\n const resolve = await measureAsync('loadDocument', async () => await loadDocument({ ...input, fetch }))\n\n // Log the time taken to add a document\n return await measureAsync('addDocument', async () => {\n if (!resolve.ok) {\n console.error(`Failed to fetch document '${name}': request was not successful`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n if (!isObject(resolve.data)) {\n console.error(`Failed to load document '${name}': response data is not a valid object`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n await addInMemoryDocument(\n {\n ...input,\n document: resolve.data,\n documentSource: getDocumentSource(input),\n documentHash: generateHash(resolve.raw),\n },\n navigationOptions,\n )\n\n return true\n })\n }\n\n /**\n * Builds (or updates) the navigation sidebar for the specified document.\n *\n * This method generates the sidebar navigation structure for a workspace document,\n * and attaches it to the document's metadata under the navigation extension key.\n * The document is unpacked to avoid assigning proxy objects as direct property references.\n *\n * - Only the top-level object is proxied; all child objects should be unproxied.\n * - This approach enables safe unpacking of the proxy object without recursively traversing the full object tree.\n *\n * @param documentName - The name/key of the document whose sidebar should be built.\n * @returns {boolean} True if the sidebar was built successfully, false if the document does not exist.\n */\n const buildSidebar = (documentName: string): boolean => {\n const document = workspace.documents[documentName]\n\n if (!document) {\n // Log and exit if the document does not exist in the workspace\n console.error(`Document '${documentName}' does not exist in the workspace.`)\n return false\n }\n\n // Generate the navigation structure for the sidebar.\n const navigation = createNavigation(documentName, document)\n\n // Set the computed navigation structure on the document metadata.\n document[extensions.document.navigation] = navigation\n\n return true\n }\n\n // Cache to track visited nodes during reference resolution to prevent bundling the same subtree multiple times\n // This is needed because we are doing partial bundle operations\n const visitedNodesCache = new Set()\n\n return {\n get workspace() {\n return workspace\n },\n update(key, value) {\n preventPollution(key)\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 preventPollution(key)\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 documentSource: currentDocument['x-scalar-original-source-url'],\n documentHash: currentDocument['x-scalar-original-document-hash'],\n meta: {\n 'x-scalar-active-auth': currentDocument['x-scalar-active-auth'],\n 'x-scalar-active-server': currentDocument['x-scalar-active-server'],\n },\n initialize: false,\n })\n },\n resolve: (path) => {\n const activeDocument = workspace.activeDocument\n\n const target = getValueByPath(activeDocument, path)\n\n if (!isObject(target)) {\n console.error(\n `Invalid path provided for resolution. Path: [${path.join(', ')}]. Found value of type: ${typeof target}. Expected an object.`,\n )\n return Promise.resolve()\n }\n\n // Bundle the target document with the active document as root, resolving any external references\n // and tracking resolution status through hooks\n return bundle(target, {\n root: activeDocument,\n treeShake: false,\n plugins: [fetchUrls(), loadingStatus(), externalValueResolver()],\n urlMap: true,\n visitedNodes: visitedNodesCache,\n })\n },\n addDocument,\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This function removes the document and all related data structures.\n * If the deleted document was active, it automatically selects the first remaining document.\n */\n deleteDocument: (documentName: string): void => {\n // Check if the document exists before attempting deletion\n if (!workspace.documents[documentName]) {\n return\n }\n\n // Delete the document from the workspace (this will trigger change detection events)\n delete workspace.documents[documentName]\n\n // Clean up all associated data structures\n delete originalDocuments[documentName]\n delete intermediateDocuments[documentName]\n delete overrides[documentName]\n delete extraDocumentConfigurations[documentName]\n\n // Get remaining documents before deletion to properly set the active document\n const remainingDocuments = Object.keys(workspace.documents)\n const wasActiveDocument = workspace['x-scalar-active-document'] === documentName\n\n // Reset the active document to the first remaining one if the deleted document was the active one\n if (wasActiveDocument) {\n workspace['x-scalar-active-document'] = remainingDocuments[0] ?? undefined\n }\n\n // Fire the deleteDocument event\n fireWorkspaceChange({\n type: 'deleteDocument',\n documentName,\n })\n },\n exportDocument,\n exportActiveDocument: (format, minify) => exportDocument(getActiveDocumentName(), format, minify),\n buildSidebar,\n saveDocument,\n async revertDocumentChanges(documentName: string) {\n const workspaceDocument = workspace.documents[documentName]\n const intermediate = intermediateDocuments[documentName]\n\n if (!workspaceDocument || !intermediate) {\n return\n }\n\n await addInMemoryDocument({\n name: documentName,\n document: intermediate,\n documentSource: workspaceDocument['x-scalar-original-source-url'],\n documentHash: workspaceDocument['x-scalar-original-document-hash'],\n initialize: false,\n })\n },\n commitDocument(documentName: string) {\n // TODO: Implement commit logic\n console.warn(`Commit operation for document '${documentName}' is not implemented yet.`)\n },\n exportWorkspace() {\n const { activeDocument: _, documents, ...meta } = unpackProxyObject(workspace)\n return {\n documents: {\n ...Object.fromEntries(\n Object.entries(documents).map(([name, doc]) => [\n name,\n // Get the raw document without any proxies\n unpackProxyObject(doc),\n ]),\n ),\n },\n meta: unpackProxyObject(meta) ?? {},\n originalDocuments: unpackProxyObject(originalDocuments),\n intermediateDocuments: unpackProxyObject(intermediateDocuments),\n overrides: unpackProxyObject(overrides),\n } satisfies InMemoryWorkspace\n },\n loadWorkspace(input: InMemoryWorkspace) {\n safeAssign(\n workspace.documents,\n Object.fromEntries(\n Object.entries(input.documents).map(([name, doc]) => [\n name,\n createOverridesProxy(createMagicProxy(doc), {\n overrides: input.overrides[name],\n }),\n ]),\n ),\n )\n\n safeAssign(originalDocuments, input.originalDocuments)\n safeAssign(intermediateDocuments, input.intermediateDocuments)\n safeAssign(overrides, input.overrides)\n safeAssign(workspace, input.meta)\n },\n importWorkspaceFromSpecification: (specification: WorkspaceSpecification) => {\n const { documents, overrides, info: _info, workspace: _workspaceVersion, ...meta } = specification\n\n // Assign workspace metadata\n safeAssign(workspace, meta)\n\n // Add workspace documents\n return Promise.all(\n Object.entries(documents ?? {}).map(([name, doc]) =>\n addDocument({ url: doc.$ref, name, overrides: overrides?.[name] }),\n ),\n )\n },\n rebaseDocument: async (input: WorkspaceDocumentInput) => {\n const { name } = input\n\n // ---- Get the current documents\n const originalDocument = originalDocuments[name]\n const intermediateDocument = intermediateDocuments[name]\n // raw version without any proxies\n const activeDocument = workspace.documents[name]\n ? toRaw(getRaw(unpackOverridesProxy(workspace.documents[name])))\n : undefined\n\n if (!originalDocument || !intermediateDocument || !activeDocument) {\n // If any required document state is missing, do nothing\n return {\n ok: false,\n type: 'CORRUPTED_STATE' as const,\n message: `Cannot rebase document '${name}': missing original, intermediate, or active document state`,\n }\n }\n\n // ---- Resolve input document\n const resolve = await measureAsync(\n 'loadDocument',\n async () => await loadDocument({ ...input, fetch: input.fetch ?? workspaceProps?.fetch }),\n )\n\n if (!resolve.ok || !isObject(resolve.data)) {\n return {\n ok: false,\n type: 'FETCH_FAILED' as const,\n message: `Failed to fetch document '${name}': request was not successful or returned invalid data`,\n }\n }\n\n // Compare document hashes to see if the document has changed\n // When the hashes match, we can skip the rebase process\n const newHash = generateHash(resolve.raw)\n if (activeDocument['x-scalar-original-document-hash'] === newHash) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}': document hash matches the active document`,\n }\n }\n\n const newDocumentOrigin = resolve.data\n\n // ---- Override the configurations and metadata\n overrides[name] = input.overrides ?? {}\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n\n // ---- Get the new intermediate document\n const changelogAA = diff(originalDocument, newDocumentOrigin)\n\n // When there are no changes, we can return early since we don't need to do anything\n // This is not supposed to happen due to the hash check above, but just in case\n if (changelogAA.length === 0) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}' after fetching the latest version.`,\n }\n }\n\n const changelogAB = diff(originalDocument, intermediateDocument)\n\n const changesA = merge(changelogAA, changelogAB)\n\n return {\n ok: true,\n conflicts: changesA.conflicts,\n applyChanges: async (resolvedConflicts: Difference<unknown>[]) => {\n const changesetA = changesA.diffs.concat(resolvedConflicts)\n\n // Apply the changes to the original document to get the new intermediate\n const newIntermediateDocument = apply(deepClone(originalDocument), changesetA)\n intermediateDocuments[name] = newIntermediateDocument\n\n // Update the original document\n originalDocuments[name] = newDocumentOrigin\n\n // ---- Get the new active document\n const changelogBA = diff(intermediateDocument, newIntermediateDocument)\n const changelogBB = diff(intermediateDocument, activeDocument)\n\n const changesB = merge(changelogBA, changelogBB)\n\n // Auto-conflict resolution: pick only the changes from the first changeset\n // TODO: In the future, implement smarter conflict resolution if needed\n const changesetB = changesB.diffs.concat(changesB.conflicts.flatMap((it) => it[0]))\n\n const newActiveDocument = coerceValue(\n OpenAPIDocumentSchemaStrict,\n apply(deepClone(newIntermediateDocument), changesetB),\n )\n\n // add the new active document to the workspace but don't re-initialize\n await addInMemoryDocument({\n ...input,\n document: {\n ...newActiveDocument,\n // force regeneration of navigation\n // when we are rebasing, we want to ensure that the navigation is always up to date\n [extensions.document.navigation]: undefined,\n },\n documentSource: getDocumentSource(input),\n // Update the original document hash\n documentHash: generateHash(resolve.raw),\n initialize: false,\n })\n },\n }\n },\n }\n}\n\n// biome-ignore lint/performance/noBarrelFile: It's a package entry point\nexport { generateClientMutators } from '@/mutators'\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { isObject } from '@scalar/helpers/object/is-object'\nimport { preventPollution } from '@scalar/helpers/object/prevent-pollution'\nimport { generateHash } from '@scalar/helpers/string/generate-hash'\nimport { measureAsync, measureSync } from '@scalar/helpers/testing/measure'\nimport { type LoaderPlugin, bundle } from '@scalar/json-magic/bundle'\nimport { fetchUrls } from '@scalar/json-magic/bundle/plugins/browser'\nimport { type Difference, apply, diff, merge } from '@scalar/json-magic/diff'\nimport { createMagicProxy, getRaw } from '@scalar/json-magic/magic-proxy'\nimport { upgrade } from '@scalar/openapi-upgrader'\nimport type { Record } from '@scalar/typebox'\nimport { Value } from '@scalar/typebox/value'\nimport type { PartialDeep } from 'type-fest'\nimport { reactive, toRaw } from 'vue'\nimport YAML from 'yaml'\n\nimport { applySelectiveUpdates } from '@/helpers/apply-selective-updates'\nimport { deepClone } from '@/helpers/deep-clone'\nimport { createDetectChangesProxy } from '@/helpers/detect-changes-proxy'\nimport { type UnknownObject, safeAssign } from '@/helpers/general'\nimport { getFetch } from '@/helpers/get-fetch'\nimport { getValueByPath } from '@/helpers/json-path-utils'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport { createOverridesProxy, unpackOverridesProxy } from '@/helpers/overrides-proxy'\nimport { unpackProxyObject } from '@/helpers/unpack-proxy'\nimport { createNavigation } from '@/navigation'\nimport type { NavigationOptions } from '@/navigation/get-navigation-options'\nimport {\n externalValueResolver,\n loadingStatus,\n normalizeAuthSchemes,\n refsEverywhere,\n restoreOriginalRefs,\n} from '@/plugins/bundler'\nimport { extensions } from '@/schemas/extensions'\nimport type { InMemoryWorkspace } from '@/schemas/inmemory-workspace'\nimport { coerceValue } from '@/schemas/typebox-coerce'\nimport {\n OpenAPIDocumentSchema as OpenAPIDocumentSchemaStrict,\n type OpenApiDocument,\n} from '@/schemas/v3.1/strict/openapi-document'\nimport type { Workspace, WorkspaceDocumentMeta, WorkspaceExtensions, WorkspaceMeta } from '@/schemas/workspace'\nimport type { WorkspaceSpecification } from '@/schemas/workspace-specification'\nimport type { WorkspacePlugin, WorkspaceStateChangeEvent } from '@/workspace-plugin'\n\ntype ExtraDocumentConfigurations = Record<\n string,\n {\n fetch: WorkspaceDocumentMetaInput['fetch']\n }\n>\n\n/**\n * Input type for workspace document metadata and configuration.\n * This type defines the required and optional fields for initializing a document in the workspace.\n */\ntype WorkspaceDocumentMetaInput = {\n /** Optional metadata about the document like title, description, etc */\n meta?: WorkspaceDocumentMeta\n /** Required unique identifier for the document */\n name: string\n /** Overrides for the document */\n overrides?: PartialDeep<OpenApiDocument>\n /** Optional custom fetch implementation to use when retrieving the document. By default the global fetch implementation will be used */\n fetch?: (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response>\n}\n\n/**\n * Represents a document that is loaded from a URL.\n * This type extends WorkspaceDocumentMetaInput to include URL-specific properties.\n */\nexport type UrlDoc = {\n /** URL to fetch the OpenAPI document from */\n url: string\n} & WorkspaceDocumentMetaInput\n\n/** 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 */\nfunction loadDocument(workspaceDocument: WorkspaceDocumentInput): ReturnType<LoaderPlugin['exec']> {\n if ('url' in workspaceDocument) {\n return fetchUrls({ fetch: workspaceDocument.fetch }).exec(workspaceDocument.url)\n }\n\n return Promise.resolve({\n ok: true,\n data: workspaceDocument.document,\n // string version of the raw document for hashing purposes\n raw: JSON.stringify(workspaceDocument.document),\n })\n}\n\n/**\n * Returns the 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 /** Fetch function for retrieving documents */\n fetch?: WorkspaceDocumentInput['fetch']\n /** A list of all registered plugins for the current workspace */\n plugins?: WorkspacePlugin[]\n /** A file loader plugin for resolving local file references (for non browser environments) */\n fileLoader?: LoaderPlugin\n}\n\n/**\n * Type definition for the workspace store return object.\n * This explicit type is needed to avoid TypeScript inference limits.\n *\n * @see https://github.com/microsoft/TypeScript/issues/43817#issuecomment-827746462\n */\nexport type WorkspaceStore = {\n /**\n * Returns the reactive workspace object with an additional activeDocument getter\n */\n readonly workspace: Workspace\n /**\n * Updates a specific metadata field in the workspace\n * @param key - The metadata field to update\n * @param value - The new value for the field\n * @example\n * // Update the workspace title\n * update('x-scalar-active-document', 'document-name')\n */\n update<K extends keyof WorkspaceMeta | keyof WorkspaceExtensions>(\n key: K,\n value: (WorkspaceMeta & WorkspaceExtensions)[K],\n ): void\n /**\n * Updates a specific metadata field 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, navigationOptions?: NavigationOptions): Promise<boolean>\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This method removes the document from the workspace along with all related data including:\n * - The document itself from the workspace documents map\n * - Original document data\n * - Intermediate document data (saved local versions)\n * - Document-specific configuration\n * - Document overrides\n * - Extra document configurations\n *\n * If the deleted document was the active document, the active document is automatically\n * reset to the first remaining document in the workspace, or undefined if no documents remain.\n *\n * The deletion is automatically tracked by the workspace change detection system,\n * and appropriate events will be fired to notify registered plugins.\n *\n * @param documentName - The name of the document to delete\n * @returns void\n *\n * @example\n * // Delete the document named 'api'\n * store.deleteDocument('api')\n *\n * @example\n * // Delete multiple documents\n * ['api', 'petstore'].forEach(name => store.deleteDocument(name))\n */\n deleteDocument(documentName: string): void\n /**\n * Exports the specified document in the requested format.\n *\n * This method serializes the most recently saved local version of the document (from the intermediateDocuments map)\n * to either JSON or YAML. The exported document reflects the last locally saved state, including any edits\n * that have been saved but not yet synced to a remote registry. Runtime/in-memory changes that have not been saved\n * will not be included.\n *\n * @param documentName - The name of the document to export.\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The document as a string in the requested format, or undefined if the document does not exist.\n *\n * @example\n * // Export a document as JSON\n * const jsonString = store.exportDocument('api', 'json')\n *\n * // Export a document as YAML\n * const yamlString = store.exportDocument('api', 'yaml')\n */\n exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Exports the currently active document in the requested format.\n *\n * This is a convenience method that exports the active document (determined by the workspace's\n * activeDocument extension) without requiring the caller to specify the document name.\n * The exported document reflects the last locally saved state, including any edits that have\n * been saved but not yet synced to a remote registry.\n *\n * @param format - The output format: 'json' for a JSON string, or 'yaml' for a YAML string.\n * @returns The active document as a string in the requested format, or undefined if no active document exists.\n *\n * @example\n * // Export the active document as JSON\n * const jsonString = store.exportActiveDocument('json')\n *\n * // Export the active document as YAML\n * const yamlString = store.exportActiveDocument('yaml')\n */\n exportActiveDocument(format: 'json' | 'yaml', minify?: boolean): string | undefined\n /**\n * Saves the current state of the specified document to the intermediate documents map.\n *\n * This function captures the latest (reactive) state of the document from the workspace and\n * applies its changes to the corresponding entry in the `intermediateDocuments` map.\n * The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n * which may include edits not yet synced to the remote registry.\n *\n * The update is performed in-place. A deep clone of the current document\n * state is used to avoid mutating the reactive object directly.\n *\n * @param documentName - The name of the document to save.\n * @returns An array of diffs that were excluded from being applied (such as changes to ignored keys),\n * or undefined if the document does not exist or cannot be updated.\n *\n * @example\n * // Save the current state of the document named 'api'\n * const excludedDiffs = store.saveDocument('api')\n */\n saveDocument(documentName: string): Promise<unknown[] | undefined>\n /**\n * Builds the sidebar for the specified document.\n *\n * @param documentName - The name of the document to build the sidebar for\n * @returns boolean indicating if the sidebar was built successfully\n */\n buildSidebar: (documentName: string) => boolean\n /**\n * Restores the specified document to its last locally saved state.\n *\n * This method updates the current reactive document (in the workspace) with the contents of the\n * corresponding intermediate document (from the `intermediateDocuments` map), effectively discarding\n * any unsaved in-memory changes and reverting to the last saved version.\n * Vue reactivity is preserved by updating the existing reactive object in place.\n *\n * **Warning:** This operation will discard all unsaved (in-memory) changes to the specified document.\n *\n * @param documentName - The name of the document to restore.\n * @returns void\n *\n * @example\n * // Restore the document named 'api' to its last saved state\n * store.revertDocumentChanges('api')\n */\n revertDocumentChanges(documentName: string): Promise<void>\n /**\n * Commits the specified document.\n *\n * This method is intended to finalize and persist the current state of the document,\n * potentially syncing it with a remote registry or marking it as the latest committed version.\n *\n * @param documentName - The name of the document to commit.\n * @remarks\n * The actual commit logic is not implemented yet.\n */\n commitDocument(documentName: string): void\n /**\n * Exports the complete current workspace state as a plain JavaScript object.\n *\n * The returned object includes all workspace documents (with Vue reactivity removed), workspace metadata,\n * document configurations, and both the original and intermediate document maps. This object can be\n * serialized (e.g., with JSON.stringify) and later imported to fully restore the workspace\u2014including\n * all documents, their configurations, metadata, and historical states.\n *\n * @returns An `InMemoryWorkspace` object representing the entire workspace state,\n * suitable for persistence, backup, or sharing.\n */\n exportWorkspace(): InMemoryWorkspace\n /**\n * Imports a workspace from a serialized JSON string.\n *\n * This method parses the input string using the InMemoryWorkspaceSchema,\n * then updates the current workspace state, including documents, metadata,\n * and configuration, with the imported values.\n *\n * @param input - The serialized workspace JSON string to import.\n */\n loadWorkspace(input: InMemoryWorkspace): void\n /**\n * Imports a workspace from a WorkspaceSpecification object.\n *\n * This method assigns workspace metadata and adds all documents defined in the specification.\n * Each document is added using its $ref and optional overrides.\n *\n * @example\n * ```ts\n * await store.importWorkspaceFromSpecification({\n * documents: {\n * api: { $ref: '/specs/api.yaml' },\n * petstore: { $ref: '/specs/petstore.yaml' }\n * },\n * overrides: {\n * api: { config: { features: { showModels: true } } }\n * },\n * info: { title: 'My Workspace' },\n * workspace: 'v1',\n * \"x-scalar-color-mode\": true\n * })\n * ```\n *\n * @param specification - The workspace specification to import.\n */\n importWorkspaceFromSpecification(specification: WorkspaceSpecification): Promise<boolean[]>\n /**\n * Rebases a document in the workspace by refetching its origin and merging with local edits.\n *\n * This method fetches the latest version of the document (optionally with custom fetch/config),\n * calculates changes relative to the original and locally edited versions,\n * and attempts to update the workspace document while preserving user edits.\n * If automatic resolution isn't possible due to conflicts, returns a conflict list for the caller to resolve.\n * If `resolvedConflicts` are provided (e.g., after user intervention), applies them to complete the rebase.\n *\n * @param input Object specifying which document to rebase\n * @returns If there are unresolved conflicts, resolves to an object containing the list of conflicts and a method to apply user-resolved conflicts; otherwise resolves to void.\n *\n * @example\n * // Rebase a document and handle conflicts interactively\n * const result = await store.rebaseDocument({ name: 'api', fetch: customFetch });\n * if (result && result.ok) {\n * // Present conflicts to the user and collect resolutions...\n * await result.applyChanges(userResolvedConflicts);\n * }\n */\n rebaseDocument: (input: WorkspaceDocumentInput) => Promise<\n | { ok: false; type: 'CORRUPTED_STATE' | 'FETCH_FAILED' | 'NO_CHANGES_DETECTED'; message: string }\n | {\n ok: true\n conflicts: ReturnType<typeof merge>['conflicts']\n applyChanges: (resolvedConflicts: Difference<unknown>[]) => Promise<void>\n }\n >\n}\n\n/**\n * Creates a reactive workspace store that manages documents and their metadata.\n * The store provides functionality for accessing, updating, and resolving document references.\n *\n * @param workspaceProps - Configuration object for the workspace\n * @param workspaceProps.meta - Optional metadata for the workspace\n * @param workspaceProps.documents - Optional record of documents to initialize the workspace with\n * Documents that require asynchronous loading must be added using `1` after the store is created\n * this allows atomic awaiting and does not block page load for the store initialization\n * @returns An object containing methods and getters for managing the workspace\n */\nexport const createWorkspaceStore = (workspaceProps?: WorkspaceProps): WorkspaceStore => {\n /**\n * Holds additional configuration options for each document in the workspace.\n *\n * This can include settings that can not be persisted between sessions (not JSON serializable)\n */\n const extraDocumentConfigurations: ExtraDocumentConfigurations = {}\n\n /**\n * Notifies all workspace plugins of a workspace state change event.\n *\n * This function iterates through all registered plugins (if any) and invokes\n * their onWorkspaceStateChanges hook with the given event object.\n *\n * @param event - The workspace state change event to broadcast to plugins\n */\n const fireWorkspaceChange = (event: WorkspaceStateChangeEvent) => {\n workspaceProps?.plugins?.forEach((plugin) => plugin.hooks?.onWorkspaceStateChanges?.(event))\n }\n\n /**\n * An object containing the reactive workspace state.\n *\n * Every change to the workspace, is tracked and broadcast to all registered plugins.\n * allowing for change tracking.\n *\n * NOTE:\n * The detect changes proxy is applied separately beacause the vue reactitvity proxy have to be the outer most proxy.\n * If the order is reversed, Vue cannot properly track mutations, leading to lost reactivity and bugs.\n * By wrapping the contents with the detect changes proxy first, and then passing the result to Vue's `reactive`,\n * we ensure that Vue manages its reactivity as expected and our change detection hooks\n * are also triggered reliably.\n * Do not reverse this order\u203C\uFE0F\n */\n const workspace = reactive<Workspace>(\n createDetectChangesProxy(\n {\n ...workspaceProps?.meta,\n documents: {},\n /**\n * Returns the currently active document from the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The active document or undefined if no document is found\n */\n get activeDocument(): NonNullable<Workspace['activeDocument']> | undefined {\n return workspace.documents[getActiveDocumentName()]\n },\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n /** Document changes */\n if (type === 'documents') {\n // We are overriding the while documents object, ignore. This should not happen\n if (path.length < 2) {\n console.log('[WARN]: Overriding entire documents object is not supported')\n return\n }\n\n const documentName = path[1] as string\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Active document changes */\n if (type === 'activeDocument') {\n const documentName = getActiveDocumentName()\n const document = workspace.documents[documentName] ?? {\n openapi: '3.1.0',\n info: { title: '', version: '' },\n 'x-scalar-original-document-hash': '',\n }\n // Active document changed\n const event = {\n type: 'documents',\n documentName,\n value: unpackProxyObject(document),\n path: path.slice(2),\n } satisfies WorkspaceStateChangeEvent\n\n // Don't mark as dirty when the document is first created\n if (event.path.length > 0 && event.path[0] !== 'x-scalar-is-dirty') {\n // The document has been modified since it was last saved\n document['x-scalar-is-dirty'] = true\n }\n\n fireWorkspaceChange(event)\n return\n }\n\n /** Workspace meta changes */\n const { activeDocument: _a, documents: _d, ...meta } = workspace\n const event = {\n type: 'meta',\n value: unpackProxyObject(meta, { depth: 1 }),\n } satisfies WorkspaceStateChangeEvent\n\n fireWorkspaceChange(event)\n return\n },\n },\n },\n ),\n )\n\n /**\n * An object containing all the workspace state, wrapped in a detect changes proxy.\n *\n * Every change to the workspace state (documents, configs, metadata, etc.) can be detected here,\n * allowing for change tracking.\n */\n const { originalDocuments, intermediateDocuments, overrides } = createDetectChangesProxy(\n {\n /**\n * Holds the original, unmodified documents as they were initially loaded into the workspace.\n * These documents are stored in their raw form\u2014prior to any reactive wrapping, dereferencing, or bundling.\n * This map preserves the pristine structure of each document, using deep clones to ensure that\n * subsequent mutations in the workspace do not affect the originals.\n * The originals are retained so that we can restore, compare, or sync with the remote registry as needed.\n */\n originalDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores the intermediate state of documents after local edits but before syncing with the remote registry.\n *\n * This map acts as a local \"saved\" version of the document, reflecting the user's changes after they hit \"save\".\n * The `originalDocuments` map, by contrast, always mirrors the document as it exists in the remote registry.\n *\n * Use this map to stage local changes that are ready to be propagated back to the remote registry.\n * This separation allows us to distinguish between:\n * - The last known remote version (`originalDocuments`)\n * - The latest locally saved version (`intermediateDocuments`)\n * - The current in-memory (possibly unsaved) workspace document (`workspace.documents`)\n */\n intermediateDocuments: {} as Record<string, UnknownObject>,\n /**\n * Stores per-document overrides for OpenAPI documents.\n * This object is used to override specific fields of a document\n * when you cannot (or should not) modify the source document directly.\n * For example, this enables UI-driven or temporary changes to be applied\n * on top of the original document, without mutating the source.\n * The key is the document name, and the value is a deep partial\n * OpenAPI document representing the overridden fields.\n */\n overrides: {} as InMemoryWorkspace['overrides'],\n },\n {\n hooks: {\n onAfterChange(path) {\n const type = path[0]\n\n if (!type) {\n return\n }\n\n if (path.length < 2) {\n return\n }\n\n const documentName = path[1] as string\n if (type === 'originalDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(originalDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'intermediateDocuments') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(intermediateDocuments[documentName] ?? {}),\n path: path.splice(2),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n\n if (type === 'overrides') {\n const event = {\n type,\n documentName: documentName,\n value: unpackProxyObject(overrides[documentName] ?? {}),\n } satisfies WorkspaceStateChangeEvent\n fireWorkspaceChange(event)\n }\n },\n },\n },\n )\n\n /**\n * Returns the name of the currently active document in the workspace.\n * The active document is determined by the 'x-scalar-active-document' metadata field,\n * falling back to the first document in the workspace if no active document is specified.\n *\n * @returns The name of the active document or an empty string if no document is found\n */\n function getActiveDocumentName() {\n return workspace[extensions.workspace.activeDocument] ?? Object.keys(workspace.documents)[0] ?? ''\n }\n\n function exportDocument(documentName: string, format: 'json' | 'yaml', minify?: boolean) {\n const intermediateDocument = intermediateDocuments[documentName]\n\n if (!intermediateDocument) {\n return\n }\n\n if (format === 'json') {\n return minify ? JSON.stringify(intermediateDocument) : JSON.stringify(intermediateDocument, null, 2)\n }\n\n return YAML.stringify(intermediateDocument)\n }\n\n // Save the current state of the specified document to the intermediate documents map.\n // This function captures the latest (reactive) state of the document from the workspace and\n // applies its changes to the corresponding entry in the `intermediateDocuments` map.\n // The `intermediateDocuments` map represents the most recently \"saved\" local version of the document,\n // which may include edits not yet synced to the remote registry.\n async function saveDocument(documentName: string) {\n const intermediateDocument = intermediateDocuments[documentName]\n const workspaceDocument = workspace.documents[documentName]\n\n if (!workspaceDocument) {\n return\n }\n\n // Obtain the raw state of the current document to ensure accurate diffing\n const activeDocumentRaw = unpackProxyObject(workspaceDocument)\n\n // If either the intermediate or updated document is missing, do nothing\n if (!intermediateDocument || !activeDocumentRaw) {\n console.warn('Failed to save document, intermediate document and/or active document is missing')\n return\n }\n\n // Traverse the document and convert refs back to the original shape\n const updatedWithOriginalRefs = await bundle(deepClone(activeDocumentRaw), {\n plugins: [restoreOriginalRefs()],\n treeShake: false,\n urlMap: true,\n })\n\n // Apply changes from the current document to the intermediate document in place\n const excludedDiffs = applySelectiveUpdates(intermediateDocument, updatedWithOriginalRefs as UnknownObject)\n\n // Mark the document as not dirty since we are saving it\n workspaceDocument['x-scalar-is-dirty'] = false\n\n return excludedDiffs\n }\n\n // Add a document to the store synchronously from an in-memory OpenAPI document\n async function addInMemoryDocument(\n input: ObjectDoc & { initialize?: boolean; documentSource?: string; documentHash: string },\n navigationOptions?: NavigationOptions,\n ) {\n const { name, meta } = input\n const clonedRawInputDocument = measureSync('deepClone', () => deepClone(input.document))\n\n measureSync('initialize', () => {\n if (input.initialize !== false) {\n // Store the original document in the originalDocuments map\n // This is used to track the original state of the document as it was loaded into the workspace\n originalDocuments[name] = deepClone(clonedRawInputDocument)\n\n // Store the intermediate document state for local edits\n // This is used to track the last saved state of the document\n // It allows us to differentiate between the original document and the latest saved version\n // This is important for local edits that are not yet synced with the remote registry\n // The intermediate document is used to store the latest saved state of the document\n // This allows us to track changes and revert to the last saved state if needed\n intermediateDocuments[name] = deepClone(clonedRawInputDocument)\n // Store the overrides for this document, or an empty object if none are provided\n overrides[name] = input.overrides ?? {}\n // Store extra document configurations that can not be persisted\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n }\n })\n\n const inputDocument = measureSync('upgrade', () => upgrade(deepClone(clonedRawInputDocument), '3.1'))\n\n const strictDocument: UnknownObject = createMagicProxy(\n {\n ...inputDocument,\n ...meta,\n 'x-original-oas-version': originalDocuments[name]?.openapi ?? originalDocuments[name]?.swagger,\n 'x-scalar-original-document-hash': input.documentHash,\n 'x-scalar-original-source-url': input.documentSource,\n },\n { showInternal: true },\n )\n\n // If the document navigation is not already present, bundle the entire document to resolve all references.\n // This typically applies when the document is not preprocessed by the server and needs local reference resolution.\n // We need to bundle document first before we validate, so we can also validate the external references\n if (strictDocument[extensions.document.navigation] === undefined) {\n const loaders = [\n fetchUrls({\n fetch: extraDocumentConfigurations[name]?.fetch ?? workspaceProps?.fetch,\n }),\n ]\n\n // If a file loader plugin is provided, use it to resolve local file references\n // This is useful for non browser environments\n if (workspaceProps?.fileLoader) {\n loaders.push(workspaceProps.fileLoader)\n }\n\n await measureAsync(\n 'bundle',\n async () =>\n await bundle(getRaw(strictDocument), {\n treeShake: false,\n plugins: [...loaders, externalValueResolver(), refsEverywhere(), normalizeAuthSchemes()],\n urlMap: true,\n origin: input.documentSource, // use the document origin (if provided) as the base URL for resolution\n }),\n )\n\n // We coerce the values only when the document is not preprocessed by the server-side-store\n const coerced = measureSync('coerceValue', () =>\n coerceValue(OpenAPIDocumentSchemaStrict, deepClone(strictDocument)),\n )\n measureSync('mergeObjects', () => mergeObjects(strictDocument, coerced))\n }\n\n const isValid = Value.Check(OpenAPIDocumentSchemaStrict, strictDocument)\n\n if (!isValid) {\n const validationErrors = Array.from(Value.Errors(OpenAPIDocumentSchemaStrict, strictDocument))\n\n console.warn('document validation errors: ')\n console.warn(\n validationErrors.map((error) => ({\n message: error.message,\n path: error.path,\n schema: error.schema,\n value: error.value,\n })),\n )\n }\n\n // Skip navigation generation if the document already has a server-side generated navigation structure\n if (strictDocument[extensions.document.navigation] === undefined) {\n const navigation = createNavigation(name, strictDocument as OpenApiDocument, navigationOptions)\n strictDocument[extensions.document.navigation] = navigation\n }\n\n // Create a proxied document with magic proxy and apply any overrides, then store it in the workspace documents map\n // We create a new proxy here in order to hide internal properties after validation and processing\n // This ensures that the workspace document only exposes the intended OpenAPI properties and extensions\n workspace.documents[name] = createOverridesProxy(createMagicProxy(getRaw(strictDocument)) as OpenApiDocument, {\n overrides: unpackProxyObject(overrides[name]),\n })\n }\n\n // Asynchronously adds a new document to the workspace by loading and validating the input.\n // If loading fails, a placeholder error document is added instead.\n async function addDocument(input: WorkspaceDocumentInput, navigationOptions?: NavigationOptions) {\n const { name, meta } = input\n\n /** Ensure we use the active proxy to fetch documents unless we have a custom fetch override */\n const fetch = getFetch({\n fetch: input.fetch ?? workspaceProps?.fetch,\n proxyUrl: workspace['x-scalar-active-proxy'],\n })\n\n const resolve = await measureAsync('loadDocument', async () => await loadDocument({ ...input, fetch }))\n\n // Log the time taken to add a document\n return await measureAsync('addDocument', async () => {\n if (!resolve.ok) {\n console.error(`Failed to fetch document '${name}': request was not successful`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n if (!isObject(resolve.data)) {\n console.error(`Failed to load document '${name}': response data is not a valid object`)\n\n workspace.documents[name] = {\n ...meta,\n openapi: '3.1.0',\n info: {\n title: `Document '${name}' could not be loaded`,\n version: 'unknown',\n },\n 'x-scalar-original-document-hash': 'not-a-hash',\n }\n\n return false\n }\n\n await addInMemoryDocument(\n {\n ...input,\n document: resolve.data,\n documentSource: getDocumentSource(input),\n documentHash: generateHash(resolve.raw),\n },\n navigationOptions,\n )\n\n return true\n })\n }\n\n /**\n * Builds (or updates) the navigation sidebar for the specified document.\n *\n * This method generates the sidebar navigation structure for a workspace document,\n * and attaches it to the document's metadata under the navigation extension key.\n * The document is unpacked to avoid assigning proxy objects as direct property references.\n *\n * - Only the top-level object is proxied; all child objects should be unproxied.\n * - This approach enables safe unpacking of the proxy object without recursively traversing the full object tree.\n *\n * @param documentName - The name/key of the document whose sidebar should be built.\n * @returns {boolean} True if the sidebar was built successfully, false if the document does not exist.\n */\n const buildSidebar = (documentName: string): boolean => {\n const document = workspace.documents[documentName]\n\n if (!document) {\n // Log and exit if the document does not exist in the workspace\n console.error(`Document '${documentName}' does not exist in the workspace.`)\n return false\n }\n\n // Generate the navigation structure for the sidebar.\n const navigation = createNavigation(documentName, document)\n\n // Set the computed navigation structure on the document metadata.\n document[extensions.document.navigation] = navigation\n\n return true\n }\n\n // Cache to track visited nodes during reference resolution to prevent bundling the same subtree multiple times\n // This is needed because we are doing partial bundle operations\n const visitedNodesCache = new Set()\n\n return {\n get workspace() {\n return workspace\n },\n update(key, value) {\n preventPollution(key)\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 preventPollution(key)\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 documentSource: currentDocument['x-scalar-original-source-url'],\n documentHash: currentDocument['x-scalar-original-document-hash'],\n meta: {\n 'x-scalar-active-auth': currentDocument['x-scalar-active-auth'],\n 'x-scalar-active-server': currentDocument['x-scalar-active-server'],\n },\n initialize: false,\n })\n },\n resolve: (path) => {\n const activeDocument = workspace.activeDocument\n\n const target = getValueByPath(activeDocument, path)\n\n if (!isObject(target)) {\n console.error(\n `Invalid path provided for resolution. Path: [${path.join(', ')}]. Found value of type: ${typeof target}. Expected an object.`,\n )\n return Promise.resolve()\n }\n\n // Bundle the target document with the active document as root, resolving any external references\n // and tracking resolution status through hooks\n return bundle(target, {\n root: activeDocument,\n treeShake: false,\n plugins: [fetchUrls(), loadingStatus(), externalValueResolver()],\n urlMap: true,\n visitedNodes: visitedNodesCache,\n })\n },\n addDocument,\n /**\n * Deletes a document from the workspace and all associated data.\n *\n * This function removes the document and all related data structures.\n * If the deleted document was active, it automatically selects the first remaining document.\n */\n deleteDocument: (documentName: string): void => {\n // Check if the document exists before attempting deletion\n if (!workspace.documents[documentName]) {\n return\n }\n\n // Delete the document from the workspace (this will trigger change detection events)\n delete workspace.documents[documentName]\n\n // Clean up all associated data structures\n delete originalDocuments[documentName]\n delete intermediateDocuments[documentName]\n delete overrides[documentName]\n delete extraDocumentConfigurations[documentName]\n\n // Get remaining documents before deletion to properly set the active document\n const remainingDocuments = Object.keys(workspace.documents)\n const wasActiveDocument = workspace['x-scalar-active-document'] === documentName\n\n // Reset the active document to the first remaining one if the deleted document was the active one\n if (wasActiveDocument) {\n workspace['x-scalar-active-document'] = remainingDocuments[0] ?? undefined\n }\n\n // Fire the deleteDocument event\n fireWorkspaceChange({\n type: 'deleteDocument',\n documentName,\n })\n },\n exportDocument,\n exportActiveDocument: (format, minify) => exportDocument(getActiveDocumentName(), format, minify),\n buildSidebar,\n saveDocument,\n async revertDocumentChanges(documentName: string) {\n const workspaceDocument = workspace.documents[documentName]\n const intermediate = intermediateDocuments[documentName]\n\n if (!workspaceDocument || !intermediate) {\n return\n }\n\n await addInMemoryDocument({\n name: documentName,\n document: intermediate,\n documentSource: workspaceDocument['x-scalar-original-source-url'],\n documentHash: workspaceDocument['x-scalar-original-document-hash'],\n initialize: false,\n })\n },\n commitDocument(documentName: string) {\n // TODO: Implement commit logic\n console.warn(`Commit operation for document '${documentName}' is not implemented yet.`)\n },\n exportWorkspace() {\n const { activeDocument: _, documents, ...meta } = unpackProxyObject(workspace)\n return {\n documents: {\n ...Object.fromEntries(\n Object.entries(documents).map(([name, doc]) => [\n name,\n // Get the raw document without any proxies\n unpackProxyObject(doc),\n ]),\n ),\n },\n meta: unpackProxyObject(meta) ?? {},\n originalDocuments: unpackProxyObject(originalDocuments),\n intermediateDocuments: unpackProxyObject(intermediateDocuments),\n overrides: unpackProxyObject(overrides),\n } satisfies InMemoryWorkspace\n },\n loadWorkspace(input: InMemoryWorkspace) {\n safeAssign(\n workspace.documents,\n Object.fromEntries(\n Object.entries(input.documents).map(([name, doc]) => [\n name,\n createOverridesProxy(createMagicProxy(doc), {\n overrides: input.overrides[name],\n }),\n ]),\n ),\n )\n\n safeAssign(originalDocuments, input.originalDocuments)\n safeAssign(intermediateDocuments, input.intermediateDocuments)\n safeAssign(overrides, input.overrides)\n safeAssign(workspace, input.meta)\n },\n importWorkspaceFromSpecification: (specification: WorkspaceSpecification) => {\n const { documents, overrides, info: _info, workspace: _workspaceVersion, ...meta } = specification\n\n // Assign workspace metadata\n safeAssign(workspace, meta)\n\n // Add workspace documents\n return Promise.all(\n Object.entries(documents ?? {}).map(([name, doc]) =>\n addDocument({ url: doc.$ref, name, overrides: overrides?.[name] }),\n ),\n )\n },\n rebaseDocument: async (input: WorkspaceDocumentInput) => {\n const { name } = input\n\n // ---- Get the current documents\n const originalDocument = originalDocuments[name]\n const intermediateDocument = intermediateDocuments[name]\n // raw version without any proxies\n const activeDocument = workspace.documents[name]\n ? toRaw(getRaw(unpackOverridesProxy(workspace.documents[name])))\n : undefined\n\n if (!originalDocument || !intermediateDocument || !activeDocument) {\n // If any required document state is missing, do nothing\n return {\n ok: false,\n type: 'CORRUPTED_STATE' as const,\n message: `Cannot rebase document '${name}': missing original, intermediate, or active document state`,\n }\n }\n\n // ---- Resolve input document\n const resolve = await measureAsync(\n 'loadDocument',\n async () => await loadDocument({ ...input, fetch: input.fetch ?? workspaceProps?.fetch }),\n )\n\n if (!resolve.ok || !isObject(resolve.data)) {\n return {\n ok: false,\n type: 'FETCH_FAILED' as const,\n message: `Failed to fetch document '${name}': request was not successful or returned invalid data`,\n }\n }\n\n // Compare document hashes to see if the document has changed\n // When the hashes match, we can skip the rebase process\n const newHash = generateHash(resolve.raw)\n if (activeDocument['x-scalar-original-document-hash'] === newHash) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}': document hash matches the active document`,\n }\n }\n\n const newDocumentOrigin = resolve.data\n\n // ---- Override the configurations and metadata\n overrides[name] = input.overrides ?? {}\n extraDocumentConfigurations[name] = { fetch: input.fetch }\n\n // ---- Get the new intermediate document\n const changelogAA = diff(originalDocument, newDocumentOrigin)\n\n // When there are no changes, we can return early since we don't need to do anything\n // This is not supposed to happen due to the hash check above, but just in case\n if (changelogAA.length === 0) {\n return {\n ok: false,\n type: 'NO_CHANGES_DETECTED' as const,\n message: `No changes detected for document '${name}' after fetching the latest version.`,\n }\n }\n\n const changelogAB = diff(originalDocument, intermediateDocument)\n\n const changesA = merge(changelogAA, changelogAB)\n\n return {\n ok: true,\n conflicts: changesA.conflicts,\n applyChanges: async (resolvedConflicts: Difference<unknown>[]) => {\n const changesetA = changesA.diffs.concat(resolvedConflicts)\n\n // Apply the changes to the original document to get the new intermediate\n const newIntermediateDocument = apply(deepClone(originalDocument), changesetA)\n intermediateDocuments[name] = newIntermediateDocument\n\n // Update the original document\n originalDocuments[name] = newDocumentOrigin\n\n // ---- Get the new active document\n const changelogBA = diff(intermediateDocument, newIntermediateDocument)\n const changelogBB = diff(intermediateDocument, activeDocument)\n\n const changesB = merge(changelogBA, changelogBB)\n\n // Auto-conflict resolution: pick only the changes from the first changeset\n // TODO: In the future, implement smarter conflict resolution if needed\n const changesetB = changesB.diffs.concat(changesB.conflicts.flatMap((it) => it[0]))\n\n const newActiveDocument = coerceValue(\n OpenAPIDocumentSchemaStrict,\n apply(deepClone(newIntermediateDocument), changesetB),\n )\n\n // add the new active document to the workspace but don't re-initialize\n await addInMemoryDocument({\n ...input,\n document: {\n ...newActiveDocument,\n // force regeneration of navigation\n // when we are rebasing, we want to ensure that the navigation is always up to date\n [extensions.document.navigation]: undefined,\n },\n documentSource: getDocumentSource(input),\n // Update the original document hash\n documentHash: generateHash(resolve.raw),\n initialize: false,\n })\n },\n }\n },\n }\n}\n\n// biome-ignore lint/performance/noBarrelFile: It's a package entry point\nexport { generateClientMutators } from '@/mutators'\n"],
5
+ "mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAC7B,SAAS,cAAc,mBAAmB;AAC1C,SAA4B,cAAc;AAC1C,SAAS,iBAAiB;AAC1B,SAA0B,OAAO,MAAM,aAAa;AACpD,SAAS,kBAAkB,cAAc;AACzC,SAAS,eAAe;AAExB,SAAS,aAAa;AAEtB,SAAS,UAAU,aAAa;AAChC,OAAO,UAAU;AAEjB,SAAS,6BAA6B;AACtC,SAAS,iBAAiB;AAC1B,SAAS,gCAAgC;AACzC,SAA6B,kBAAkB;AAC/C,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB,4BAA4B;AAC3D,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AAEjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAE3B,SAAS,mBAAmB;AAC5B;AAAA,EACE,yBAAyB;AAAA,OAEpB;AAqEP,SAAS,aAAa,mBAA6E;AACjG,MAAI,SAAS,mBAAmB;AAC9B,WAAO,UAAU,EAAE,OAAO,kBAAkB,MAAM,CAAC,EAAE,KAAK,kBAAkB,GAAG;AAAA,EACjF;AAEA,SAAO,QAAQ,QAAQ;AAAA,IACrB,IAAI;AAAA,IACJ,MAAM,kBAAkB;AAAA;AAAA,IAExB,KAAK,KAAK,UAAU,kBAAkB,QAAQ;AAAA,EAChD,CAAC;AACH;AASA,MAAM,oBAAoB,CAAC,UAAkC;AAC3D,MAAI,SAAS,OAAO;AAClB,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;AA6TO,MAAM,uBAAuB,CAAC,mBAAoD;AAMvF,QAAM,8BAA2D,CAAC;AAUlE,QAAM,sBAAsB,CAAC,UAAqC;AAChE,oBAAgB,SAAS,QAAQ,CAAC,WAAW,OAAO,OAAO,0BAA0B,KAAK,CAAC;AAAA,EAC7F;AAgBA,QAAM,YAAY;AAAA,IAChB;AAAA,MACE;AAAA,QACE,GAAG,gBAAgB;AAAA,QACnB,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQZ,IAAI,iBAAuE;AACzE,iBAAO,UAAU,UAAU,sBAAsB,CAAC;AAAA,QACpD;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO;AAAA,UACL,cAAc,MAAM;AAClB,kBAAM,OAAO,KAAK,CAAC;AAGnB,gBAAI,SAAS,aAAa;AAExB,kBAAI,KAAK,SAAS,GAAG;AACnB,wBAAQ,IAAI,6DAA6D;AACzE;AAAA,cACF;AAEA,oBAAM,eAAe,KAAK,CAAC;AAC3B,oBAAM,WAAW,UAAU,UAAU,YAAY,KAAK;AAAA,gBACpD,SAAS;AAAA,gBACT,MAAM,EAAE,OAAO,IAAI,SAAS,GAAG;AAAA,gBAC/B,mCAAmC;AAAA,cACrC;AACA,oBAAMA,SAAQ;AAAA,gBACZ,MAAM;AAAA,gBACN;AAAA,gBACA,OAAO,kBAAkB,QAAQ;AAAA,gBACjC,MAAM,KAAK,MAAM,CAAC;AAAA,cACpB;AAGA,kBAAIA,OAAM,KAAK,SAAS,KAAKA,OAAM,KAAK,CAAC,MAAM,qBAAqB;AAElE,yBAAS,mBAAmB,IAAI;AAAA,cAClC;AAEA,kCAAoBA,MAAK;AACzB;AAAA,YACF;AAGA,gBAAI,SAAS,kBAAkB;AAC7B,oBAAM,eAAe,sBAAsB;AAC3C,oBAAM,WAAW,UAAU,UAAU,YAAY,KAAK;AAAA,gBACpD,SAAS;AAAA,gBACT,MAAM,EAAE,OAAO,IAAI,SAAS,GAAG;AAAA,gBAC/B,mCAAmC;AAAA,cACrC;AAEA,oBAAMA,SAAQ;AAAA,gBACZ,MAAM;AAAA,gBACN;AAAA,gBACA,OAAO,kBAAkB,QAAQ;AAAA,gBACjC,MAAM,KAAK,MAAM,CAAC;AAAA,cACpB;AAGA,kBAAIA,OAAM,KAAK,SAAS,KAAKA,OAAM,KAAK,CAAC,MAAM,qBAAqB;AAElE,yBAAS,mBAAmB,IAAI;AAAA,cAClC;AAEA,kCAAoBA,MAAK;AACzB;AAAA,YACF;AAGA,kBAAM,EAAE,gBAAgB,IAAI,WAAW,IAAI,GAAG,KAAK,IAAI;AACvD,kBAAM,QAAQ;AAAA,cACZ,MAAM;AAAA,cACN,OAAO,kBAAkB,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,YAC7C;AAEA,gCAAoB,KAAK;AACzB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAQA,QAAM,EAAE,mBAAmB,uBAAuB,UAAU,IAAI;AAAA,IAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQE,mBAAmB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAapB,uBAAuB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUxB,WAAW,CAAC;AAAA,IACd;AAAA,IACA;AAAA,MACE,OAAO;AAAA,QACL,cAAc,MAAM;AAClB,gBAAM,OAAO,KAAK,CAAC;AAEnB,cAAI,CAAC,MAAM;AACT;AAAA,UACF;AAEA,cAAI,KAAK,SAAS,GAAG;AACnB;AAAA,UACF;AAEA,gBAAM,eAAe,KAAK,CAAC;AAC3B,cAAI,SAAS,qBAAqB;AAChC,kBAAM,QAAQ;AAAA,cACZ;AAAA,cACA;AAAA,cACA,OAAO,kBAAkB,kBAAkB,YAAY,KAAK,CAAC,CAAC;AAAA,cAC9D,MAAM,KAAK,OAAO,CAAC;AAAA,YACrB;AACA,gCAAoB,KAAK;AAAA,UAC3B;AAEA,cAAI,SAAS,yBAAyB;AACpC,kBAAM,QAAQ;AAAA,cACZ;AAAA,cACA;AAAA,cACA,OAAO,kBAAkB,sBAAsB,YAAY,KAAK,CAAC,CAAC;AAAA,cAClE,MAAM,KAAK,OAAO,CAAC;AAAA,YACrB;AACA,gCAAoB,KAAK;AAAA,UAC3B;AAEA,cAAI,SAAS,aAAa;AACxB,kBAAM,QAAQ;AAAA,cACZ;AAAA,cACA;AAAA,cACA,OAAO,kBAAkB,UAAU,YAAY,KAAK,CAAC,CAAC;AAAA,YACxD;AACA,gCAAoB,KAAK;AAAA,UAC3B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AASA,WAAS,wBAAwB;AAC/B,WAAO,UAAU,WAAW,UAAU,cAAc,KAAK,OAAO,KAAK,UAAU,SAAS,EAAE,CAAC,KAAK;AAAA,EAClG;AAEA,WAAS,eAAe,cAAsB,QAAyB,QAAkB;AACvF,UAAM,uBAAuB,sBAAsB,YAAY;AAE/D,QAAI,CAAC,sBAAsB;AACzB;AAAA,IACF;AAEA,QAAI,WAAW,QAAQ;AACrB,aAAO,SAAS,KAAK,UAAU,oBAAoB,IAAI,KAAK,UAAU,sBAAsB,MAAM,CAAC;AAAA,IACrG;AAEA,WAAO,KAAK,UAAU,oBAAoB;AAAA,EAC5C;AAOA,iBAAe,aAAa,cAAsB;AAChD,UAAM,uBAAuB,sBAAsB,YAAY;AAC/D,UAAM,oBAAoB,UAAU,UAAU,YAAY;AAE1D,QAAI,CAAC,mBAAmB;AACtB;AAAA,IACF;AAGA,UAAM,oBAAoB,kBAAkB,iBAAiB;AAG7D,QAAI,CAAC,wBAAwB,CAAC,mBAAmB;AAC/C,cAAQ,KAAK,kFAAkF;AAC/F;AAAA,IACF;AAGA,UAAM,0BAA0B,MAAM,OAAO,UAAU,iBAAiB,GAAG;AAAA,MACzE,SAAS,CAAC,oBAAoB,CAAC;AAAA,MAC/B,WAAW;AAAA,MACX,QAAQ;AAAA,IACV,CAAC;AAGD,UAAM,gBAAgB,sBAAsB,sBAAsB,uBAAwC;AAG1G,sBAAkB,mBAAmB,IAAI;AAEzC,WAAO;AAAA,EACT;AAGA,iBAAe,oBACb,OACA,mBACA;AACA,UAAM,EAAE,MAAM,KAAK,IAAI;AACvB,UAAM,yBAAyB,YAAY,aAAa,MAAM,UAAU,MAAM,QAAQ,CAAC;AAEvF,gBAAY,cAAc,MAAM;AAC9B,UAAI,MAAM,eAAe,OAAO;AAG9B,0BAAkB,IAAI,IAAI,UAAU,sBAAsB;AAQ1D,8BAAsB,IAAI,IAAI,UAAU,sBAAsB;AAE9D,kBAAU,IAAI,IAAI,MAAM,aAAa,CAAC;AAEtC,oCAA4B,IAAI,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,MAC3D;AAAA,IACF,CAAC;AAED,UAAM,gBAAgB,YAAY,WAAW,MAAM,QAAQ,UAAU,sBAAsB,GAAG,KAAK,CAAC;AAEpG,UAAM,iBAAgC;AAAA,MACpC;AAAA,QACE,GAAG;AAAA,QACH,GAAG;AAAA,QACH,0BAA0B,kBAAkB,IAAI,GAAG,WAAW,kBAAkB,IAAI,GAAG;AAAA,QACvF,mCAAmC,MAAM;AAAA,QACzC,gCAAgC,MAAM;AAAA,MACxC;AAAA,MACA,EAAE,cAAc,KAAK;AAAA,IACvB;AAKA,QAAI,eAAe,WAAW,SAAS,UAAU,MAAM,QAAW;AAChE,YAAM,UAAU;AAAA,QACd,UAAU;AAAA,UACR,OAAO,4BAA4B,IAAI,GAAG,SAAS,gBAAgB;AAAA,QACrE,CAAC;AAAA,MACH;AAIA,UAAI,gBAAgB,YAAY;AAC9B,gBAAQ,KAAK,eAAe,UAAU;AAAA,MACxC;AAEA,YAAM;AAAA,QACJ;AAAA,QACA,YACE,MAAM,OAAO,OAAO,cAAc,GAAG;AAAA,UACnC,WAAW;AAAA,UACX,SAAS,CAAC,GAAG,SAAS,sBAAsB,GAAG,eAAe,GAAG,qBAAqB,CAAC;AAAA,UACvF,QAAQ;AAAA,UACR,QAAQ,MAAM;AAAA;AAAA,QAChB,CAAC;AAAA,MACL;AAGA,YAAM,UAAU;AAAA,QAAY;AAAA,QAAe,MACzC,YAAY,6BAA6B,UAAU,cAAc,CAAC;AAAA,MACpE;AACA,kBAAY,gBAAgB,MAAM,aAAa,gBAAgB,OAAO,CAAC;AAAA,IACzE;AAEA,UAAM,UAAU,MAAM,MAAM,6BAA6B,cAAc;AAEvE,QAAI,CAAC,SAAS;AACZ,YAAM,mBAAmB,MAAM,KAAK,MAAM,OAAO,6BAA6B,cAAc,CAAC;AAE7F,cAAQ,KAAK,8BAA8B;AAC3C,cAAQ;AAAA,QACN,iBAAiB,IAAI,CAAC,WAAW;AAAA,UAC/B,SAAS,MAAM;AAAA,UACf,MAAM,MAAM;AAAA,UACZ,QAAQ,MAAM;AAAA,UACd,OAAO,MAAM;AAAA,QACf,EAAE;AAAA,MACJ;AAAA,IACF;AAGA,QAAI,eAAe,WAAW,SAAS,UAAU,MAAM,QAAW;AAChE,YAAM,aAAa,iBAAiB,MAAM,gBAAmC,iBAAiB;AAC9F,qBAAe,WAAW,SAAS,UAAU,IAAI;AAAA,IACnD;AAKA,cAAU,UAAU,IAAI,IAAI,qBAAqB,iBAAiB,OAAO,cAAc,CAAC,GAAsB;AAAA,MAC5G,WAAW,kBAAkB,UAAU,IAAI,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAIA,iBAAe,YAAY,OAA+B,mBAAuC;AAC/F,UAAM,EAAE,MAAM,KAAK,IAAI;AAGvB,UAAM,QAAQ,SAAS;AAAA,MACrB,OAAO,MAAM,SAAS,gBAAgB;AAAA,MACtC,UAAU,UAAU,uBAAuB;AAAA,IAC7C,CAAC;AAED,UAAM,UAAU,MAAM,aAAa,gBAAgB,YAAY,MAAM,aAAa,EAAE,GAAG,OAAO,MAAM,CAAC,CAAC;AAGtG,WAAO,MAAM,aAAa,eAAe,YAAY;AACnD,UAAI,CAAC,QAAQ,IAAI;AACf,gBAAQ,MAAM,6BAA6B,IAAI,+BAA+B;AAE9E,kBAAU,UAAU,IAAI,IAAI;AAAA,UAC1B,GAAG;AAAA,UACH,SAAS;AAAA,UACT,MAAM;AAAA,YACJ,OAAO,aAAa,IAAI;AAAA,YACxB,SAAS;AAAA,UACX;AAAA,UACA,mCAAmC;AAAA,QACrC;AAEA,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,SAAS,QAAQ,IAAI,GAAG;AAC3B,gBAAQ,MAAM,4BAA4B,IAAI,wCAAwC;AAEtF,kBAAU,UAAU,IAAI,IAAI;AAAA,UAC1B,GAAG;AAAA,UACH,SAAS;AAAA,UACT,MAAM;AAAA,YACJ,OAAO,aAAa,IAAI;AAAA,YACxB,SAAS;AAAA,UACX;AAAA,UACA,mCAAmC;AAAA,QACrC;AAEA,eAAO;AAAA,MACT;AAEA,YAAM;AAAA,QACJ;AAAA,UACE,GAAG;AAAA,UACH,UAAU,QAAQ;AAAA,UAClB,gBAAgB,kBAAkB,KAAK;AAAA,UACvC,cAAc,aAAa,QAAQ,GAAG;AAAA,QACxC;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAeA,QAAM,eAAe,CAAC,iBAAkC;AACtD,UAAM,WAAW,UAAU,UAAU,YAAY;AAEjD,QAAI,CAAC,UAAU;AAEb,cAAQ,MAAM,aAAa,YAAY,oCAAoC;AAC3E,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,iBAAiB,cAAc,QAAQ;AAG1D,aAAS,WAAW,SAAS,UAAU,IAAI;AAE3C,WAAO;AAAA,EACT;AAIA,QAAM,oBAAoB,oBAAI,IAAI;AAElC,SAAO;AAAA,IACL,IAAI,YAAY;AACd,aAAO;AAAA,IACT;AAAA,IACA,OAAO,KAAK,OAAO;AACjB,uBAAiB,GAAG;AACpB,aAAO,OAAO,WAAW,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC;AAAA,IAC3C;AAAA,IACA,eACE,MACA,KACA,OACA;AACA,YAAM,kBAAkB,UAAU,UAAU,SAAS,WAAW,sBAAsB,IAAI,IAAI;AAE9F,UAAI,CAAC,iBAAiB;AACpB,cAAM;AAAA,MACR;AAEA,uBAAiB,GAAG;AACpB,aAAO,OAAO,iBAAiB,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC;AAAA,IACjD;AAAA,IACA,MAAM,gBAAgB,cAAsB,OAAgC;AAC1E,YAAM,kBAAkB,UAAU,UAAU,YAAY;AAExD,UAAI,CAAC,iBAAiB;AACpB,eAAO,QAAQ,MAAM,aAAa,YAAY,oCAAoC;AAAA,MACpF;AAGA,YAAM,oBAAoB;AAAA,QACxB,MAAM;AAAA,QACN,UAAU;AAAA;AAAA,QAEV,gBAAgB,gBAAgB,8BAA8B;AAAA,QAC9D,cAAc,gBAAgB,iCAAiC;AAAA,QAC/D,MAAM;AAAA,UACJ,wBAAwB,gBAAgB,sBAAsB;AAAA,UAC9D,0BAA0B,gBAAgB,wBAAwB;AAAA,QACpE;AAAA,QACA,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IACA,SAAS,CAAC,SAAS;AACjB,YAAM,iBAAiB,UAAU;AAEjC,YAAM,SAAS,eAAe,gBAAgB,IAAI;AAElD,UAAI,CAAC,SAAS,MAAM,GAAG;AACrB,gBAAQ;AAAA,UACN,gDAAgD,KAAK,KAAK,IAAI,CAAC,2BAA2B,OAAO,MAAM;AAAA,QACzG;AACA,eAAO,QAAQ,QAAQ;AAAA,MACzB;AAIA,aAAO,OAAO,QAAQ;AAAA,QACpB,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS,CAAC,UAAU,GAAG,cAAc,GAAG,sBAAsB,CAAC;AAAA,QAC/D,QAAQ;AAAA,QACR,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,gBAAgB,CAAC,iBAA+B;AAE9C,UAAI,CAAC,UAAU,UAAU,YAAY,GAAG;AACtC;AAAA,MACF;AAGA,aAAO,UAAU,UAAU,YAAY;AAGvC,aAAO,kBAAkB,YAAY;AACrC,aAAO,sBAAsB,YAAY;AACzC,aAAO,UAAU,YAAY;AAC7B,aAAO,4BAA4B,YAAY;AAG/C,YAAM,qBAAqB,OAAO,KAAK,UAAU,SAAS;AAC1D,YAAM,oBAAoB,UAAU,0BAA0B,MAAM;AAGpE,UAAI,mBAAmB;AACrB,kBAAU,0BAA0B,IAAI,mBAAmB,CAAC,KAAK;AAAA,MACnE;AAGA,0BAAoB;AAAA,QAClB,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,IACA,sBAAsB,CAAC,QAAQ,WAAW,eAAe,sBAAsB,GAAG,QAAQ,MAAM;AAAA,IAChG;AAAA,IACA;AAAA,IACA,MAAM,sBAAsB,cAAsB;AAChD,YAAM,oBAAoB,UAAU,UAAU,YAAY;AAC1D,YAAM,eAAe,sBAAsB,YAAY;AAEvD,UAAI,CAAC,qBAAqB,CAAC,cAAc;AACvC;AAAA,MACF;AAEA,YAAM,oBAAoB;AAAA,QACxB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,gBAAgB,kBAAkB,8BAA8B;AAAA,QAChE,cAAc,kBAAkB,iCAAiC;AAAA,QACjE,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IACA,eAAe,cAAsB;AAEnC,cAAQ,KAAK,kCAAkC,YAAY,2BAA2B;AAAA,IACxF;AAAA,IACA,kBAAkB;AAChB,YAAM,EAAE,gBAAgB,GAAG,WAAW,GAAG,KAAK,IAAI,kBAAkB,SAAS;AAC7E,aAAO;AAAA,QACL,WAAW;AAAA,UACT,GAAG,OAAO;AAAA,YACR,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM;AAAA,cAC7C;AAAA;AAAA,cAEA,kBAAkB,GAAG;AAAA,YACvB,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QACA,MAAM,kBAAkB,IAAI,KAAK,CAAC;AAAA,QAClC,mBAAmB,kBAAkB,iBAAiB;AAAA,QACtD,uBAAuB,kBAAkB,qBAAqB;AAAA,QAC9D,WAAW,kBAAkB,SAAS;AAAA,MACxC;AAAA,IACF;AAAA,IACA,cAAc,OAA0B;AACtC;AAAA,QACE,UAAU;AAAA,QACV,OAAO;AAAA,UACL,OAAO,QAAQ,MAAM,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM;AAAA,YACnD;AAAA,YACA,qBAAqB,iBAAiB,GAAG,GAAG;AAAA,cAC1C,WAAW,MAAM,UAAU,IAAI;AAAA,YACjC,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF;AAEA,iBAAW,mBAAmB,MAAM,iBAAiB;AACrD,iBAAW,uBAAuB,MAAM,qBAAqB;AAC7D,iBAAW,WAAW,MAAM,SAAS;AACrC,iBAAW,WAAW,MAAM,IAAI;AAAA,IAClC;AAAA,IACA,kCAAkC,CAAC,kBAA0C;AAC3E,YAAM,EAAE,WAAW,WAAAC,YAAW,MAAM,OAAO,WAAW,mBAAmB,GAAG,KAAK,IAAI;AAGrF,iBAAW,WAAW,IAAI;AAG1B,aAAO,QAAQ;AAAA,QACb,OAAO,QAAQ,aAAa,CAAC,CAAC,EAAE;AAAA,UAAI,CAAC,CAAC,MAAM,GAAG,MAC7C,YAAY,EAAE,KAAK,IAAI,MAAM,MAAM,WAAWA,aAAY,IAAI,EAAE,CAAC;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAAA,IACA,gBAAgB,OAAO,UAAkC;AACvD,YAAM,EAAE,KAAK,IAAI;AAGjB,YAAM,mBAAmB,kBAAkB,IAAI;AAC/C,YAAM,uBAAuB,sBAAsB,IAAI;AAEvD,YAAM,iBAAiB,UAAU,UAAU,IAAI,IAC3C,MAAM,OAAO,qBAAqB,UAAU,UAAU,IAAI,CAAC,CAAC,CAAC,IAC7D;AAEJ,UAAI,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,gBAAgB;AAEjE,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,SAAS,2BAA2B,IAAI;AAAA,QAC1C;AAAA,MACF;AAGA,YAAM,UAAU,MAAM;AAAA,QACpB;AAAA,QACA,YAAY,MAAM,aAAa,EAAE,GAAG,OAAO,OAAO,MAAM,SAAS,gBAAgB,MAAM,CAAC;AAAA,MAC1F;AAEA,UAAI,CAAC,QAAQ,MAAM,CAAC,SAAS,QAAQ,IAAI,GAAG;AAC1C,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,SAAS,6BAA6B,IAAI;AAAA,QAC5C;AAAA,MACF;AAIA,YAAM,UAAU,aAAa,QAAQ,GAAG;AACxC,UAAI,eAAe,iCAAiC,MAAM,SAAS;AACjE,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,SAAS,qCAAqC,IAAI;AAAA,QACpD;AAAA,MACF;AAEA,YAAM,oBAAoB,QAAQ;AAGlC,gBAAU,IAAI,IAAI,MAAM,aAAa,CAAC;AACtC,kCAA4B,IAAI,IAAI,EAAE,OAAO,MAAM,MAAM;AAGzD,YAAM,cAAc,KAAK,kBAAkB,iBAAiB;AAI5D,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,SAAS,qCAAqC,IAAI;AAAA,QACpD;AAAA,MACF;AAEA,YAAM,cAAc,KAAK,kBAAkB,oBAAoB;AAE/D,YAAM,WAAW,MAAM,aAAa,WAAW;AAE/C,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,WAAW,SAAS;AAAA,QACpB,cAAc,OAAO,sBAA6C;AAChE,gBAAM,aAAa,SAAS,MAAM,OAAO,iBAAiB;AAG1D,gBAAM,0BAA0B,MAAM,UAAU,gBAAgB,GAAG,UAAU;AAC7E,gCAAsB,IAAI,IAAI;AAG9B,4BAAkB,IAAI,IAAI;AAG1B,gBAAM,cAAc,KAAK,sBAAsB,uBAAuB;AACtE,gBAAM,cAAc,KAAK,sBAAsB,cAAc;AAE7D,gBAAM,WAAW,MAAM,aAAa,WAAW;AAI/C,gBAAM,aAAa,SAAS,MAAM,OAAO,SAAS,UAAU,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;AAElF,gBAAM,oBAAoB;AAAA,YACxB;AAAA,YACA,MAAM,UAAU,uBAAuB,GAAG,UAAU;AAAA,UACtD;AAGA,gBAAM,oBAAoB;AAAA,YACxB,GAAG;AAAA,YACH,UAAU;AAAA,cACR,GAAG;AAAA;AAAA;AAAA,cAGH,CAAC,WAAW,SAAS,UAAU,GAAG;AAAA,YACpC;AAAA,YACA,gBAAgB,kBAAkB,KAAK;AAAA;AAAA,YAEvC,cAAc,aAAa,QAAQ,GAAG;AAAA,YACtC,YAAY;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,8BAA8B;",
6
6
  "names": ["event", "overrides"]
7
7
  }
@@ -15,5 +15,5 @@ export type ApiReferenceEvents = AuthEvents & AnalyticsEvents & CookieEvents & W
15
15
  export type { AuthMeta } from './auth.js';
16
16
  export type { CollectionType } from './common.js';
17
17
  export type { OperationExampleMeta, OperationMeta } from './operation.js';
18
- export type { CommandPaletteAction, CommandPalettePayload } from './ui.js';
18
+ export type { CommandPaletteAction, CommandPalettePayload, KeyboardEventPayload } from './ui.js';
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/events/definitions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAEpC,MAAM,MAAM,kBAAkB,GAAG,UAAU,GACzC,eAAe,GACf,YAAY,GACZ,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,UAAU,GACV,eAAe,GACf,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,SAAS,GACT,WAAW,CAAA;AAEb,YAAY,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACtC,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/events/definitions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAEpC,MAAM,MAAM,kBAAkB,GAAG,UAAU,GACzC,eAAe,GACf,YAAY,GACZ,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,UAAU,GACV,eAAe,GACf,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,SAAS,GACT,WAAW,CAAA;AAEb,YAAY,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACtC,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,MAAM,CAAA"}
@@ -54,7 +54,7 @@ export type CommandPaletteAction<K extends keyof CommandPalettePayload = keyof C
54
54
  * Used when we need to track the original keyboard event for things like
55
55
  * preventing default behavior or stopping propagation.
56
56
  */
57
- type KeyboardEventPayload = {
57
+ export type KeyboardEventPayload = {
58
58
  /** The keyboard event that triggered this action */
59
59
  event: KeyboardEvent;
60
60
  };
@@ -127,7 +127,7 @@ export type UIEvents = {
127
127
  * Can optionally pre-fill with a specific action to execute.
128
128
  * If undefined is passed, opens the palette without a pre-selected action.
129
129
  */
130
- 'ui:open:command-palette': CommandPaletteAction | undefined;
130
+ 'ui:open:command-palette': CommandPaletteAction | KeyboardEventPayload | undefined;
131
131
  /**
132
132
  * Toggle a navigation item's expanded state.
133
133
  * Used for collapsible items like tags, folders, or operation groups.
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/events/definitions/ui.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/events/definitions/ui.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { type WorkspaceEventBus, createWorkspaceEventBus } from './bus.js';
2
- export type { ApiReferenceEvents, AuthMeta, CollectionType, CommandPaletteAction, CommandPalettePayload, OperationExampleMeta, OperationMeta, } from './definitions/index.js';
2
+ export type { ApiReferenceEvents, AuthMeta, CollectionType, CommandPaletteAction, CommandPalettePayload, KeyboardEventPayload, OperationExampleMeta, OperationMeta, } from './definitions/index.js';
3
3
  export { onCustomEvent } from './listeners.js';
4
4
  export { emitCustomEvent } from './old-definitions.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,OAAO,CAAA;AACvE,YAAY,EACV,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,OAAO,CAAA;AACvE,YAAY,EACV,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/events/index.ts"],
4
- "sourcesContent": ["export { type WorkspaceEventBus, createWorkspaceEventBus } from './bus'\nexport type {\n ApiReferenceEvents,\n AuthMeta,\n CollectionType,\n CommandPaletteAction,\n CommandPalettePayload,\n OperationExampleMeta,\n OperationMeta,\n} from './definitions'\nexport { onCustomEvent } from './listeners'\nexport { emitCustomEvent } from './old-definitions'\n"],
5
- "mappings": "AAAA,SAAiC,+BAA+B;AAUhE,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;",
4
+ "sourcesContent": ["export { type WorkspaceEventBus, createWorkspaceEventBus } from './bus'\nexport type {\n ApiReferenceEvents,\n AuthMeta,\n CollectionType,\n CommandPaletteAction,\n CommandPalettePayload,\n KeyboardEventPayload,\n OperationExampleMeta,\n OperationMeta,\n} from './definitions'\nexport { onCustomEvent } from './listeners'\nexport { emitCustomEvent } from './old-definitions'\n"],
5
+ "mappings": "AAAA,SAAiC,+BAA+B;AAWhE,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- import { isObject } from "../helpers/general.js";
1
+ import { isObject } from "@scalar/helpers/object/is-object";
2
2
  const isDetectChangesProxy = Symbol("isDetectChangesProxy");
3
3
  const detectChangesProxyTarget = Symbol("detectChangesProxyTarget");
4
4
  const createDetectChangesProxy = (target, options, args = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/helpers/detect-changes-proxy.ts"],
4
- "sourcesContent": ["import { isObject } from '@/helpers/general'\n\nconst isDetectChangesProxy = Symbol('isDetectChangesProxy')\nconst detectChangesProxyTarget = Symbol('detectChangesProxyTarget')\n\n/**\n * createDetectChangesProxy - Creates a proxy for an object or array that detects and triggers hooks on changes.\n *\n * This proxy enables detection of set operations, triggering optional hooks (onBeforeChange, onAfterChange) with the path and value changed.\n * The proxy can be applied recursively to all nested objects/arrays, and caches proxies to prevent creating multiple proxies for the same object.\n *\n * Example usage:\n *\n * const obj = { foo: 1, bar: { baz: 2 } };\n * const proxy = createDetectChangesProxy(obj, {\n * hooks: {\n * onBeforeChange: (path, value) => console.log('Before', path, value),\n * onAfterChange: (path, value) => console.log('After', path, value),\n * }\n * });\n * proxy.foo = 42; // Console: Before ['foo'] '42', After ['foo'] '42'\n * proxy.bar.baz = 99; // Console: Before ['bar', 'baz'] '99', After ['bar', 'baz'] '99'\n *\n * @param target The target object or array to wrap in a proxy\n * @param options Optional: hooks for change detection\n * @param args Internal: proxy cache and current property path (used for recursion)\n * @returns The proxied object/array with change detection capabilities\n */\nexport const createDetectChangesProxy = <T>(\n target: T,\n options?: {\n hooks: Partial<{\n onBeforeChange: (path: string[], value: unknown) => void\n onAfterChange: (path: string[], value: unknown) => void\n }>\n },\n args: {\n /** Cache for storing proxies */\n proxyCache: WeakMap<object, unknown>\n /** Path for the target */\n path: string[]\n } = {\n proxyCache: new WeakMap<object, unknown>(),\n path: [],\n },\n): T => {\n // Only wrap objects or arrays\n if (!isObject(target) && !Array.isArray(target)) {\n return target\n }\n\n // Return cached proxy if already created for this target\n if (args.proxyCache.has(target)) {\n return args.proxyCache.get(target)! as T\n }\n\n const proxy = new Proxy(target, {\n get(target, prop, receiver) {\n // Allow identifying if an object is a detect changes proxy\n if (prop === isDetectChangesProxy) {\n return true\n }\n // Allow access to the original target\n if (prop === detectChangesProxyTarget) {\n return target\n }\n\n // Recursively wrap property values in the detect changes proxy\n const value = Reflect.get(target, prop, receiver)\n\n if (isDetectChangesProxyObject(value)) {\n return value\n }\n\n return createDetectChangesProxy(value, options, { ...args, path: [...args.path, String(prop)] })\n },\n set(target, prop, value, receiver) {\n const path = [...args.path, String(prop)]\n // Call before-change hook if provided\n options?.hooks?.onBeforeChange?.(path, value)\n const result = Reflect.set(target, prop, value, receiver)\n // Call after-change hook if provided\n options?.hooks?.onAfterChange?.(path, value)\n return result\n },\n })\n\n // Cache the proxy for this target\n args.proxyCache.set(target, proxy)\n return proxy\n}\n\nexport const isDetectChangesProxyObject = (obj: unknown): boolean => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n (obj as { [isDetectChangesProxy]: boolean })[isDetectChangesProxy] === true\n )\n}\n\n/**\n * Returns the raw/original (non-proxy) object if the passed object is a detect-changes proxy.\n * If the object is not a proxy, it returns the same object.\n *\n * @example\n * const proxy = createDetectChangesProxy({ a: 1 });\n * const raw = unpackDetectChangesProxy(proxy); // Gets the original object { a: 1 }\n * const notProxy = { b: 2 };\n * const stillRaw = unpackDetectChangesProxy(notProxy); // Returns { b: 2 }, unchanged\n */\nexport const unpackDetectChangesProxy = <T>(obj: T): T => {\n if (typeof obj !== 'object' || obj === null) {\n return obj\n }\n\n // If object is a detect-changes proxy, return its underlying target\n if ((obj as T & { [isDetectChangesProxy]: boolean | undefined })[isDetectChangesProxy]) {\n return (obj as T & { [detectChangesProxyTarget]: T })[detectChangesProxyTarget]\n }\n\n return obj\n}\n"],
4
+ "sourcesContent": ["import { isObject } from '@scalar/helpers/object/is-object'\n\nconst isDetectChangesProxy = Symbol('isDetectChangesProxy')\nconst detectChangesProxyTarget = Symbol('detectChangesProxyTarget')\n\n/**\n * createDetectChangesProxy - Creates a proxy for an object or array that detects and triggers hooks on changes.\n *\n * This proxy enables detection of set operations, triggering optional hooks (onBeforeChange, onAfterChange) with the path and value changed.\n * The proxy can be applied recursively to all nested objects/arrays, and caches proxies to prevent creating multiple proxies for the same object.\n *\n * Example usage:\n *\n * const obj = { foo: 1, bar: { baz: 2 } };\n * const proxy = createDetectChangesProxy(obj, {\n * hooks: {\n * onBeforeChange: (path, value) => console.log('Before', path, value),\n * onAfterChange: (path, value) => console.log('After', path, value),\n * }\n * });\n * proxy.foo = 42; // Console: Before ['foo'] '42', After ['foo'] '42'\n * proxy.bar.baz = 99; // Console: Before ['bar', 'baz'] '99', After ['bar', 'baz'] '99'\n *\n * @param target The target object or array to wrap in a proxy\n * @param options Optional: hooks for change detection\n * @param args Internal: proxy cache and current property path (used for recursion)\n * @returns The proxied object/array with change detection capabilities\n */\nexport const createDetectChangesProxy = <T>(\n target: T,\n options?: {\n hooks: Partial<{\n onBeforeChange: (path: string[], value: unknown) => void\n onAfterChange: (path: string[], value: unknown) => void\n }>\n },\n args: {\n /** Cache for storing proxies */\n proxyCache: WeakMap<object, unknown>\n /** Path for the target */\n path: string[]\n } = {\n proxyCache: new WeakMap<object, unknown>(),\n path: [],\n },\n): T => {\n // Only wrap objects or arrays\n if (!isObject(target) && !Array.isArray(target)) {\n return target\n }\n\n // Return cached proxy if already created for this target\n if (args.proxyCache.has(target)) {\n return args.proxyCache.get(target)! as T\n }\n\n const proxy = new Proxy(target, {\n get(target, prop, receiver) {\n // Allow identifying if an object is a detect changes proxy\n if (prop === isDetectChangesProxy) {\n return true\n }\n // Allow access to the original target\n if (prop === detectChangesProxyTarget) {\n return target\n }\n\n // Recursively wrap property values in the detect changes proxy\n const value = Reflect.get(target, prop, receiver)\n\n if (isDetectChangesProxyObject(value)) {\n return value\n }\n\n return createDetectChangesProxy(value, options, { ...args, path: [...args.path, String(prop)] })\n },\n set(target, prop, value, receiver) {\n const path = [...args.path, String(prop)]\n // Call before-change hook if provided\n options?.hooks?.onBeforeChange?.(path, value)\n const result = Reflect.set(target, prop, value, receiver)\n // Call after-change hook if provided\n options?.hooks?.onAfterChange?.(path, value)\n return result\n },\n })\n\n // Cache the proxy for this target\n args.proxyCache.set(target, proxy)\n return proxy\n}\n\nexport const isDetectChangesProxyObject = (obj: unknown): boolean => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n (obj as { [isDetectChangesProxy]: boolean })[isDetectChangesProxy] === true\n )\n}\n\n/**\n * Returns the raw/original (non-proxy) object if the passed object is a detect-changes proxy.\n * If the object is not a proxy, it returns the same object.\n *\n * @example\n * const proxy = createDetectChangesProxy({ a: 1 });\n * const raw = unpackDetectChangesProxy(proxy); // Gets the original object { a: 1 }\n * const notProxy = { b: 2 };\n * const stillRaw = unpackDetectChangesProxy(notProxy); // Returns { b: 2 }, unchanged\n */\nexport const unpackDetectChangesProxy = <T>(obj: T): T => {\n if (typeof obj !== 'object' || obj === null) {\n return obj\n }\n\n // If object is a detect-changes proxy, return its underlying target\n if ((obj as T & { [isDetectChangesProxy]: boolean | undefined })[isDetectChangesProxy]) {\n return (obj as T & { [detectChangesProxyTarget]: T })[detectChangesProxyTarget]\n }\n\n return obj\n}\n"],
5
5
  "mappings": "AAAA,SAAS,gBAAgB;AAEzB,MAAM,uBAAuB,OAAO,sBAAsB;AAC1D,MAAM,2BAA2B,OAAO,0BAA0B;AAyB3D,MAAM,2BAA2B,CACtC,QACA,SAMA,OAKI;AAAA,EACF,YAAY,oBAAI,QAAyB;AAAA,EACzC,MAAM,CAAC;AACT,MACM;AAEN,MAAI,CAAC,SAAS,MAAM,KAAK,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC/C,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,WAAW,IAAI,MAAM,GAAG;AAC/B,WAAO,KAAK,WAAW,IAAI,MAAM;AAAA,EACnC;AAEA,QAAM,QAAQ,IAAI,MAAM,QAAQ;AAAA,IAC9B,IAAIA,SAAQ,MAAM,UAAU;AAE1B,UAAI,SAAS,sBAAsB;AACjC,eAAO;AAAA,MACT;AAEA,UAAI,SAAS,0BAA0B;AACrC,eAAOA;AAAA,MACT;AAGA,YAAM,QAAQ,QAAQ,IAAIA,SAAQ,MAAM,QAAQ;AAEhD,UAAI,2BAA2B,KAAK,GAAG;AACrC,eAAO;AAAA,MACT;AAEA,aAAO,yBAAyB,OAAO,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,KAAK,MAAM,OAAO,IAAI,CAAC,EAAE,CAAC;AAAA,IACjG;AAAA,IACA,IAAIA,SAAQ,MAAM,OAAO,UAAU;AACjC,YAAM,OAAO,CAAC,GAAG,KAAK,MAAM,OAAO,IAAI,CAAC;AAExC,eAAS,OAAO,iBAAiB,MAAM,KAAK;AAC5C,YAAM,SAAS,QAAQ,IAAIA,SAAQ,MAAM,OAAO,QAAQ;AAExD,eAAS,OAAO,gBAAgB,MAAM,KAAK;AAC3C,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAGD,OAAK,WAAW,IAAI,QAAQ,KAAK;AACjC,SAAO;AACT;AAEO,MAAM,6BAA6B,CAAC,QAA0B;AACnE,SACE,OAAO,QAAQ,YACf,QAAQ,QACP,IAA4C,oBAAoB,MAAM;AAE3E;AAYO,MAAM,2BAA2B,CAAI,QAAc;AACxD,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,WAAO;AAAA,EACT;AAGA,MAAK,IAA4D,oBAAoB,GAAG;AACtF,WAAQ,IAA8C,wBAAwB;AAAA,EAChF;AAEA,SAAO;AACT;",
6
6
  "names": ["target"]
7
7
  }
@@ -1,15 +1,4 @@
1
1
  export type UnknownObject = Record<string, unknown>;
2
- /**
3
- * Returns true if the value is a non-null object (but not an array).
4
- *
5
- * @example
6
- * ```ts
7
- * isObject({}) // true
8
- * isObject([]) // false
9
- * isObject(null) // false
10
- * ```
11
- */
12
- export declare function isObject(value: unknown): value is UnknownObject;
13
2
  /**
14
3
  * Checks if a string is a local reference (starts with #)
15
4
  * @param value - The reference string to check
@@ -1 +1 @@
1
- {"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/helpers/general.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEnD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAE/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,GAClC,CAAC,MAAM,CAAC,CAAC,EAAE,CACzC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CAEvC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,eAOtE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,OAAO,CAAC,CAAC,CAAC,SAE1F,CAAA"}
1
+ {"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/helpers/general.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEnD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,GAClC,CAAC,MAAM,CAAC,CAAC,EAAE,CACzC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CAEvC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,eAOtE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,OAAO,CAAC,CAAC,CAAC,SAE1F,CAAA"}
@@ -1,6 +1,3 @@
1
- function isObject(value) {
2
- return typeof value === "object" && value !== null && !Array.isArray(value);
3
- }
4
1
  function isLocalRef(value) {
5
2
  return value.startsWith("#");
6
3
  }
@@ -24,7 +21,6 @@ const safeAssign = (target, source) => {
24
21
  export {
25
22
  deepClone,
26
23
  isLocalRef,
27
- isObject,
28
24
  keyOf,
29
25
  safeAssign,
30
26
  split
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/helpers/general.ts"],
4
- "sourcesContent": ["export type UnknownObject = Record<string, unknown>\n\n/**\n * Returns true if the value is a non-null object (but not an array).\n *\n * @example\n * ```ts\n * isObject({}) // true\n * isObject([]) // false\n * isObject(null) // false\n * ```\n */\nexport function isObject(value: unknown): value is UnknownObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Checks if a string is a local reference (starts with #)\n * @param value - The reference string to check\n * @returns true if the string is a local reference, false otherwise\n * @example\n * ```ts\n * isLocalRef('#/components/schemas/User') // true\n * isLocalRef('https://example.com/schema.json') // false\n * isLocalRef('./local-schema.json') // false\n * ```\n */\nexport function isLocalRef(value: string): boolean {\n return value.startsWith('#')\n}\n\nexport function keyOf<T extends Record<string, unknown>>(value: T) {\n return Object.keys(value) as (keyof T)[]\n}\n\n/**\n * Deep clones a value using JSON serialization.\n *\n * @param value - The value to deep clone\n * @template T - The type of the value\n * @returns A deep clone of the value\n */\nexport const deepClone = <T>(value: T): T => {\n return JSON.parse(JSON.stringify(value)) as T\n}\n\n/**\n * Splits an array into two arrays based on a condition.\n *\n * This function takes an array and a predicate function, then returns a tuple containing\n * two arrays: the first contains elements that pass the condition, and the second contains\n * elements that fail the condition.\n *\n * @param array - The array to split\n * @param condition - A predicate function that determines which array each element belongs to\n * @returns A tuple of two arrays: [passingElements, failingElements]\n *\n * @example\n * ```ts\n * const numbers = [1, 2, 3, 4, 5, 6]\n * const [evens, odds] = split(numbers, (n) => n % 2 === 0)\n * // evens: [2, 4, 6]\n * // odds: [1, 3, 5]\n *\n * const words = ['apple', 'banana', 'cherry', 'date']\n * const [longWords, shortWords] = split(words, (word) => word.length > 5)\n * // longWords: ['banana', 'cherry']\n * // shortWords: ['apple', 'date']\n * ```\n */\nexport const split = <T>(array: T[], condition: (element: T) => boolean) => {\n return array.reduce<[T[], T[]]>(\n ([pass, fail], item) => {\n return condition(item) ? [[...pass, item], fail] : [pass, [...fail, item]]\n },\n [[], []],\n )\n}\n\n/**\n * Safely assigns properties from a source object to a target object.\n *\n * This function uses Object.assign to copy enumerable properties from the source object\n * to the target object. It's a type-safe wrapper around Object.assign that ensures\n * the source object is compatible with the target object's type.\n *\n * @param target - The target object to assign properties to\n * @param source - The source object containing properties to assign\n * @template T - The type of the target object\n *\n * @example\n * ```ts\n * const target = { name: 'John', age: 30 }\n * const source = { age: 31, city: 'New York' }\n * safeAssign(target, source)\n * // target is now: { name: 'John', age: 31, city: 'New York' }\n *\n * const config = { theme: 'dark', language: 'en' }\n * const updates = { theme: 'light' }\n * safeAssign(config, updates)\n * // config is now: { theme: 'light', language: 'en' }\n * ```\n */\nexport const safeAssign = <T extends Record<string, unknown>>(target: T, source: Partial<T>) => {\n Object.assign(target, source)\n}\n"],
5
- "mappings": "AAYO,SAAS,SAAS,OAAwC;AAC/D,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAaO,SAAS,WAAW,OAAwB;AACjD,SAAO,MAAM,WAAW,GAAG;AAC7B;AAEO,SAAS,MAAyC,OAAU;AACjE,SAAO,OAAO,KAAK,KAAK;AAC1B;AASO,MAAM,YAAY,CAAI,UAAgB;AAC3C,SAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzC;AA0BO,MAAM,QAAQ,CAAI,OAAY,cAAuC;AAC1E,SAAO,MAAM;AAAA,IACX,CAAC,CAAC,MAAM,IAAI,GAAG,SAAS;AACtB,aAAO,UAAU,IAAI,IAAI,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,IAC3E;AAAA,IACA,CAAC,CAAC,GAAG,CAAC,CAAC;AAAA,EACT;AACF;AA0BO,MAAM,aAAa,CAAoC,QAAW,WAAuB;AAC9F,SAAO,OAAO,QAAQ,MAAM;AAC9B;",
4
+ "sourcesContent": ["export type UnknownObject = Record<string, unknown>\n\n/**\n * Checks if a string is a local reference (starts with #)\n * @param value - The reference string to check\n * @returns true if the string is a local reference, false otherwise\n * @example\n * ```ts\n * isLocalRef('#/components/schemas/User') // true\n * isLocalRef('https://example.com/schema.json') // false\n * isLocalRef('./local-schema.json') // false\n * ```\n */\nexport function isLocalRef(value: string): boolean {\n return value.startsWith('#')\n}\n\nexport function keyOf<T extends Record<string, unknown>>(value: T) {\n return Object.keys(value) as (keyof T)[]\n}\n\n/**\n * Deep clones a value using JSON serialization.\n *\n * @param value - The value to deep clone\n * @template T - The type of the value\n * @returns A deep clone of the value\n */\nexport const deepClone = <T>(value: T): T => {\n return JSON.parse(JSON.stringify(value)) as T\n}\n\n/**\n * Splits an array into two arrays based on a condition.\n *\n * This function takes an array and a predicate function, then returns a tuple containing\n * two arrays: the first contains elements that pass the condition, and the second contains\n * elements that fail the condition.\n *\n * @param array - The array to split\n * @param condition - A predicate function that determines which array each element belongs to\n * @returns A tuple of two arrays: [passingElements, failingElements]\n *\n * @example\n * ```ts\n * const numbers = [1, 2, 3, 4, 5, 6]\n * const [evens, odds] = split(numbers, (n) => n % 2 === 0)\n * // evens: [2, 4, 6]\n * // odds: [1, 3, 5]\n *\n * const words = ['apple', 'banana', 'cherry', 'date']\n * const [longWords, shortWords] = split(words, (word) => word.length > 5)\n * // longWords: ['banana', 'cherry']\n * // shortWords: ['apple', 'date']\n * ```\n */\nexport const split = <T>(array: T[], condition: (element: T) => boolean) => {\n return array.reduce<[T[], T[]]>(\n ([pass, fail], item) => {\n return condition(item) ? [[...pass, item], fail] : [pass, [...fail, item]]\n },\n [[], []],\n )\n}\n\n/**\n * Safely assigns properties from a source object to a target object.\n *\n * This function uses Object.assign to copy enumerable properties from the source object\n * to the target object. It's a type-safe wrapper around Object.assign that ensures\n * the source object is compatible with the target object's type.\n *\n * @param target - The target object to assign properties to\n * @param source - The source object containing properties to assign\n * @template T - The type of the target object\n *\n * @example\n * ```ts\n * const target = { name: 'John', age: 30 }\n * const source = { age: 31, city: 'New York' }\n * safeAssign(target, source)\n * // target is now: { name: 'John', age: 31, city: 'New York' }\n *\n * const config = { theme: 'dark', language: 'en' }\n * const updates = { theme: 'light' }\n * safeAssign(config, updates)\n * // config is now: { theme: 'light', language: 'en' }\n * ```\n */\nexport const safeAssign = <T extends Record<string, unknown>>(target: T, source: Partial<T>) => {\n Object.assign(target, source)\n}\n"],
5
+ "mappings": "AAaO,SAAS,WAAW,OAAwB;AACjD,SAAO,MAAM,WAAW,GAAG;AAC7B;AAEO,SAAS,MAAyC,OAAU;AACjE,SAAO,OAAO,KAAK,KAAK;AAC1B;AASO,MAAM,YAAY,CAAI,UAAgB;AAC3C,SAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzC;AA0BO,MAAM,QAAQ,CAAI,OAAY,cAAuC;AAC1E,SAAO,MAAM;AAAA,IACX,CAAC,CAAC,MAAM,IAAI,GAAG,SAAS;AACtB,aAAO,UAAU,IAAI,IAAI,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,IAC3E;AAAA,IACA,CAAC,CAAC,GAAG,CAAC,CAAC;AAAA,EACT;AACF;AA0BO,MAAM,aAAa,CAAoC,QAAW,WAAuB;AAC9F,SAAO,OAAO,QAAQ,MAAM;AAC9B;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- import { isObject } from "../helpers/general.js";
1
+ import { isObject } from "@scalar/helpers/object/is-object";
2
2
  const isOverridesProxy = Symbol("isOverridesProxy");
3
3
  const getOverridesTarget = Symbol("getOverridesTarget");
4
4
  const createOverridesProxy = (target, options, args = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/helpers/overrides-proxy.ts"],
4
- "sourcesContent": ["import { isObject } from '@/helpers/general'\n\nconst isOverridesProxy = Symbol('isOverridesProxy')\nexport const getOverridesTarget = Symbol('getOverridesTarget')\n\n/**\n * Recursively makes all properties of a type optional.\n *\n * - If T is an object, recursively applies DeepPartial to each property, making them optional.\n * - Otherwise, T is returned as-is.\n *\n * @template T - The type to make deeply partial (optional).\n * @example\n * type Example = { a: { b: number } }\n * type PartialExample = DeepPartial<Example>\n * // Result: { a?: { b?: number } }\n */\nexport type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T\n\n/**\n * Creates a proxy object that overlays \"overrides\" on top of a target object.\n *\n * - When reading a property, if an override exists, it is returned; otherwise, the original value is returned.\n * - When writing to a property, if an override exists, it is updated; otherwise, the original object is updated.\n * - This works recursively for nested objects, so overrides can be deeply partial.\n * - Special symbols are used to identify the proxy and to access the original target.\n *\n * @template T - The type of the target object.\n * @param target - The original object to proxy.\n * @param overrides - An optional object containing override values (deeply partial).\n * @returns A proxy object that reflects overrides on top of the target.\n *\n * @example\n * const original = { a: 1, b: { c: 2 } }\n * const overrides = { b: { c: 42 } }\n * const proxy = createOverridesProxy(original, { overrides })\n *\n * console.log(proxy.a) // 1 (from original)\n * console.log(proxy.b.c) // 42 (from overrides)\n *\n * proxy.a = 100\n * console.log(original.a) // 100\n *\n * proxy.b.c = 99\n * console.log(overrides.b.c) // 99\n */\nexport const createOverridesProxy = <T extends Record<string, unknown>>(\n target: T,\n options?: {\n overrides?: DeepPartial<T>\n },\n args: {\n cache: WeakMap<object, any>\n } = {\n cache: new WeakMap(),\n },\n): T => {\n if (!target || typeof target !== 'object') {\n return target\n }\n\n // Return existing proxy for the same target to ensure referential stability\n if (args.cache.has(target)) {\n return args.cache.get(target)!\n }\n\n const { overrides } = options ?? {}\n\n // Proxy handler to intercept get/set operations\n const handler: ProxyHandler<T> = {\n get(target, prop, receiver) {\n // Special symbol to identify this as an overrides proxy\n if (prop === isOverridesProxy) {\n return true\n }\n\n // Special symbol to access the original target object\n if (prop === getOverridesTarget) {\n return target\n }\n\n const value = Reflect.get(target, prop, receiver)\n\n // Return early if the value is already an overrides proxy\n if (isOverridesProxyObject(value)) {\n return value\n }\n\n // If the value is not an object, return the override if it exists, else the original value\n if (!isObject(value)) {\n return Reflect.get(overrides ?? {}, prop) ?? value\n }\n\n // For nested objects, recursively create a proxy with the corresponding overrides\n return createOverridesProxy(value, { overrides: Reflect.get(overrides ?? {}, prop) }, args)\n },\n\n set(target, prop, value, receiver) {\n // Prevent setting special symbols\n if (prop === isOverridesProxy || prop === getOverridesTarget) {\n return false\n }\n\n // If an override exists for this property, update it\n const hasOverride = overrides && Reflect.has(overrides, prop)\n\n if (hasOverride && overrides && typeof overrides === 'object') {\n ;(overrides as any)[prop] = value\n return true\n }\n\n // Otherwise, update the original target\n return Reflect.set(target, prop, value, receiver)\n },\n }\n\n // Return the proxy object\n const proxy = new Proxy<T>(target, handler)\n args.cache.set(target, proxy)\n return proxy\n}\n\nexport const isOverridesProxyObject = (obj: unknown): boolean => {\n return typeof obj === 'object' && obj !== null && (obj as { [isOverridesProxy]: boolean })[isOverridesProxy] === true\n}\n\n/**\n * Unpacks an object from the overrides proxy, returning the original (unproxied) target object.\n * If the input is not an overrides proxy, returns the object as-is.\n *\n * @param input - The potentially proxied object\n * @returns The original unproxied target object or the input object\n */\nexport function unpackOverridesProxy<T>(input: T): T {\n if (\n typeof input === 'object' &&\n input !== null &&\n (input as T & { [isOverridesProxy]: boolean | undefined })[isOverridesProxy]\n ) {\n return (input as T & { [getOverridesTarget]: T })[getOverridesTarget]\n }\n\n return input\n}\n"],
4
+ "sourcesContent": ["import { isObject } from '@scalar/helpers/object/is-object'\n\nconst isOverridesProxy = Symbol('isOverridesProxy')\nexport const getOverridesTarget = Symbol('getOverridesTarget')\n\n/**\n * Recursively makes all properties of a type optional.\n *\n * - If T is an object, recursively applies DeepPartial to each property, making them optional.\n * - Otherwise, T is returned as-is.\n *\n * @template T - The type to make deeply partial (optional).\n * @example\n * type Example = { a: { b: number } }\n * type PartialExample = DeepPartial<Example>\n * // Result: { a?: { b?: number } }\n */\nexport type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T\n\n/**\n * Creates a proxy object that overlays \"overrides\" on top of a target object.\n *\n * - When reading a property, if an override exists, it is returned; otherwise, the original value is returned.\n * - When writing to a property, if an override exists, it is updated; otherwise, the original object is updated.\n * - This works recursively for nested objects, so overrides can be deeply partial.\n * - Special symbols are used to identify the proxy and to access the original target.\n *\n * @template T - The type of the target object.\n * @param target - The original object to proxy.\n * @param overrides - An optional object containing override values (deeply partial).\n * @returns A proxy object that reflects overrides on top of the target.\n *\n * @example\n * const original = { a: 1, b: { c: 2 } }\n * const overrides = { b: { c: 42 } }\n * const proxy = createOverridesProxy(original, { overrides })\n *\n * console.log(proxy.a) // 1 (from original)\n * console.log(proxy.b.c) // 42 (from overrides)\n *\n * proxy.a = 100\n * console.log(original.a) // 100\n *\n * proxy.b.c = 99\n * console.log(overrides.b.c) // 99\n */\nexport const createOverridesProxy = <T extends Record<string, unknown>>(\n target: T,\n options?: {\n overrides?: DeepPartial<T>\n },\n args: {\n cache: WeakMap<object, any>\n } = {\n cache: new WeakMap(),\n },\n): T => {\n if (!target || typeof target !== 'object') {\n return target\n }\n\n // Return existing proxy for the same target to ensure referential stability\n if (args.cache.has(target)) {\n return args.cache.get(target)!\n }\n\n const { overrides } = options ?? {}\n\n // Proxy handler to intercept get/set operations\n const handler: ProxyHandler<T> = {\n get(target, prop, receiver) {\n // Special symbol to identify this as an overrides proxy\n if (prop === isOverridesProxy) {\n return true\n }\n\n // Special symbol to access the original target object\n if (prop === getOverridesTarget) {\n return target\n }\n\n const value = Reflect.get(target, prop, receiver)\n\n // Return early if the value is already an overrides proxy\n if (isOverridesProxyObject(value)) {\n return value\n }\n\n // If the value is not an object, return the override if it exists, else the original value\n if (!isObject(value)) {\n return Reflect.get(overrides ?? {}, prop) ?? value\n }\n\n // For nested objects, recursively create a proxy with the corresponding overrides\n return createOverridesProxy(value, { overrides: Reflect.get(overrides ?? {}, prop) }, args)\n },\n\n set(target, prop, value, receiver) {\n // Prevent setting special symbols\n if (prop === isOverridesProxy || prop === getOverridesTarget) {\n return false\n }\n\n // If an override exists for this property, update it\n const hasOverride = overrides && Reflect.has(overrides, prop)\n\n if (hasOverride && overrides && typeof overrides === 'object') {\n ;(overrides as any)[prop] = value\n return true\n }\n\n // Otherwise, update the original target\n return Reflect.set(target, prop, value, receiver)\n },\n }\n\n // Return the proxy object\n const proxy = new Proxy<T>(target, handler)\n args.cache.set(target, proxy)\n return proxy\n}\n\nexport const isOverridesProxyObject = (obj: unknown): boolean => {\n return typeof obj === 'object' && obj !== null && (obj as { [isOverridesProxy]: boolean })[isOverridesProxy] === true\n}\n\n/**\n * Unpacks an object from the overrides proxy, returning the original (unproxied) target object.\n * If the input is not an overrides proxy, returns the object as-is.\n *\n * @param input - The potentially proxied object\n * @returns The original unproxied target object or the input object\n */\nexport function unpackOverridesProxy<T>(input: T): T {\n if (\n typeof input === 'object' &&\n input !== null &&\n (input as T & { [isOverridesProxy]: boolean | undefined })[isOverridesProxy]\n ) {\n return (input as T & { [getOverridesTarget]: T })[getOverridesTarget]\n }\n\n return input\n}\n"],
5
5
  "mappings": "AAAA,SAAS,gBAAgB;AAEzB,MAAM,mBAAmB,OAAO,kBAAkB;AAC3C,MAAM,qBAAqB,OAAO,oBAAoB;AA2CtD,MAAM,uBAAuB,CAClC,QACA,SAGA,OAEI;AAAA,EACF,OAAO,oBAAI,QAAQ;AACrB,MACM;AACN,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,MAAM,IAAI,MAAM,GAAG;AAC1B,WAAO,KAAK,MAAM,IAAI,MAAM;AAAA,EAC9B;AAEA,QAAM,EAAE,UAAU,IAAI,WAAW,CAAC;AAGlC,QAAM,UAA2B;AAAA,IAC/B,IAAIA,SAAQ,MAAM,UAAU;AAE1B,UAAI,SAAS,kBAAkB;AAC7B,eAAO;AAAA,MACT;AAGA,UAAI,SAAS,oBAAoB;AAC/B,eAAOA;AAAA,MACT;AAEA,YAAM,QAAQ,QAAQ,IAAIA,SAAQ,MAAM,QAAQ;AAGhD,UAAI,uBAAuB,KAAK,GAAG;AACjC,eAAO;AAAA,MACT;AAGA,UAAI,CAAC,SAAS,KAAK,GAAG;AACpB,eAAO,QAAQ,IAAI,aAAa,CAAC,GAAG,IAAI,KAAK;AAAA,MAC/C;AAGA,aAAO,qBAAqB,OAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,CAAC,GAAG,IAAI,EAAE,GAAG,IAAI;AAAA,IAC5F;AAAA,IAEA,IAAIA,SAAQ,MAAM,OAAO,UAAU;AAEjC,UAAI,SAAS,oBAAoB,SAAS,oBAAoB;AAC5D,eAAO;AAAA,MACT;AAGA,YAAM,cAAc,aAAa,QAAQ,IAAI,WAAW,IAAI;AAE5D,UAAI,eAAe,aAAa,OAAO,cAAc,UAAU;AAC7D;AAAC,QAAC,UAAkB,IAAI,IAAI;AAC5B,eAAO;AAAA,MACT;AAGA,aAAO,QAAQ,IAAIA,SAAQ,MAAM,OAAO,QAAQ;AAAA,IAClD;AAAA,EACF;AAGA,QAAM,QAAQ,IAAI,MAAS,QAAQ,OAAO;AAC1C,OAAK,MAAM,IAAI,QAAQ,KAAK;AAC5B,SAAO;AACT;AAEO,MAAM,yBAAyB,CAAC,QAA0B;AAC/D,SAAO,OAAO,QAAQ,YAAY,QAAQ,QAAS,IAAwC,gBAAgB,MAAM;AACnH;AASO,SAAS,qBAAwB,OAAa;AACnD,MACE,OAAO,UAAU,YACjB,UAAU,QACT,MAA0D,gBAAgB,GAC3E;AACA,WAAQ,MAA0C,kBAAkB;AAAA,EACtE;AAEA,SAAO;AACT;",
6
6
  "names": ["target"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/mutators/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,iBAAiB,GAAG,IAAI,SAMhE,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,WAAW,OAAO,SAOrF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,cAAc,CAAC,sBAAsB,CAAC,SAOhD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,MAAM,MAAM,SASlF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,GAAG,IAAI,EAC5B,SAAS,cAAc,CAAC,gCAAgC,CAAC,kBA8B1D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,cAAc,GAAG,IAAI,EAAE,SAAS,cAAc,CAAC,0BAA0B,CAAC,SAM/G,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,sBAGrC;IACD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAClC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CAC7B;;kCAGiC,cAAc,CAAC,sBAAsB,CAAC;+BACzC,cAAc,CAAC,4BAA4B,CAAC;kCACzC,cAAc,CAAC,sBAAsB,CAAC;mCACrC,cAAc,CAAC,gCAAgC,CAAC;8BAErD,cAAc,CAAC,0BAA0B,CAAC;CAEvE,CAAA"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/mutators/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,iBAAiB,GAAG,IAAI,SAMhE,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,WAAW,OAAO,SAOrF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,iBAAiB,GAAG,IAAI,EAClC,SAAS,cAAc,CAAC,sBAAsB,CAAC,SAahD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,iBAAiB,GAAG,IAAI,EAAE,MAAM,MAAM,SASlF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,GAAG,IAAI,EAC5B,SAAS,cAAc,CAAC,gCAAgC,CAAC,kBA8B1D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,cAAc,GAAG,IAAI,EAAE,SAAS,cAAc,CAAC,0BAA0B,CAAC,SAM/G,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,sBAGrC;IACD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAClC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CAC7B;;kCAGiC,cAAc,CAAC,sBAAsB,CAAC;+BACzC,cAAc,CAAC,4BAA4B,CAAC;kCACzC,cAAc,CAAC,sBAAsB,CAAC;mCACrC,cAAc,CAAC,gCAAgC,CAAC;8BAErD,cAAc,CAAC,0BAA0B,CAAC;CAEvE,CAAA"}
@@ -16,6 +16,9 @@ const updateDocumentInfo = (document, payload) => {
16
16
  return;
17
17
  }
18
18
  mergeObjects(document.info, payload);
19
+ if (payload.title && document["x-scalar-navigation"]) {
20
+ document["x-scalar-navigation"].title = payload.title;
21
+ }
19
22
  };
20
23
  const updateDocumentIcon = (document, icon) => {
21
24
  if (!document || !document["x-scalar-navigation"]) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mutators/document.ts"],
4
- "sourcesContent": ["import type { WorkspaceStore } from '@/client'\nimport type { DocumentEvents } from '@/events/definitions/document'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport type { WorkspaceDocument } from '@/schemas'\n\n/**\n * Toggle setting selected security schemes at the operation level\n */\nexport const toggleSecurity = (document: WorkspaceDocument | null) => {\n if (!document) {\n return\n }\n\n document['x-scalar-set-operation-security'] = !document['x-scalar-set-operation-security']\n}\n\n/**\n * Updates the \"watch mode\" state of the given document.\n *\n * @param document WorkspaceDocument or null \u2013 The document to modify.\n * @param watchMode boolean \u2013 True enables watch mode, false disables it.\n *\n * If document is null, does nothing.\n */\nexport const updateWatchMode = (document: WorkspaceDocument | null, watchMode: boolean) => {\n if (!document) {\n return\n }\n\n // Set (or unset) the x-scalar-watch-mode property on the document\n document['x-scalar-watch-mode'] = watchMode\n}\n\n/**\n * Updates the document's info object (typically, title, description, version, etc.).\n *\n * Uses a shallow merge: only properties present in payload will be overwritten or added.\n *\n * @param document WorkspaceDocument | null \u2013 The document whose info should be updated.\n * @param payload DocumentEvents['document:update:info'] \u2013 Partial info fields to update/merge.\n *\n * If document is null, does nothing.\n */\nexport const updateDocumentInfo = (\n document: WorkspaceDocument | null,\n payload: DocumentEvents['document:update:info'],\n) => {\n if (!document) {\n return\n }\n // Merge the given payload into the document's info object\n mergeObjects(document.info, payload)\n}\n\n/**\n * Update the document icon and also update the corresponding sidebar entry\n *\n * Does not perform a sidebar rebuild for performance benefit\n */\nexport const updateDocumentIcon = (document: WorkspaceDocument | null, icon: string) => {\n if (!document || !document['x-scalar-navigation']) {\n return\n }\n\n // Update the document icon\n document['x-scalar-icon'] = icon\n // Update the sidebar document icon\n document['x-scalar-navigation'].icon = icon\n}\n\n/**\n * Creates an empty OpenAPI document and adds it to the workspace.\n *\n * - If the store is null, this is a no-op.\n * - The document name must be unique; if already present, callback is called with `false`.\n * - On success, a new OpenAPI 3.1.0 document is added with a basic path and info.\n * - Callback is called with `true` if document is created.\n *\n * @param store WorkspaceStore | null \u2013 The workspace store to add the document to.\n * @param payload DocumentEvents['document:create:empty-document'] \u2013 Contains name, icon, and callback.\n */\nexport const createEmptyDocument = async (\n store: WorkspaceStore | null,\n payload: DocumentEvents['document:create:empty-document'],\n) => {\n if (!store) {\n return\n }\n\n // Check if the document already exists by name for uniqueness\n if (store.workspace.documents[payload.name]) {\n // Document name already exists, call callback with false\n payload.callback?.(false)\n return\n }\n\n // Add a new empty OpenAPI 3.1.0 document with minimal info and icon\n await store.addDocument({\n name: payload.name,\n document: {\n openapi: '3.1.0',\n info: { title: payload.name, version: '1.0.0' },\n paths: {\n '/': {\n get: {},\n },\n },\n 'x-scalar-icon': payload.icon,\n },\n })\n\n // Notify success via callback\n payload.callback?.(true)\n}\n\n/**\n * Deletes a document from the workspace by its name.\n *\n * Safely no-ops if the store is null.\n */\nexport const deleteDocument = (store: WorkspaceStore | null, payload: DocumentEvents['document:delete:document']) => {\n if (!store) {\n return\n }\n\n store.deleteDocument(payload.name)\n}\n\nexport const documentMutatorsFactory = ({\n document,\n store,\n}: {\n document: WorkspaceDocument | null\n store: WorkspaceStore | null\n}) => {\n return {\n toggleSecurity: () => toggleSecurity(document),\n updateDocumentInfo: (payload: DocumentEvents['document:update:info']) => updateDocumentInfo(document, payload),\n updateWatchMode: (payload: DocumentEvents['document:update:watch-mode']) => updateWatchMode(document, payload),\n updateDocumentIcon: (payload: DocumentEvents['document:update:icon']) => updateDocumentIcon(document, payload),\n createEmptyDocument: (payload: DocumentEvents['document:create:empty-document']) =>\n createEmptyDocument(store, payload),\n deleteDocument: (payload: DocumentEvents['document:delete:document']) => deleteDocument(store, payload),\n }\n}\n"],
5
- "mappings": "AAEA,SAAS,oBAAoB;AAMtB,MAAM,iBAAiB,CAAC,aAAuC;AACpE,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,WAAS,iCAAiC,IAAI,CAAC,SAAS,iCAAiC;AAC3F;AAUO,MAAM,kBAAkB,CAAC,UAAoC,cAAuB;AACzF,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAGA,WAAS,qBAAqB,IAAI;AACpC;AAYO,MAAM,qBAAqB,CAChC,UACA,YACG;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,eAAa,SAAS,MAAM,OAAO;AACrC;AAOO,MAAM,qBAAqB,CAAC,UAAoC,SAAiB;AACtF,MAAI,CAAC,YAAY,CAAC,SAAS,qBAAqB,GAAG;AACjD;AAAA,EACF;AAGA,WAAS,eAAe,IAAI;AAE5B,WAAS,qBAAqB,EAAE,OAAO;AACzC;AAaO,MAAM,sBAAsB,OACjC,OACA,YACG;AACH,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AAGA,MAAI,MAAM,UAAU,UAAU,QAAQ,IAAI,GAAG;AAE3C,YAAQ,WAAW,KAAK;AACxB;AAAA,EACF;AAGA,QAAM,MAAM,YAAY;AAAA,IACtB,MAAM,QAAQ;AAAA,IACd,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM,EAAE,OAAO,QAAQ,MAAM,SAAS,QAAQ;AAAA,MAC9C,OAAO;AAAA,QACL,KAAK;AAAA,UACH,KAAK,CAAC;AAAA,QACR;AAAA,MACF;AAAA,MACA,iBAAiB,QAAQ;AAAA,IAC3B;AAAA,EACF,CAAC;AAGD,UAAQ,WAAW,IAAI;AACzB;AAOO,MAAM,iBAAiB,CAAC,OAA8B,YAAwD;AACnH,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AAEA,QAAM,eAAe,QAAQ,IAAI;AACnC;AAEO,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AACF,MAGM;AACJ,SAAO;AAAA,IACL,gBAAgB,MAAM,eAAe,QAAQ;AAAA,IAC7C,oBAAoB,CAAC,YAAoD,mBAAmB,UAAU,OAAO;AAAA,IAC7G,iBAAiB,CAAC,YAA0D,gBAAgB,UAAU,OAAO;AAAA,IAC7G,oBAAoB,CAAC,YAAoD,mBAAmB,UAAU,OAAO;AAAA,IAC7G,qBAAqB,CAAC,YACpB,oBAAoB,OAAO,OAAO;AAAA,IACpC,gBAAgB,CAAC,YAAwD,eAAe,OAAO,OAAO;AAAA,EACxG;AACF;",
4
+ "sourcesContent": ["import type { WorkspaceStore } from '@/client'\nimport type { DocumentEvents } from '@/events/definitions/document'\nimport { mergeObjects } from '@/helpers/merge-object'\nimport type { WorkspaceDocument } from '@/schemas'\n\n/**\n * Toggle setting selected security schemes at the operation level\n */\nexport const toggleSecurity = (document: WorkspaceDocument | null) => {\n if (!document) {\n return\n }\n\n document['x-scalar-set-operation-security'] = !document['x-scalar-set-operation-security']\n}\n\n/**\n * Updates the \"watch mode\" state of the given document.\n *\n * @param document WorkspaceDocument or null \u2013 The document to modify.\n * @param watchMode boolean \u2013 True enables watch mode, false disables it.\n *\n * If document is null, does nothing.\n */\nexport const updateWatchMode = (document: WorkspaceDocument | null, watchMode: boolean) => {\n if (!document) {\n return\n }\n\n // Set (or unset) the x-scalar-watch-mode property on the document\n document['x-scalar-watch-mode'] = watchMode\n}\n\n/**\n * Updates the document's info object (typically, title, description, version, etc.).\n *\n * Uses a shallow merge: only properties present in payload will be overwritten or added.\n *\n * @param document WorkspaceDocument | null \u2013 The document whose info should be updated.\n * @param payload DocumentEvents['document:update:info'] \u2013 Partial info fields to update/merge.\n *\n * If document is null, does nothing.\n */\nexport const updateDocumentInfo = (\n document: WorkspaceDocument | null,\n payload: DocumentEvents['document:update:info'],\n) => {\n if (!document) {\n return\n }\n // Merge the given payload into the document's info object\n mergeObjects(document.info, payload)\n\n // Update the document title if it is present and the navigation object is present\n // We do this because we don't want to rebuild the entire navigation object if only the title is changed\n if (payload.title && document['x-scalar-navigation']) {\n document['x-scalar-navigation'].title = payload.title\n }\n}\n\n/**\n * Update the document icon and also update the corresponding sidebar entry\n *\n * Does not perform a sidebar rebuild for performance benefit\n */\nexport const updateDocumentIcon = (document: WorkspaceDocument | null, icon: string) => {\n if (!document || !document['x-scalar-navigation']) {\n return\n }\n\n // Update the document icon\n document['x-scalar-icon'] = icon\n // Update the sidebar document icon\n document['x-scalar-navigation'].icon = icon\n}\n\n/**\n * Creates an empty OpenAPI document and adds it to the workspace.\n *\n * - If the store is null, this is a no-op.\n * - The document name must be unique; if already present, callback is called with `false`.\n * - On success, a new OpenAPI 3.1.0 document is added with a basic path and info.\n * - Callback is called with `true` if document is created.\n *\n * @param store WorkspaceStore | null \u2013 The workspace store to add the document to.\n * @param payload DocumentEvents['document:create:empty-document'] \u2013 Contains name, icon, and callback.\n */\nexport const createEmptyDocument = async (\n store: WorkspaceStore | null,\n payload: DocumentEvents['document:create:empty-document'],\n) => {\n if (!store) {\n return\n }\n\n // Check if the document already exists by name for uniqueness\n if (store.workspace.documents[payload.name]) {\n // Document name already exists, call callback with false\n payload.callback?.(false)\n return\n }\n\n // Add a new empty OpenAPI 3.1.0 document with minimal info and icon\n await store.addDocument({\n name: payload.name,\n document: {\n openapi: '3.1.0',\n info: { title: payload.name, version: '1.0.0' },\n paths: {\n '/': {\n get: {},\n },\n },\n 'x-scalar-icon': payload.icon,\n },\n })\n\n // Notify success via callback\n payload.callback?.(true)\n}\n\n/**\n * Deletes a document from the workspace by its name.\n *\n * Safely no-ops if the store is null.\n */\nexport const deleteDocument = (store: WorkspaceStore | null, payload: DocumentEvents['document:delete:document']) => {\n if (!store) {\n return\n }\n\n store.deleteDocument(payload.name)\n}\n\nexport const documentMutatorsFactory = ({\n document,\n store,\n}: {\n document: WorkspaceDocument | null\n store: WorkspaceStore | null\n}) => {\n return {\n toggleSecurity: () => toggleSecurity(document),\n updateDocumentInfo: (payload: DocumentEvents['document:update:info']) => updateDocumentInfo(document, payload),\n updateWatchMode: (payload: DocumentEvents['document:update:watch-mode']) => updateWatchMode(document, payload),\n updateDocumentIcon: (payload: DocumentEvents['document:update:icon']) => updateDocumentIcon(document, payload),\n createEmptyDocument: (payload: DocumentEvents['document:create:empty-document']) =>\n createEmptyDocument(store, payload),\n deleteDocument: (payload: DocumentEvents['document:delete:document']) => deleteDocument(store, payload),\n }\n}\n"],
5
+ "mappings": "AAEA,SAAS,oBAAoB;AAMtB,MAAM,iBAAiB,CAAC,aAAuC;AACpE,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,WAAS,iCAAiC,IAAI,CAAC,SAAS,iCAAiC;AAC3F;AAUO,MAAM,kBAAkB,CAAC,UAAoC,cAAuB;AACzF,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAGA,WAAS,qBAAqB,IAAI;AACpC;AAYO,MAAM,qBAAqB,CAChC,UACA,YACG;AACH,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAEA,eAAa,SAAS,MAAM,OAAO;AAInC,MAAI,QAAQ,SAAS,SAAS,qBAAqB,GAAG;AACpD,aAAS,qBAAqB,EAAE,QAAQ,QAAQ;AAAA,EAClD;AACF;AAOO,MAAM,qBAAqB,CAAC,UAAoC,SAAiB;AACtF,MAAI,CAAC,YAAY,CAAC,SAAS,qBAAqB,GAAG;AACjD;AAAA,EACF;AAGA,WAAS,eAAe,IAAI;AAE5B,WAAS,qBAAqB,EAAE,OAAO;AACzC;AAaO,MAAM,sBAAsB,OACjC,OACA,YACG;AACH,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AAGA,MAAI,MAAM,UAAU,UAAU,QAAQ,IAAI,GAAG;AAE3C,YAAQ,WAAW,KAAK;AACxB;AAAA,EACF;AAGA,QAAM,MAAM,YAAY;AAAA,IACtB,MAAM,QAAQ;AAAA,IACd,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM,EAAE,OAAO,QAAQ,MAAM,SAAS,QAAQ;AAAA,MAC9C,OAAO;AAAA,QACL,KAAK;AAAA,UACH,KAAK,CAAC;AAAA,QACR;AAAA,MACF;AAAA,MACA,iBAAiB,QAAQ;AAAA,IAC3B;AAAA,EACF,CAAC;AAGD,UAAQ,WAAW,IAAI;AACzB;AAOO,MAAM,iBAAiB,CAAC,OAA8B,YAAwD;AACnH,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AAEA,QAAM,eAAe,QAAQ,IAAI;AACnC;AAEO,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AACF,MAGM;AACJ,SAAO;AAAA,IACL,gBAAgB,MAAM,eAAe,QAAQ;AAAA,IAC7C,oBAAoB,CAAC,YAAoD,mBAAmB,UAAU,OAAO;AAAA,IAC7G,iBAAiB,CAAC,YAA0D,gBAAgB,UAAU,OAAO;AAAA,IAC7G,oBAAoB,CAAC,YAAoD,mBAAmB,UAAU,OAAO;AAAA,IAC7G,qBAAqB,CAAC,YACpB,oBAAoB,OAAO,OAAO;AAAA,IACpC,gBAAgB,CAAC,YAAwD,eAAe,OAAO,OAAO;AAAA,EACxG;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,11 @@
1
1
  import type { InMemoryWorkspace } from '../schemas/inmemory-workspace.js';
2
2
  import type { WorkspaceMeta } from '../schemas/workspace.js';
3
+ type WorkspaceKey = {
4
+ namespace?: string;
5
+ slug: string;
6
+ };
3
7
  type WorkspaceStoreShape = {
8
+ teamUid?: string;
4
9
  name: string;
5
10
  workspace: InMemoryWorkspace;
6
11
  };
@@ -51,9 +56,7 @@ export declare const createWorkspaceStorePersistence: () => Promise<{
51
56
  * Returns undefined if the workspace does not exist.
52
57
  * Gathers all workspace 'chunk' tables and assembles a full workspace shape.
53
58
  */
54
- getItem: (id: string) => Promise<(WorkspaceStoreShape & {
55
- id: string;
56
- }) | undefined>;
59
+ getItem: ({ namespace, slug, }: Required<WorkspaceKey>) => Promise<(WorkspaceStoreShape & Required<WorkspaceKey>) | undefined>;
57
60
  /**
58
61
  * Retrieves all workspaces from the database.
59
62
  * Returns only the workspace ID and name for each workspace.
@@ -64,7 +67,15 @@ export declare const createWorkspaceStorePersistence: () => Promise<{
64
67
  slug: string;
65
68
  name: string;
66
69
  namespace: string;
67
- id: string;
70
+ teamUid: string;
71
+ }[]>;
72
+ /**
73
+ * Retrieves all workspaces for a given team UID.
74
+ */
75
+ getAllByTeamUid: (teamUid: string) => Promise<{
76
+ slug: string;
77
+ name: string;
78
+ namespace: string;
68
79
  teamUid: string;
69
80
  }[]>;
70
81
  /**
@@ -72,16 +83,21 @@ export declare const createWorkspaceStorePersistence: () => Promise<{
72
83
  * All chunks (meta, documents, configs, etc.) are upsert in their respective tables.
73
84
  * If a workspace with the same ID already exists, it will be replaced.
74
85
  */
75
- setItem: (id: string, value: WorkspaceStoreShape) => Promise<void>;
86
+ setItem: ({ namespace, slug }: WorkspaceKey, value: WorkspaceStoreShape) => Promise<{
87
+ slug: string;
88
+ name: string;
89
+ namespace: string;
90
+ teamUid: string;
91
+ }>;
76
92
  /**
77
93
  * Deletes an entire workspace and all associated chunk records from all tables by ID.
78
94
  */
79
- deleteItem: (id: string) => Promise<void>;
95
+ deleteItem: ({ namespace, slug }: Required<WorkspaceKey>) => Promise<void>;
80
96
  deleteDocument: (workspaceId: string, documentName: string) => Promise<void>;
81
97
  /**
82
98
  * Checks if a workspace with the given ID exists in the store.
83
99
  */
84
- has: (id: string) => Promise<boolean>;
100
+ has: ({ namespace, slug }: Required<WorkspaceKey>) => Promise<boolean>;
85
101
  };
86
102
  clear: () => Promise<void>;
87
103
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,iBAAiB,CAAA;CAC7B,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B;;;QA0DtC;;WAEG;+BAC0B,MAAM,QAAQ,aAAa;;;QAKxD;;WAEG;+BAC0B,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;;;QAKvG;;WAEG;+BAEY,MAAM,gBACL,MAAM,QACd,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC;;;QAMtD;;WAEG;+BAEY,MAAM,gBACL,MAAM,QACd,iBAAiB,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC;;;QAM1D;;WAEG;+BAC0B,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;;;QAKvG;;;;WAIG;sBACiB,MAAM,KAAG,OAAO,CAAC,CAAC,mBAAmB,GAAG;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC,GAAG,SAAS,CAAC;QAgCxF;;;;;WAKG;;;;;;;;QAKH;;;;WAIG;sBACiB,MAAM,SAAS,mBAAmB,KAAG,OAAO,CAAC,IAAI,CAAC;QAmCtE;;WAEG;yBACoB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;sCAgBT,MAAM,gBAAgB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;QAShF;;WAEG;kBACa,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;;;EAQ9C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,KAAK,YAAY,GAAG;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,iBAAiB,CAAA;CAC7B,CAAA;AAKD;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B;;;QA2DtC;;WAEG;+BAC0B,MAAM,QAAQ,aAAa;;;QAKxD;;WAEG;+BAC0B,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;;;QAKvG;;WAEG;+BAEY,MAAM,gBACL,MAAM,QACd,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC;;;QAMtD;;WAEG;+BAEY,MAAM,gBACL,MAAM,QACd,iBAAiB,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC;;;QAM1D;;WAEG;+BAC0B,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;;;QAKvG;;;;WAIG;wCAIA,QAAQ,CAAC,YAAY,CAAC,KAAG,OAAO,CAAC,CAAC,mBAAmB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC;QAqC/F;;;;;WAKG;;;;;;;QAKH;;WAEG;mCAC8B,MAAM;;;;;;QAIvC;;;;WAIG;uCAC4C,YAAY,SAAS,mBAAmB;;;;;;QA6CvF;;WAEG;0CACqC,QAAQ,CAAC,YAAY,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;sCAkB1C,MAAM,gBAAgB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;QAShF;;WAEG;mCAC8B,QAAQ,CAAC,YAAY,CAAC,KAAG,OAAO,CAAC,OAAO,CAAC;;;EAQ/E,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { Type } from "@scalar/typebox";
2
2
  import { createIndexDbConnection } from "../persistence/indexdb.js";
3
+ const getWorkspaceId = (namespace, slug) => `${namespace}/${slug}`;
3
4
  const createWorkspaceStorePersistence = async () => {
4
5
  const connection = await createIndexDbConnection({
5
6
  name: "scalar-workspace-store",
@@ -7,38 +8,39 @@ const createWorkspaceStorePersistence = async () => {
7
8
  tables: {
8
9
  workspace: {
9
10
  schema: Type.Object({
10
- /** UID for workspaces stored in the DB */
11
- id: Type.String(),
12
11
  /** Visual name for a given workspace */
13
12
  name: Type.String(),
14
13
  /** When logged in all new workspaces (remote and local) are scoped to a team */
15
- teamUid: Type.String({ default: "LOCAL" }),
14
+ teamUid: Type.String({ default: "local" }),
16
15
  /** Namespace associated with a remote workspace */
17
- namespace: Type.String({ default: "LOCAL" }),
16
+ namespace: Type.String({ default: "local" }),
18
17
  /** Slug associated with a remote workspace */
19
- slug: Type.String({ default: "LOCAL" })
18
+ slug: Type.String({ default: "local" })
20
19
  }),
21
- index: ["id"]
20
+ keyPath: ["namespace", "slug"],
21
+ indexes: {
22
+ teamUid: ["teamUid"]
23
+ }
22
24
  },
23
25
  meta: {
24
26
  schema: Type.Object({ workspaceId: Type.String(), data: Type.Any() }),
25
- index: ["workspaceId"]
27
+ keyPath: ["workspaceId"]
26
28
  },
27
29
  documents: {
28
30
  schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),
29
- index: ["workspaceId", "documentName"]
31
+ keyPath: ["workspaceId", "documentName"]
30
32
  },
31
33
  originalDocuments: {
32
34
  schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),
33
- index: ["workspaceId", "documentName"]
35
+ keyPath: ["workspaceId", "documentName"]
34
36
  },
35
37
  intermediateDocuments: {
36
38
  schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),
37
- index: ["workspaceId", "documentName"]
39
+ keyPath: ["workspaceId", "documentName"]
38
40
  },
39
41
  overrides: {
40
42
  schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),
41
- index: ["workspaceId", "documentName"]
43
+ keyPath: ["workspaceId", "documentName"]
42
44
  }
43
45
  }
44
46
  });
@@ -98,19 +100,25 @@ const createWorkspaceStorePersistence = async () => {
98
100
  * Returns undefined if the workspace does not exist.
99
101
  * Gathers all workspace 'chunk' tables and assembles a full workspace shape.
100
102
  */
101
- getItem: async (id) => {
102
- const workspace = await workspaceTable.getItem({ id });
103
+ getItem: async ({
104
+ namespace,
105
+ slug
106
+ }) => {
107
+ const workspace = await workspaceTable.getItem({ namespace, slug });
103
108
  if (!workspace) {
104
109
  return void 0;
105
110
  }
111
+ const id = getWorkspaceId(namespace, slug);
106
112
  const workspaceDocuments = await documentsTable.getRange([id]);
107
113
  const workspaceOriginalDocuments = await originalDocumentTable.getRange([id]);
108
114
  const workspaceIntermediateDocuments = await intermediateDocumentTable.getRange([id]);
109
115
  const workspaceOverrides = await overridesTable.getRange([id]);
110
116
  const workspaceMeta = await metaTable.getItem({ workspaceId: id });
111
117
  return {
112
- id,
113
118
  name: workspace.name,
119
+ teamUid: workspace.teamUid,
120
+ namespace: workspace.namespace,
121
+ slug: workspace.slug,
114
122
  workspace: {
115
123
  documents: Object.fromEntries(workspaceDocuments.map((item) => [item.documentName, item.data])),
116
124
  originalDocuments: Object.fromEntries(
@@ -133,13 +141,26 @@ const createWorkspaceStorePersistence = async () => {
133
141
  getAll: async () => {
134
142
  return await workspaceTable.getAll();
135
143
  },
144
+ /**
145
+ * Retrieves all workspaces for a given team UID.
146
+ */
147
+ getAllByTeamUid: async (teamUid) => {
148
+ return await workspaceTable.getRange([teamUid], "teamUid");
149
+ },
136
150
  /**
137
151
  * Saves a workspace to the database.
138
152
  * All chunks (meta, documents, configs, etc.) are upsert in their respective tables.
139
153
  * If a workspace with the same ID already exists, it will be replaced.
140
154
  */
141
- setItem: async (id, value) => {
142
- await workspaceTable.addItem({ id }, { name: value.name });
155
+ setItem: async ({ namespace = "local", slug }, value) => {
156
+ const workspace = await workspaceTable.addItem(
157
+ { namespace, slug },
158
+ {
159
+ name: value.name,
160
+ teamUid: value.teamUid ?? "local"
161
+ }
162
+ );
163
+ const id = getWorkspaceId(namespace, slug);
143
164
  await metaTable.addItem({ workspaceId: id }, { data: value.workspace.meta });
144
165
  await Promise.all(
145
166
  Object.entries(value.workspace.documents ?? {}).map(([name, data]) => {
@@ -161,12 +182,14 @@ const createWorkspaceStorePersistence = async () => {
161
182
  return overridesTable.addItem({ workspaceId: id, documentName: name }, { data });
162
183
  })
163
184
  );
185
+ return workspace;
164
186
  },
165
187
  /**
166
188
  * Deletes an entire workspace and all associated chunk records from all tables by ID.
167
189
  */
168
- deleteItem: async (id) => {
169
- await workspaceTable.deleteItem({ id });
190
+ deleteItem: async ({ namespace, slug }) => {
191
+ const id = getWorkspaceId(namespace, slug);
192
+ await workspaceTable.deleteItem({ namespace, slug });
170
193
  await Promise.all([
171
194
  // By id
172
195
  metaTable.deleteItem({ workspaceId: id }),
@@ -188,8 +211,8 @@ const createWorkspaceStorePersistence = async () => {
188
211
  /**
189
212
  * Checks if a workspace with the given ID exists in the store.
190
213
  */
191
- has: async (id) => {
192
- return await workspaceTable.getItem({ id }) !== void 0;
214
+ has: async ({ namespace, slug }) => {
215
+ return await workspaceTable.getItem({ namespace, slug }) !== void 0;
193
216
  }
194
217
  },
195
218
  clear: async () => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/persistence/index.ts"],
4
- "sourcesContent": ["import { Type } from '@scalar/typebox'\n\nimport { createIndexDbConnection } from '@/persistence/indexdb'\nimport type { InMemoryWorkspace } from '@/schemas/inmemory-workspace'\nimport type { WorkspaceMeta } from '@/schemas/workspace'\n\ntype WorkspaceStoreShape = {\n name: string\n workspace: InMemoryWorkspace\n}\n\n/**\n * Creates the persistence layer for the workspace store using IndexedDB.\n * This sets up all the required tables for storing workspace chunk information,\n * such as workspace meta, documents, original documents, intermediate documents, overrides, etc.\n * Each logical group (meta, documents, etc) gets its own table keyed appropriately for efficient sub-document access.\n * Returns an object containing `meta`, `documents`, `originalDocuments`, `intermediateDocuments`, `overrides`,\n * `documentMeta`, `documentConfigs`, and `workspace` sections, each exposing a `setItem` method\n * for upsetting records, and in the case of `workspace`, also `getItem` and `deleteItem`.\n */\nexport const createWorkspaceStorePersistence = async () => {\n // Create the database connection and setup all required tables for workspace storage.\n const connection = await createIndexDbConnection({\n name: 'scalar-workspace-store',\n version: 1,\n tables: {\n workspace: {\n schema: Type.Object({\n /** UID for workspaces stored in the DB */\n id: Type.String(),\n /** Visual name for a given workspace */\n name: Type.String(),\n /** When logged in all new workspaces (remote and local) are scoped to a team */\n teamUid: Type.String({ default: 'LOCAL' }),\n /** Namespace associated with a remote workspace */\n namespace: Type.String({ default: 'LOCAL' }),\n /** Slug associated with a remote workspace */\n slug: Type.String({ default: 'LOCAL' }),\n }),\n index: ['id'],\n },\n meta: {\n schema: Type.Object({ workspaceId: Type.String(), data: Type.Any() }),\n index: ['workspaceId'],\n },\n documents: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n index: ['workspaceId', 'documentName'],\n },\n originalDocuments: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n index: ['workspaceId', 'documentName'],\n },\n intermediateDocuments: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n index: ['workspaceId', 'documentName'],\n },\n overrides: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n index: ['workspaceId', 'documentName'],\n },\n },\n })\n\n // Tables wrappers for each logical section.\n const workspaceTable = connection.get('workspace')\n const metaTable = connection.get('meta')\n const documentsTable = connection.get('documents')\n const originalDocumentTable = connection.get('originalDocuments')\n const intermediateDocumentTable = connection.get('intermediateDocuments')\n const overridesTable = connection.get('overrides')\n\n // The returned persistence API with logical sections for each table and mapping.\n return {\n close: () => {\n connection.closeDatabase()\n },\n meta: {\n /**\n * Set meta data for a workspace.\n */\n setItem: async (workspaceId: string, data: WorkspaceMeta) => {\n await metaTable.addItem({ workspaceId }, { data })\n },\n },\n documents: {\n /**\n * Set (persist) a workspace document using workspaceId and documentName as composite key.\n */\n setItem: async (workspaceId: string, documentName: string, data: InMemoryWorkspace['documents'][string]) => {\n await documentsTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n originalDocuments: {\n /**\n * Set an original (raw) document for a workspace/document pair.\n */\n setItem: async (\n workspaceId: string,\n documentName: string,\n data: InMemoryWorkspace['originalDocuments'][string],\n ) => {\n await originalDocumentTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n intermediateDocuments: {\n /**\n * Set an intermediate (transformed) document for a workspace/document pair.\n */\n setItem: async (\n workspaceId: string,\n documentName: string,\n data: InMemoryWorkspace['intermediateDocuments'][string],\n ) => {\n await intermediateDocumentTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n overrides: {\n /**\n * Set document overrides for a workspace/document pair.\n */\n setItem: async (workspaceId: string, documentName: string, data: InMemoryWorkspace['overrides'][string]) => {\n await overridesTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n workspace: {\n /**\n * Retrieves a workspace by its ID.\n * Returns undefined if the workspace does not exist.\n * Gathers all workspace 'chunk' tables and assembles a full workspace shape.\n */\n getItem: async (id: string): Promise<(WorkspaceStoreShape & { id: string }) | undefined> => {\n const workspace = await workspaceTable.getItem({ id })\n\n if (!workspace) {\n return undefined\n }\n\n // Retrieve all chunk records for this workspace.\n const workspaceDocuments = await documentsTable.getRange([id])\n const workspaceOriginalDocuments = await originalDocumentTable.getRange([id])\n const workspaceIntermediateDocuments = await intermediateDocumentTable.getRange([id])\n const workspaceOverrides = await overridesTable.getRange([id])\n const workspaceMeta = await metaTable.getItem({ workspaceId: id })\n\n // Compose the workspace structure from table records.\n return {\n id,\n name: workspace.name,\n workspace: {\n documents: Object.fromEntries(workspaceDocuments.map((item) => [item.documentName, item.data])),\n originalDocuments: Object.fromEntries(\n workspaceOriginalDocuments.map((item) => [item.documentName, item.data]),\n ),\n intermediateDocuments: Object.fromEntries(\n workspaceIntermediateDocuments.map((item) => [item.documentName, item.data]),\n ),\n overrides: Object.fromEntries(workspaceOverrides.map((item) => [item.documentName, item.data])),\n meta: workspaceMeta?.data,\n },\n }\n },\n\n /**\n * Retrieves all workspaces from the database.\n * Returns only the workspace ID and name for each workspace.\n * To get the full workspace data including documents and metadata, use getItem() with a specific ID.\n * Returns an empty array if no workspaces exist.\n */\n getAll: async () => {\n return await workspaceTable.getAll()\n },\n\n /**\n * Saves a workspace to the database.\n * All chunks (meta, documents, configs, etc.) are upsert in their respective tables.\n * If a workspace with the same ID already exists, it will be replaced.\n */\n setItem: async (id: string, value: WorkspaceStoreShape): Promise<void> => {\n await workspaceTable.addItem({ id }, { name: value.name })\n\n // Save all meta info for workspace.\n await metaTable.addItem({ workspaceId: id }, { data: value.workspace.meta })\n\n // Persist all workspace documents (chunks).\n await Promise.all(\n Object.entries(value.workspace.documents ?? {}).map(([name, data]) => {\n return documentsTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n // Persist all original documents.\n await Promise.all(\n Object.entries(value.workspace.originalDocuments ?? {}).map(([name, data]) => {\n return originalDocumentTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n // Persist all intermediate documents.\n await Promise.all(\n Object.entries(value.workspace.intermediateDocuments ?? {}).map(([name, data]) => {\n return intermediateDocumentTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n // Persist all document overrides.\n await Promise.all(\n Object.entries(value.workspace.overrides ?? {}).map(([name, data]) => {\n return overridesTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n },\n\n /**\n * Deletes an entire workspace and all associated chunk records from all tables by ID.\n */\n deleteItem: async (id: string): Promise<void> => {\n await workspaceTable.deleteItem({ id })\n\n // Remove all workspace-related records from all chunk tables.\n await Promise.all([\n // By id\n metaTable.deleteItem({ workspaceId: id }),\n\n // By range (composite-key tables)\n documentsTable.deleteRange([id]),\n originalDocumentTable.deleteRange([id]),\n intermediateDocumentTable.deleteRange([id]),\n overridesTable.deleteRange([id]),\n ])\n },\n\n deleteDocument: async (workspaceId: string, documentName: string): Promise<void> => {\n await Promise.all([\n documentsTable.deleteItem({ workspaceId, documentName }),\n intermediateDocumentTable.deleteItem({ workspaceId, documentName }),\n originalDocumentTable.deleteItem({ workspaceId, documentName }),\n overridesTable.deleteItem({ workspaceId, documentName }),\n ])\n },\n\n /**\n * Checks if a workspace with the given ID exists in the store.\n */\n has: async (id: string): Promise<boolean> => {\n return (await workspaceTable.getItem({ id })) !== undefined\n },\n },\n clear: async () => {\n await workspaceTable.deleteAll()\n },\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Type } from '@scalar/typebox'\n\nimport { createIndexDbConnection } from '@/persistence/indexdb'\nimport type { InMemoryWorkspace } from '@/schemas/inmemory-workspace'\nimport type { WorkspaceMeta } from '@/schemas/workspace'\n\ntype WorkspaceKey = {\n namespace?: string\n slug: string\n}\n\ntype WorkspaceStoreShape = {\n teamUid?: string\n name: string\n workspace: InMemoryWorkspace\n}\n\n/** Generates a workspace ID from namespace and slug. */\nconst getWorkspaceId = (namespace: string, slug: string) => `${namespace}/${slug}`\n\n/**\n * Creates the persistence layer for the workspace store using IndexedDB.\n * This sets up all the required tables for storing workspace chunk information,\n * such as workspace meta, documents, original documents, intermediate documents, overrides, etc.\n * Each logical group (meta, documents, etc) gets its own table keyed appropriately for efficient sub-document access.\n * Returns an object containing `meta`, `documents`, `originalDocuments`, `intermediateDocuments`, `overrides`,\n * `documentMeta`, `documentConfigs`, and `workspace` sections, each exposing a `setItem` method\n * for upsetting records, and in the case of `workspace`, also `getItem` and `deleteItem`.\n */\nexport const createWorkspaceStorePersistence = async () => {\n // Create the database connection and setup all required tables for workspace storage.\n const connection = await createIndexDbConnection({\n name: 'scalar-workspace-store',\n version: 1,\n tables: {\n workspace: {\n schema: Type.Object({\n /** Visual name for a given workspace */\n name: Type.String(),\n /** When logged in all new workspaces (remote and local) are scoped to a team */\n teamUid: Type.String({ default: 'local' }),\n /** Namespace associated with a remote workspace */\n namespace: Type.String({ default: 'local' }),\n /** Slug associated with a remote workspace */\n slug: Type.String({ default: 'local' }),\n }),\n keyPath: ['namespace', 'slug'],\n indexes: {\n teamUid: ['teamUid'],\n },\n },\n meta: {\n schema: Type.Object({ workspaceId: Type.String(), data: Type.Any() }),\n keyPath: ['workspaceId'],\n },\n documents: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n keyPath: ['workspaceId', 'documentName'],\n },\n originalDocuments: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n keyPath: ['workspaceId', 'documentName'],\n },\n intermediateDocuments: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n keyPath: ['workspaceId', 'documentName'],\n },\n overrides: {\n schema: Type.Object({ workspaceId: Type.String(), documentName: Type.String(), data: Type.Any() }),\n keyPath: ['workspaceId', 'documentName'],\n },\n },\n })\n\n // Tables wrappers for each logical section.\n const workspaceTable = connection.get('workspace')\n const metaTable = connection.get('meta')\n const documentsTable = connection.get('documents')\n const originalDocumentTable = connection.get('originalDocuments')\n const intermediateDocumentTable = connection.get('intermediateDocuments')\n const overridesTable = connection.get('overrides')\n\n // The returned persistence API with logical sections for each table and mapping.\n return {\n close: () => {\n connection.closeDatabase()\n },\n meta: {\n /**\n * Set meta data for a workspace.\n */\n setItem: async (workspaceId: string, data: WorkspaceMeta) => {\n await metaTable.addItem({ workspaceId }, { data })\n },\n },\n documents: {\n /**\n * Set (persist) a workspace document using workspaceId and documentName as composite key.\n */\n setItem: async (workspaceId: string, documentName: string, data: InMemoryWorkspace['documents'][string]) => {\n await documentsTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n originalDocuments: {\n /**\n * Set an original (raw) document for a workspace/document pair.\n */\n setItem: async (\n workspaceId: string,\n documentName: string,\n data: InMemoryWorkspace['originalDocuments'][string],\n ) => {\n await originalDocumentTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n intermediateDocuments: {\n /**\n * Set an intermediate (transformed) document for a workspace/document pair.\n */\n setItem: async (\n workspaceId: string,\n documentName: string,\n data: InMemoryWorkspace['intermediateDocuments'][string],\n ) => {\n await intermediateDocumentTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n overrides: {\n /**\n * Set document overrides for a workspace/document pair.\n */\n setItem: async (workspaceId: string, documentName: string, data: InMemoryWorkspace['overrides'][string]) => {\n await overridesTable.addItem({ workspaceId, documentName }, { data })\n },\n },\n workspace: {\n /**\n * Retrieves a workspace by its ID.\n * Returns undefined if the workspace does not exist.\n * Gathers all workspace 'chunk' tables and assembles a full workspace shape.\n */\n getItem: async ({\n namespace,\n slug,\n }: Required<WorkspaceKey>): Promise<(WorkspaceStoreShape & Required<WorkspaceKey>) | undefined> => {\n const workspace = await workspaceTable.getItem({ namespace, slug })\n\n if (!workspace) {\n return undefined\n }\n\n // Create a composite key for the workspace chunks.\n const id = getWorkspaceId(namespace, slug)\n\n // Retrieve all chunk records for this workspace.\n const workspaceDocuments = await documentsTable.getRange([id])\n const workspaceOriginalDocuments = await originalDocumentTable.getRange([id])\n const workspaceIntermediateDocuments = await intermediateDocumentTable.getRange([id])\n const workspaceOverrides = await overridesTable.getRange([id])\n const workspaceMeta = await metaTable.getItem({ workspaceId: id })\n\n // Compose the workspace structure from table records.\n return {\n name: workspace.name,\n teamUid: workspace.teamUid,\n namespace: workspace.namespace,\n slug: workspace.slug,\n workspace: {\n documents: Object.fromEntries(workspaceDocuments.map((item) => [item.documentName, item.data])),\n originalDocuments: Object.fromEntries(\n workspaceOriginalDocuments.map((item) => [item.documentName, item.data]),\n ),\n intermediateDocuments: Object.fromEntries(\n workspaceIntermediateDocuments.map((item) => [item.documentName, item.data]),\n ),\n overrides: Object.fromEntries(workspaceOverrides.map((item) => [item.documentName, item.data])),\n meta: workspaceMeta?.data,\n },\n }\n },\n\n /**\n * Retrieves all workspaces from the database.\n * Returns only the workspace ID and name for each workspace.\n * To get the full workspace data including documents and metadata, use getItem() with a specific ID.\n * Returns an empty array if no workspaces exist.\n */\n getAll: async () => {\n return await workspaceTable.getAll()\n },\n\n /**\n * Retrieves all workspaces for a given team UID.\n */\n getAllByTeamUid: async (teamUid: string) => {\n return await workspaceTable.getRange([teamUid], 'teamUid')\n },\n\n /**\n * Saves a workspace to the database.\n * All chunks (meta, documents, configs, etc.) are upsert in their respective tables.\n * If a workspace with the same ID already exists, it will be replaced.\n */\n setItem: async ({ namespace = 'local', slug }: WorkspaceKey, value: WorkspaceStoreShape) => {\n const workspace = await workspaceTable.addItem(\n { namespace, slug },\n {\n name: value.name,\n teamUid: value.teamUid ?? 'local',\n },\n )\n\n const id = getWorkspaceId(namespace, slug)\n\n // Save all meta info for workspace.\n await metaTable.addItem({ workspaceId: id }, { data: value.workspace.meta })\n\n // Persist all workspace documents (chunks).\n await Promise.all(\n Object.entries(value.workspace.documents ?? {}).map(([name, data]) => {\n return documentsTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n // Persist all original documents.\n await Promise.all(\n Object.entries(value.workspace.originalDocuments ?? {}).map(([name, data]) => {\n return originalDocumentTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n // Persist all intermediate documents.\n await Promise.all(\n Object.entries(value.workspace.intermediateDocuments ?? {}).map(([name, data]) => {\n return intermediateDocumentTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n // Persist all document overrides.\n await Promise.all(\n Object.entries(value.workspace.overrides ?? {}).map(([name, data]) => {\n return overridesTable.addItem({ workspaceId: id, documentName: name }, { data })\n }),\n )\n\n return workspace\n },\n\n /**\n * Deletes an entire workspace and all associated chunk records from all tables by ID.\n */\n deleteItem: async ({ namespace, slug }: Required<WorkspaceKey>): Promise<void> => {\n const id = getWorkspaceId(namespace, slug)\n\n await workspaceTable.deleteItem({ namespace, slug })\n\n // Remove all workspace-related records from all chunk tables.\n await Promise.all([\n // By id\n metaTable.deleteItem({ workspaceId: id }),\n\n // By range (composite-key tables)\n documentsTable.deleteRange([id]),\n originalDocumentTable.deleteRange([id]),\n intermediateDocumentTable.deleteRange([id]),\n overridesTable.deleteRange([id]),\n ])\n },\n\n deleteDocument: async (workspaceId: string, documentName: string): Promise<void> => {\n await Promise.all([\n documentsTable.deleteItem({ workspaceId, documentName }),\n intermediateDocumentTable.deleteItem({ workspaceId, documentName }),\n originalDocumentTable.deleteItem({ workspaceId, documentName }),\n overridesTable.deleteItem({ workspaceId, documentName }),\n ])\n },\n\n /**\n * Checks if a workspace with the given ID exists in the store.\n */\n has: async ({ namespace, slug }: Required<WorkspaceKey>): Promise<boolean> => {\n return (await workspaceTable.getItem({ namespace, slug })) !== undefined\n },\n },\n clear: async () => {\n await workspaceTable.deleteAll()\n },\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,8 @@
1
1
  import type { Static, TObject } from '@scalar/typebox';
2
2
  type TableEntry<S extends TObject, K extends readonly (keyof Static<S>)[]> = {
3
3
  schema: S;
4
- index: K;
4
+ keyPath: K;
5
+ indexes?: Record<string, readonly (keyof Static<S>)[]>;
5
6
  };
6
7
  /**
7
8
  * Initializes and manages an IndexedDB database connection for table-based persistence.
@@ -64,18 +65,18 @@ export declare const createIndexDbConnection: <T extends Record<string, TableEnt
64
65
  }[];
65
66
  }) => Promise<{
66
67
  get: <Name extends keyof T>(name: Name) => {
67
- addItem: (key: Record<T[Name]["index"][number], IDBValidKey>, value: Omit<(T[Name]["schema"] & {
68
+ addItem: (key: Record<T[Name]["keyPath"][number], IDBValidKey>, value: Omit<(T[Name]["schema"] & {
68
69
  params: [];
69
- })["static"], T[Name]["index"][number]>) => Promise<(T[Name]["schema"] & {
70
+ })["static"], T[Name]["keyPath"][number]>) => Promise<(T[Name]["schema"] & {
70
71
  params: [];
71
72
  })["static"]>;
72
- getItem: (key: Record<T[Name]["index"][number], IDBValidKey>) => Promise<(T[Name]["schema"] & {
73
+ getItem: (key: Record<T[Name]["keyPath"][number], IDBValidKey>) => Promise<(T[Name]["schema"] & {
73
74
  params: [];
74
75
  })["static"] | undefined>;
75
- getRange: (partialKey: IDBValidKey[]) => Promise<(T[Name]["schema"] & {
76
+ getRange: (partialKey: IDBValidKey[], indexName?: string) => Promise<(T[Name]["schema"] & {
76
77
  params: [];
77
78
  })["static"][]>;
78
- deleteItem: (key: Record<T[Name]["index"][number], IDBValidKey>) => Promise<void>;
79
+ deleteItem: (key: Record<T[Name]["keyPath"][number], IDBValidKey>) => Promise<void>;
79
80
  deleteRange: (partialKey: IDBValidKey[]) => Promise<number>;
80
81
  getAll: () => Promise<(T[Name]["schema"] & {
81
82
  params: [];
@@ -1 +1 @@
1
- {"version":3,"file":"indexdb.d.ts","sourceRoot":"","sources":["../../src/persistence/indexdb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAW,MAAM,iBAAiB,CAAA;AAE/D,KAAK,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI;IAC3E,MAAM,EAAE,CAAC,CAAA;IACT,KAAK,EAAE,CAAC,CAAA;CACT,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,eAAO,MAAM,uBAAuB,GAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,wCAK9G;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;IACT,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,qBAAqB,KAAK,EAAE,CAAA;KAAE,EAAE,CAAA;CAChG;UAgCS,IAAI,SAAS,MAAM,CAAC,QAAQ,IAAI;;;;;;;;;+BA+FV,WAAW,EAAE;;;4EA6Ba,OAAO,CAAC,IAAI,CAAC;kCAmBpC,WAAW,EAAE,KAAG,OAAO,CAAC,MAAM,CAAC;;;;yBA6BpC,OAAO,CAAC,IAAI,CAAC;;;EArK1C,CAAA"}
1
+ {"version":3,"file":"indexdb.d.ts","sourceRoot":"","sources":["../../src/persistence/indexdb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAW,MAAM,iBAAiB,CAAA;AAE/D,KAAK,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI;IAC3E,MAAM,EAAE,CAAC,CAAA;IACT,OAAO,EAAE,CAAC,CAAA;IACV,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;CACvD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,eAAO,MAAM,uBAAuB,GAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,wCAK9G;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;IACT,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,qBAAqB,KAAK,EAAE,CAAA;KAAE,EAAE,CAAA;CAChG;UAqCS,IAAI,SAAS,MAAM,CAAC,QAAQ,IAAI;;;;;;;;;+BA+FV,WAAW,EAAE,cAAc,MAAM;;;8EA+BP,OAAO,CAAC,IAAI,CAAC;kCAmBpC,WAAW,EAAE,KAAG,OAAO,CAAC,MAAM,CAAC;;;;yBA6BpC,OAAO,CAAC,IAAI,CAAC;;;EAvK1C,CAAA"}
@@ -10,8 +10,11 @@ const createIndexDbConnection = async ({
10
10
  const database = db.result;
11
11
  Object.entries(tables).forEach(([name2, options]) => {
12
12
  if (!database.objectStoreNames.contains(name2)) {
13
- database.createObjectStore(name2, {
14
- keyPath: options.index.length === 1 ? options.index[0] : options.index
13
+ const objectStore = database.createObjectStore(name2, {
14
+ keyPath: options.keyPath.length === 1 ? options.keyPath[0] : options.keyPath
15
+ });
16
+ Object.entries(options.indexes ?? {}).forEach(([indexName, indexPath]) => {
17
+ objectStore.createIndex(indexName, indexPath);
15
18
  });
16
19
  }
17
20
  });
@@ -53,14 +56,15 @@ function createTableWrapper(name, db) {
53
56
  const keyToUse = keyValues.length === 1 ? keyValues[0] : keyValues;
54
57
  return requestAsPromise(store.get(keyToUse));
55
58
  }
56
- function getRange(partialKey) {
59
+ function getRange(partialKey, indexName) {
57
60
  const store = getStore("readonly");
61
+ const objectStoreOrIndex = indexName ? store.index(indexName) : store;
58
62
  const results = [];
59
63
  const upperBound = [...partialKey];
60
64
  upperBound.push([]);
61
65
  const range = IDBKeyRange.bound(partialKey, upperBound, false, true);
62
66
  return new Promise((resolve, reject) => {
63
- const request = store.openCursor(range);
67
+ const request = objectStoreOrIndex.openCursor(range);
64
68
  request.onerror = () => reject(request.error);
65
69
  request.onsuccess = (event) => {
66
70
  const cursor = event.target.result;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/persistence/indexdb.ts"],
4
- "sourcesContent": ["import type { Static, TObject, TRecord } from '@scalar/typebox'\n\ntype TableEntry<S extends TObject, K extends readonly (keyof Static<S>)[]> = {\n schema: S\n index: K\n}\n\n/**\n * Initializes and manages an IndexedDB database connection for table-based persistence.\n *\n * @param name - The database name. Defaults to 'scalar-workspace-store'.\n * @param tables - Table definitions: the tables to create and their key schemas.\n * @param version - The database version. Bump this to trigger upgrades (default: 1).\n * @param migrations - Optional migration steps to run for version upgrades.\n * @returns An object with the following methods:\n * - `get(tableName)` \u2014 Get a wrapper to interact with the object store for the given table name.\n * - `closeDatabase()` \u2014 Closes the database connection.\n *\n * Example usage:\n * ```ts\n * import { Type } from '@scalar/typebox'\n * import { createIndexDbConnection } from './indexdb'\n *\n * // Define a schema for a user\n * const UserSchema = Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * age: Type.Number(),\n * })\n *\n * // Define tables in the database\n * const dbConfig = {\n * users: {\n * schema: UserSchema,\n * index: ['id'] as const,\n * },\n * }\n *\n * // Open the database connection and get table API\n * const { get, closeDatabase } = await createIndexDbConnection({\n * name: 'my-app-db',\n * tables: dbConfig,\n * version: 1,\n * })\n *\n * // Get a strongly-typed users table API\n * const usersTable = get('users')\n *\n * // Add a user\n * await usersTable.addItem({ id: 'user-1' }, { name: 'Alice', age: 25 })\n *\n * // Retrieve a user by id\n * const user = await usersTable.getItem({ id: 'user-1' })\n *\n * // Don't forget to close the database when done!\n * closeDatabase()\n * ```\n */\nexport const createIndexDbConnection = async <T extends Record<string, TableEntry<any, readonly (keyof any)[]>>>({\n name = 'scalar-workspace-store',\n tables,\n version = 1,\n migrations = [],\n}: {\n name: string\n tables: T\n version: number\n migrations?: { version: number; exec: (db: IDBDatabase, event: IDBVersionChangeEvent) => {} }[]\n}) => {\n const db = indexedDB.open(name, version)\n\n db.onupgradeneeded = (e) => {\n // Initial setup of object stores\n if (e.oldVersion < 1) {\n const database = db.result\n\n // Initialize all the tables\n Object.entries(tables).forEach(([name, options]) => {\n if (!database.objectStoreNames.contains(name)) {\n database.createObjectStore(name, {\n keyPath: options.index.length === 1 ? (options.index[0] as string) : (options.index as string[]),\n })\n }\n })\n }\n\n // Run any future migrations here\n migrations.forEach((migration) => {\n if (e.oldVersion < migration.version) {\n migration.exec(db.result, e)\n }\n })\n }\n\n await new Promise((resolve, reject) => {\n db.onsuccess = () => resolve(true)\n db.onerror = () => reject(db.error)\n })\n\n return {\n get: <Name extends keyof T>(name: Name) => {\n return createTableWrapper<T[Name]['schema'], T[Name]['index'][number]>(name as string, db.result)\n },\n closeDatabase: () => {\n db.result.close()\n },\n }\n}\n\n/**\n * Utility wrapper for interacting with an IndexedDB object store, typed by the schema.\n *\n * Usage example:\n * ```\n * // Define a TypeBox schema for users\n * const UserSchema = Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * age: Type.Number(),\n * })\n * \n * // Open or create the users table\n * const usersTable = createTableWrapper<typeof UserSchema, 'id'>('users', openDatabase)\n * \n * // Add a user\n await usersTable.addItem({ id: 'user-1' }, { name: 'Alice', age: 24 })\n * \n * // Get a user by id\n * const alic = await usersTable.getItem({ id: 'user-1' })\n * \n * // Get users with a partial key (use [] if no composite key)\n * const users = await usersTable.getRange(['user-1'])\n * \n * // Get all users\n * const allUsers = await usersTable.getAll()\n * ```\n *\n * @template T TypeBox schema type for objects in the store\n * @template K Key property names that compose the primary key\n *\n * @param name - Object store name\n * @param getDb - Function returning a Promise for the IDBDatabase\n * @returns Methods to interact with the object store\n */\nfunction createTableWrapper<T extends TRecord | TObject, const K extends keyof Static<T>>(\n name: string,\n db: IDBDatabase,\n) {\n /**\n * Gets the object store from the latest DB connection, for the given transaction mode.\n */\n const getStore = (mode: IDBTransactionMode): IDBObjectStore => {\n const tx = db.transaction(name, mode)\n return tx.objectStore(name)\n }\n\n /**\n * Adds or updates an item in the store.\n * @param key - The primary key values, as { key1, key2 }\n * @param value - The value for the other properties, omitting keys\n * @returns The full inserted/updated object\n */\n async function addItem(key: Record<K, IDBValidKey>, value: Omit<Static<T>, K>): Promise<Static<T>> {\n const store = getStore('readwrite')\n const keyObj: any = { ...key }\n const finalValue = { ...keyObj, ...value }\n await requestAsPromise(store.put(finalValue))\n\n return finalValue\n }\n\n /**\n * Retrieves a single item by composite key.\n * @param key - Key values. For a single key: { id: '...' }\n * @returns The found object or undefined\n */\n function getItem(key: Record<K, IDBValidKey>): Promise<Static<T> | undefined> {\n const store = getStore('readonly')\n const keyValues = Object.values(key)\n // For single keys, pass value directly; for compound keys, pass array\n const keyToUse = keyValues.length === 1 ? keyValues[0] : keyValues\n return requestAsPromise(store.get(keyToUse as IDBValidKey))\n }\n\n /**\n * Returns all records matching a partial (prefix) key. Use for composite keys.\n * For non-compound keys, pass single-element array: getRange(['some-id'])\n * For prefix search, pass subset of key parts.\n * @param partialKey - Array of partial key values\n * @returns Matching objects\n *\n * Example (composite [a,b]):\n * getRange(['foo']) // All with a === 'foo'\n * getRange(['foo', 'bar']) // All with a === 'foo' and b === 'bar'\n */\n function getRange(partialKey: IDBValidKey[]): Promise<Static<T>[]> {\n const store = getStore('readonly')\n const results: Static<T>[] = []\n\n // Construct upper bound to match all keys starting with partialKey\n const upperBound = [...partialKey]\n upperBound.push([]) // ensures upper bound includes all keys with this prefix\n const range = IDBKeyRange.bound(partialKey, upperBound, false, true)\n\n return new Promise((resolve, reject) => {\n const request = store.openCursor(range)\n request.onerror = () => reject(request.error)\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) {\n results.push(cursor.value)\n cursor.continue()\n } else {\n resolve(results)\n }\n }\n })\n }\n\n /**\n * Deletes an item from the store by its composite key.\n * @param key - Key values. For a single key: { id: '...' }\n * @returns void\n */\n async function deleteItem(key: Record<K, IDBValidKey>): Promise<void> {\n const store = getStore('readwrite')\n const keyValues = Object.values(key)\n // For single keys, pass value directly; for compound keys, pass array\n const keyToUse = keyValues.length === 1 ? keyValues[0] : keyValues\n await requestAsPromise(store.delete(keyToUse as IDBValidKey))\n }\n\n /**\n * Deletes all records matching a partial (prefix) key. Use for composite keys.\n * For non-compound keys, pass single-element array: deleteRange(['some-id'])\n * For prefix deletion, pass subset of key parts.\n * @param partialKey - Array of partial key values\n * @returns Number of deleted items\n *\n * Example (composite [a,b]):\n * deleteRange(['foo']) // Delete all with a === 'foo'\n * deleteRange(['foo', 'bar']) // Delete all with a === 'foo' and b === 'bar'\n */\n function deleteRange(partialKey: IDBValidKey[]): Promise<number> {\n const store = getStore('readwrite')\n let deletedCount = 0\n\n // Construct upper bound to match all keys starting with partialKey\n const upperBound = [...partialKey]\n upperBound.push([]) // ensures upper bound includes all keys with this prefix\n const range = IDBKeyRange.bound(partialKey, upperBound, false, true)\n\n return new Promise((resolve, reject) => {\n const request = store.openCursor(range)\n request.onerror = () => reject(request.error)\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) {\n cursor.delete()\n deletedCount++\n cursor.continue()\n } else {\n resolve(deletedCount)\n }\n }\n })\n }\n\n /**\n * Deletes all items from the table.\n * @returns void\n */\n async function deleteAll(): Promise<void> {\n const store = getStore('readwrite')\n await requestAsPromise(store.clear())\n }\n\n /**\n * Retrieves all items from the table.\n * @returns Array of all objects in the store\n */\n function getAll(): Promise<Static<T>[]> {\n const store = getStore('readonly')\n return requestAsPromise(store.getAll())\n }\n\n return {\n addItem,\n getItem,\n getRange,\n deleteItem,\n deleteRange,\n getAll,\n deleteAll,\n }\n}\n\n// ---- Utility ----\nfunction requestAsPromise<T>(req: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n req.onsuccess = () => resolve(req.result)\n req.onerror = () => reject(req.error)\n })\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Static, TObject, TRecord } from '@scalar/typebox'\n\ntype TableEntry<S extends TObject, K extends readonly (keyof Static<S>)[]> = {\n schema: S\n keyPath: K\n indexes?: Record<string, readonly (keyof Static<S>)[]>\n}\n\n/**\n * Initializes and manages an IndexedDB database connection for table-based persistence.\n *\n * @param name - The database name. Defaults to 'scalar-workspace-store'.\n * @param tables - Table definitions: the tables to create and their key schemas.\n * @param version - The database version. Bump this to trigger upgrades (default: 1).\n * @param migrations - Optional migration steps to run for version upgrades.\n * @returns An object with the following methods:\n * - `get(tableName)` \u2014 Get a wrapper to interact with the object store for the given table name.\n * - `closeDatabase()` \u2014 Closes the database connection.\n *\n * Example usage:\n * ```ts\n * import { Type } from '@scalar/typebox'\n * import { createIndexDbConnection } from './indexdb'\n *\n * // Define a schema for a user\n * const UserSchema = Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * age: Type.Number(),\n * })\n *\n * // Define tables in the database\n * const dbConfig = {\n * users: {\n * schema: UserSchema,\n * index: ['id'] as const,\n * },\n * }\n *\n * // Open the database connection and get table API\n * const { get, closeDatabase } = await createIndexDbConnection({\n * name: 'my-app-db',\n * tables: dbConfig,\n * version: 1,\n * })\n *\n * // Get a strongly-typed users table API\n * const usersTable = get('users')\n *\n * // Add a user\n * await usersTable.addItem({ id: 'user-1' }, { name: 'Alice', age: 25 })\n *\n * // Retrieve a user by id\n * const user = await usersTable.getItem({ id: 'user-1' })\n *\n * // Don't forget to close the database when done!\n * closeDatabase()\n * ```\n */\nexport const createIndexDbConnection = async <T extends Record<string, TableEntry<any, readonly (keyof any)[]>>>({\n name = 'scalar-workspace-store',\n tables,\n version = 1,\n migrations = [],\n}: {\n name: string\n tables: T\n version: number\n migrations?: { version: number; exec: (db: IDBDatabase, event: IDBVersionChangeEvent) => {} }[]\n}) => {\n const db = indexedDB.open(name, version)\n\n db.onupgradeneeded = (e) => {\n // Initial setup of object stores\n if (e.oldVersion < 1) {\n const database = db.result\n\n // Initialize all the tables\n Object.entries(tables).forEach(([name, options]) => {\n if (!database.objectStoreNames.contains(name)) {\n const objectStore = database.createObjectStore(name, {\n keyPath: options.keyPath.length === 1 ? (options.keyPath[0] as string) : (options.keyPath as string[]),\n })\n\n // Create any indexes for the object store\n Object.entries(options.indexes ?? {}).forEach(([indexName, indexPath]) => {\n objectStore.createIndex(indexName, indexPath as string[])\n })\n }\n })\n }\n\n // Run any future migrations here\n migrations.forEach((migration) => {\n if (e.oldVersion < migration.version) {\n migration.exec(db.result, e)\n }\n })\n }\n\n await new Promise((resolve, reject) => {\n db.onsuccess = () => resolve(true)\n db.onerror = () => reject(db.error)\n })\n\n return {\n get: <Name extends keyof T>(name: Name) => {\n return createTableWrapper<T[Name]['schema'], T[Name]['keyPath'][number]>(name as string, db.result)\n },\n closeDatabase: () => {\n db.result.close()\n },\n }\n}\n\n/**\n * Utility wrapper for interacting with an IndexedDB object store, typed by the schema.\n *\n * Usage example:\n * ```\n * // Define a TypeBox schema for users\n * const UserSchema = Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * age: Type.Number(),\n * })\n * \n * // Open or create the users table\n * const usersTable = createTableWrapper<typeof UserSchema, 'id'>('users', openDatabase)\n * \n * // Add a user\n await usersTable.addItem({ id: 'user-1' }, { name: 'Alice', age: 24 })\n * \n * // Get a user by id\n * const alic = await usersTable.getItem({ id: 'user-1' })\n * \n * // Get users with a partial key (use [] if no composite key)\n * const users = await usersTable.getRange(['user-1'])\n * \n * // Get all users\n * const allUsers = await usersTable.getAll()\n * ```\n *\n * @template T TypeBox schema type for objects in the store\n * @template K Key property names that compose the primary key\n *\n * @param name - Object store name\n * @param getDb - Function returning a Promise for the IDBDatabase\n * @returns Methods to interact with the object store\n */\nfunction createTableWrapper<T extends TRecord | TObject, const K extends keyof Static<T>>(\n name: string,\n db: IDBDatabase,\n) {\n /**\n * Gets the object store from the latest DB connection, for the given transaction mode.\n */\n const getStore = (mode: IDBTransactionMode): IDBObjectStore => {\n const tx = db.transaction(name, mode)\n return tx.objectStore(name)\n }\n\n /**\n * Adds or updates an item in the store.\n * @param key - The primary key values, as { key1, key2 }\n * @param value - The value for the other properties, omitting keys\n * @returns The full inserted/updated object\n */\n async function addItem(key: Record<K, IDBValidKey>, value: Omit<Static<T>, K>): Promise<Static<T>> {\n const store = getStore('readwrite')\n const keyObj: any = { ...key }\n const finalValue = { ...keyObj, ...value }\n await requestAsPromise(store.put(finalValue))\n\n return finalValue\n }\n\n /**\n * Retrieves a single item by composite key.\n * @param key - Key values. For a single key: { id: '...' }\n * @returns The found object or undefined\n */\n function getItem(key: Record<K, IDBValidKey>): Promise<Static<T> | undefined> {\n const store = getStore('readonly')\n const keyValues = Object.values(key)\n // For single keys, pass value directly; for compound keys, pass array\n const keyToUse = keyValues.length === 1 ? keyValues[0] : keyValues\n return requestAsPromise(store.get(keyToUse as IDBValidKey))\n }\n\n /**\n * Returns all records matching a partial (prefix) key. Use for composite keys.\n * For non-compound keys, pass single-element array: getRange(['some-id'])\n * For prefix search, pass subset of key parts.\n * @param partialKey - Array of partial key values\n * @returns Matching objects\n *\n * Example (composite [a,b]):\n * getRange(['foo']) // All with a === 'foo'\n * getRange(['foo', 'bar']) // All with a === 'foo' and b === 'bar'\n */\n function getRange(partialKey: IDBValidKey[], indexName?: string): Promise<Static<T>[]> {\n const store = getStore('readonly')\n const objectStoreOrIndex = indexName ? store.index(indexName as string) : store\n\n const results: Static<T>[] = []\n\n // Construct upper bound to match all keys starting with partialKey\n const upperBound = [...partialKey]\n upperBound.push([]) // ensures upper bound includes all keys with this prefix\n const range = IDBKeyRange.bound(partialKey, upperBound, false, true)\n\n return new Promise((resolve, reject) => {\n const request = objectStoreOrIndex.openCursor(range)\n request.onerror = () => reject(request.error)\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) {\n results.push(cursor.value)\n cursor.continue()\n } else {\n resolve(results)\n }\n }\n })\n }\n\n /**\n * Deletes an item from the store by its composite key.\n * @param key - Key values. For a single key: { id: '...' }\n * @returns void\n */\n async function deleteItem(key: Record<K, IDBValidKey>): Promise<void> {\n const store = getStore('readwrite')\n const keyValues = Object.values(key)\n // For single keys, pass value directly; for compound keys, pass array\n const keyToUse = keyValues.length === 1 ? keyValues[0] : keyValues\n await requestAsPromise(store.delete(keyToUse as IDBValidKey))\n }\n\n /**\n * Deletes all records matching a partial (prefix) key. Use for composite keys.\n * For non-compound keys, pass single-element array: deleteRange(['some-id'])\n * For prefix deletion, pass subset of key parts.\n * @param partialKey - Array of partial key values\n * @returns Number of deleted items\n *\n * Example (composite [a,b]):\n * deleteRange(['foo']) // Delete all with a === 'foo'\n * deleteRange(['foo', 'bar']) // Delete all with a === 'foo' and b === 'bar'\n */\n function deleteRange(partialKey: IDBValidKey[]): Promise<number> {\n const store = getStore('readwrite')\n let deletedCount = 0\n\n // Construct upper bound to match all keys starting with partialKey\n const upperBound = [...partialKey]\n upperBound.push([]) // ensures upper bound includes all keys with this prefix\n const range = IDBKeyRange.bound(partialKey, upperBound, false, true)\n\n return new Promise((resolve, reject) => {\n const request = store.openCursor(range)\n request.onerror = () => reject(request.error)\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) {\n cursor.delete()\n deletedCount++\n cursor.continue()\n } else {\n resolve(deletedCount)\n }\n }\n })\n }\n\n /**\n * Deletes all items from the table.\n * @returns void\n */\n async function deleteAll(): Promise<void> {\n const store = getStore('readwrite')\n await requestAsPromise(store.clear())\n }\n\n /**\n * Retrieves all items from the table.\n * @returns Array of all objects in the store\n */\n function getAll(): Promise<Static<T>[]> {\n const store = getStore('readonly')\n return requestAsPromise(store.getAll())\n }\n\n return {\n addItem,\n getItem,\n getRange,\n deleteItem,\n deleteRange,\n getAll,\n deleteAll,\n }\n}\n\n// ---- Utility ----\nfunction requestAsPromise<T>(req: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n req.onsuccess = () => resolve(req.result)\n req.onerror = () => reject(req.error)\n })\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["name"]
7
7
  }
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "openapi",
17
17
  "scalar"
18
18
  ],
19
- "version": "0.27.2",
19
+ "version": "0.28.1",
20
20
  "engines": {
21
21
  "node": ">=18"
22
22
  },
@@ -114,13 +114,13 @@
114
114
  "vue": "^3.5.26",
115
115
  "yaml": "^2.8.0",
116
116
  "@scalar/code-highlight": "0.2.2",
117
- "@scalar/helpers": "0.2.9",
118
- "@scalar/object-utils": "1.2.23",
117
+ "@scalar/json-magic": "0.9.5",
118
+ "@scalar/helpers": "0.2.10",
119
+ "@scalar/object-utils": "1.2.24",
119
120
  "@scalar/openapi-upgrader": "0.1.8",
120
- "@scalar/json-magic": "0.9.4",
121
- "@scalar/snippetz": "0.6.9",
121
+ "@scalar/snippetz": "0.6.10",
122
122
  "@scalar/themes": "0.14.0",
123
- "@scalar/types": "0.6.0"
123
+ "@scalar/types": "0.6.1"
124
124
  },
125
125
  "devDependencies": {
126
126
  "@google-cloud/storage": "7.16.0",