@scalar/api-client 3.16.3 → 3.17.0
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 +11 -0
- package/README.md +18 -0
- package/dist/style.css +18 -29
- package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts +2 -0
- package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +36 -10
- package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.d.ts +4 -0
- package/dist/v2/blocks/operation-block/components/Header.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.js +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.js.map +1 -1
- package/dist/v2/blocks/operation-block/components/Header.vue.script.js +14 -9
- package/dist/v2/blocks/operation-block/components/Header.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts +4 -0
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js +61 -24
- package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/modal/Modal.vue.d.ts +2 -0
- package/dist/v2/features/modal/Modal.vue.d.ts.map +1 -1
- package/dist/v2/features/modal/Modal.vue.js.map +1 -1
- package/dist/v2/features/modal/Modal.vue.script.js +3 -0
- package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.d.ts.map +1 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.js +5 -1
- package/dist/v2/features/modal/helpers/create-api-client-modal.js.map +1 -1
- package/dist/v2/features/modal/helpers/resolve-route-parameters.d.ts +12 -3
- package/dist/v2/features/modal/helpers/resolve-route-parameters.d.ts.map +1 -1
- package/dist/v2/features/modal/helpers/resolve-route-parameters.js +13 -9
- package/dist/v2/features/modal/helpers/resolve-route-parameters.js.map +1 -1
- package/dist/v2/features/modal/hooks/use-modal-sidebar.d.ts +3 -1
- package/dist/v2/features/modal/hooks/use-modal-sidebar.d.ts.map +1 -1
- package/dist/v2/features/modal/hooks/use-modal-sidebar.js +28 -7
- package/dist/v2/features/modal/hooks/use-modal-sidebar.js.map +1 -1
- package/dist/v2/features/modal/modal-events.d.ts.map +1 -1
- package/dist/v2/features/modal/modal-events.js +2 -1
- package/dist/v2/features/modal/modal-events.js.map +1 -1
- package/dist/v2/features/operation/Operation.vue.d.ts +2 -0
- package/dist/v2/features/operation/Operation.vue.d.ts.map +1 -1
- package/dist/v2/features/operation/Operation.vue.js.map +1 -1
- package/dist/v2/features/operation/Operation.vue.script.js +8 -1
- package/dist/v2/features/operation/Operation.vue.script.js.map +1 -1
- package/dist/v2/helpers/generate-location-id.d.ts +3 -1
- package/dist/v2/helpers/generate-location-id.d.ts.map +1 -1
- package/dist/v2/helpers/generate-location-id.js +2 -1
- package/dist/v2/helpers/generate-location-id.js.map +1 -1
- package/dist/vue-styles.css +17 -17
- package/package.json +11 -11
|
@@ -3,13 +3,22 @@ import type { WorkspaceStore } from '@scalar/workspace-store/client';
|
|
|
3
3
|
import type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation';
|
|
4
4
|
/** Payload for routing and opening the API client modal. */
|
|
5
5
|
export type RoutePayload = {
|
|
6
|
+
/** API path, or webhook name when `isWebhook` is true. */
|
|
6
7
|
path: string;
|
|
7
8
|
method: HttpMethod;
|
|
8
9
|
example?: string;
|
|
9
10
|
documentSlug?: string;
|
|
11
|
+
/** Resolve `path` from the OpenAPI webhooks map. */
|
|
12
|
+
isWebhook?: boolean;
|
|
10
13
|
};
|
|
11
14
|
/** Raw input values that may contain "default" placeholders. */
|
|
12
|
-
export type DefaultEntities =
|
|
15
|
+
export type DefaultEntities = {
|
|
16
|
+
path: string;
|
|
17
|
+
method: string;
|
|
18
|
+
example: string;
|
|
19
|
+
documentSlug: string;
|
|
20
|
+
isWebhook?: boolean;
|
|
21
|
+
};
|
|
13
22
|
/** Context for resolving route parameters from the workspace store. */
|
|
14
23
|
type ResolverContext = {
|
|
15
24
|
store: WorkspaceStore;
|
|
@@ -33,14 +42,14 @@ export declare const resolveDocumentSlug: (store: WorkspaceStore, slug: string |
|
|
|
33
42
|
* When "default" is specified, returns the first available path in the document.
|
|
34
43
|
* This is useful for initial navigation when no specific path is requested.
|
|
35
44
|
*/
|
|
36
|
-
export declare const resolvePath: (ctx: ResolverContext, path: string | undefined) => string | undefined;
|
|
45
|
+
export declare const resolvePath: (ctx: ResolverContext, path: string | undefined, isWebhook?: boolean) => string | undefined;
|
|
37
46
|
/**
|
|
38
47
|
* Resolves the HTTP method from a raw input value.
|
|
39
48
|
*
|
|
40
49
|
* When "default" is specified, returns the first valid HTTP method for the given path.
|
|
41
50
|
* This ensures we select a real method rather than metadata keys like "parameters" or "summary".
|
|
42
51
|
*/
|
|
43
|
-
export declare const resolveMethod: (ctx: ResolverContext, path: string | undefined, method: string | undefined) => HttpMethod | undefined;
|
|
52
|
+
export declare const resolveMethod: (ctx: ResolverContext, path: string | undefined, method: string | undefined, isWebhook?: boolean) => HttpMethod | undefined;
|
|
44
53
|
/**
|
|
45
54
|
* Resolves the example name from a raw input value.
|
|
46
55
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-route-parameters.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,4CAA4C,CAAA;AAGlG,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve-route-parameters.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,4CAA4C,CAAA;AAGlG,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,uEAAuE;AACvE,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,cAAc,CAAA;IACrB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAeD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,cAAc,EAAE,MAAM,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAe9F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,eAAe,EAAE,MAAM,MAAM,GAAG,SAAS,EAAE,mBAAiB,KAAG,MAAM,GAAG,SAYxG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,MAAM,MAAM,GAAG,SAAS,EACxB,QAAQ,MAAM,GAAG,SAAS,EAC1B,mBAAiB,KAChB,UAAU,GAAG,SAiBf,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,eAAe,EACpB,WAAW,cAAc,GAAG,SAAS,EACrC,YAAY,MAAM,GAAG,SAAS,KAC7B,MAmBF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,cAAc,EAAE,QAAQ,eAAe,KAAG,OAAO,CAAC,YAAY,CAsB3G,CAAA"}
|
|
@@ -37,10 +37,10 @@ var resolveDocumentSlug = (store, slug) => {
|
|
|
37
37
|
* When "default" is specified, returns the first available path in the document.
|
|
38
38
|
* This is useful for initial navigation when no specific path is requested.
|
|
39
39
|
*/
|
|
40
|
-
var resolvePath = (ctx, path) => {
|
|
40
|
+
var resolvePath = (ctx, path, isWebhook = false) => {
|
|
41
41
|
const document = getDocument(ctx);
|
|
42
42
|
if (!document) return;
|
|
43
|
-
if (path === "default") return Object.keys(document.paths ?? {})[0];
|
|
43
|
+
if (path === "default") return Object.keys(isWebhook ? document.webhooks ?? {} : document.paths ?? {})[0];
|
|
44
44
|
return path;
|
|
45
45
|
};
|
|
46
46
|
/**
|
|
@@ -49,11 +49,11 @@ var resolvePath = (ctx, path) => {
|
|
|
49
49
|
* When "default" is specified, returns the first valid HTTP method for the given path.
|
|
50
50
|
* This ensures we select a real method rather than metadata keys like "parameters" or "summary".
|
|
51
51
|
*/
|
|
52
|
-
var resolveMethod = (ctx, path, method) => {
|
|
52
|
+
var resolveMethod = (ctx, path, method, isWebhook = false) => {
|
|
53
53
|
const document = getDocument(ctx);
|
|
54
54
|
if (!document || !path) return;
|
|
55
55
|
if (method === "default") {
|
|
56
|
-
const pathItem = getResolvedPathItem(document.paths?.[path]);
|
|
56
|
+
const pathItem = getResolvedPathItem(isWebhook ? document.webhooks?.[path] : document.paths?.[path]);
|
|
57
57
|
if (!pathItem) return;
|
|
58
58
|
return Object.keys(pathItem).filter(isHttpMethod)[0];
|
|
59
59
|
}
|
|
@@ -85,21 +85,25 @@ var resolveRouteParameters = (store, params) => {
|
|
|
85
85
|
store,
|
|
86
86
|
documentSlug
|
|
87
87
|
};
|
|
88
|
-
const
|
|
89
|
-
const
|
|
88
|
+
const isWebhook = params.isWebhook ?? false;
|
|
89
|
+
const path = resolvePath(ctx, params.path, isWebhook);
|
|
90
|
+
const method = resolveMethod(ctx, path, params.method, isWebhook);
|
|
91
|
+
const routeType = isWebhook ? { isWebhook: true } : {};
|
|
90
92
|
const traversedDocument = getDocument(ctx)?.["x-scalar-navigation"];
|
|
91
93
|
if (!traversedDocument) return {
|
|
92
94
|
documentSlug,
|
|
93
95
|
path,
|
|
94
96
|
method,
|
|
95
|
-
example: "default"
|
|
97
|
+
example: "default",
|
|
98
|
+
...routeType
|
|
96
99
|
};
|
|
97
|
-
const operation = getOperationEntries(traversedDocument).get(`${path}|${method}`)?.find((entry) => entry.type === "operation");
|
|
100
|
+
const operation = getOperationEntries(traversedDocument).get(`${path}|${method}`)?.find((entry) => entry.type === (isWebhook ? "webhook" : "operation"));
|
|
98
101
|
return {
|
|
99
102
|
documentSlug,
|
|
100
103
|
path,
|
|
101
104
|
method,
|
|
102
|
-
example: resolveExampleName(ctx, operation, params.example)
|
|
105
|
+
example: resolveExampleName(ctx, operation, params.example),
|
|
106
|
+
...routeType
|
|
103
107
|
};
|
|
104
108
|
};
|
|
105
109
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-route-parameters.js","names":[],"sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"sourcesContent":["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { getResolvedPathItem } from '@scalar/workspace-store/helpers/for-each-path-item-operation'\nimport { getOperationEntries } from '@scalar/workspace-store/navigation'\nimport type { TraversedEntry, TraversedExample } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\n\n/** Payload for routing and opening the API client modal. */\nexport type RoutePayload = {\n path: string\n method: HttpMethod\n example?: string\n documentSlug?: string\n}\n\n/** Raw input values that may contain \"default\" placeholders. */\nexport type DefaultEntities =
|
|
1
|
+
{"version":3,"file":"resolve-route-parameters.js","names":[],"sources":["../../../../../src/v2/features/modal/helpers/resolve-route-parameters.ts"],"sourcesContent":["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { isHttpMethod } from '@scalar/helpers/http/is-http-method'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { getResolvedPathItem } from '@scalar/workspace-store/helpers/for-each-path-item-operation'\nimport { getOperationEntries } from '@scalar/workspace-store/navigation'\nimport type { TraversedEntry, TraversedExample } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\n\n/** Payload for routing and opening the API client modal. */\nexport type RoutePayload = {\n /** API path, or webhook name when `isWebhook` is true. */\n path: string\n method: HttpMethod\n example?: string\n documentSlug?: string\n /** Resolve `path` from the OpenAPI webhooks map. */\n isWebhook?: boolean\n}\n\n/** Raw input values that may contain \"default\" placeholders. */\nexport type DefaultEntities = {\n path: string\n method: string\n example: string\n documentSlug: string\n isWebhook?: boolean\n}\n\n/** Context for resolving route parameters from the workspace store. */\ntype ResolverContext = {\n store: WorkspaceStore\n documentSlug: string | undefined\n}\n\n/** Type guard to check if an entry is an example. */\nconst isExample = (entry: TraversedEntry): entry is TraversedExample => entry.type === 'example'\n\n/**\n * Gets the document from the workspace store.\n * Returns undefined if the document slug is not provided or the document does not exist.\n * Modal routing is OpenAPI-only — AsyncAPI docs surface as undefined here.\n */\nconst getDocument = (ctx: ResolverContext) => {\n const doc = ctx.store.workspace.documents[ctx.documentSlug ?? '']\n return isOpenApiDocument(doc) ? doc : undefined\n}\n\n/**\n * Resolves the document slug from a raw input value.\n *\n * When \"default\" is specified and no document exists with that slug,\n * we fall back to the active document or the first available document.\n * Modal routing is OpenAPI-only, so the fallback skips AsyncAPI documents —\n * otherwise opening the modal with default params on a workspace that has\n * an AsyncAPI active or first document would hand a slug back that\n * `getDocument` then resolves to undefined, rendering the modal with\n * `document: null` even when OpenAPI documents exist.\n */\nexport const resolveDocumentSlug = (store: WorkspaceStore, slug: string | undefined): string | undefined => {\n const hasMatchingDocument = slug !== 'default' || store.workspace.documents[slug] !== undefined\n\n if (hasMatchingDocument) {\n return slug\n }\n\n // Prefer the active document when it is OpenAPI; otherwise pick the first\n // OpenAPI document in the workspace.\n const activeSlug = store.workspace['x-scalar-active-document']\n if (activeSlug && isOpenApiDocument(store.workspace.documents[activeSlug])) {\n return activeSlug\n }\n\n return Object.entries(store.workspace.documents).find(([, document]) => isOpenApiDocument(document))?.[0]\n}\n\n/**\n * Resolves the path from a raw input value.\n *\n * When \"default\" is specified, returns the first available path in the document.\n * This is useful for initial navigation when no specific path is requested.\n */\nexport const resolvePath = (ctx: ResolverContext, path: string | undefined, isWebhook = false): string | undefined => {\n const document = getDocument(ctx)\n\n if (!document) {\n return undefined\n }\n\n if (path === 'default') {\n return Object.keys(isWebhook ? (document.webhooks ?? {}) : (document.paths ?? {}))[0]\n }\n\n return path\n}\n\n/**\n * Resolves the HTTP method from a raw input value.\n *\n * When \"default\" is specified, returns the first valid HTTP method for the given path.\n * This ensures we select a real method rather than metadata keys like \"parameters\" or \"summary\".\n */\nexport const resolveMethod = (\n ctx: ResolverContext,\n path: string | undefined,\n method: string | undefined,\n isWebhook = false,\n): HttpMethod | undefined => {\n const document = getDocument(ctx)\n\n if (!document || !path) {\n return undefined\n }\n\n if (method === 'default') {\n const pathItem = getResolvedPathItem(isWebhook ? document.webhooks?.[path] : document.paths?.[path])\n if (!pathItem) {\n return undefined\n }\n const pathMethods = Object.keys(pathItem).filter(isHttpMethod)\n return pathMethods[0]\n }\n\n return isHttpMethod(method) ? method : undefined\n}\n\n/**\n * Resolves the example name from a raw input value.\n *\n * When \"default\" is specified, returns the first available example name.\n * Falls back to \"default\" when no examples exist, which signals to use the default request body.\n */\nexport const resolveExampleName = (\n ctx: ResolverContext,\n operation: TraversedEntry | undefined,\n exampleKey: string | undefined,\n): string => {\n const document = getDocument(ctx)\n\n if (!document || operation?.type !== 'operation') {\n return 'default'\n }\n\n const examples = operation.children?.filter(isExample) ?? []\n const matchingExample = examples.find((child) => child.name === exampleKey)\n\n if (matchingExample) {\n return matchingExample.name\n }\n\n if (exampleKey === 'default') {\n return examples[0]?.name ?? 'default'\n }\n\n return 'default'\n}\n\n/**\n * Resolves all route parameters from raw input values to their actual values.\n *\n * This function handles \"default\" placeholders by looking up actual values from the workspace store.\n * It ensures the modal can be opened even when the caller does not know specific paths, methods, or examples.\n */\nexport const resolveRouteParameters = (store: WorkspaceStore, params: DefaultEntities): Partial<RoutePayload> => {\n const documentSlug = resolveDocumentSlug(store, params.documentSlug)\n const ctx: ResolverContext = { store, documentSlug }\n const isWebhook = params.isWebhook ?? false\n\n const path = resolvePath(ctx, params.path, isWebhook)\n const method = resolveMethod(ctx, path, params.method, isWebhook)\n const routeType = isWebhook ? { isWebhook: true as const } : {}\n\n const traversedDocument = getDocument(ctx)?.['x-scalar-navigation']\n\n if (!traversedDocument) {\n return { documentSlug, path, method, example: 'default', ...routeType }\n }\n\n const operations = getOperationEntries(traversedDocument)\n const operation = operations\n .get(`${path}|${method}`)\n ?.find((entry) => entry.type === (isWebhook ? 'webhook' : 'operation'))\n const example = resolveExampleName(ctx, operation, params.example)\n\n return { documentSlug, path, method, example, ...routeType }\n}\n"],"mappings":";;;;;;AAmCA,IAAM,aAAa,UAAqD,MAAM,SAAS;;;;;;AAOvF,IAAM,eAAe,QAAyB;CAC5C,MAAM,MAAM,IAAI,MAAM,UAAU,UAAU,IAAI,gBAAgB;CAC9D,OAAO,kBAAkB,GAAG,IAAI,MAAM,KAAA;AACxC;;;;;;;;;;;;AAaA,IAAa,uBAAuB,OAAuB,SAAiD;CAG1G,IAF4B,SAAS,aAAa,MAAM,UAAU,UAAU,UAAU,KAAA,GAGpF,OAAO;CAKT,MAAM,aAAa,MAAM,UAAU;CACnC,IAAI,cAAc,kBAAkB,MAAM,UAAU,UAAU,WAAW,GACvE,OAAO;CAGT,OAAO,OAAO,QAAQ,MAAM,UAAU,SAAS,CAAC,CAAC,MAAM,GAAG,cAAc,kBAAkB,QAAQ,CAAC,CAAC,GAAG;AACzG;;;;;;;AAQA,IAAa,eAAe,KAAsB,MAA0B,YAAY,UAA8B;CACpH,MAAM,WAAW,YAAY,GAAG;CAEhC,IAAI,CAAC,UACH;CAGF,IAAI,SAAS,WACX,OAAO,OAAO,KAAK,YAAa,SAAS,YAAY,CAAC,IAAM,SAAS,SAAS,CAAC,CAAE,CAAC,CAAC;CAGrF,OAAO;AACT;;;;;;;AAQA,IAAa,iBACX,KACA,MACA,QACA,YAAY,UACe;CAC3B,MAAM,WAAW,YAAY,GAAG;CAEhC,IAAI,CAAC,YAAY,CAAC,MAChB;CAGF,IAAI,WAAW,WAAW;EACxB,MAAM,WAAW,oBAAoB,YAAY,SAAS,WAAW,QAAQ,SAAS,QAAQ,KAAK;EACnG,IAAI,CAAC,UACH;EAGF,OADoB,OAAO,KAAK,QAAQ,CAAC,CAAC,OAAO,YAC1C,CAAA,CAAY;CACrB;CAEA,OAAO,aAAa,MAAM,IAAI,SAAS,KAAA;AACzC;;;;;;;AAQA,IAAa,sBACX,KACA,WACA,eACW;CAGX,IAAI,CAFa,YAAY,GAExB,KAAY,WAAW,SAAS,aACnC,OAAO;CAGT,MAAM,WAAW,UAAU,UAAU,OAAO,SAAS,KAAK,CAAC;CAC3D,MAAM,kBAAkB,SAAS,MAAM,UAAU,MAAM,SAAS,UAAU;CAE1E,IAAI,iBACF,OAAO,gBAAgB;CAGzB,IAAI,eAAe,WACjB,OAAO,SAAS,EAAE,EAAE,QAAQ;CAG9B,OAAO;AACT;;;;;;;AAQA,IAAa,0BAA0B,OAAuB,WAAmD;CAC/G,MAAM,eAAe,oBAAoB,OAAO,OAAO,YAAY;CACnE,MAAM,MAAuB;EAAE;EAAO;CAAa;CACnD,MAAM,YAAY,OAAO,aAAa;CAEtC,MAAM,OAAO,YAAY,KAAK,OAAO,MAAM,SAAS;CACpD,MAAM,SAAS,cAAc,KAAK,MAAM,OAAO,QAAQ,SAAS;CAChE,MAAM,YAAY,YAAY,EAAE,WAAW,KAAc,IAAI,CAAC;CAE9D,MAAM,oBAAoB,YAAY,GAAG,CAAC,GAAG;CAE7C,IAAI,CAAC,mBACH,OAAO;EAAE;EAAc;EAAM;EAAQ,SAAS;EAAW,GAAG;CAAU;CAIxE,MAAM,YADa,oBAAoB,iBACrB,CAAA,CACf,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC,EACvB,MAAM,UAAU,MAAM,UAAU,YAAY,YAAY,YAAY;CAGxE,OAAO;EAAE;EAAc;EAAM;EAAQ,SAFrB,mBAAmB,KAAK,WAAW,OAAO,OAErB;EAAS,GAAG;CAAU;AAC7D"}
|
|
@@ -12,6 +12,7 @@ export type UseModalSidebarReturn = {
|
|
|
12
12
|
path?: string;
|
|
13
13
|
method?: HttpMethod;
|
|
14
14
|
example?: string;
|
|
15
|
+
isWebhook?: boolean;
|
|
15
16
|
}) => TraversedEntry | undefined;
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
@@ -31,12 +32,13 @@ export type UseModalSidebarReturn = {
|
|
|
31
32
|
* exampleName,
|
|
32
33
|
* })
|
|
33
34
|
*/
|
|
34
|
-
export declare const useModalSidebar: ({ workspaceStore, documentSlug, path, method, exampleName, route, }: {
|
|
35
|
+
export declare const useModalSidebar: ({ workspaceStore, documentSlug, path, method, exampleName, isWebhook, route, }: {
|
|
35
36
|
workspaceStore: WorkspaceStore | null;
|
|
36
37
|
documentSlug: ComputedRef<string | undefined>;
|
|
37
38
|
path: ComputedRef<string | undefined>;
|
|
38
39
|
method: ComputedRef<HttpMethod | undefined>;
|
|
39
40
|
exampleName: ComputedRef<string | undefined>;
|
|
41
|
+
isWebhook?: ComputedRef<boolean>;
|
|
40
42
|
route: (payload: RoutePayload) => void;
|
|
41
43
|
}) => UseModalSidebarReturn;
|
|
42
44
|
//# sourceMappingURL=use-modal-sidebar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-modal-sidebar.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/hooks/use-modal-sidebar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,kBAAkB,EAAuC,MAAM,iBAAiB,CAAA;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAA;AAEhF,OAAO,EAAE,KAAK,WAAW,EAA4B,MAAM,KAAK,CAAA;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sDAAsD,CAAA;AAGxF,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAA;IAC5D,kBAAkB,EAAE,CAAC,QAAQ,EAAE;QAC7B,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,MAAM,CAAC,EAAE,UAAU,CAAA;QACnB,OAAO,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"use-modal-sidebar.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/modal/hooks/use-modal-sidebar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,kBAAkB,EAAuC,MAAM,iBAAiB,CAAA;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAA;AAEhF,OAAO,EAAE,KAAK,WAAW,EAA4B,MAAM,KAAK,CAAA;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sDAAsD,CAAA;AAGxF,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAA;IAC5D,kBAAkB,EAAE,CAAC,QAAQ,EAAE;QAC7B,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,MAAM,CAAC,EAAE,UAAU,CAAA;QACnB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,CAAA;KACpB,KAAK,cAAc,GAAG,SAAS,CAAA;CACjC,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,GAAI,gFAQ7B;IACD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC7C,IAAI,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACrC,MAAM,EAAE,WAAW,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;IAC3C,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5C,SAAS,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAA;CACvC,KAAG,qBAiLH,CAAA"}
|
|
@@ -21,7 +21,8 @@ import { getParentEntry } from "@scalar/workspace-store/navigation";
|
|
|
21
21
|
* exampleName,
|
|
22
22
|
* })
|
|
23
23
|
*/
|
|
24
|
-
var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName, route }) => {
|
|
24
|
+
var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName, isWebhook, route }) => {
|
|
25
|
+
const activeIsWebhook = isWebhook ?? computed(() => false);
|
|
25
26
|
const entries = computed(() => {
|
|
26
27
|
const doc = workspaceStore?.workspace.documents[toValue(documentSlug) ?? ""];
|
|
27
28
|
return isOpenApiDocument(doc) ? doc["x-scalar-navigation"]?.children ?? [] : [];
|
|
@@ -37,8 +38,14 @@ var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName
|
|
|
37
38
|
const locationIndex = computed(() => generateReverseIndex({
|
|
38
39
|
items: entries.value,
|
|
39
40
|
nestedKey: "children",
|
|
40
|
-
filter: (node) => node.type === "operation" || node.type === "example",
|
|
41
|
+
filter: (node) => node.type === "operation" || node.type === "example" || node.type === "webhook",
|
|
41
42
|
getId: (node) => {
|
|
43
|
+
if (node.type === "webhook") return generateLocationId({
|
|
44
|
+
document: toValue(documentSlug) ?? "",
|
|
45
|
+
path: node.name,
|
|
46
|
+
method: node.method,
|
|
47
|
+
isWebhook: true
|
|
48
|
+
});
|
|
42
49
|
const operation = getParentEntry("operation", node);
|
|
43
50
|
return generateLocationId({
|
|
44
51
|
document: toValue(documentSlug) ?? "",
|
|
@@ -70,13 +77,15 @@ var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName
|
|
|
70
77
|
document: location.document,
|
|
71
78
|
path: location.path,
|
|
72
79
|
method: location.method,
|
|
73
|
-
example: location.example
|
|
80
|
+
example: location.example,
|
|
81
|
+
isWebhook: location.isWebhook
|
|
74
82
|
}));
|
|
75
83
|
if (entryWithExample) return entryWithExample;
|
|
76
84
|
return locationIndex.value.get(generateLocationId({
|
|
77
85
|
document: location.document,
|
|
78
86
|
path: location.path,
|
|
79
|
-
method: location.method
|
|
87
|
+
method: location.method,
|
|
88
|
+
isWebhook: location.isWebhook
|
|
80
89
|
}));
|
|
81
90
|
};
|
|
82
91
|
/**
|
|
@@ -110,6 +119,16 @@ var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName
|
|
|
110
119
|
example: example?.name ?? "default"
|
|
111
120
|
});
|
|
112
121
|
}
|
|
122
|
+
if (entry.type === "webhook") {
|
|
123
|
+
state.setSelected(id);
|
|
124
|
+
return route({
|
|
125
|
+
documentSlug: toValue(documentSlug),
|
|
126
|
+
path: entry.name,
|
|
127
|
+
method: entry.method,
|
|
128
|
+
example: "default",
|
|
129
|
+
isWebhook: true
|
|
130
|
+
});
|
|
131
|
+
}
|
|
113
132
|
state.setExpanded(id, !state.isExpanded(id));
|
|
114
133
|
};
|
|
115
134
|
/** Keep the sidebar state in sync with the modal parameters */
|
|
@@ -117,8 +136,9 @@ var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName
|
|
|
117
136
|
documentSlug,
|
|
118
137
|
path,
|
|
119
138
|
method,
|
|
120
|
-
exampleName
|
|
121
|
-
|
|
139
|
+
exampleName,
|
|
140
|
+
activeIsWebhook
|
|
141
|
+
], ([newDocument, newPath, newMethod, newExample, newIsWebhook]) => {
|
|
122
142
|
if (!newDocument) {
|
|
123
143
|
state.setSelected(null);
|
|
124
144
|
return;
|
|
@@ -127,7 +147,8 @@ var useModalSidebar = ({ workspaceStore, documentSlug, path, method, exampleName
|
|
|
127
147
|
document: newDocument,
|
|
128
148
|
path: newPath,
|
|
129
149
|
method: newMethod,
|
|
130
|
-
example: newExample
|
|
150
|
+
example: newExample,
|
|
151
|
+
isWebhook: newIsWebhook
|
|
131
152
|
});
|
|
132
153
|
if (entry) {
|
|
133
154
|
state.setSelected(entry.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-modal-sidebar.js","names":[],"sources":["../../../../../src/v2/features/modal/hooks/use-modal-sidebar.ts"],"sourcesContent":["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { createSidebarState, generateReverseIndex, getChildEntry } from '@scalar/sidebar'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { getParentEntry } from '@scalar/workspace-store/navigation'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type ComputedRef, computed, toValue, watch } from 'vue'\n\nimport type { RoutePayload } from '@/v2/features/modal/helpers/resolve-route-parameters'\nimport { generateLocationId } from '@/v2/helpers/generate-location-id'\n\nexport type UseModalSidebarReturn = {\n handleSelectItem: (id: string) => void\n state: ReturnType<typeof createSidebarState<TraversedEntry>>\n getEntryByLocation: (location: {\n document: string\n path?: string\n method?: HttpMethod\n example?: string\n }) => TraversedEntry | undefined\n}\n\n/**\n * useSidebarState - Custom hook to manage the sidebar state and navigation logic in the Scalar API client\n *\n * This composable manages the sidebar structure, synchronizes selection state\n * with the current route, and provides a handler for selecting sidebar items.\n *\n * Example usage:\n *\n * const { handleSelectItem, sidebarState } = useSidebarState({\n * workspaceStore,\n * workspaceSlug,\n * documentSlug,\n * path,\n * method,\n * exampleName,\n * })\n */\nexport const useModalSidebar = ({\n workspaceStore,\n documentSlug,\n path,\n method,\n exampleName,\n route,\n}: {\n workspaceStore: WorkspaceStore | null\n documentSlug: ComputedRef<string | undefined>\n path: ComputedRef<string | undefined>\n method: ComputedRef<HttpMethod | undefined>\n exampleName: ComputedRef<string | undefined>\n route: (payload: RoutePayload) => void\n}): UseModalSidebarReturn => {\n const entries = computed<TraversedEntry[]>(() => {\n const doc = workspaceStore?.workspace.documents[toValue(documentSlug) ?? '']\n return isOpenApiDocument(doc) ? (doc['x-scalar-navigation']?.children ?? []) : []\n })\n const state = createSidebarState(entries)\n\n /**\n * Computed index for fast lookup of sidebar nodes by their unique API location.\n *\n * - Only indexes nodes of type 'operation', or 'example'.\n * - The lookup key is a serialized array of: [operationPath, operationMethod, exampleName?].\n * - Supports precise resolution of sidebar entries given an API \"location\".\n */\n const locationIndex = computed(() =>\n generateReverseIndex({\n items: entries.value,\n nestedKey: 'children',\n filter: (node) => node.type === 'operation' || node.type === 'example',\n getId: (node) => {\n const operation = getParentEntry('operation', node)\n return generateLocationId({\n document: toValue(documentSlug) ?? '',\n path: operation?.path,\n method: operation?.method,\n example: node.type === 'example' ? node.name : undefined,\n })\n },\n }),\n )\n\n /**\n * Looks up a sidebar entry by its unique API location.\n * - First tries to find an entry matching all provided properties (including example).\n * - If not found, falls back to matching only the operation (ignores example field).\n * This allows resolving either examples, operations, or documents as appropriate.\n *\n * @param location - Object specifying the document name, path, method, and optional example name.\n * @returns The matching sidebar entry, or undefined if none found.\n *\n * Example:\n * const entry = getEntryByLocation({\n * document: 'pets',\n * path: '/pets',\n * method: 'get',\n * example: 'default',\n * })\n */\n const getEntryByLocation: UseModalSidebarReturn['getEntryByLocation'] = (location) => {\n // Try to find an entry with the most-specific location (including example)\n const entryWithExample = locationIndex.value.get(\n generateLocationId({\n document: location.document,\n path: location.path,\n method: location.method,\n example: location.example,\n }),\n )\n\n if (entryWithExample) {\n return entryWithExample\n }\n\n // Fallback to the operation (ignoring example) if an example wasn't found or specified\n return locationIndex.value.get(\n generateLocationId({\n document: location.document,\n path: location.path,\n method: location.method,\n }),\n )\n }\n\n /**\n * Handles item selection from the sidebar and routes navigation accordingly.\n *\n * Example:\n * handleSelectItem('id-of-entry')\n */\n const handleSelectItem = (id: string) => {\n const entry = state.getEntryById(id)\n\n if (!entry) {\n console.warn(`Could not find sidebar entry with id ${id} to select`)\n return\n }\n\n // Navigate to the example page\n if (entry.type === 'operation' || entry.type === 'example') {\n // If we are already in the operation, just toggle expansion\n if (state.isSelected(id)) {\n state.setExpanded(id, !state.isExpanded(id))\n return\n }\n\n const operation = getParentEntry('operation', entry)\n const example = getChildEntry('example', entry)\n\n if (example) {\n state.setSelected(example.id)\n state.setExpanded(example.id, true)\n } else {\n state.setSelected(id)\n }\n\n if (!operation) {\n return\n }\n\n return route({\n documentSlug: toValue(documentSlug),\n path: operation.path,\n method: operation.method,\n example: example?.name ?? 'default',\n })\n }\n\n state.setExpanded(id, !state.isExpanded(id))\n return\n }\n\n /** Keep the sidebar state in sync with the modal parameters */\n watch(\n [documentSlug, path, method, exampleName],\n ([newDocument, newPath, newMethod, newExample]) => {\n if (!newDocument) {\n // Reset selection if no document is selected\n state.setSelected(null)\n return\n }\n\n const entry = getEntryByLocation({\n document: newDocument,\n path: newPath,\n method: newMethod,\n example: newExample,\n })\n\n if (entry) {\n state.setSelected(entry.id)\n state.setExpanded(entry.id, true)\n }\n },\n {\n immediate: true,\n },\n )\n\n return {\n handleSelectItem,\n state,\n getEntryByLocation,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"use-modal-sidebar.js","names":[],"sources":["../../../../../src/v2/features/modal/hooks/use-modal-sidebar.ts"],"sourcesContent":["import type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { createSidebarState, generateReverseIndex, getChildEntry } from '@scalar/sidebar'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { getParentEntry } from '@scalar/workspace-store/navigation'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type ComputedRef, computed, toValue, watch } from 'vue'\n\nimport type { RoutePayload } from '@/v2/features/modal/helpers/resolve-route-parameters'\nimport { generateLocationId } from '@/v2/helpers/generate-location-id'\n\nexport type UseModalSidebarReturn = {\n handleSelectItem: (id: string) => void\n state: ReturnType<typeof createSidebarState<TraversedEntry>>\n getEntryByLocation: (location: {\n document: string\n path?: string\n method?: HttpMethod\n example?: string\n isWebhook?: boolean\n }) => TraversedEntry | undefined\n}\n\n/**\n * useSidebarState - Custom hook to manage the sidebar state and navigation logic in the Scalar API client\n *\n * This composable manages the sidebar structure, synchronizes selection state\n * with the current route, and provides a handler for selecting sidebar items.\n *\n * Example usage:\n *\n * const { handleSelectItem, sidebarState } = useSidebarState({\n * workspaceStore,\n * workspaceSlug,\n * documentSlug,\n * path,\n * method,\n * exampleName,\n * })\n */\nexport const useModalSidebar = ({\n workspaceStore,\n documentSlug,\n path,\n method,\n exampleName,\n isWebhook,\n route,\n}: {\n workspaceStore: WorkspaceStore | null\n documentSlug: ComputedRef<string | undefined>\n path: ComputedRef<string | undefined>\n method: ComputedRef<HttpMethod | undefined>\n exampleName: ComputedRef<string | undefined>\n isWebhook?: ComputedRef<boolean>\n route: (payload: RoutePayload) => void\n}): UseModalSidebarReturn => {\n const activeIsWebhook = isWebhook ?? computed(() => false)\n const entries = computed<TraversedEntry[]>(() => {\n const doc = workspaceStore?.workspace.documents[toValue(documentSlug) ?? '']\n return isOpenApiDocument(doc) ? (doc['x-scalar-navigation']?.children ?? []) : []\n })\n const state = createSidebarState(entries)\n\n /**\n * Computed index for fast lookup of sidebar nodes by their unique API location.\n *\n * - Only indexes nodes of type 'operation', or 'example'.\n * - The lookup key is a serialized array of: [operationPath, operationMethod, exampleName?].\n * - Supports precise resolution of sidebar entries given an API \"location\".\n */\n const locationIndex = computed(() =>\n generateReverseIndex({\n items: entries.value,\n nestedKey: 'children',\n filter: (node) => node.type === 'operation' || node.type === 'example' || node.type === 'webhook',\n getId: (node) => {\n if (node.type === 'webhook') {\n return generateLocationId({\n document: toValue(documentSlug) ?? '',\n path: node.name,\n method: node.method,\n isWebhook: true,\n })\n }\n\n const operation = getParentEntry('operation', node)\n return generateLocationId({\n document: toValue(documentSlug) ?? '',\n path: operation?.path,\n method: operation?.method,\n example: node.type === 'example' ? node.name : undefined,\n })\n },\n }),\n )\n\n /**\n * Looks up a sidebar entry by its unique API location.\n * - First tries to find an entry matching all provided properties (including example).\n * - If not found, falls back to matching only the operation (ignores example field).\n * This allows resolving either examples, operations, or documents as appropriate.\n *\n * @param location - Object specifying the document name, path, method, and optional example name.\n * @returns The matching sidebar entry, or undefined if none found.\n *\n * Example:\n * const entry = getEntryByLocation({\n * document: 'pets',\n * path: '/pets',\n * method: 'get',\n * example: 'default',\n * })\n */\n const getEntryByLocation: UseModalSidebarReturn['getEntryByLocation'] = (location) => {\n // Try to find an entry with the most-specific location (including example)\n const entryWithExample = locationIndex.value.get(\n generateLocationId({\n document: location.document,\n path: location.path,\n method: location.method,\n example: location.example,\n isWebhook: location.isWebhook,\n }),\n )\n\n if (entryWithExample) {\n return entryWithExample\n }\n\n // Fallback to the operation (ignoring example) if an example wasn't found or specified\n return locationIndex.value.get(\n generateLocationId({\n document: location.document,\n path: location.path,\n method: location.method,\n isWebhook: location.isWebhook,\n }),\n )\n }\n\n /**\n * Handles item selection from the sidebar and routes navigation accordingly.\n *\n * Example:\n * handleSelectItem('id-of-entry')\n */\n const handleSelectItem = (id: string) => {\n const entry = state.getEntryById(id)\n\n if (!entry) {\n console.warn(`Could not find sidebar entry with id ${id} to select`)\n return\n }\n\n // Navigate to the example page\n if (entry.type === 'operation' || entry.type === 'example') {\n // If we are already in the operation, just toggle expansion\n if (state.isSelected(id)) {\n state.setExpanded(id, !state.isExpanded(id))\n return\n }\n\n const operation = getParentEntry('operation', entry)\n const example = getChildEntry('example', entry)\n\n if (example) {\n state.setSelected(example.id)\n state.setExpanded(example.id, true)\n } else {\n state.setSelected(id)\n }\n\n if (!operation) {\n return\n }\n\n return route({\n documentSlug: toValue(documentSlug),\n path: operation.path,\n method: operation.method,\n example: example?.name ?? 'default',\n })\n }\n\n if (entry.type === 'webhook') {\n state.setSelected(id)\n return route({\n documentSlug: toValue(documentSlug),\n path: entry.name,\n method: entry.method,\n example: 'default',\n isWebhook: true,\n })\n }\n\n state.setExpanded(id, !state.isExpanded(id))\n return\n }\n\n /** Keep the sidebar state in sync with the modal parameters */\n watch(\n [documentSlug, path, method, exampleName, activeIsWebhook],\n ([newDocument, newPath, newMethod, newExample, newIsWebhook]) => {\n if (!newDocument) {\n // Reset selection if no document is selected\n state.setSelected(null)\n return\n }\n\n const entry = getEntryByLocation({\n document: newDocument,\n path: newPath,\n method: newMethod,\n example: newExample,\n isWebhook: newIsWebhook,\n })\n\n if (entry) {\n state.setSelected(entry.id)\n state.setExpanded(entry.id, true)\n }\n },\n {\n immediate: true,\n },\n )\n\n return {\n handleSelectItem,\n state,\n getEntryByLocation,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal-events.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/modal/modal-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAGvE,OAAO,EAAE,KAAK,GAAG,EAAO,MAAM,KAAK,CAAA;AAEnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;AAOxF,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,aAAa,EACb,+BAA+B,EAC/B,YAAY,EACZ,UAAU,EACV,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC3B,+BAA+B,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,YAAY,EAAE,qBAAqB,CAAA;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,cAAc,CAAA;CACtB,
|
|
1
|
+
{"version":3,"file":"modal-events.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/modal/modal-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAGvE,OAAO,EAAE,KAAK,GAAG,EAAO,MAAM,KAAK,CAAA;AAEnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;AAOxF,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,aAAa,EACb,+BAA+B,EAC/B,YAAY,EACZ,UAAU,EACV,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC3B,+BAA+B,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,YAAY,EAAE,qBAAqB,CAAA;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,cAAc,CAAA;CACtB,QAkFA"}
|
|
@@ -20,6 +20,7 @@ function initializeModalEvents({ eventBus, isSidebarOpen, requestBodyComposition
|
|
|
20
20
|
modalState.show();
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
+
const previousSelectedId = sidebarState.state.selectedItem.value;
|
|
23
24
|
if ("id" in payload && payload.id) {
|
|
24
25
|
let targetId = payload.id;
|
|
25
26
|
if ("exampleName" in payload && payload.exampleName) {
|
|
@@ -39,7 +40,7 @@ function initializeModalEvents({ eventBus, isSidebarOpen, requestBodyComposition
|
|
|
39
40
|
example: payload.exampleName
|
|
40
41
|
})?.id ?? "");
|
|
41
42
|
}
|
|
42
|
-
requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection;
|
|
43
|
+
if (!(modalState.open && sidebarState.state.selectedItem.value === previousSelectedId)) requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection;
|
|
43
44
|
modalState.show();
|
|
44
45
|
});
|
|
45
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal-events.js","names":[],"sources":["../../../../src/v2/features/modal/modal-events.ts"],"sourcesContent":["import type { ModalState } from '@scalar/components/modal'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type Ref, ref } from 'vue'\n\nimport type { UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeWorkspaceEventHandlers } from '@/v2/workspace-events'\n\n// Frozen so this shared fallback cannot be mutated in place, which would leak a stale selection into\n// every future open that falls back to empty. Callers only ever reassign the ref, never mutate it.\nconst EMPTY_REQUEST_BODY_COMPOSITION_SELECTION = Object.freeze({}) as Record<string, number>\n\nexport function initializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store,\n}: {\n eventBus: WorkspaceEventBus\n isSidebarOpen: Ref<boolean>\n requestBodyCompositionSelection: Ref<Record<string, number>>\n sidebarState: UseModalSidebarReturn\n modalState: ModalState\n store: WorkspaceStore\n}) {\n /** Initialize workspace event handlers */\n initializeWorkspaceEventHandlers({\n eventBus,\n store: ref(store),\n hooks: {},\n })\n\n //------------------------------------------------------------------------------------\n // Navigation Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('scroll-to:nav-item', ({ id }) => sidebarState.handleSelectItem(id))\n\n //------------------------------------------------------------------------------------\n // UI Related Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('ui:toggle:sidebar', () => (isSidebarOpen.value = !isSidebarOpen.value))\n eventBus.on('ui:close:client-modal', () => modalState.hide())\n eventBus.on('ui:open:client-modal', (payload) => {\n // Every open re-establishes the selection (falling back to empty), so the modal no longer needs\n // to reset it on close
|
|
1
|
+
{"version":3,"file":"modal-events.js","names":[],"sources":["../../../../src/v2/features/modal/modal-events.ts"],"sourcesContent":["import type { ModalState } from '@scalar/components/modal'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport { isOpenApiDocument } from '@scalar/workspace-store/schemas/type-guards'\nimport { type Ref, ref } from 'vue'\n\nimport type { UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeWorkspaceEventHandlers } from '@/v2/workspace-events'\n\n// Frozen so this shared fallback cannot be mutated in place, which would leak a stale selection into\n// every future open that falls back to empty. Callers only ever reassign the ref, never mutate it.\nconst EMPTY_REQUEST_BODY_COMPOSITION_SELECTION = Object.freeze({}) as Record<string, number>\n\nexport function initializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store,\n}: {\n eventBus: WorkspaceEventBus\n isSidebarOpen: Ref<boolean>\n requestBodyCompositionSelection: Ref<Record<string, number>>\n sidebarState: UseModalSidebarReturn\n modalState: ModalState\n store: WorkspaceStore\n}) {\n /** Initialize workspace event handlers */\n initializeWorkspaceEventHandlers({\n eventBus,\n store: ref(store),\n hooks: {},\n })\n\n //------------------------------------------------------------------------------------\n // Navigation Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('scroll-to:nav-item', ({ id }) => sidebarState.handleSelectItem(id))\n\n //------------------------------------------------------------------------------------\n // UI Related Event Handlers\n //------------------------------------------------------------------------------------\n eventBus.on('ui:toggle:sidebar', () => (isSidebarOpen.value = !isSidebarOpen.value))\n eventBus.on('ui:close:client-modal', () => modalState.hide())\n eventBus.on('ui:open:client-modal', (payload) => {\n // Every open re-establishes the selection (falling back to empty), so the modal no longer needs\n // to reset it on close.\n const nextRequestBodyCompositionSelection = (\n payload && 'requestBodyCompositionSelection' in payload && payload.requestBodyCompositionSelection\n ? payload.requestBodyCompositionSelection\n : EMPTY_REQUEST_BODY_COMPOSITION_SELECTION\n ) as Record<string, number>\n\n // Just open the modal\n if (!payload) {\n requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection\n modalState.show()\n return\n }\n\n const previousSelectedId = sidebarState.state.selectedItem.value\n\n // We route to the exact ID\n if ('id' in payload && payload.id) {\n let targetId = payload.id\n\n // If exampleName is provided, try to find the specific example entry\n if ('exampleName' in payload && payload.exampleName) {\n const operationEntry = sidebarState.state.getEntryById(payload.id)\n\n // Try to find the specific example in the operation's children\n if (operationEntry && 'children' in operationEntry && operationEntry.children) {\n const exampleEntry = operationEntry.children.find(\n (child: TraversedEntry) => child.type === 'example' && child.name === payload.exampleName,\n )\n if (exampleEntry) {\n targetId = exampleEntry.id\n }\n }\n }\n\n sidebarState.handleSelectItem(targetId)\n }\n // We must find the ID first from the entries\n else if ('method' in payload && 'path' in payload) {\n const activeDoc = store.workspace.activeDocument\n sidebarState.handleSelectItem(\n sidebarState.getEntryByLocation({\n document: isOpenApiDocument(activeDoc) ? (activeDoc['x-scalar-navigation']?.id ?? '') : '',\n path: payload.path,\n method: payload.method,\n example: payload.exampleName,\n })?.id ?? '',\n )\n }\n\n // Apply the selection after routing so the request body compares it with the selection used\n // for this operation, rather than briefly resetting the operation that was previously open.\n // Reopening the entry already on screen routes nowhere, so a new selection would read as a\n // manual branch switch and discard the edited body.\n const isReopeningVisibleEntry = modalState.open && sidebarState.state.selectedItem.value === previousSelectedId\n\n if (!isReopeningVisibleEntry) {\n requestBodyCompositionSelection.value = nextRequestBodyCompositionSelection\n }\n\n modalState.show()\n })\n}\n"],"mappings":";;;;AAYA,IAAM,2CAA2C,OAAO,OAAO,CAAC,CAAC;AAEjE,SAAgB,sBAAsB,EACpC,UACA,eACA,iCACA,cACA,YACA,SAQC;;CAED,iCAAiC;EAC/B;EACA,OAAO,IAAI,KAAK;EAChB,OAAO,CAAC;CACV,CAAC;CAKD,SAAS,GAAG,uBAAuB,EAAE,SAAS,aAAa,iBAAiB,EAAE,CAAC;CAK/E,SAAS,GAAG,2BAA4B,cAAc,QAAQ,CAAC,cAAc,KAAM;CACnF,SAAS,GAAG,+BAA+B,WAAW,KAAK,CAAC;CAC5D,SAAS,GAAG,yBAAyB,YAAY;EAG/C,MAAM,sCACJ,WAAW,qCAAqC,WAAW,QAAQ,kCAC/D,QAAQ,kCACR;EAIN,IAAI,CAAC,SAAS;GACZ,gCAAgC,QAAQ;GACxC,WAAW,KAAK;GAChB;EACF;EAEA,MAAM,qBAAqB,aAAa,MAAM,aAAa;EAG3D,IAAI,QAAQ,WAAW,QAAQ,IAAI;GACjC,IAAI,WAAW,QAAQ;GAGvB,IAAI,iBAAiB,WAAW,QAAQ,aAAa;IACnD,MAAM,iBAAiB,aAAa,MAAM,aAAa,QAAQ,EAAE;IAGjE,IAAI,kBAAkB,cAAc,kBAAkB,eAAe,UAAU;KAC7E,MAAM,eAAe,eAAe,SAAS,MAC1C,UAA0B,MAAM,SAAS,aAAa,MAAM,SAAS,QAAQ,WAChF;KACA,IAAI,cACF,WAAW,aAAa;IAE5B;GACF;GAEA,aAAa,iBAAiB,QAAQ;EACxC,OAEK,IAAI,YAAY,WAAW,UAAU,SAAS;GACjD,MAAM,YAAY,MAAM,UAAU;GAClC,aAAa,iBACX,aAAa,mBAAmB;IAC9B,UAAU,kBAAkB,SAAS,IAAK,UAAU,sBAAsB,EAAE,MAAM,KAAM;IACxF,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,SAAS,QAAQ;GACnB,CAAC,CAAC,EAAE,MAAM,EACZ;EACF;EAQA,IAAI,EAF4B,WAAW,QAAQ,aAAa,MAAM,aAAa,UAAU,qBAG3F,gCAAgC,QAAQ;EAG1C,WAAW,KAAK;CAClB,CAAC;AACH"}
|
|
@@ -32,6 +32,8 @@ export type OperationProps = {
|
|
|
32
32
|
method?: HttpMethod;
|
|
33
33
|
/** The name of the currently selected example (for examples within an endpoint) */
|
|
34
34
|
exampleName?: string;
|
|
35
|
+
/** Resolve the selected entry from the OpenAPI webhooks map. */
|
|
36
|
+
isWebhook?: boolean;
|
|
35
37
|
/** The currently active environment */
|
|
36
38
|
environment: XScalarEnvironment;
|
|
37
39
|
/** The workspace store */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Operation.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/operation/Operation.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Operation.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/operation/Operation.vue"],"names":[],"mappings":"AA8NA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAKvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAA;AACnG,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAK9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG1D;;;;;;;GAOG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAIzC,MAAM,MAAM,cAAc,GAAG;IAC3B,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAA;IAChC,8BAA8B;IAC9B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uCAAuC;IACvC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,0BAA0B;IAC1B,cAAc,EAAE,cAAc,CAAA;IAC9B,qBAAqB;IACrB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC7C,CAAA;AACD,QAAA,MAAM,YAAY;IAEd,sEAAsE;sCACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;IADxD,sEAAsE;sCACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;iGA8PxD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Operation.vue.js","names":[],"sources":["../../../../src/v2/features/operation/Operation.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Operation example page\n *\n * Displays an operation with a specific example selected\n * - View example request data\n * - Modify example request data\n * - Send example request\n */\nexport default {}\n\nexport type OperationProps = {\n /** The slug of the currently selected document in the workspace */\n documentSlug: string\n /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */\n document: OpenApiDocument | null\n /** The workspace event bus */\n eventBus: WorkspaceEventBus\n /** The layout of the client */\n layout: ClientLayout\n /** The API path currently selected (e.g. \"/users/{id}\") */\n path?: string\n /** The HTTP method for the currently selected API path (e.g. GET, POST) */\n method?: HttpMethod\n /** The name of the currently selected example (for examples within an endpoint) */\n exampleName?: string\n /** The currently active environment */\n environment: XScalarEnvironment\n /** The workspace store */\n workspaceStore: WorkspaceStore\n /** Client plugins */\n plugins: ClientPlugin[]\n /** App or modal options forwarded to operation/auth blocks */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n getActiveProxyUrl,\n getRequestExampleContext,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nimport { OperationBlock } from '@/v2/blocks/operation-block'\nimport { APP_VERSION } from '@/v2/constants'\nimport { mapHiddenClientsConfig } from '@/v2/features/modal/helpers/map-hidden-clients-config'\nimport type { ClientLayout } from '@/v2/types/layout'\nimport type { ApiClientOptions } from '@/v2/types/options'\n\nconst {\n document,\n layout,\n eventBus,\n path,\n method,\n environment,\n exampleName,\n options,\n workspaceStore,\n plugins,\n documentSlug,\n} = defineProps<\n OperationProps & {\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n }\n>()\n\n/**\n * Shared request-example context (operation, servers, auth scope, cookies). Recomputed when any\n * underlying workspace or route input changes — same reactivity as the previous local computeds.\n */\nconst requestExample = computed(() => {\n if (!path || !method || !exampleName || !document) {\n return null\n }\n\n const result = getRequestExampleContext(\n workspaceStore,\n documentSlug,\n { path, method, exampleName },\n {\n baseServerUrl: toValue(options)?.baseServerURL,\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: layout === 'web' ? 'web' : 'other',\n servers: toValue(options)?.servers,\n appVersion: APP_VERSION,\n authentication: toValue(options)?.authentication,\n },\n )\n\n return result.ok ? result.data : null\n})\n\nconst operation = computed(() => requestExample.value?.operation ?? null)\nconst workspaceCookies = computed(\n () => requestExample.value?.cookies.workspace ?? [],\n)\nconst documentCookies = computed(\n () => requestExample.value?.cookies.document ?? [],\n)\nconst servers = computed(() => requestExample.value?.servers.list ?? [])\nconst selectedServer = computed(\n () => requestExample.value?.servers.selected ?? null,\n)\nconst serverMeta = computed(\n () => requestExample.value?.servers.meta ?? { type: 'document' as const },\n)\n\nconst securitySchemes = computed(\n () => requestExample.value?.security.schemes ?? {},\n)\n\nconst selectedSecurity = computed(\n () =>\n requestExample.value?.security.selected ?? {\n selectedIndex: -1,\n selectedSchemes: [],\n },\n)\nconst selectedSecuritySchemes = computed(\n () => requestExample.value?.security.selectedSchemes ?? [],\n)\nconst securityRequirements = computed(\n () => requestExample.value?.security.requirements ?? [],\n)\nconst authMeta = computed(\n () => requestExample.value?.security.meta ?? { type: 'document' as const },\n)\n\nconst defaultHeaders = computed(\n () => requestExample.value?.headers.default ?? {},\n)\n\n/** Combine environments from document and workspace into a unique array of environment names */\nconst environments = computed(() => {\n return Array.from(\n new Set(\n Object.keys({\n ...document?.['x-scalar-environments'],\n ...workspaceStore.workspace['x-scalar-environments'],\n }),\n ),\n )\n})\n\n/** Temporarily use the old config.hiddenClients until we migrate to the new httpClients config */\nconst httpClients = computed(() =>\n mapHiddenClientsConfig(toValue(options)?.hiddenClients),\n)\n</script>\n\n<template>\n <!-- Operation exists -->\n <template v-if=\"path && method && exampleName && operation && document\">\n <OperationBlock\n :activeEnvironment=\"\n workspaceStore.workspace['x-scalar-active-environment']\n \"\n :appVersion=\"APP_VERSION\"\n :authMeta\n :defaultHeaders\n :document\n :documentCookies\n :documentSecurity=\"document?.security ?? []\"\n :documentSlug\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :environment\n :environments\n :eventBus\n :exampleKey=\"exampleName\"\n :hideClientButton=\"toValue(options)?.hideClientButton ?? false\"\n :history=\"workspaceStore.history.getHistory(documentSlug, path, method)\"\n :httpClients\n :layout\n :method\n :operation\n :options\n :path\n :plugins=\"plugins\"\n :proxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n ) ?? ''\n \"\n :requestBodyCompositionSelection\n :securityRequirements=\"securityRequirements\"\n :securitySchemes\n :selectedClient=\"workspaceStore.workspace['x-scalar-default-client']\"\n :selectedSecurity=\"selectedSecurity\"\n :selectedSecuritySchemes=\"selectedSecuritySchemes\"\n :server=\"selectedServer\"\n :serverMeta\n :servers\n :workspaceCookies />\n </template>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">Select an operation to view details</span>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Operation.vue.js","names":[],"sources":["../../../../src/v2/features/operation/Operation.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Operation example page\n *\n * Displays an operation with a specific example selected\n * - View example request data\n * - Modify example request data\n * - Send example request\n */\nexport default {}\n\nexport type OperationProps = {\n /** The slug of the currently selected document in the workspace */\n documentSlug: string\n /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */\n document: OpenApiDocument | null\n /** The workspace event bus */\n eventBus: WorkspaceEventBus\n /** The layout of the client */\n layout: ClientLayout\n /** The API path currently selected (e.g. \"/users/{id}\") */\n path?: string\n /** The HTTP method for the currently selected API path (e.g. GET, POST) */\n method?: HttpMethod\n /** The name of the currently selected example (for examples within an endpoint) */\n exampleName?: string\n /** Resolve the selected entry from the OpenAPI webhooks map. */\n isWebhook?: boolean\n /** The currently active environment */\n environment: XScalarEnvironment\n /** The workspace store */\n workspaceStore: WorkspaceStore\n /** Client plugins */\n plugins: ClientPlugin[]\n /** App or modal options forwarded to operation/auth blocks */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n getActiveProxyUrl,\n getRequestExampleContext,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nimport { OperationBlock } from '@/v2/blocks/operation-block'\nimport { APP_VERSION } from '@/v2/constants'\nimport { mapHiddenClientsConfig } from '@/v2/features/modal/helpers/map-hidden-clients-config'\nimport type { ClientLayout } from '@/v2/types/layout'\nimport type { ApiClientOptions } from '@/v2/types/options'\n\nconst {\n document,\n layout,\n eventBus,\n path,\n method,\n environment,\n exampleName,\n options,\n workspaceStore,\n plugins,\n documentSlug,\n isWebhook = false,\n} = defineProps<\n OperationProps & {\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n }\n>()\n\n/**\n * Shared request-example context (operation, servers, auth scope, cookies). Recomputed when any\n * underlying workspace or route input changes — same reactivity as the previous local computeds.\n */\nconst requestExample = computed(() => {\n if (!path || !method || !exampleName || !document) {\n return null\n }\n\n const result = getRequestExampleContext(\n workspaceStore,\n documentSlug,\n { path, method, exampleName, isWebhook },\n {\n baseServerUrl: toValue(options)?.baseServerURL,\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: layout === 'web' ? 'web' : 'other',\n servers: toValue(options)?.servers,\n appVersion: APP_VERSION,\n authentication: toValue(options)?.authentication,\n },\n )\n\n return result.ok ? result.data : null\n})\n\nconst operation = computed(() => requestExample.value?.operation ?? null)\nconst workspaceCookies = computed(\n () => requestExample.value?.cookies.workspace ?? [],\n)\nconst documentCookies = computed(\n () => requestExample.value?.cookies.document ?? [],\n)\nconst servers = computed(() => requestExample.value?.servers.list ?? [])\nconst selectedServer = computed(\n () => requestExample.value?.servers.selected ?? null,\n)\nconst serverMeta = computed(\n () => requestExample.value?.servers.meta ?? { type: 'document' as const },\n)\n\nconst securitySchemes = computed(\n () => requestExample.value?.security.schemes ?? {},\n)\n\nconst selectedSecurity = computed(\n () =>\n requestExample.value?.security.selected ?? {\n selectedIndex: -1,\n selectedSchemes: [],\n },\n)\nconst selectedSecuritySchemes = computed(\n () => requestExample.value?.security.selectedSchemes ?? [],\n)\nconst securityRequirements = computed(\n () => requestExample.value?.security.requirements ?? [],\n)\nconst authMeta = computed(\n () => requestExample.value?.security.meta ?? { type: 'document' as const },\n)\n\nconst defaultHeaders = computed(\n () => requestExample.value?.headers.default ?? {},\n)\n\n/** Combine environments from document and workspace into a unique array of environment names */\nconst environments = computed(() => {\n return Array.from(\n new Set(\n Object.keys({\n ...document?.['x-scalar-environments'],\n ...workspaceStore.workspace['x-scalar-environments'],\n }),\n ),\n )\n})\n\n/** Temporarily use the old config.hiddenClients until we migrate to the new httpClients config */\nconst httpClients = computed(() =>\n mapHiddenClientsConfig(toValue(options)?.hiddenClients),\n)\n</script>\n\n<template>\n <!-- Operation exists -->\n <template v-if=\"path && method && exampleName && operation && document\">\n <OperationBlock\n :activeEnvironment=\"\n workspaceStore.workspace['x-scalar-active-environment']\n \"\n :appVersion=\"APP_VERSION\"\n :authMeta\n :defaultHeaders\n :document\n :documentCookies\n :documentSecurity=\"document?.security ?? []\"\n :documentSlug\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :environment\n :environments\n :eventBus\n :exampleKey=\"exampleName\"\n :hideClientButton=\"toValue(options)?.hideClientButton ?? false\"\n :history=\"workspaceStore.history.getHistory(documentSlug, path, method)\"\n :httpClients\n :layout\n :method\n :isWebhook\n :operation\n :options\n :path\n :plugins=\"plugins\"\n :proxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n ) ?? ''\n \"\n :requestBodyCompositionSelection\n :securityRequirements=\"securityRequirements\"\n :securitySchemes\n :selectedClient=\"workspaceStore.workspace['x-scalar-default-client']\"\n :selectedSecurity=\"selectedSecurity\"\n :selectedSecuritySchemes=\"selectedSecuritySchemes\"\n :server=\"selectedServer\"\n :serverMeta\n :servers\n :workspaceCookies />\n </template>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">Select an operation to view details</span>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -19,6 +19,10 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
19
19
|
path: {},
|
|
20
20
|
method: {},
|
|
21
21
|
exampleName: {},
|
|
22
|
+
isWebhook: {
|
|
23
|
+
type: Boolean,
|
|
24
|
+
default: false
|
|
25
|
+
},
|
|
22
26
|
environment: {},
|
|
23
27
|
workspaceStore: {},
|
|
24
28
|
plugins: {},
|
|
@@ -35,7 +39,8 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
35
39
|
const result = getRequestExampleContext(__props.workspaceStore, __props.documentSlug, {
|
|
36
40
|
path: __props.path,
|
|
37
41
|
method: __props.method,
|
|
38
|
-
exampleName: __props.exampleName
|
|
42
|
+
exampleName: __props.exampleName,
|
|
43
|
+
isWebhook: __props.isWebhook
|
|
39
44
|
}, {
|
|
40
45
|
baseServerUrl: toValue(__props.options)?.baseServerURL,
|
|
41
46
|
fallbackDocument: __props.document,
|
|
@@ -92,6 +97,7 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
92
97
|
httpClients: httpClients.value,
|
|
93
98
|
layout: __props.layout,
|
|
94
99
|
method: __props.method,
|
|
100
|
+
isWebhook: __props.isWebhook,
|
|
95
101
|
operation: operation.value,
|
|
96
102
|
options: __props.options,
|
|
97
103
|
path: __props.path,
|
|
@@ -126,6 +132,7 @@ var Operation_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
126
132
|
"httpClients",
|
|
127
133
|
"layout",
|
|
128
134
|
"method",
|
|
135
|
+
"isWebhook",
|
|
129
136
|
"operation",
|
|
130
137
|
"options",
|
|
131
138
|
"path",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Operation.vue.script.js","names":[],"sources":["../../../../src/v2/features/operation/Operation.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Operation example page\n *\n * Displays an operation with a specific example selected\n * - View example request data\n * - Modify example request data\n * - Send example request\n */\nexport default {}\n\nexport type OperationProps = {\n /** The slug of the currently selected document in the workspace */\n documentSlug: string\n /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */\n document: OpenApiDocument | null\n /** The workspace event bus */\n eventBus: WorkspaceEventBus\n /** The layout of the client */\n layout: ClientLayout\n /** The API path currently selected (e.g. \"/users/{id}\") */\n path?: string\n /** The HTTP method for the currently selected API path (e.g. GET, POST) */\n method?: HttpMethod\n /** The name of the currently selected example (for examples within an endpoint) */\n exampleName?: string\n /** The currently active environment */\n environment: XScalarEnvironment\n /** The workspace store */\n workspaceStore: WorkspaceStore\n /** Client plugins */\n plugins: ClientPlugin[]\n /** App or modal options forwarded to operation/auth blocks */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n getActiveProxyUrl,\n getRequestExampleContext,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nimport { OperationBlock } from '@/v2/blocks/operation-block'\nimport { APP_VERSION } from '@/v2/constants'\nimport { mapHiddenClientsConfig } from '@/v2/features/modal/helpers/map-hidden-clients-config'\nimport type { ClientLayout } from '@/v2/types/layout'\nimport type { ApiClientOptions } from '@/v2/types/options'\n\nconst {\n document,\n layout,\n eventBus,\n path,\n method,\n environment,\n exampleName,\n options,\n workspaceStore,\n plugins,\n documentSlug,\n} = defineProps<\n OperationProps & {\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n }\n>()\n\n/**\n * Shared request-example context (operation, servers, auth scope, cookies). Recomputed when any\n * underlying workspace or route input changes — same reactivity as the previous local computeds.\n */\nconst requestExample = computed(() => {\n if (!path || !method || !exampleName || !document) {\n return null\n }\n\n const result = getRequestExampleContext(\n workspaceStore,\n documentSlug,\n { path, method, exampleName },\n {\n baseServerUrl: toValue(options)?.baseServerURL,\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: layout === 'web' ? 'web' : 'other',\n servers: toValue(options)?.servers,\n appVersion: APP_VERSION,\n authentication: toValue(options)?.authentication,\n },\n )\n\n return result.ok ? result.data : null\n})\n\nconst operation = computed(() => requestExample.value?.operation ?? null)\nconst workspaceCookies = computed(\n () => requestExample.value?.cookies.workspace ?? [],\n)\nconst documentCookies = computed(\n () => requestExample.value?.cookies.document ?? [],\n)\nconst servers = computed(() => requestExample.value?.servers.list ?? [])\nconst selectedServer = computed(\n () => requestExample.value?.servers.selected ?? null,\n)\nconst serverMeta = computed(\n () => requestExample.value?.servers.meta ?? { type: 'document' as const },\n)\n\nconst securitySchemes = computed(\n () => requestExample.value?.security.schemes ?? {},\n)\n\nconst selectedSecurity = computed(\n () =>\n requestExample.value?.security.selected ?? {\n selectedIndex: -1,\n selectedSchemes: [],\n },\n)\nconst selectedSecuritySchemes = computed(\n () => requestExample.value?.security.selectedSchemes ?? [],\n)\nconst securityRequirements = computed(\n () => requestExample.value?.security.requirements ?? [],\n)\nconst authMeta = computed(\n () => requestExample.value?.security.meta ?? { type: 'document' as const },\n)\n\nconst defaultHeaders = computed(\n () => requestExample.value?.headers.default ?? {},\n)\n\n/** Combine environments from document and workspace into a unique array of environment names */\nconst environments = computed(() => {\n return Array.from(\n new Set(\n Object.keys({\n ...document?.['x-scalar-environments'],\n ...workspaceStore.workspace['x-scalar-environments'],\n }),\n ),\n )\n})\n\n/** Temporarily use the old config.hiddenClients until we migrate to the new httpClients config */\nconst httpClients = computed(() =>\n mapHiddenClientsConfig(toValue(options)?.hiddenClients),\n)\n</script>\n\n<template>\n <!-- Operation exists -->\n <template v-if=\"path && method && exampleName && operation && document\">\n <OperationBlock\n :activeEnvironment=\"\n workspaceStore.workspace['x-scalar-active-environment']\n \"\n :appVersion=\"APP_VERSION\"\n :authMeta\n :defaultHeaders\n :document\n :documentCookies\n :documentSecurity=\"document?.security ?? []\"\n :documentSlug\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :environment\n :environments\n :eventBus\n :exampleKey=\"exampleName\"\n :hideClientButton=\"toValue(options)?.hideClientButton ?? false\"\n :history=\"workspaceStore.history.getHistory(documentSlug, path, method)\"\n :httpClients\n :layout\n :method\n :operation\n :options\n :path\n :plugins=\"plugins\"\n :proxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n ) ?? ''\n \"\n :requestBodyCompositionSelection\n :securityRequirements=\"securityRequirements\"\n :securitySchemes\n :selectedClient=\"workspaceStore.workspace['x-scalar-default-client']\"\n :selectedSecurity=\"selectedSecurity\"\n :selectedSecuritySchemes=\"selectedSecuritySchemes\"\n :server=\"selectedServer\"\n :serverMeta\n :servers\n :workspaceCookies />\n </template>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">Select an operation to view details</span>\n </div>\n</template>\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Operation.vue.script.js","names":[],"sources":["../../../../src/v2/features/operation/Operation.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Operation example page\n *\n * Displays an operation with a specific example selected\n * - View example request data\n * - Modify example request data\n * - Send example request\n */\nexport default {}\n\nexport type OperationProps = {\n /** The slug of the currently selected document in the workspace */\n documentSlug: string\n /** The currently active document — OpenAPI-only, the operation page has no AsyncAPI path */\n document: OpenApiDocument | null\n /** The workspace event bus */\n eventBus: WorkspaceEventBus\n /** The layout of the client */\n layout: ClientLayout\n /** The API path currently selected (e.g. \"/users/{id}\") */\n path?: string\n /** The HTTP method for the currently selected API path (e.g. GET, POST) */\n method?: HttpMethod\n /** The name of the currently selected example (for examples within an endpoint) */\n exampleName?: string\n /** Resolve the selected entry from the OpenAPI webhooks map. */\n isWebhook?: boolean\n /** The currently active environment */\n environment: XScalarEnvironment\n /** The workspace store */\n workspaceStore: WorkspaceStore\n /** Client plugins */\n plugins: ClientPlugin[]\n /** App or modal options forwarded to operation/auth blocks */\n options?: MaybeRefOrGetter<ApiClientOptions>\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { isElectron } from '@scalar/helpers/general/is-electron'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport {\n getActiveProxyUrl,\n getRequestExampleContext,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nimport { OperationBlock } from '@/v2/blocks/operation-block'\nimport { APP_VERSION } from '@/v2/constants'\nimport { mapHiddenClientsConfig } from '@/v2/features/modal/helpers/map-hidden-clients-config'\nimport type { ClientLayout } from '@/v2/types/layout'\nimport type { ApiClientOptions } from '@/v2/types/options'\n\nconst {\n document,\n layout,\n eventBus,\n path,\n method,\n environment,\n exampleName,\n options,\n workspaceStore,\n plugins,\n documentSlug,\n isWebhook = false,\n} = defineProps<\n OperationProps & {\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection?: Record<string, number>\n }\n>()\n\n/**\n * Shared request-example context (operation, servers, auth scope, cookies). Recomputed when any\n * underlying workspace or route input changes — same reactivity as the previous local computeds.\n */\nconst requestExample = computed(() => {\n if (!path || !method || !exampleName || !document) {\n return null\n }\n\n const result = getRequestExampleContext(\n workspaceStore,\n documentSlug,\n { path, method, exampleName, isWebhook },\n {\n baseServerUrl: toValue(options)?.baseServerURL,\n fallbackDocument: document,\n isElectron: isElectron(),\n layout: layout === 'web' ? 'web' : 'other',\n servers: toValue(options)?.servers,\n appVersion: APP_VERSION,\n authentication: toValue(options)?.authentication,\n },\n )\n\n return result.ok ? result.data : null\n})\n\nconst operation = computed(() => requestExample.value?.operation ?? null)\nconst workspaceCookies = computed(\n () => requestExample.value?.cookies.workspace ?? [],\n)\nconst documentCookies = computed(\n () => requestExample.value?.cookies.document ?? [],\n)\nconst servers = computed(() => requestExample.value?.servers.list ?? [])\nconst selectedServer = computed(\n () => requestExample.value?.servers.selected ?? null,\n)\nconst serverMeta = computed(\n () => requestExample.value?.servers.meta ?? { type: 'document' as const },\n)\n\nconst securitySchemes = computed(\n () => requestExample.value?.security.schemes ?? {},\n)\n\nconst selectedSecurity = computed(\n () =>\n requestExample.value?.security.selected ?? {\n selectedIndex: -1,\n selectedSchemes: [],\n },\n)\nconst selectedSecuritySchemes = computed(\n () => requestExample.value?.security.selectedSchemes ?? [],\n)\nconst securityRequirements = computed(\n () => requestExample.value?.security.requirements ?? [],\n)\nconst authMeta = computed(\n () => requestExample.value?.security.meta ?? { type: 'document' as const },\n)\n\nconst defaultHeaders = computed(\n () => requestExample.value?.headers.default ?? {},\n)\n\n/** Combine environments from document and workspace into a unique array of environment names */\nconst environments = computed(() => {\n return Array.from(\n new Set(\n Object.keys({\n ...document?.['x-scalar-environments'],\n ...workspaceStore.workspace['x-scalar-environments'],\n }),\n ),\n )\n})\n\n/** Temporarily use the old config.hiddenClients until we migrate to the new httpClients config */\nconst httpClients = computed(() =>\n mapHiddenClientsConfig(toValue(options)?.hiddenClients),\n)\n</script>\n\n<template>\n <!-- Operation exists -->\n <template v-if=\"path && method && exampleName && operation && document\">\n <OperationBlock\n :activeEnvironment=\"\n workspaceStore.workspace['x-scalar-active-environment']\n \"\n :appVersion=\"APP_VERSION\"\n :authMeta\n :defaultHeaders\n :document\n :documentCookies\n :documentSecurity=\"document?.security ?? []\"\n :documentSlug\n :documentUrl=\"document?.['x-scalar-original-source-url']\"\n :environment\n :environments\n :eventBus\n :exampleKey=\"exampleName\"\n :hideClientButton=\"toValue(options)?.hideClientButton ?? false\"\n :history=\"workspaceStore.history.getHistory(documentSlug, path, method)\"\n :httpClients\n :layout\n :method\n :isWebhook\n :operation\n :options\n :path\n :plugins=\"plugins\"\n :proxyUrl=\"\n getActiveProxyUrl(\n workspaceStore.workspace['x-scalar-active-proxy'],\n layout === 'web' ? 'web' : 'other',\n ) ?? ''\n \"\n :requestBodyCompositionSelection\n :securityRequirements=\"securityRequirements\"\n :securitySchemes\n :selectedClient=\"workspaceStore.workspace['x-scalar-default-client']\"\n :selectedSecurity=\"selectedSecurity\"\n :selectedSecuritySchemes=\"selectedSecuritySchemes\"\n :server=\"selectedServer\"\n :serverMeta\n :servers\n :workspaceCookies />\n </template>\n\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">Select an operation to view details</span>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -10,10 +10,12 @@ import type { HttpMethod } from '@scalar/helpers/http/http-methods';
|
|
|
10
10
|
* generateLocationId({ document: 'mydoc', path: '/users', method: 'get', example: 'default' })
|
|
11
11
|
* // => '["mydoc","/users","get","default"]'
|
|
12
12
|
*/
|
|
13
|
-
export declare const generateLocationId: ({ document, path, method, example, }: {
|
|
13
|
+
export declare const generateLocationId: ({ document, path, method, example, isWebhook, }: {
|
|
14
14
|
document: string;
|
|
15
15
|
path?: string;
|
|
16
16
|
method?: HttpMethod;
|
|
17
17
|
example?: string;
|
|
18
|
+
/** Namespace webhook entries without changing existing operation IDs. */
|
|
19
|
+
isWebhook?: boolean;
|
|
18
20
|
}) => string;
|
|
19
21
|
//# sourceMappingURL=generate-location-id.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-location-id.d.ts","sourceRoot":"","sources":["../../../src/v2/helpers/generate-location-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,
|
|
1
|
+
{"version":3,"file":"generate-location-id.d.ts","sourceRoot":"","sources":["../../../src/v2/helpers/generate-location-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,iDAMhC;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,WAEA,CAAA"}
|
|
@@ -11,9 +11,10 @@ import { isDefined } from "@scalar/helpers/array/is-defined";
|
|
|
11
11
|
* generateLocationId({ document: 'mydoc', path: '/users', method: 'get', example: 'default' })
|
|
12
12
|
* // => '["mydoc","/users","get","default"]'
|
|
13
13
|
*/
|
|
14
|
-
var generateLocationId = ({ document, path, method, example }) => {
|
|
14
|
+
var generateLocationId = ({ document, path, method, example, isWebhook = false }) => {
|
|
15
15
|
return JSON.stringify([
|
|
16
16
|
document,
|
|
17
|
+
isWebhook ? "webhook" : void 0,
|
|
17
18
|
path,
|
|
18
19
|
method,
|
|
19
20
|
example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-location-id.js","names":[],"sources":["../../../src/v2/helpers/generate-location-id.ts"],"sourcesContent":["import { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\n\n/**\n * Generates a unique string ID for an API location, based on the document, path, method, and example.\n * Filters out undefined values and serializes the composite array into a stable string.\n *\n * @param params - An object containing document, path, method, and optional example name.\n * @returns A stringified array representing the unique location identifier.\n *\n * Example:\n * generateLocationId({ document: 'mydoc', path: '/users', method: 'get', example: 'default' })\n * // => '[\"mydoc\",\"/users\",\"get\",\"default\"]'\n */\nexport const generateLocationId = ({\n document,\n path,\n method,\n example,\n}: {\n document: string\n path?: string\n method?: HttpMethod\n example?: string\n}) => {\n return JSON.stringify([document, path, method, example].filter(isDefined))\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,sBAAsB,EACjC,UACA,MACA,QACA,
|
|
1
|
+
{"version":3,"file":"generate-location-id.js","names":[],"sources":["../../../src/v2/helpers/generate-location-id.ts"],"sourcesContent":["import { isDefined } from '@scalar/helpers/array/is-defined'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\n\n/**\n * Generates a unique string ID for an API location, based on the document, path, method, and example.\n * Filters out undefined values and serializes the composite array into a stable string.\n *\n * @param params - An object containing document, path, method, and optional example name.\n * @returns A stringified array representing the unique location identifier.\n *\n * Example:\n * generateLocationId({ document: 'mydoc', path: '/users', method: 'get', example: 'default' })\n * // => '[\"mydoc\",\"/users\",\"get\",\"default\"]'\n */\nexport const generateLocationId = ({\n document,\n path,\n method,\n example,\n isWebhook = false,\n}: {\n document: string\n path?: string\n method?: HttpMethod\n example?: string\n /** Namespace webhook entries without changing existing operation IDs. */\n isWebhook?: boolean\n}) => {\n return JSON.stringify([document, isWebhook ? 'webhook' : undefined, path, method, example].filter(isDefined))\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,sBAAsB,EACjC,UACA,MACA,QACA,SACA,YAAY,YAQR;CACJ,OAAO,KAAK,UAAU;EAAC;EAAU,YAAY,YAAY,KAAA;EAAW;EAAM;EAAQ;CAAO,CAAC,CAAC,OAAO,SAAS,CAAC;AAC9G"}
|