@scalar/api-client
Version:
the open source API testing client
190 lines (189 loc) • 6.78 kB
JavaScript
import { CLIENT_CONFIGURATION_SYMBOL as N } from "../hooks/useClientConfig.js";
import { LAYOUT_SYMBOL as F } from "../hooks/useLayout.js";
import { createSidebarState as j, SIDEBAR_SYMBOL as W } from "../hooks/useSidebar.js";
import { getRequestUidByPathMethod as K } from "./get-request-uid-by-path-method.js";
import { loadAllResources as D } from "./local-storage.js";
import { createActiveEntitiesStore as G, ACTIVE_ENTITIES_SYMBOL as V } from "../store/active-entities.js";
import { createWorkspaceStore as z, WORKSPACE_SYMBOL as H } from "../store/store.js";
import { workspaceSchema as J } from "@scalar/oas-utils/entities/workspace";
import { prettyPrintJson as Q } from "@scalar/oas-utils/helpers";
import { LS_KEYS as X } from "@scalar/helpers/object/local-storage";
import { DATA_VERSION_LS_LEY as Z, DATA_VERSION as $ } from "@scalar/oas-utils/migrations";
import { apiClientConfigurationSchema as _ } from "@scalar/types/api-reference";
import { ref as ee, createApp as te, watch as re } from "vue";
import { createPluginManager as oe } from "../plugins/plugin-manager.js";
import { PLUGIN_MANAGER_SYMBOL as ae } from "../plugins/hooks/usePluginManager.js";
const Me = ({
el: O,
appComponent: y,
configuration: U = {},
isReadOnly: l = !1,
store: x,
persistData: C = !0,
mountOnInitialize: L = !0,
layout: m = "desktop",
router: n
}) => {
const a = ee(_.parse(U)), o = x || z({
proxyUrl: a.value.proxyUrl,
theme: a.value.theme,
showSidebar: a.value.showSidebar ?? !0,
hideClientButton: a.value.hideClientButton ?? !1,
_integration: a.value._integration,
useLocalStorage: C
}), f = G({ ...o, router: n }), b = j({ layout: m }), E = oe({
plugins: a.value.plugins ?? []
}), v = () => {
try {
return typeof window < "u" && window.localStorage !== void 0;
} catch {
return !1;
}
};
if (v() && localStorage.getItem(X.WORKSPACE) && !l)
try {
const t = {};
let e = 0, r = 0, s = "";
for (s in localStorage)
Object.hasOwn(localStorage, s) && (r = (localStorage[s].length + s.length) * 2, e += r, t[s] = (r / 1024).toFixed(2) + " KB");
t.Total = (e / 1024).toFixed(2) + " KB", console.table(t), D(o);
} catch (t) {
console.warn("Failed to load from localStorage:", t);
}
else if (!l && !a.value.url && !a.value.content) {
if (o.workspaceMutators.add({
uid: "default",
name: "Workspace",
proxyUrl: a.value.proxyUrl
}), v())
try {
localStorage.setItem(Z, $);
} catch (t) {
console.warn("Failed to set localStorage version:", t);
}
} else {
const t = J.parse({
uid: "default",
name: "Workspace",
proxyUrl: a.value.proxyUrl
});
o.workspaceMutators.rawAdd(t);
}
const i = te(y);
i.use(n), i.provide(H, o), i.provide(F, m), i.provide(V, f), i.provide(W, b), i.provide(N, a), i.provide(ae, E), i.config.idPrefix = "scalar-client";
const {
collectionMutators: k,
importSpecFile: I,
importSpecFromUrl: q,
modalState: S,
requests: h,
securitySchemes: B,
securitySchemeMutators: T,
servers: g,
workspaceMutators: P,
requestExampleMutators: R
} = o, { activeCollection: u, activeWorkspace: p } = f, w = (t = O) => {
if (!t) {
console.error(
"[@scalar/api-client-modal] Could not create the API client.",
"Invalid HTML element provided.",
"Read more: https://github.com/scalar/scalar/tree/main/packages/api-client"
);
return;
}
i.mount(t);
};
L && w();
const M = (t) => {
const e = K(h, t);
e ? n.push({
name: "request",
query: t?._source ? { source: t._source } : {},
params: {
workspace: "default",
request: e
}
}) : console.warn("[@scalar/api-client] Could not find request for path and method", t);
}, A = () => {
o.collectionMutators.reset(), o.requestMutators.reset(), o.requestExampleMutators.reset(), o.securitySchemeMutators.reset(), o.serverMutators.reset(), o.tagMutators.reset(), P.edit(p.value?.uid, "collections", []);
};
return {
/** The vue app instance for the modal, be careful with this */
app: i,
resetStore: A,
/**
* Update the API client config
*
* Deletes the current store before importing again for now, in the future will Diff and only update what is needed
*/
updateConfig: async (t) => {
const e = _.parse(t);
if (e.url || e.content || e.servers || e.authentication || e.slug || e.title || e.baseServerURL || e.proxyUrl || e.showSidebar) {
A();
const r = {
...e,
useCollectionSecurity: l
};
a.value = r, e.url ? await q(e.url, p.value?.uid ?? "default", r) : e.content ? await I(e.content, p.value?.uid ?? "default", r) : console.error(
"[@scalar/api-client-modal] Could not create the API client.",
'Please provide an OpenAPI document: { url: "…" }',
"Read more: https://github.com/scalar/scalar/tree/main/packages/api-client"
);
}
},
/** Update the currently selected server via URL */
updateServer: (t) => {
const e = Object.values(g).find((r) => r.url === t);
e && u.value && k.edit(u.value?.uid, "selectedServerUid", e.uid);
},
/** Update the currently selected server via URL */
onUpdateServer: (t) => {
re(
() => u.value?.selectedServerUid,
(e) => {
const r = Object.values(g).find((s) => s.uid === e);
r?.url && t(r.url);
}
);
},
/**
* Update the auth values, we currently don't change the auth selection
*/
updateAuth: ({
nameKey: t,
propertyKey: e,
value: r
}) => {
const c = Object.values(B).find((d) => d.nameKey === t);
c && T.edit(c.uid, e, r);
},
/** Route to a method + path */
route: M,
/** Open the API client modal and optionally route to a request */
open: (t) => {
const { method: e, path: r, requestUid: s } = t ?? {};
(e && r || s) && M(t), S.open = !0;
},
/** Mount the references to a given element */
mount: w,
/** State for controlling the modal */
modalState: S,
/* The workspace store */
store: o,
/** Update the currently selected example */
updateExample: (t, e) => {
if (!t || !e)
return;
const r = Object.values(h).find(
({ operationId: d, path: Y }) => d === e || Y === e
);
if (!r)
return;
const s = Object.keys(r.requestBody?.content || {})[0] || "", c = r.requestBody?.content?.[s]?.examples?.[t];
c && R.edit(r.examples[0], "body.raw.value", Q(c.value));
}
};
};
export {
Me as createApiClient
};