@scalar/api-client-react 1.4.20 → 2.0.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 +8 -0
- package/README.md +41 -18
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -99
- package/dist/index.js.map +1 -1
- package/dist/lazy-load.d.ts +87 -0
- package/dist/lazy-load.d.ts.map +1 -0
- package/dist/style.css +106 -36
- package/dist/use-api-client.d.ts +26 -0
- package/dist/use-api-client.d.ts.map +1 -0
- package/dist/vitest.setup.d.ts +2 -0
- package/dist/vitest.setup.d.ts.map +1 -0
- package/package.json +11 -4
- package/dist/ApiClientModalProvider.d.ts +0 -21
- package/dist/ApiClientModalProvider.d.ts.map +0 -1
- package/dist/client-store.d.ts +0 -12
- package/dist/client-store.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -11,34 +11,57 @@
|
|
|
11
11
|
npm install @scalar/api-client-react
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
## ⚠️ Breaking Changes
|
|
15
|
+
|
|
16
|
+
We have updated the API for the client! Please see the new hook based usage below.
|
|
17
|
+
|
|
14
18
|
## Usage
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
Call `useApiClient()` from any component. No provider is needed.
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
The Vue app is created once and appended to `document.body` where it lives for the lifetime of the
|
|
23
|
+
page — it survives client-side navigation without losing state.
|
|
20
24
|
|
|
25
|
+
The code is ESM lazy loaded with the dynamic import function to make the smallest possible initial bundle size. We also
|
|
26
|
+
handle de-duplication of documents so as long as the URL is the same you will only get one.
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { useApiClient } from '@scalar/api-client-react'
|
|
21
30
|
import '@scalar/api-client-react/style.css'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
|
|
32
|
+
export const OpenButton = () => {
|
|
33
|
+
const client = useApiClient({
|
|
34
|
+
configuration: {
|
|
35
|
+
url: 'https://registry.scalar.com/@scalar/apis/galaxy?format=json',
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<button onClick={() => client?.open({ path: '/planets', method: 'get' })}>
|
|
41
|
+
Open API Client
|
|
42
|
+
</button>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
28
45
|
```
|
|
29
46
|
|
|
30
|
-
|
|
47
|
+
### Options
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
| Option | Type | Description |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `configuration.url` | `string` | URL of an OpenAPI document to load |
|
|
52
|
+
| `configuration.content` | `Record<string, unknown>` | Inline OpenAPI document object |
|
|
53
|
+
|
|
54
|
+
### Routing to a specific request
|
|
34
55
|
|
|
35
|
-
|
|
56
|
+
Pass a `RoutePayload` to `client.open()` to navigate directly to a specific endpoint:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
const client = useApiClient({
|
|
60
|
+
configuration: { url: '...' },
|
|
61
|
+
})
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Click me to open the Api Client
|
|
40
|
-
</button>
|
|
41
|
-
)
|
|
63
|
+
// Open to a specific request
|
|
64
|
+
client?.open({ path: '/auth/token', method: 'post' })
|
|
42
65
|
```
|
|
43
66
|
|
|
44
67
|
Check out the playground for a working example.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
export {
|
|
1
|
+
export type { RoutePayload } from '@scalar/api-client/v2/features/modal';
|
|
2
|
+
export type { ApiClientConfigurationReact, UseApiClientModalProps } from './use-api-client';
|
|
3
|
+
export { useApiClient } from './use-api-client';
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAA;AAExE,YAAY,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,115 +1,136 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
/** Get the current state at this moment in time */
|
|
21
|
-
var getSnapshot = () => state;
|
|
22
|
-
/** Trigger all listeners */
|
|
23
|
-
var emit = () => listeners.forEach((listener) => listener());
|
|
24
|
-
/** Set the create client state */
|
|
25
|
-
var setCreateClient = (clientFactory) => {
|
|
26
|
-
state = {
|
|
27
|
-
...state,
|
|
28
|
-
createClient: clientFactory
|
|
29
|
-
};
|
|
30
|
-
emit();
|
|
31
|
-
};
|
|
32
|
-
/** Add a client to the client dict */
|
|
33
|
-
var addClient = (url, client) => {
|
|
34
|
-
state = {
|
|
35
|
-
...state,
|
|
36
|
-
clientDict: {
|
|
37
|
-
...state.clientDict,
|
|
38
|
-
[url]: client
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
emit();
|
|
42
|
-
};
|
|
43
|
-
/** Remove a client from the client dict */
|
|
44
|
-
var removeClient = (url) => {
|
|
45
|
-
const { [url]: _, ...clientDict } = state.clientDict;
|
|
46
|
-
state = {
|
|
47
|
-
...state,
|
|
48
|
-
clientDict
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
//#region src/lazy-load.ts
|
|
4
|
+
/**
|
|
5
|
+
* Creates a lazy singleton getter: the factory runs at most once, caches the resulting promise,
|
|
6
|
+
* and clears the cache on failure so the next call can retry.
|
|
7
|
+
*
|
|
8
|
+
* Optional args are forwarded to the factory on the first (cache-miss) call only.
|
|
9
|
+
* Subsequent calls return the cached promise regardless of the args passed.
|
|
10
|
+
*/
|
|
11
|
+
var makeLazySingleton = (factory) => {
|
|
12
|
+
let cached;
|
|
13
|
+
return (...args) => {
|
|
14
|
+
cached ??= factory(...args).catch((error) => {
|
|
15
|
+
cached = void 0;
|
|
16
|
+
throw error;
|
|
17
|
+
});
|
|
18
|
+
return cached;
|
|
49
19
|
};
|
|
50
|
-
emit();
|
|
51
|
-
};
|
|
52
|
-
var clientStore = {
|
|
53
|
-
getSnapshot,
|
|
54
|
-
subscribe,
|
|
55
|
-
setCreateClient,
|
|
56
|
-
addClient,
|
|
57
|
-
removeClient
|
|
58
20
|
};
|
|
21
|
+
/** Lazy load the client modal creator */
|
|
22
|
+
var getClientModalCreator = makeLazySingleton(() => import("@scalar/api-client/v2/features/modal").then(({ createApiClientModal }) => createApiClientModal));
|
|
23
|
+
/** Module-scoped singleton workspace store (lazy-loaded on first use). */
|
|
24
|
+
var getWorkspaceStoreSingleton = makeLazySingleton(() => import("@scalar/workspace-store/client").then(({ createWorkspaceStore }) => createWorkspaceStore()));
|
|
25
|
+
/** Module-scoped singleton workspace event bus (lazy-loaded on first use). */
|
|
26
|
+
var getWorkspaceEventBusSingleton = makeLazySingleton(() => import("@scalar/workspace-store/events").then(({ createWorkspaceEventBus }) => createWorkspaceEventBus()));
|
|
27
|
+
/**
|
|
28
|
+
* Lazily creates the singleton Vue app, mounts it as the last child of document.body,
|
|
29
|
+
* and returns the controller. Subsequent calls return the same promise.
|
|
30
|
+
*
|
|
31
|
+
* Only modal-level options (e.g. `proxyUrl`) are accepted here. Document-specific fields
|
|
32
|
+
* (`url`, `content`) must be registered via `workspaceStore.addDocument` after the client
|
|
33
|
+
* is ready — they are not part of the modal constructor.
|
|
34
|
+
*/
|
|
35
|
+
var getOrCreateApiClient = makeLazySingleton(async (options = {}) => {
|
|
36
|
+
const el = document.createElement("div");
|
|
37
|
+
el.className = "scalar-app";
|
|
38
|
+
document.body.appendChild(el);
|
|
39
|
+
try {
|
|
40
|
+
const [createModal, workspaceStore, eventBus] = await Promise.all([
|
|
41
|
+
getClientModalCreator(),
|
|
42
|
+
getWorkspaceStoreSingleton(),
|
|
43
|
+
getWorkspaceEventBusSingleton()
|
|
44
|
+
]);
|
|
45
|
+
return {
|
|
46
|
+
apiClient: createModal({
|
|
47
|
+
el,
|
|
48
|
+
eventBus,
|
|
49
|
+
workspaceStore,
|
|
50
|
+
options
|
|
51
|
+
}),
|
|
52
|
+
workspaceStore
|
|
53
|
+
};
|
|
54
|
+
} catch (error) {
|
|
55
|
+
el.remove();
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
59
|
//#endregion
|
|
60
|
-
//#region src/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
var
|
|
60
|
+
//#region src/use-api-client.ts
|
|
61
|
+
globalThis.__VUE_OPTIONS_API__ = true;
|
|
62
|
+
globalThis.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ = true;
|
|
63
|
+
globalThis.__VUE_PROD_DEVTOOLS__ = false;
|
|
64
|
+
/** Tracks which documents are/have been loaded so we dont duplicate */
|
|
65
|
+
var documentDict = {};
|
|
66
66
|
/**
|
|
67
|
-
* Api Client
|
|
67
|
+
* Returns the singleton Api Client
|
|
68
|
+
*
|
|
69
|
+
* On first call the Vue app is lazily created and appended to document.body where it
|
|
70
|
+
* lives for the lifetime of the page — it is never unmounted, so it survives client-side
|
|
71
|
+
* navigation without losing state.
|
|
68
72
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
73
|
+
* Subsequent calls from any component share the same instance of the client but can use the same
|
|
74
|
+
* or different documents
|
|
71
75
|
*/
|
|
72
|
-
var
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
+
var useApiClient = ({ configuration } = {}) => {
|
|
77
|
+
const [client, setClient] = useState(void 0);
|
|
78
|
+
const [workspaceStore, setWorkspaceStore] = useState(void 0);
|
|
79
|
+
const [documentSlug, setDocumentSlug] = useState("");
|
|
80
|
+
/** Small wrapper to set the documentSlug */
|
|
81
|
+
const open = (payload) => client?.open({
|
|
82
|
+
documentSlug,
|
|
83
|
+
...payload
|
|
84
|
+
});
|
|
76
85
|
useEffect(() => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
86
|
+
let cancelled = false;
|
|
87
|
+
const { url, content, ...modalOptions } = configuration ?? {};
|
|
88
|
+
getOrCreateApiClient(modalOptions)?.then((_client) => {
|
|
89
|
+
if (cancelled || !_client) return;
|
|
90
|
+
const slug = url || content?.info?.title || "";
|
|
91
|
+
setClient(_client.apiClient);
|
|
92
|
+
setWorkspaceStore(_client.workspaceStore);
|
|
93
|
+
setDocumentSlug(slug);
|
|
94
|
+
if (slug && !documentDict[slug]) {
|
|
95
|
+
documentDict[slug] = true;
|
|
96
|
+
_client.workspaceStore.addDocument(content ? {
|
|
97
|
+
name: slug,
|
|
98
|
+
document: content
|
|
99
|
+
} : {
|
|
100
|
+
name: slug,
|
|
101
|
+
url: url ?? ""
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return () => {
|
|
106
|
+
cancelled = true;
|
|
81
107
|
};
|
|
82
|
-
if (!isLoading) loadApiClientJs();
|
|
83
108
|
}, []);
|
|
84
109
|
useEffect(() => {
|
|
85
|
-
if (!
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
110
|
+
if (!client || !configuration || !workspaceStore) return;
|
|
111
|
+
const slug = configuration.url || configuration.content?.info?.title || "default";
|
|
112
|
+
setDocumentSlug(slug);
|
|
113
|
+
if (documentDict[slug]) return;
|
|
114
|
+
documentDict[slug] = true;
|
|
115
|
+
workspaceStore.addDocument(configuration.content ? {
|
|
116
|
+
name: slug,
|
|
117
|
+
document: configuration.content
|
|
118
|
+
} : {
|
|
119
|
+
name: slug,
|
|
120
|
+
url: configuration.url ?? ""
|
|
89
121
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
delete clientDict[key];
|
|
101
|
-
};
|
|
102
|
-
}, [el.current, state.createClient]);
|
|
103
|
-
return /* @__PURE__ */ jsxs(ApiClientModalContext.Provider, {
|
|
104
|
-
value: state.clientDict[key] ?? null,
|
|
105
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
106
|
-
className: "scalar-app",
|
|
107
|
-
ref: el
|
|
108
|
-
}), children]
|
|
109
|
-
});
|
|
122
|
+
}, [
|
|
123
|
+
client,
|
|
124
|
+
configuration?.url,
|
|
125
|
+
configuration?.content,
|
|
126
|
+
workspaceStore
|
|
127
|
+
]);
|
|
128
|
+
return client ? {
|
|
129
|
+
...client,
|
|
130
|
+
open
|
|
131
|
+
} : void 0;
|
|
110
132
|
};
|
|
111
|
-
var useApiClientModal = () => useContext(ApiClientModalContext);
|
|
112
133
|
//#endregion
|
|
113
|
-
export {
|
|
134
|
+
export { useApiClient };
|
|
114
135
|
|
|
115
136
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/lazy-load.ts","../src/use-api-client.ts"],"sourcesContent":["import type { ApiClientConfiguration } from '@scalar/types/api-reference'\n\n/**\n * Creates a lazy singleton getter: the factory runs at most once, caches the resulting promise,\n * and clears the cache on failure so the next call can retry.\n *\n * Optional args are forwarded to the factory on the first (cache-miss) call only.\n * Subsequent calls return the cached promise regardless of the args passed.\n */\nconst makeLazySingleton = <T, Args extends unknown[] = []>(\n factory: (...args: Args) => Promise<T>,\n): ((...args: Args) => Promise<T>) => {\n let cached: Promise<T> | undefined\n return (...args: Args) => {\n cached ??= factory(...args).catch((error) => {\n cached = undefined\n throw error\n })\n return cached\n }\n}\n\n/** Lazy load the client modal creator */\nexport const getClientModalCreator = makeLazySingleton(() =>\n import('@scalar/api-client/v2/features/modal').then(({ createApiClientModal }) => createApiClientModal),\n)\n\n/** Module-scoped singleton workspace store (lazy-loaded on first use). */\nexport const getWorkspaceStoreSingleton = makeLazySingleton(() =>\n import('@scalar/workspace-store/client').then(({ createWorkspaceStore }) => createWorkspaceStore()),\n)\n\n/** Module-scoped singleton workspace event bus (lazy-loaded on first use). */\nexport const getWorkspaceEventBusSingleton = makeLazySingleton(() =>\n import('@scalar/workspace-store/events').then(({ createWorkspaceEventBus }) => createWorkspaceEventBus()),\n)\n\n/**\n * Lazily creates the singleton Vue app, mounts it as the last child of document.body,\n * and returns the controller. Subsequent calls return the same promise.\n *\n * Only modal-level options (e.g. `proxyUrl`) are accepted here. Document-specific fields\n * (`url`, `content`) must be registered via `workspaceStore.addDocument` after the client\n * is ready — they are not part of the modal constructor.\n */\nexport const getOrCreateApiClient = makeLazySingleton(async (options: Partial<ApiClientConfiguration> = {}) => {\n const el = document.createElement('div')\n el.className = 'scalar-app'\n document.body.appendChild(el)\n\n try {\n const [createModal, workspaceStore, eventBus] = await Promise.all([\n getClientModalCreator(),\n getWorkspaceStoreSingleton(),\n getWorkspaceEventBusSingleton(),\n ])\n\n const apiClient = createModal({\n el,\n eventBus,\n workspaceStore,\n options,\n // TODO: map plugins from configuration when available\n // plugins: mapConfigPlugins(options),\n })\n\n return { apiClient, workspaceStore }\n } catch (error) {\n el.remove()\n throw error\n }\n})\n","'use client'\n\nimport type { ApiClientModal, RoutePayload } from '@scalar/api-client/v2/features/modal'\nimport type { ApiClientConfiguration } from '@scalar/types/api-reference'\nimport { useEffect, useState } from 'react'\n\nimport './style.css'\n\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\n\nimport { getOrCreateApiClient } from './lazy-load'\n\nglobalThis.__VUE_OPTIONS_API__ = true\nglobalThis.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ = true\nglobalThis.__VUE_PROD_DEVTOOLS__ = false\n\n/** We don't really need all of the content types so we just accept an object instead */\nexport type ApiClientConfigurationReact = Partial<\n Omit<ApiClientConfiguration, 'content' | 'url'> & { content?: Record<string, unknown>; url?: string }\n>\n\nexport type UseApiClientModalProps = {\n /** Configuration for the Api Client (url or inline content) */\n configuration?: ApiClientConfigurationReact\n}\n\n/** Tracks which documents are/have been loaded so we dont duplicate */\nconst documentDict: Record<string, true> = {}\n\n/**\n * Returns the singleton Api Client\n *\n * On first call the Vue app is lazily created and appended to document.body where it\n * lives for the lifetime of the page — it is never unmounted, so it survives client-side\n * navigation without losing state.\n *\n * Subsequent calls from any component share the same instance of the client but can use the same\n * or different documents\n */\nexport const useApiClient = ({\n configuration,\n}: UseApiClientModalProps = {}):\n | (Omit<ApiClientModal, 'open'> & { open: (payload: RoutePayload) => void })\n | undefined => {\n const [client, setClient] = useState<ApiClientModal | undefined>(undefined)\n const [workspaceStore, setWorkspaceStore] = useState<WorkspaceStore | undefined>(undefined)\n const [documentSlug, setDocumentSlug] = useState('')\n\n /** Small wrapper to set the documentSlug */\n const open = (payload: RoutePayload) => client?.open({ documentSlug, ...payload })\n\n useEffect(() => {\n let cancelled = false\n\n // Strip document-specific fields before passing to the modal constructor.\n // `url` and `content` are registered separately via workspaceStore.addDocument.\n const { url, content, ...modalOptions } = configuration ?? {}\n\n void getOrCreateApiClient(modalOptions)?.then((_client) => {\n if (cancelled || !_client) {\n return\n }\n\n // Compute the slug here so we can batch all three state updates into one render,\n // preventing a render where `client` is set but `documentSlug` is still ''.\n const slug = url || (content as { info?: { title?: string } })?.info?.title || ''\n\n setClient(_client.apiClient)\n setWorkspaceStore(_client.workspaceStore)\n setDocumentSlug(slug)\n\n if (slug && !documentDict[slug]) {\n documentDict[slug] = true\n void _client.workspaceStore.addDocument(\n content ? { name: slug, document: content } : { name: slug, url: url ?? '' },\n )\n }\n })\n\n return () => {\n cancelled = true\n }\n\n // Only run once per mount\n }, [])\n\n // When url or content changes after the client is already mounted, register the new document\n useEffect(() => {\n if (!client || !configuration || !workspaceStore) {\n return\n }\n\n const slug = configuration.url || (configuration.content as { info?: { title?: string } })?.info?.title || 'default'\n setDocumentSlug(slug)\n\n if (documentDict[slug]) {\n return\n }\n documentDict[slug] = true\n\n void workspaceStore.addDocument(\n configuration.content\n ? { name: slug, document: configuration.content }\n : { name: slug, url: configuration.url ?? '' },\n )\n }, [client, configuration?.url, configuration?.content, workspaceStore])\n\n return client\n ? {\n ...client,\n open,\n }\n : undefined\n}\n"],"mappings":";;;;;;;;;;AASA,IAAM,qBACJ,YACoC;CACpC,IAAI;AACJ,SAAQ,GAAG,SAAe;AACxB,aAAW,QAAQ,GAAG,KAAK,CAAC,OAAO,UAAU;AAC3C,YAAS,KAAA;AACT,SAAM;IACN;AACF,SAAO;;;;AAKX,IAAa,wBAAwB,wBACnC,OAAO,wCAAwC,MAAM,EAAE,2BAA2B,qBAAqB,CACxG;;AAGD,IAAa,6BAA6B,wBACxC,OAAO,kCAAkC,MAAM,EAAE,2BAA2B,sBAAsB,CAAC,CACpG;;AAGD,IAAa,gCAAgC,wBAC3C,OAAO,kCAAkC,MAAM,EAAE,8BAA8B,yBAAyB,CAAC,CAC1G;;;;;;;;;AAUD,IAAa,uBAAuB,kBAAkB,OAAO,UAA2C,EAAE,KAAK;CAC7G,MAAM,KAAK,SAAS,cAAc,MAAM;AACxC,IAAG,YAAY;AACf,UAAS,KAAK,YAAY,GAAG;AAE7B,KAAI;EACF,MAAM,CAAC,aAAa,gBAAgB,YAAY,MAAM,QAAQ,IAAI;GAChE,uBAAuB;GACvB,4BAA4B;GAC5B,+BAAA;GACD,CAAC;AAWF,SAAO;GAAE,WATS,YAAY;IAC5B;IACA;IACA;IACA;IAGD,CAAC;GAEkB;GAAgB;UAC7B,OAAO;AACd,KAAG,QAAQ;AACX,QAAM;;EAER;;;AC3DF,WAAW,sBAAsB;AACjC,WAAW,0CAA0C;AACrD,WAAW,wBAAwB;;AAanC,IAAM,eAAqC,EAAE;;;;;;;;;;;AAY7C,IAAa,gBAAgB,EAC3B,kBAC0B,EAAE,KAEb;CACf,MAAM,CAAC,QAAQ,aAAa,SAAqC,KAAA,EAAU;CAC3E,MAAM,CAAC,gBAAgB,qBAAqB,SAAqC,KAAA,EAAU;CAC3F,MAAM,CAAC,cAAc,mBAAmB,SAAS,GAAG;;CAGpD,MAAM,QAAQ,YAA0B,QAAQ,KAAK;EAAE;EAAc,GAAG;EAAS,CAAC;AAElF,iBAAgB;EACd,IAAI,YAAY;EAIhB,MAAM,EAAE,KAAK,SAAS,GAAG,iBAAiB,iBAAiB,EAAE;AAExD,uBAAqB,aAAa,EAAE,MAAM,YAAY;AACzD,OAAI,aAAa,CAAC,QAChB;GAKF,MAAM,OAAO,OAAQ,SAA2C,MAAM,SAAS;AAE/E,aAAU,QAAQ,UAAU;AAC5B,qBAAkB,QAAQ,eAAe;AACzC,mBAAgB,KAAK;AAErB,OAAI,QAAQ,CAAC,aAAa,OAAO;AAC/B,iBAAa,QAAQ;AAChB,YAAQ,eAAe,YAC1B,UAAU;KAAE,MAAM;KAAM,UAAU;KAAS,GAAG;KAAE,MAAM;KAAM,KAAK,OAAO;KAAI,CAC7E;;IAEH;AAEF,eAAa;AACX,eAAY;;IAIb,EAAE,CAAC;AAGN,iBAAgB;AACd,MAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,eAChC;EAGF,MAAM,OAAO,cAAc,OAAQ,cAAc,SAA2C,MAAM,SAAS;AAC3G,kBAAgB,KAAK;AAErB,MAAI,aAAa,MACf;AAEF,eAAa,QAAQ;AAEhB,iBAAe,YAClB,cAAc,UACV;GAAE,MAAM;GAAM,UAAU,cAAc;GAAS,GAC/C;GAAE,MAAM;GAAM,KAAK,cAAc,OAAO;GAAI,CACjD;IACA;EAAC;EAAQ,eAAe;EAAK,eAAe;EAAS;EAAe,CAAC;AAExE,QAAO,SACH;EACE,GAAG;EACH;EACD,GACD,KAAA"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/** Lazy load the client modal creator */
|
|
2
|
+
export declare const getClientModalCreator: () => Promise<({ el, eventBus, mountOnInitialize, plugins, workspaceStore, options, }: {
|
|
3
|
+
el: HTMLElement | null;
|
|
4
|
+
mountOnInitialize?: boolean;
|
|
5
|
+
eventBus?: import("@scalar/workspace-store/events").WorkspaceEventBus;
|
|
6
|
+
workspaceStore: import("@scalar/workspace-store/client").WorkspaceStore;
|
|
7
|
+
plugins?: import("@scalar/oas-utils/helpers").ClientPlugin[];
|
|
8
|
+
options?: import("vue").MaybeRefOrGetter<Partial<Pick<import("@scalar/types/api-reference").ApiReferenceConfigurationRaw, "authentication" | "baseServerURL" | "hideClientButton" | "servers" | "hiddenClients">>>;
|
|
9
|
+
}) => import("@scalar/api-client/v2/features/modal").ApiClientModal>;
|
|
10
|
+
/** Module-scoped singleton workspace store (lazy-loaded on first use). */
|
|
11
|
+
export declare const getWorkspaceStoreSingleton: () => Promise<import("@scalar/workspace-store/client").WorkspaceStore>;
|
|
12
|
+
/** Module-scoped singleton workspace event bus (lazy-loaded on first use). */
|
|
13
|
+
export declare const getWorkspaceEventBusSingleton: () => Promise<import("@scalar/workspace-store/events").WorkspaceEventBus>;
|
|
14
|
+
/**
|
|
15
|
+
* Lazily creates the singleton Vue app, mounts it as the last child of document.body,
|
|
16
|
+
* and returns the controller. Subsequent calls return the same promise.
|
|
17
|
+
*
|
|
18
|
+
* Only modal-level options (e.g. `proxyUrl`) are accepted here. Document-specific fields
|
|
19
|
+
* (`url`, `content`) must be registered via `workspaceStore.addDocument` after the client
|
|
20
|
+
* is ready — they are not part of the modal constructor.
|
|
21
|
+
*/
|
|
22
|
+
export declare const getOrCreateApiClient: (options?: Partial<{
|
|
23
|
+
hideClientButton: boolean;
|
|
24
|
+
showSidebar: boolean;
|
|
25
|
+
showDeveloperTools: "never" | "always" | "localhost";
|
|
26
|
+
showToolbar: "never" | "always" | "localhost";
|
|
27
|
+
operationTitleSource: "summary" | "path";
|
|
28
|
+
theme: "default" | "alternate" | "moon" | "purple" | "solarized" | "bluePlanet" | "deepSpace" | "saturn" | "kepler" | "elysiajs" | "fastify" | "mars" | "laserwave" | "none";
|
|
29
|
+
persistAuth: boolean;
|
|
30
|
+
telemetry: boolean;
|
|
31
|
+
externalUrls: {
|
|
32
|
+
dashboardUrl: string;
|
|
33
|
+
registryUrl: string;
|
|
34
|
+
proxyUrl: string;
|
|
35
|
+
apiBaseUrl: string;
|
|
36
|
+
};
|
|
37
|
+
authentication?: any;
|
|
38
|
+
baseServerURL?: string | undefined;
|
|
39
|
+
proxyUrl?: string | undefined;
|
|
40
|
+
oauth2RedirectUri?: string | undefined;
|
|
41
|
+
searchHotKey?: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | undefined;
|
|
42
|
+
servers?: any[] | undefined;
|
|
43
|
+
_integration?: "elysiajs" | "fastify" | "adonisjs" | "astro" | "docusaurus" | "dotnet" | "express" | "fastapi" | "go" | "hono" | "html" | "laravel" | "litestar" | "nestjs" | "nextjs" | "nitro" | "nuxt" | "platformatic" | "react" | "rust" | "svelte" | "vue" | null | undefined;
|
|
44
|
+
onRequestSent?: import("zod/v4/core").$InferOuterFunctionType<import("zod").ZodTuple<readonly [import("zod").ZodString], null>, import("zod").ZodVoid> | undefined;
|
|
45
|
+
plugins?: import("zod/v4/core").$InferOuterFunctionType<import("zod").ZodTuple<readonly [], null>, import("zod").ZodObject<{
|
|
46
|
+
name: import("zod").ZodString;
|
|
47
|
+
views: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
48
|
+
"request.section": import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
|
|
49
|
+
title: import("zod").ZodOptional<import("zod").ZodString>;
|
|
50
|
+
component: import("zod").ZodUnknown;
|
|
51
|
+
props: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
|
|
52
|
+
}, import("zod/v4/core").$strip>>>;
|
|
53
|
+
"response.section": import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
|
|
54
|
+
title: import("zod").ZodOptional<import("zod").ZodString>;
|
|
55
|
+
component: import("zod").ZodUnknown;
|
|
56
|
+
props: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
|
|
57
|
+
}, import("zod/v4/core").$strip>>>;
|
|
58
|
+
}, import("zod/v4/core").$strip>>;
|
|
59
|
+
hooks: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
60
|
+
onBeforeRequest: import("zod").ZodOptional<import("zod").ZodFunction<import("zod").ZodTuple<readonly [import("zod").ZodObject<{
|
|
61
|
+
request: import("zod").ZodAny;
|
|
62
|
+
}, import("zod/v4/core").$strip>], null>, import("zod/v4/core").$ZodFunctionOut>>;
|
|
63
|
+
onResponseReceived: import("zod").ZodOptional<import("zod").ZodFunction<import("zod").ZodTuple<readonly [import("zod").ZodObject<{
|
|
64
|
+
response: import("zod").ZodCustom<Response, Response>;
|
|
65
|
+
operation: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>;
|
|
66
|
+
}, import("zod/v4/core").$strip>], null>, import("zod/v4/core").$ZodFunctionOut>>;
|
|
67
|
+
}, import("zod/v4/core").$strip>>;
|
|
68
|
+
}, import("zod/v4/core").$strip>>[] | undefined;
|
|
69
|
+
default?: boolean | undefined;
|
|
70
|
+
url?: string | undefined;
|
|
71
|
+
content?: string | Record<string, any> | import("zod/v4/core").$InferOuterFunctionType<import("zod").ZodTuple<readonly [], null>, import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>> | null | undefined;
|
|
72
|
+
title?: string | undefined;
|
|
73
|
+
slug?: string | undefined;
|
|
74
|
+
spec?: {
|
|
75
|
+
url?: string | undefined;
|
|
76
|
+
content?: string | Record<string, any> | import("zod/v4/core").$InferOuterFunctionType<import("zod").ZodTuple<readonly [], null>, import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>> | null | undefined;
|
|
77
|
+
} | undefined;
|
|
78
|
+
agent?: {
|
|
79
|
+
key?: string | undefined;
|
|
80
|
+
disabled?: boolean | undefined;
|
|
81
|
+
hideAddApi?: boolean | undefined;
|
|
82
|
+
} | undefined;
|
|
83
|
+
}> | undefined) => Promise<{
|
|
84
|
+
apiClient: import("@scalar/api-client/v2/features/modal").ApiClientModal;
|
|
85
|
+
workspaceStore: import("@scalar/workspace-store/client").WorkspaceStore;
|
|
86
|
+
}>;
|
|
87
|
+
//# sourceMappingURL=lazy-load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-load.d.ts","sourceRoot":"","sources":["../src/lazy-load.ts"],"names":[],"mappings":"AAsBA,yCAAyC;AACzC,eAAO,MAAM,qBAAqB;;;;;;;oEAEjC,CAAA;AAED,0EAA0E;AAC1E,eAAO,MAAM,0BAA0B,wEAEtC,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,2EAEzC,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0B/B,CAAA"}
|
package/dist/style.css
CHANGED
|
@@ -1014,6 +1014,7 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
1014
1014
|
--scalar-text-decoration-hover: underline;
|
|
1015
1015
|
--scalar-link-font-weight: inherit;
|
|
1016
1016
|
--scalar-sidebar-indent: 20px;
|
|
1017
|
+
--scalar-sidebar-padding: 12px;
|
|
1017
1018
|
}
|
|
1018
1019
|
|
|
1019
1020
|
.dark-mode {
|
|
@@ -1436,6 +1437,15 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
1436
1437
|
width: 50dvw !important;
|
|
1437
1438
|
}
|
|
1438
1439
|
}
|
|
1440
|
+
@keyframes border-bottom {
|
|
1441
|
+
from {
|
|
1442
|
+
border-bottom-width: 0;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
to {
|
|
1446
|
+
border-bottom-width: var(--scalar-border-width);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1439
1449
|
@property --tw-font-weight {
|
|
1440
1450
|
syntax: "*";
|
|
1441
1451
|
inherits: false
|
|
@@ -2935,6 +2945,11 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
2935
2945
|
max-height: 3.40282e38px;
|
|
2936
2946
|
display: flex;
|
|
2937
2947
|
}
|
|
2948
|
+
.animate-sidebar-border-bottom {
|
|
2949
|
+
animation: forwards border-bottom;
|
|
2950
|
+
animation-timeline: scroll();
|
|
2951
|
+
animation-range-end: 1px;
|
|
2952
|
+
}
|
|
2938
2953
|
.group\/sidebar-section:first-of-type > .group\/spacer-before, .group\/sidebar-section:last-of-type > .group\/spacer-after {
|
|
2939
2954
|
height: 0;
|
|
2940
2955
|
}
|
|
@@ -3144,6 +3159,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
3144
3159
|
.scalar-app .top-\(--nested-items-offset\)\! {
|
|
3145
3160
|
top: var(--nested-items-offset) !important;
|
|
3146
3161
|
}
|
|
3162
|
+
.scalar-app .top-\(--scalar-sidebar-sticky-offset\,0\) {
|
|
3163
|
+
top: var(--scalar-sidebar-sticky-offset, 0);
|
|
3164
|
+
}
|
|
3147
3165
|
.scalar-app .top-0\.5 {
|
|
3148
3166
|
top: 2px;
|
|
3149
3167
|
}
|
|
@@ -3231,6 +3249,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
3231
3249
|
max-width: 96rem;
|
|
3232
3250
|
}
|
|
3233
3251
|
}
|
|
3252
|
+
.scalar-app .-m-\(--scalar-sidebar-padding\) {
|
|
3253
|
+
margin: calc(var(--scalar-sidebar-padding) * -1);
|
|
3254
|
+
}
|
|
3234
3255
|
.scalar-app .-m-1 {
|
|
3235
3256
|
margin: -4px;
|
|
3236
3257
|
}
|
|
@@ -3358,6 +3379,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
3358
3379
|
.scalar-app .min-h-header {
|
|
3359
3380
|
min-height: 48px;
|
|
3360
3381
|
}
|
|
3382
|
+
.scalar-app .w-\(--scalar-sidebar-width\) {
|
|
3383
|
+
width: var(--scalar-sidebar-width);
|
|
3384
|
+
}
|
|
3361
3385
|
.scalar-app .w-12 {
|
|
3362
3386
|
width: 48px;
|
|
3363
3387
|
}
|
|
@@ -3543,6 +3567,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
3543
3567
|
.scalar-app .border-sidebar-border-search {
|
|
3544
3568
|
border-color: var(--scalar-sidebar-search-border-color, var(--scalar-border-color));
|
|
3545
3569
|
}
|
|
3570
|
+
.scalar-app .border-b-sidebar-border {
|
|
3571
|
+
border-bottom-color: var(--scalar-sidebar-border-color, var(--scalar-border-color));
|
|
3572
|
+
}
|
|
3546
3573
|
.scalar-app .bg-\(--bg-light\) {
|
|
3547
3574
|
background-color: var(--bg-light);
|
|
3548
3575
|
}
|
|
@@ -3651,6 +3678,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
3651
3678
|
-webkit-mask-repeat: repeat;
|
|
3652
3679
|
mask-repeat: repeat;
|
|
3653
3680
|
}
|
|
3681
|
+
.scalar-app .p-\(--scalar-sidebar-padding\) {
|
|
3682
|
+
padding: var(--scalar-sidebar-padding);
|
|
3683
|
+
}
|
|
3654
3684
|
.scalar-app .p-0\.25 {
|
|
3655
3685
|
padding: 1px;
|
|
3656
3686
|
}
|
|
@@ -3862,11 +3892,11 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
3862
3892
|
.scalar-app .placeholder\:font-\[inherit\]::placeholder {
|
|
3863
3893
|
font-family: inherit;
|
|
3864
3894
|
}
|
|
3865
|
-
.scalar-app .first\:rounded-t-\[inherit\]:first-child
|
|
3895
|
+
.scalar-app .first\:rounded-t-\[inherit\]:first-child {
|
|
3866
3896
|
border-top-left-radius: inherit;
|
|
3867
3897
|
border-top-right-radius: inherit;
|
|
3868
3898
|
}
|
|
3869
|
-
.scalar-app .last\:rounded-b-\[inherit\]:last-child
|
|
3899
|
+
.scalar-app .last\:rounded-b-\[inherit\]:last-child {
|
|
3870
3900
|
border-bottom-right-radius: inherit;
|
|
3871
3901
|
border-bottom-left-radius: inherit;
|
|
3872
3902
|
}
|
|
@@ -4042,6 +4072,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
4042
4072
|
inherits: false;
|
|
4043
4073
|
initial-value: "";
|
|
4044
4074
|
}
|
|
4075
|
+
:where(.scalar-app) [class*="rotate-"], :where(.scalar-app) [class*="translate-"], :where(.scalar-app) [class*="scale-"] {
|
|
4076
|
+
transform: none;
|
|
4077
|
+
}
|
|
4045
4078
|
.scalar-app .pointer-events-auto {
|
|
4046
4079
|
pointer-events: auto;
|
|
4047
4080
|
}
|
|
@@ -4727,12 +4760,18 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
4727
4760
|
.scalar-app .min-h-20 {
|
|
4728
4761
|
min-height: 80px;
|
|
4729
4762
|
}
|
|
4763
|
+
.scalar-app .min-h-\[4rem\] {
|
|
4764
|
+
min-height: 4rem;
|
|
4765
|
+
}
|
|
4730
4766
|
.scalar-app .min-h-\[64px\] {
|
|
4731
4767
|
min-height: 64px;
|
|
4732
4768
|
}
|
|
4733
4769
|
.scalar-app .min-h-\[65px\] {
|
|
4734
4770
|
min-height: 65px;
|
|
4735
4771
|
}
|
|
4772
|
+
.scalar-app .min-h-\[300px\] {
|
|
4773
|
+
min-height: 300px;
|
|
4774
|
+
}
|
|
4736
4775
|
.scalar-app .min-h-\[calc\(1rem\*4\)\] {
|
|
4737
4776
|
min-height: 4rem;
|
|
4738
4777
|
}
|
|
@@ -4757,6 +4796,9 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
4757
4796
|
.scalar-app .w-1\/2 {
|
|
4758
4797
|
width: 50%;
|
|
4759
4798
|
}
|
|
4799
|
+
.scalar-app .w-2 {
|
|
4800
|
+
width: 8px;
|
|
4801
|
+
}
|
|
4760
4802
|
.scalar-app .w-2\.5 {
|
|
4761
4803
|
width: 10px;
|
|
4762
4804
|
}
|
|
@@ -5342,7 +5384,7 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
5342
5384
|
.scalar-app .border-\(--scalar-color-alert\) {
|
|
5343
5385
|
border-color: var(--scalar-color-alert);
|
|
5344
5386
|
}
|
|
5345
|
-
.scalar-app .border-border {
|
|
5387
|
+
.scalar-app .border-\[var\(--scalar-border-color\)\], .scalar-app .border-border {
|
|
5346
5388
|
border-color: var(--scalar-border-color);
|
|
5347
5389
|
}
|
|
5348
5390
|
.scalar-app .border-c-1 {
|
|
@@ -5379,6 +5421,18 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
5379
5421
|
.scalar-app .bg-\(--scalar-background-alert\) {
|
|
5380
5422
|
background-color: var(--scalar-background-alert);
|
|
5381
5423
|
}
|
|
5424
|
+
.scalar-app .bg-\[var\(--scalar-background-1\)\] {
|
|
5425
|
+
background-color: var(--scalar-background-1);
|
|
5426
|
+
}
|
|
5427
|
+
.scalar-app .bg-\[var\(--scalar-background-2\)\] {
|
|
5428
|
+
background-color: var(--scalar-background-2);
|
|
5429
|
+
}
|
|
5430
|
+
.scalar-app .bg-\[var\(--scalar-background-3\)\] {
|
|
5431
|
+
background-color: var(--scalar-background-3);
|
|
5432
|
+
}
|
|
5433
|
+
.scalar-app .bg-\[var\(--scalar-color-green\)\] {
|
|
5434
|
+
background-color: var(--scalar-color-green);
|
|
5435
|
+
}
|
|
5382
5436
|
.scalar-app .bg-b-1 {
|
|
5383
5437
|
background-color: var(--scalar-background-1);
|
|
5384
5438
|
}
|
|
@@ -6036,6 +6090,10 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
6036
6090
|
--tw-shadow: 0 -8px 0 8px var(--tw-shadow-color, var(--scalar-background-1)), 0 0 8px 8px var(--tw-shadow-color, var(--scalar-background-1));
|
|
6037
6091
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
6038
6092
|
}
|
|
6093
|
+
.scalar-app .shadow-\[var\(--scalar-shadow-1\)\] {
|
|
6094
|
+
--tw-shadow: var(--scalar-shadow-1);
|
|
6095
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
6096
|
+
}
|
|
6039
6097
|
.scalar-app .shadow-border {
|
|
6040
6098
|
--tw-shadow: inset 0 0 0 var(--tw-shadow-color, var(--scalar-border-width)) var(--scalar-border-color);
|
|
6041
6099
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -6096,6 +6154,11 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
6096
6154
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
6097
6155
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
6098
6156
|
}
|
|
6157
|
+
.scalar-app .transition-all {
|
|
6158
|
+
transition-property: all;
|
|
6159
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
6160
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
6161
|
+
}
|
|
6099
6162
|
.scalar-app .transition-colors {
|
|
6100
6163
|
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
|
|
6101
6164
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
@@ -6479,6 +6542,10 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
6479
6542
|
border-color: inherit;
|
|
6480
6543
|
}
|
|
6481
6544
|
|
|
6545
|
+
.scalar-app .hover\:bg-\[var\(--scalar-background-3\)\]:hover {
|
|
6546
|
+
background-color: var(--scalar-background-3);
|
|
6547
|
+
}
|
|
6548
|
+
|
|
6482
6549
|
.scalar-app .hover\:bg-b-2:hover, .scalar-app .hover\:bg-b-2\/40:hover {
|
|
6483
6550
|
background-color: var(--scalar-background-2);
|
|
6484
6551
|
}
|
|
@@ -7359,51 +7426,51 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7359
7426
|
.description[data-v-1b7a32a4] .markdown > *:first-child {
|
|
7360
7427
|
margin-top: 0;
|
|
7361
7428
|
}
|
|
7362
|
-
[data-v-
|
|
7429
|
+
[data-v-0ec7147f] .cm-editor {
|
|
7363
7430
|
height: 100%;
|
|
7364
7431
|
outline: none;
|
|
7365
7432
|
width: 100%;
|
|
7366
7433
|
}
|
|
7367
|
-
[data-v-
|
|
7434
|
+
[data-v-0ec7147f] .cm-line {
|
|
7368
7435
|
padding: 0;
|
|
7369
7436
|
}
|
|
7370
|
-
[data-v-
|
|
7437
|
+
[data-v-0ec7147f] .cm-content {
|
|
7371
7438
|
padding: 0;
|
|
7372
7439
|
display: flex;
|
|
7373
7440
|
align-items: center;
|
|
7374
7441
|
font-size: var(--scalar-small);
|
|
7375
7442
|
}
|
|
7376
|
-
.scroll-timeline-x[data-v-
|
|
7443
|
+
.scroll-timeline-x[data-v-0ec7147f] {
|
|
7377
7444
|
scroll-timeline: --scroll-timeline x;
|
|
7378
7445
|
/* Firefox supports */
|
|
7379
7446
|
scroll-timeline: --scroll-timeline horizontal;
|
|
7380
7447
|
-ms-overflow-style: none; /* IE and Edge */
|
|
7381
7448
|
}
|
|
7382
|
-
.scroll-timeline-x-hidden[data-v-
|
|
7449
|
+
.scroll-timeline-x-hidden[data-v-0ec7147f] {
|
|
7383
7450
|
overflow-x: auto;
|
|
7384
7451
|
}
|
|
7385
|
-
.scroll-timeline-x-hidden[data-v-
|
|
7452
|
+
.scroll-timeline-x-hidden[data-v-0ec7147f] .cm-scroller {
|
|
7386
7453
|
scrollbar-width: none;
|
|
7387
7454
|
-ms-overflow-style: none;
|
|
7388
7455
|
padding-right: 20px;
|
|
7389
7456
|
overflow: auto;
|
|
7390
7457
|
}
|
|
7391
|
-
.scroll-timeline-x-hidden[data-v-
|
|
7458
|
+
.scroll-timeline-x-hidden[data-v-0ec7147f]::-webkit-scrollbar {
|
|
7392
7459
|
width: 0;
|
|
7393
7460
|
height: 0;
|
|
7394
7461
|
display: none;
|
|
7395
7462
|
}
|
|
7396
|
-
.scroll-timeline-x-hidden[data-v-
|
|
7463
|
+
.scroll-timeline-x-hidden[data-v-0ec7147f] .cm-scroller::-webkit-scrollbar {
|
|
7397
7464
|
width: 0;
|
|
7398
7465
|
height: 0;
|
|
7399
7466
|
display: none;
|
|
7400
7467
|
}
|
|
7401
|
-
.scroll-timeline-x-address[data-v-
|
|
7468
|
+
.scroll-timeline-x-address[data-v-0ec7147f] {
|
|
7402
7469
|
line-height: 27px;
|
|
7403
7470
|
scrollbar-width: none; /* Firefox */
|
|
7404
7471
|
}
|
|
7405
7472
|
/* make clickable are to left of send button */
|
|
7406
|
-
.scroll-timeline-x-address[data-v-
|
|
7473
|
+
.scroll-timeline-x-address[data-v-0ec7147f]:after {
|
|
7407
7474
|
content: '';
|
|
7408
7475
|
position: absolute;
|
|
7409
7476
|
height: 100%;
|
|
@@ -7411,24 +7478,24 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7411
7478
|
right: 0;
|
|
7412
7479
|
cursor: text;
|
|
7413
7480
|
}
|
|
7414
|
-
.scroll-timeline-x-address[data-v-
|
|
7481
|
+
.scroll-timeline-x-address[data-v-0ec7147f]:empty:before {
|
|
7415
7482
|
content: 'Enter URL or cURL request';
|
|
7416
7483
|
color: var(--scalar-color-3);
|
|
7417
7484
|
pointer-events: none;
|
|
7418
7485
|
}
|
|
7419
|
-
.fade-left[data-v-
|
|
7420
|
-
.fade-right[data-v-
|
|
7486
|
+
.fade-left[data-v-0ec7147f],
|
|
7487
|
+
.fade-right[data-v-0ec7147f] {
|
|
7421
7488
|
content: '';
|
|
7422
7489
|
position: sticky;
|
|
7423
7490
|
height: 100%;
|
|
7424
|
-
animation-name: fadein-
|
|
7491
|
+
animation-name: fadein-0ec7147f;
|
|
7425
7492
|
animation-duration: 1ms;
|
|
7426
7493
|
animation-direction: reverse;
|
|
7427
7494
|
animation-timeline: --scroll-timeline;
|
|
7428
7495
|
pointer-events: none;
|
|
7429
7496
|
z-index: 1;
|
|
7430
7497
|
}
|
|
7431
|
-
.fade-left[data-v-
|
|
7498
|
+
.fade-left[data-v-0ec7147f] {
|
|
7432
7499
|
background: linear-gradient(
|
|
7433
7500
|
-90deg,
|
|
7434
7501
|
color-mix(in srgb, var(--scalar-address-bar-bg), transparent 100%) 0%,
|
|
@@ -7439,7 +7506,7 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7439
7506
|
min-width: 6px;
|
|
7440
7507
|
animation-direction: normal;
|
|
7441
7508
|
}
|
|
7442
|
-
.fade-right[data-v-
|
|
7509
|
+
.fade-right[data-v-0ec7147f] {
|
|
7443
7510
|
background: linear-gradient(
|
|
7444
7511
|
90deg,
|
|
7445
7512
|
color-mix(in srgb, var(--scalar-address-bar-bg), transparent 100%) 0%,
|
|
@@ -7449,7 +7516,7 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7449
7516
|
right: -1px;
|
|
7450
7517
|
min-width: 24px;
|
|
7451
7518
|
}
|
|
7452
|
-
@keyframes fadein-
|
|
7519
|
+
@keyframes fadein-0ec7147f {
|
|
7453
7520
|
0% {
|
|
7454
7521
|
opacity: 0;
|
|
7455
7522
|
}
|
|
@@ -7457,7 +7524,7 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7457
7524
|
opacity: 1;
|
|
7458
7525
|
}
|
|
7459
7526
|
}
|
|
7460
|
-
.address-bar-bg-states[data-v-
|
|
7527
|
+
.address-bar-bg-states[data-v-0ec7147f] {
|
|
7461
7528
|
--scalar-address-bar-bg: color-mix(
|
|
7462
7529
|
in srgb,
|
|
7463
7530
|
var(--scalar-background-1),
|
|
@@ -7465,14 +7532,14 @@ input[data-v-c1a50a6e]::placeholder {
|
|
|
7465
7532
|
);
|
|
7466
7533
|
background: var(--scalar-address-bar-bg);
|
|
7467
7534
|
}
|
|
7468
|
-
.address-bar-bg-states[data-v-
|
|
7535
|
+
.address-bar-bg-states[data-v-0ec7147f]:has(.cm-focused) {
|
|
7469
7536
|
--scalar-address-bar-bg: var(--scalar-background-1);
|
|
7470
7537
|
border-color: var(--scalar-border-color);
|
|
7471
7538
|
outline-width: 1px;
|
|
7472
7539
|
outline-style: solid;
|
|
7473
7540
|
}
|
|
7474
|
-
.address-bar-bg-states:has(.cm-focused) .fade-left[data-v-
|
|
7475
|
-
.address-bar-bg-states:has(.cm-focused) .fade-right[data-v-
|
|
7541
|
+
.address-bar-bg-states:has(.cm-focused) .fade-left[data-v-0ec7147f],
|
|
7542
|
+
.address-bar-bg-states:has(.cm-focused) .fade-right[data-v-0ec7147f] {
|
|
7476
7543
|
--scalar-address-bar-bg: var(--scalar-background-1);
|
|
7477
7544
|
}
|
|
7478
7545
|
.app-exit-button[data-v-0e03d0d8] {
|
|
@@ -7881,27 +7948,27 @@ to {
|
|
|
7881
7948
|
.dark-mode .download-app-button[data-v-9b609275]:hover {
|
|
7882
7949
|
background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.1));
|
|
7883
7950
|
}
|
|
7884
|
-
.empty-sidebar-item-content[data-v-
|
|
7951
|
+
.empty-sidebar-item-content[data-v-96a54993] {
|
|
7885
7952
|
display: none;
|
|
7886
7953
|
}
|
|
7887
|
-
.empty-sidebar-item .empty-sidebar-item-content[data-v-
|
|
7954
|
+
.empty-sidebar-item .empty-sidebar-item-content[data-v-96a54993] {
|
|
7888
7955
|
display: block;
|
|
7889
7956
|
}
|
|
7890
|
-
.rabbitjump[data-v-
|
|
7957
|
+
.rabbitjump[data-v-96a54993] {
|
|
7891
7958
|
opacity: 0;
|
|
7892
7959
|
}
|
|
7893
|
-
.empty-sidebar-item:hover .rabbitjump[data-v-
|
|
7960
|
+
.empty-sidebar-item:hover .rabbitjump[data-v-96a54993] {
|
|
7894
7961
|
opacity: 1;
|
|
7895
|
-
animation: rabbitAnimation-
|
|
7962
|
+
animation: rabbitAnimation-96a54993 0.5s steps(1) infinite;
|
|
7896
7963
|
}
|
|
7897
|
-
.empty-sidebar-item:hover .rabbitsit[data-v-
|
|
7964
|
+
.empty-sidebar-item:hover .rabbitsit[data-v-96a54993] {
|
|
7898
7965
|
opacity: 0;
|
|
7899
|
-
animation: rabbitAnimation2-
|
|
7966
|
+
animation: rabbitAnimation2-96a54993 0.5s steps(1) infinite;
|
|
7900
7967
|
}
|
|
7901
|
-
.empty-sidebar-item:hover .rabbit-ascii[data-v-
|
|
7902
|
-
animation: rabbitRun-
|
|
7968
|
+
.empty-sidebar-item:hover .rabbit-ascii[data-v-96a54993] {
|
|
7969
|
+
animation: rabbitRun-96a54993 8s infinite linear;
|
|
7903
7970
|
}
|
|
7904
|
-
@keyframes rabbitRun-
|
|
7971
|
+
@keyframes rabbitRun-96a54993 {
|
|
7905
7972
|
0% {
|
|
7906
7973
|
transform: translate3d(0, 0, 0);
|
|
7907
7974
|
}
|
|
@@ -7921,7 +7988,7 @@ to {
|
|
|
7921
7988
|
transform: translate3d(0, 0, 0);
|
|
7922
7989
|
}
|
|
7923
7990
|
}
|
|
7924
|
-
@keyframes rabbitAnimation-
|
|
7991
|
+
@keyframes rabbitAnimation-96a54993 {
|
|
7925
7992
|
0%,
|
|
7926
7993
|
100% {
|
|
7927
7994
|
opacity: 1;
|
|
@@ -7930,7 +7997,7 @@ to {
|
|
|
7930
7997
|
opacity: 0;
|
|
7931
7998
|
}
|
|
7932
7999
|
}
|
|
7933
|
-
@keyframes rabbitAnimation2-
|
|
8000
|
+
@keyframes rabbitAnimation2-96a54993 {
|
|
7934
8001
|
0%,
|
|
7935
8002
|
100% {
|
|
7936
8003
|
opacity: 0;
|
|
@@ -9030,5 +9097,8 @@ to {
|
|
|
9030
9097
|
justify-content: flex-end;
|
|
9031
9098
|
gap: 1rem;
|
|
9032
9099
|
}
|
|
9100
|
+
.document-scripts-editors__container[data-v-8c8fa790] {
|
|
9101
|
+
min-height: 300px;
|
|
9102
|
+
}
|
|
9033
9103
|
/*$vite$:1*/
|
|
9034
9104
|
/*$vite$:1*/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ApiClientModal, RoutePayload } from '@scalar/api-client/v2/features/modal';
|
|
2
|
+
import type { ApiClientConfiguration } from '@scalar/types/api-reference';
|
|
3
|
+
import './style.css';
|
|
4
|
+
/** We don't really need all of the content types so we just accept an object instead */
|
|
5
|
+
export type ApiClientConfigurationReact = Partial<Omit<ApiClientConfiguration, 'content' | 'url'> & {
|
|
6
|
+
content?: Record<string, unknown>;
|
|
7
|
+
url?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type UseApiClientModalProps = {
|
|
10
|
+
/** Configuration for the Api Client (url or inline content) */
|
|
11
|
+
configuration?: ApiClientConfigurationReact;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Returns the singleton Api Client
|
|
15
|
+
*
|
|
16
|
+
* On first call the Vue app is lazily created and appended to document.body where it
|
|
17
|
+
* lives for the lifetime of the page — it is never unmounted, so it survives client-side
|
|
18
|
+
* navigation without losing state.
|
|
19
|
+
*
|
|
20
|
+
* Subsequent calls from any component share the same instance of the client but can use the same
|
|
21
|
+
* or different documents
|
|
22
|
+
*/
|
|
23
|
+
export declare const useApiClient: ({ configuration, }?: UseApiClientModalProps) => (Omit<ApiClientModal, "open"> & {
|
|
24
|
+
open: (payload: RoutePayload) => void;
|
|
25
|
+
}) | undefined;
|
|
26
|
+
//# sourceMappingURL=use-api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-api-client.d.ts","sourceRoot":"","sources":["../src/use-api-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAA;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAGzE,OAAO,aAAa,CAAA;AAUpB,wFAAwF;AACxF,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAC/C,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CACtG,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,+DAA+D;IAC/D,aAAa,CAAC,EAAE,2BAA2B,CAAA;CAC5C,CAAA;AAKD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,qBAE1B,sBAA2B,KAC1B,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAA;CAAE,CAAC,GAC1E,SAsEH,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.setup.d.ts","sourceRoot":"","sources":["../src/vitest.setup.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAA"}
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"testing",
|
|
20
20
|
"react"
|
|
21
21
|
],
|
|
22
|
-
"version": "
|
|
22
|
+
"version": "2.0.1",
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=22"
|
|
25
25
|
},
|
|
@@ -39,17 +39,23 @@
|
|
|
39
39
|
"CHANGELOG.md"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@scalar/api-client": "2.
|
|
43
|
-
"@scalar/types": "0.
|
|
42
|
+
"@scalar/api-client": "2.43.0",
|
|
43
|
+
"@scalar/types": "0.8.0",
|
|
44
|
+
"@scalar/workspace-store": "0.45.0"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
47
|
+
"@testing-library/dom": "^10.4.1",
|
|
48
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
49
|
+
"@testing-library/react": "^16.3.2",
|
|
46
50
|
"@types/react": "^19.2.7",
|
|
47
51
|
"@types/react-dom": "^19.2.3",
|
|
48
52
|
"@vitejs/plugin-react": "6.0.1",
|
|
53
|
+
"jsdom": "^29.0.1",
|
|
49
54
|
"react": "^19.2.3",
|
|
50
55
|
"react-dom": "^19.2.3",
|
|
51
56
|
"rollup-preserve-directives": "^1.1.1",
|
|
52
|
-
"vite": "8.0.0"
|
|
57
|
+
"vite": "8.0.0",
|
|
58
|
+
"vitest": "^4.1.2"
|
|
53
59
|
},
|
|
54
60
|
"peerDependencies": {
|
|
55
61
|
"react": "^18.0.0 || ^19.0.0"
|
|
@@ -57,6 +63,7 @@
|
|
|
57
63
|
"scripts": {
|
|
58
64
|
"build": "vite build && vue-tsc -p tsconfig.build.json",
|
|
59
65
|
"dev": "vite ./playground -c ./vite.config.ts",
|
|
66
|
+
"test": "vitest --run",
|
|
60
67
|
"types:check": "vue-tsc --noEmit"
|
|
61
68
|
}
|
|
62
69
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { ApiClient } from '@scalar/api-client/layouts/Modal';
|
|
2
|
-
import type { OpenClientPayload } from '@scalar/api-client/libs';
|
|
3
|
-
import type { ApiClientConfiguration } from '@scalar/types/api-reference';
|
|
4
|
-
import type { PropsWithChildren } from 'react';
|
|
5
|
-
export type { OpenClientPayload };
|
|
6
|
-
import './style.css';
|
|
7
|
-
type Props = PropsWithChildren<{
|
|
8
|
-
/** Choose a request to initially route to */
|
|
9
|
-
initialRequest?: OpenClientPayload;
|
|
10
|
-
/** Configuration for the Api Client */
|
|
11
|
-
configuration?: Partial<ApiClientConfiguration>;
|
|
12
|
-
}>;
|
|
13
|
-
/**
|
|
14
|
-
* Api Client Modal React
|
|
15
|
-
*
|
|
16
|
-
* Provider which mounts the Scalar Api Client Modal vue app.
|
|
17
|
-
* Rebuilt to support multiple instances when using a unique spec.url
|
|
18
|
-
*/
|
|
19
|
-
export declare const ApiClientModalProvider: ({ children, initialRequest, configuration }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
-
export declare const useApiClientModal: () => ApiClient | null;
|
|
21
|
-
//# sourceMappingURL=ApiClientModalProvider.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApiClientModalProvider.d.ts","sourceRoot":"","sources":["../src/ApiClientModalProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAG9C,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAIjC,OAAO,aAAa,CAAA;AAIpB,KAAK,KAAK,GAAG,iBAAiB,CAAC;IAC7B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,iBAAiB,CAAA;IAClC,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;CAChD,CAAC,CAAA;AAQF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,6CAAkD,KAAK,4CA4D7F,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAO,SAAS,GAAG,IAAyC,CAAA"}
|
package/dist/client-store.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ApiClient, createApiClientModal } from '@scalar/api-client/layouts/Modal';
|
|
2
|
-
export declare const clientStore: {
|
|
3
|
-
getSnapshot: () => {
|
|
4
|
-
createClient: typeof createApiClientModal | null;
|
|
5
|
-
clientDict: Record<string, ApiClient>;
|
|
6
|
-
};
|
|
7
|
-
subscribe: (listener: () => void) => () => boolean;
|
|
8
|
-
setCreateClient: (clientFactory: typeof createApiClientModal) => void;
|
|
9
|
-
addClient: (url: string, client: ApiClient) => void;
|
|
10
|
-
removeClient: (url: string) => void;
|
|
11
|
-
};
|
|
12
|
-
//# sourceMappingURL=client-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-store.d.ts","sourceRoot":"","sources":["../src/client-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AA+CvF,eAAO,MAAM,WAAW;;sBAtCA,OAAO,oBAAoB,GAAG,IAAI;oBACtC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;;0BAOhB,MAAM,IAAI;qCAYC,OAAO,oBAAoB;qBAM3C,MAAM,UAAU,SAAS;wBAMtB,MAAM;CAYhC,CAAA"}
|