@scalar/api-client 2.22.3 → 2.23.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 +6 -0
- package/dist/style.css +1 -1
- package/dist/v2/blocks/request-block/helpers/get-default-headers.js +1 -1
- package/dist/v2/features/app/App.vue.d.ts.map +1 -1
- package/dist/v2/features/app/App.vue.js +111 -85
- package/dist/v2/features/app/app-state.d.ts.map +1 -1
- package/dist/v2/features/app/app-state.js +115 -114
- package/dist/v2/features/app/helpers/routes.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/routes.js +31 -25
- package/dist/v2/features/import-listener/ImportListener.vue.d.ts +52 -0
- package/dist/v2/features/import-listener/ImportListener.vue.d.ts.map +1 -0
- package/dist/v2/features/import-listener/ImportListener.vue.js +91 -0
- package/dist/v2/features/import-listener/ImportListener.vue2.js +4 -0
- package/dist/v2/features/import-listener/components/DropEventListener.vue.d.ts +7 -0
- package/dist/v2/features/import-listener/components/DropEventListener.vue.d.ts.map +1 -0
- package/dist/v2/features/import-listener/components/DropEventListener.vue.js +81 -0
- package/dist/v2/features/import-listener/components/DropEventListener.vue2.js +4 -0
- package/dist/v2/features/import-listener/components/ImportModal.vue.d.ts +40 -0
- package/dist/v2/features/import-listener/components/ImportModal.vue.d.ts.map +1 -0
- package/dist/v2/features/import-listener/components/ImportModal.vue.js +170 -0
- package/dist/v2/features/import-listener/components/ImportModal.vue3.js +5 -0
- package/dist/v2/features/import-listener/components/WorkspaceSelector.vue.d.ts +29 -0
- package/dist/v2/features/import-listener/components/WorkspaceSelector.vue.d.ts.map +1 -0
- package/dist/v2/features/import-listener/components/WorkspaceSelector.vue.js +83 -0
- package/dist/v2/features/import-listener/components/WorkspaceSelector.vue2.js +4 -0
- package/dist/v2/features/import-listener/helpers/generate-unique-slug.d.ts +16 -0
- package/dist/v2/features/import-listener/helpers/generate-unique-slug.d.ts.map +1 -0
- package/dist/v2/features/import-listener/helpers/generate-unique-slug.js +11 -0
- package/dist/v2/features/import-listener/helpers/get-url-query-parameter.d.ts +8 -0
- package/dist/v2/features/import-listener/helpers/get-url-query-parameter.d.ts.map +1 -0
- package/dist/v2/features/import-listener/helpers/get-url-query-parameter.js +4 -0
- package/dist/v2/features/import-listener/helpers/import-document-to-workspace.d.ts +30 -0
- package/dist/v2/features/import-listener/helpers/import-document-to-workspace.d.ts.map +1 -0
- package/dist/v2/features/import-listener/helpers/import-document-to-workspace.js +31 -0
- package/dist/v2/features/import-listener/helpers/load-document-from-source.d.ts +15 -0
- package/dist/v2/features/import-listener/helpers/load-document-from-source.d.ts.map +1 -0
- package/dist/v2/features/import-listener/helpers/load-document-from-source.js +28 -0
- package/dist/v2/features/import-listener/helpers/wait-for-condition.d.ts +15 -0
- package/dist/v2/features/import-listener/helpers/wait-for-condition.d.ts.map +1 -0
- package/dist/v2/features/import-listener/helpers/wait-for-condition.js +16 -0
- package/dist/v2/features/import-listener/index.d.ts +2 -0
- package/dist/v2/features/import-listener/index.d.ts.map +1 -0
- package/dist/v2/features/import-listener/index.js +4 -0
- package/dist/v2/features/operation/Operation.vue.js +1 -1
- package/dist/views/Request/ResponseSection/ResponseEmpty.vue2.js +1 -1
- package/package.json +13 -8
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { defineComponent as h, ref as v, onMounted as I, createElementBlock as W, openBlock as D, Fragment as L, createVNode as d, renderSlot as F, unref as M } from "vue";
|
|
2
|
+
import { useModal as T } from "@scalar/components";
|
|
3
|
+
import { useToasts as B } from "@scalar/use-toasts";
|
|
4
|
+
import { createWorkspaceStore as C } from "@scalar/workspace-store/client";
|
|
5
|
+
import { getUrlQueryParameter as i } from "./helpers/get-url-query-parameter.js";
|
|
6
|
+
import { importDocumentToWorkspace as E } from "./helpers/import-document-to-workspace.js";
|
|
7
|
+
import { loadDocumentFromSource as $ } from "./helpers/load-document-from-source.js";
|
|
8
|
+
import { waitForCondition as b } from "./helpers/wait-for-condition.js";
|
|
9
|
+
import x from "./components/DropEventListener.vue.js";
|
|
10
|
+
import z from "./components/ImportModal.vue.js";
|
|
11
|
+
/* empty css */
|
|
12
|
+
const J = /* @__PURE__ */ h({
|
|
13
|
+
__name: "ImportListener",
|
|
14
|
+
props: {
|
|
15
|
+
workspaceStore: {},
|
|
16
|
+
activeWorkspace: {},
|
|
17
|
+
workspaces: {},
|
|
18
|
+
darkMode: { type: Boolean }
|
|
19
|
+
},
|
|
20
|
+
emits: ["navigateTo:document", "select:workspace", "create:workspace"],
|
|
21
|
+
setup(r, { emit: k }) {
|
|
22
|
+
const s = k, c = v(null), a = T(), { toast: l } = B(), n = (o) => {
|
|
23
|
+
console.error(o), l("Failed to import document", "error"), a.hide();
|
|
24
|
+
}, f = async (o) => {
|
|
25
|
+
if (l("Importing document to the workspace...", "info"), !r.workspaceStore) {
|
|
26
|
+
n("Workspace store is not available");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const e = C();
|
|
30
|
+
if (!await $(
|
|
31
|
+
e,
|
|
32
|
+
o,
|
|
33
|
+
"drafts",
|
|
34
|
+
!1
|
|
35
|
+
)) {
|
|
36
|
+
n("Failed to import document");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await p(e.exportWorkspace(), "drafts");
|
|
40
|
+
}, u = async (o, e) => {
|
|
41
|
+
const t = await b(
|
|
42
|
+
() => r.workspaceStore !== null
|
|
43
|
+
), w = new Set(
|
|
44
|
+
Object.keys(r.workspaceStore?.workspace.documents ?? {})
|
|
45
|
+
), g = () => {
|
|
46
|
+
const m = w, S = m.size === 0, y = m.size === 1 && m.has("drafts");
|
|
47
|
+
return S || y;
|
|
48
|
+
};
|
|
49
|
+
if (r.workspaces.length === 1 && g() && t) {
|
|
50
|
+
await f(o);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
c.value = {
|
|
54
|
+
source: o,
|
|
55
|
+
companyLogo: e ?? null
|
|
56
|
+
}, a.show();
|
|
57
|
+
}, p = async (o, e) => {
|
|
58
|
+
const t = await E({
|
|
59
|
+
workspaceStore: r.workspaceStore,
|
|
60
|
+
workspaceState: o,
|
|
61
|
+
name: e
|
|
62
|
+
});
|
|
63
|
+
if (!t.ok) {
|
|
64
|
+
n(t.error);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
s("navigateTo:document", t.slug), a.hide();
|
|
68
|
+
};
|
|
69
|
+
return I(() => {
|
|
70
|
+
const o = i("url"), e = r.darkMode ? i("dark_logo") : i("light_logo");
|
|
71
|
+
o && u(o, e);
|
|
72
|
+
}), (o, e) => (D(), W(L, null, [
|
|
73
|
+
d(z, {
|
|
74
|
+
activeWorkspace: r.activeWorkspace,
|
|
75
|
+
companyLogo: c.value?.companyLogo || null,
|
|
76
|
+
isLoading: r.workspaceStore === null,
|
|
77
|
+
modalState: M(a),
|
|
78
|
+
source: c.value?.source || null,
|
|
79
|
+
workspaces: r.workspaces,
|
|
80
|
+
"onCreate:workspace": e[0] || (e[0] = (t) => s("create:workspace", t)),
|
|
81
|
+
"onImport:document": p,
|
|
82
|
+
"onSelect:workspace": e[1] || (e[1] = (t) => s("select:workspace", t))
|
|
83
|
+
}, null, 8, ["activeWorkspace", "companyLogo", "isLoading", "modalState", "source", "workspaces"]),
|
|
84
|
+
d(x, { onInput: u }),
|
|
85
|
+
F(o.$slots, "default")
|
|
86
|
+
], 64));
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
export {
|
|
90
|
+
J as default
|
|
91
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
2
|
+
input: (value: string) => any;
|
|
3
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
4
|
+
onInput?: ((value: string) => any) | undefined;
|
|
5
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
export default _default;
|
|
7
|
+
//# sourceMappingURL=DropEventListener.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropEventListener.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/import-listener/components/DropEventListener.vue"],"names":[],"mappings":";;;;;AAqVA,wBAMG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { defineComponent as g, ref as y, onMounted as x, onBeforeUnmount as h, createBlock as D, openBlock as p, Transition as E, withCtx as T, createElementBlock as _, createCommentVNode as L, createElementVNode as i, createVNode as C, unref as b } from "vue";
|
|
2
|
+
import { ScalarIcon as k } from "@scalar/components";
|
|
3
|
+
const A = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "bg-b-2 fixed right-1/2 bottom-1/2 z-50 h-64 w-64 translate-x-1/2 translate-y-1/2 rounded-xl border transition-opacity duration-200 md:right-10 md:bottom-10 md:translate-x-0 md:translate-y-0"
|
|
6
|
+
}, w = { class: "flex h-full flex-col items-center justify-center" }, V = /* @__PURE__ */ g({
|
|
7
|
+
__name: "DropEventListener",
|
|
8
|
+
emits: ["input"],
|
|
9
|
+
setup(B, { emit: v }) {
|
|
10
|
+
const s = v, n = y(!1);
|
|
11
|
+
let a = 0;
|
|
12
|
+
x(() => {
|
|
13
|
+
document.addEventListener("dragenter", f), document.addEventListener("dragleave", u), document.addEventListener("dragover", c), document.addEventListener("drop", l);
|
|
14
|
+
}), h(() => {
|
|
15
|
+
document.removeEventListener("dragenter", f), document.removeEventListener("dragover", c), document.removeEventListener("dragleave", u), document.removeEventListener("drop", l);
|
|
16
|
+
});
|
|
17
|
+
function d(e) {
|
|
18
|
+
return e.dataTransfer?.types.includes("text/html") ?? !1;
|
|
19
|
+
}
|
|
20
|
+
function l(e) {
|
|
21
|
+
if (e.preventDefault(), n.value = !1, a = 0, !d(e) && e.dataTransfer) {
|
|
22
|
+
const t = e.dataTransfer.getData("text").replace(/^blob:/, "");
|
|
23
|
+
if (t)
|
|
24
|
+
s("input", t);
|
|
25
|
+
else if (e.dataTransfer.files.length > 0) {
|
|
26
|
+
const r = e.dataTransfer.files[0];
|
|
27
|
+
if (!r)
|
|
28
|
+
return;
|
|
29
|
+
const m = new FileReader();
|
|
30
|
+
m.onload = (o) => {
|
|
31
|
+
o.target && typeof o.target.result == "string" && s("input", o.target.result);
|
|
32
|
+
}, m.readAsText(r);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function c(e) {
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
}
|
|
39
|
+
function u(e) {
|
|
40
|
+
e.preventDefault(), a--, a === 0 && (n.value = !1);
|
|
41
|
+
}
|
|
42
|
+
function f(e) {
|
|
43
|
+
if (e.preventDefault(), a++, !d(e)) {
|
|
44
|
+
if (e.dataTransfer) {
|
|
45
|
+
const t = e.dataTransfer.items;
|
|
46
|
+
for (const r of t)
|
|
47
|
+
if (r?.kind === "string" || r?.type?.includes("json") || r?.type?.includes("yml") || r?.type?.includes("yaml")) {
|
|
48
|
+
n.value = !0;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
n.value = !1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return (e, t) => (p(), D(E, {
|
|
56
|
+
enterActiveClass: "transition-opacity duration-200",
|
|
57
|
+
enterFromClass: "opacity-0",
|
|
58
|
+
leaveActiveClass: "transition-opacity duration-200",
|
|
59
|
+
leaveToClass: "opacity-0"
|
|
60
|
+
}, {
|
|
61
|
+
default: T(() => [
|
|
62
|
+
n.value ? (p(), _("div", A, [
|
|
63
|
+
i("div", w, [
|
|
64
|
+
i("div", null, [
|
|
65
|
+
C(b(k), {
|
|
66
|
+
icon: "Download",
|
|
67
|
+
size: "xl",
|
|
68
|
+
thickness: "2"
|
|
69
|
+
})
|
|
70
|
+
]),
|
|
71
|
+
t[0] || (t[0] = i("div", { class: "text-c-1 m-4 text-center" }, " Drop your OpenAPI document here ", -1))
|
|
72
|
+
])
|
|
73
|
+
])) : L("", !0)
|
|
74
|
+
]),
|
|
75
|
+
_: 1
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
export {
|
|
80
|
+
V as default
|
|
81
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ModalState, type ScalarListboxOption } from '@scalar/components';
|
|
2
|
+
import type { InMemoryWorkspace } from '@scalar/workspace-store/schemas/inmemory-workspace';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
/** The source URL or content to import from (URL, file path, or raw content) */
|
|
5
|
+
source: string | null;
|
|
6
|
+
/** Controls the visibility and state of the modal */
|
|
7
|
+
modalState: ModalState;
|
|
8
|
+
/** Optional company logo URL to display in the import UI */
|
|
9
|
+
companyLogo?: string | null;
|
|
10
|
+
/** Whether the workspace data is currently being loaded */
|
|
11
|
+
isLoading?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* The currently active workspace.
|
|
14
|
+
* This represents the workspace that the user is currently working in.
|
|
15
|
+
*/
|
|
16
|
+
activeWorkspace: {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
} | null;
|
|
20
|
+
/**
|
|
21
|
+
* The list of all available workspaces.
|
|
22
|
+
* Used to render options for workspace switching and selection.
|
|
23
|
+
*/
|
|
24
|
+
workspaces: ScalarListboxOption[];
|
|
25
|
+
};
|
|
26
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
27
|
+
"create:workspace": (payload: {
|
|
28
|
+
name: string;
|
|
29
|
+
}) => any;
|
|
30
|
+
"select:workspace": (id?: string | undefined) => any;
|
|
31
|
+
"import:document": (workspaceState: InMemoryWorkspace, name: string) => any;
|
|
32
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
33
|
+
"onCreate:workspace"?: ((payload: {
|
|
34
|
+
name: string;
|
|
35
|
+
}) => any) | undefined;
|
|
36
|
+
"onSelect:workspace"?: ((id?: string | undefined) => any) | undefined;
|
|
37
|
+
"onImport:document"?: ((workspaceState: InMemoryWorkspace, name: string) => any) | undefined;
|
|
38
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
39
|
+
export default _default;
|
|
40
|
+
//# sourceMappingURL=ImportModal.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImportModal.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/import-listener/components/ImportModal.vue"],"names":[],"mappings":"AAgVA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oDAAoD,CAAA;AAQ3F,KAAK,WAAW,GAAG;IACjB,gFAAgF;IAChF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAA;IACtB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;OAGG;IACH,eAAe,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACrD;;;OAGG;IACH,UAAU,EAAE,mBAAmB,EAAE,CAAA;CAClC,CAAC;;;cAayC,MAAM;;;;;;cAAN,MAAM;;;;;AA4cjD,wBAOG"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { defineComponent as W, ref as w, computed as d, watch as y, onUnmounted as N, createBlock as V, openBlock as s, unref as m, withCtx as b, createElementVNode as e, normalizeClass as M, createElementBlock as n, Fragment as k, createTextVNode as u, createCommentVNode as f, toDisplayString as O, createVNode as p } from "vue";
|
|
2
|
+
import { ScalarModal as j, ScalarButton as B, ScalarIcon as T } from "@scalar/components";
|
|
3
|
+
import { createWorkspaceStore as U } from "@scalar/workspace-store/client";
|
|
4
|
+
import z from "../../../../components/CommandPalette/WatchModeToggle.vue.js";
|
|
5
|
+
import E from "./WorkspaceSelector.vue.js";
|
|
6
|
+
import { loadDocumentFromSource as F } from "../helpers/load-document-from-source.js";
|
|
7
|
+
import { isUrl as g } from "../../../helpers/is-url.js";
|
|
8
|
+
const q = { class: "relative flex h-screen flex-col justify-center overflow-hidden px-6 md:px-0" }, R = {
|
|
9
|
+
key: 0,
|
|
10
|
+
class: "w-full text-center text-sm font-medium break-words"
|
|
11
|
+
}, $ = ["href"], G = {
|
|
12
|
+
key: 1,
|
|
13
|
+
class: "w-full text-center text-sm font-medium break-words"
|
|
14
|
+
}, H = ["src"], J = {
|
|
15
|
+
key: 1,
|
|
16
|
+
class: "text-md mb-2 line-clamp-1 text-center font-bold"
|
|
17
|
+
}, K = { class: "z-10 inline-flex w-full flex-col items-center gap-2" }, Q = { class: "flex justify-center" }, X = { class: "text-c-3 inline-flex items-center px-4 py-1 text-xs font-medium" }, Y = {
|
|
18
|
+
key: 0,
|
|
19
|
+
class: "mt-5 overflow-hidden border-t pt-4 text-sm"
|
|
20
|
+
}, Z = { class: "flex items-center justify-center" }, _ = { class: "flex flex-col items-center justify-center pb-8" }, ee = { class: "flex flex-col items-center text-center" }, te = { class: "mb-2 flex h-10 w-10 items-center justify-center rounded-[10px] border" }, oe = {
|
|
21
|
+
href: "https://scalar.com/download",
|
|
22
|
+
target: "_blank"
|
|
23
|
+
}, h = "draft", de = /* @__PURE__ */ W({
|
|
24
|
+
__name: "ImportModal",
|
|
25
|
+
props: {
|
|
26
|
+
source: {},
|
|
27
|
+
modalState: {},
|
|
28
|
+
companyLogo: {},
|
|
29
|
+
isLoading: { type: Boolean, default: !1 },
|
|
30
|
+
activeWorkspace: {},
|
|
31
|
+
workspaces: {}
|
|
32
|
+
},
|
|
33
|
+
emits: ["import:document", "select:workspace", "create:workspace"],
|
|
34
|
+
setup(o, { emit: I }) {
|
|
35
|
+
const x = I, l = w("idle"), c = w(!1), i = U(), S = d(
|
|
36
|
+
() => i.workspace.activeDocument?.info.title || "Untitled Document"
|
|
37
|
+
), A = d(
|
|
38
|
+
() => !!i.workspace.activeDocument?.info.version
|
|
39
|
+
), C = d(() => o.source && g(o.source)), D = d(() => l.value === "loading"), v = (a) => {
|
|
40
|
+
a && o.modalState.open ? document.body.classList.add("has-import-url") : document.body.classList.remove("has-import-url");
|
|
41
|
+
}, L = async (a) => {
|
|
42
|
+
if (!a)
|
|
43
|
+
return l.value = "idle", c.value = !1, v(!1);
|
|
44
|
+
if (v(!0), l.value = "loading", !await F(
|
|
45
|
+
i,
|
|
46
|
+
o.source,
|
|
47
|
+
h,
|
|
48
|
+
c.value
|
|
49
|
+
)) {
|
|
50
|
+
l.value = "error";
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
l.value = "success";
|
|
54
|
+
}, P = () => {
|
|
55
|
+
x(
|
|
56
|
+
"import:document",
|
|
57
|
+
i.exportWorkspace(),
|
|
58
|
+
h
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
return y(() => o.modalState.open, L), y(c, (a) => {
|
|
62
|
+
i.updateDocument("active", "x-scalar-watch-mode", a);
|
|
63
|
+
}), N(() => v(!1)), (a, t) => (s(), V(m(j), {
|
|
64
|
+
size: "full",
|
|
65
|
+
state: o.modalState
|
|
66
|
+
}, {
|
|
67
|
+
default: b(() => [
|
|
68
|
+
e("div", q, [
|
|
69
|
+
t[10] || (t[10] = e("div", { class: "section-flare" }, [
|
|
70
|
+
e("div", { class: "section-flare-item" }),
|
|
71
|
+
e("div", { class: "section-flare-item" }),
|
|
72
|
+
e("div", { class: "section-flare-item" }),
|
|
73
|
+
e("div", { class: "section-flare-item" }),
|
|
74
|
+
e("div", { class: "section-flare-item" }),
|
|
75
|
+
e("div", { class: "section-flare-item" }),
|
|
76
|
+
e("div", { class: "section-flare-item" }),
|
|
77
|
+
e("div", { class: "section-flare-item" })
|
|
78
|
+
], -1)),
|
|
79
|
+
e("div", {
|
|
80
|
+
class: M(["m-auto flex w-full max-w-[380px] flex-col items-center rounded-xl border px-8 py-8 transition-opacity", { "opacity-0": D.value }])
|
|
81
|
+
}, [
|
|
82
|
+
l.value === "error" ? (s(), n(k, { key: 0 }, [
|
|
83
|
+
t[4] || (t[4] = e("div", { class: "text-md mb-2 line-clamp-1 text-center font-bold" }, " No OpenAPI document found ", -1)),
|
|
84
|
+
o.source && m(g)(o.source) ? (s(), n("div", R, [
|
|
85
|
+
t[3] || (t[3] = u(" We couldn't find an OpenAPI document at the provided URL. Please download and import the ", -1)),
|
|
86
|
+
e("a", {
|
|
87
|
+
href: o.source,
|
|
88
|
+
rel: "noopener nofollow",
|
|
89
|
+
target: "_blank",
|
|
90
|
+
textContent: "OpenAPI document manually"
|
|
91
|
+
}, null, 8, $)
|
|
92
|
+
])) : (s(), n("div", G, " We can't import this document because it's not a valid OpenAPI document. "))
|
|
93
|
+
], 64)) : (s(), n(k, { key: 1 }, [
|
|
94
|
+
o.companyLogo ? (s(), n("img", {
|
|
95
|
+
key: 0,
|
|
96
|
+
alt: "Company Logo",
|
|
97
|
+
class: "mb-2 w-full object-contain",
|
|
98
|
+
src: o.companyLogo
|
|
99
|
+
}, null, 8, H)) : f("", !0),
|
|
100
|
+
o.companyLogo ? f("", !0) : (s(), n("div", J, O(S.value), 1)),
|
|
101
|
+
t[8] || (t[8] = e("div", { class: "text-c-1 text-center text-sm font-medium text-balance" }, " Import the OpenAPI document to instantly send API requests. No signup required. ", -1)),
|
|
102
|
+
A.value ? (s(), n(k, { key: 2 }, [
|
|
103
|
+
e("div", K, [
|
|
104
|
+
p(m(B), {
|
|
105
|
+
class: "mt-3 h-fit w-full rounded-lg px-6 py-2.5 font-bold",
|
|
106
|
+
disabled: o.isLoading,
|
|
107
|
+
size: "md",
|
|
108
|
+
type: "button",
|
|
109
|
+
onClick: P
|
|
110
|
+
}, {
|
|
111
|
+
default: b(() => [...t[5] || (t[5] = [
|
|
112
|
+
u(" Import Collection ", -1)
|
|
113
|
+
])]),
|
|
114
|
+
_: 1
|
|
115
|
+
}, 8, ["disabled"])
|
|
116
|
+
]),
|
|
117
|
+
e("div", Q, [
|
|
118
|
+
e("div", X, [
|
|
119
|
+
t[6] || (t[6] = u(" Import to: ", -1)),
|
|
120
|
+
p(E, {
|
|
121
|
+
activeWorkspace: o.activeWorkspace,
|
|
122
|
+
workspaces: o.workspaces,
|
|
123
|
+
"onCreate:workspace": t[0] || (t[0] = (r) => x("create:workspace", r)),
|
|
124
|
+
"onSelect:workspace": t[1] || (t[1] = (r) => x("select:workspace", r))
|
|
125
|
+
}, null, 8, ["activeWorkspace", "workspaces"])
|
|
126
|
+
])
|
|
127
|
+
]),
|
|
128
|
+
C.value ? (s(), n("div", Y, [
|
|
129
|
+
e("div", Z, [
|
|
130
|
+
p(z, {
|
|
131
|
+
modelValue: c.value,
|
|
132
|
+
"onUpdate:modelValue": t[2] || (t[2] = (r) => c.value = r),
|
|
133
|
+
disableToolTip: !0
|
|
134
|
+
}, null, 8, ["modelValue"])
|
|
135
|
+
]),
|
|
136
|
+
t[7] || (t[7] = e("div", { class: "text-c-3 pt-0 text-center text-xs font-medium text-balance" }, " Automatically update your API client when the OpenAPI document content changes. ", -1))
|
|
137
|
+
])) : f("", !0)
|
|
138
|
+
], 64)) : f("", !0)
|
|
139
|
+
], 64))
|
|
140
|
+
], 2),
|
|
141
|
+
e("div", _, [
|
|
142
|
+
e("div", ee, [
|
|
143
|
+
e("div", te, [
|
|
144
|
+
e("a", oe, [
|
|
145
|
+
p(m(T), {
|
|
146
|
+
icon: "Logo",
|
|
147
|
+
size: "xl"
|
|
148
|
+
})
|
|
149
|
+
])
|
|
150
|
+
]),
|
|
151
|
+
t[9] || (t[9] = e("span", { class: "text-c-2 text-sm leading-snug font-medium" }, [
|
|
152
|
+
e("a", {
|
|
153
|
+
class: "hover:text-c-1 mb-1 inline-block underline-offset-2",
|
|
154
|
+
href: "https://scalar.com/download",
|
|
155
|
+
target: "_blank"
|
|
156
|
+
}, " Download Desktop App "),
|
|
157
|
+
e("br"),
|
|
158
|
+
u(" free · open-source · offline first ")
|
|
159
|
+
], -1))
|
|
160
|
+
])
|
|
161
|
+
])
|
|
162
|
+
])
|
|
163
|
+
]),
|
|
164
|
+
_: 1
|
|
165
|
+
}, 8, ["state"]));
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
export {
|
|
169
|
+
de as default
|
|
170
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ScalarListboxOption } from '@scalar/components';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
/**
|
|
4
|
+
* The currently active workspace.
|
|
5
|
+
* This represents the workspace that the user is currently working in.
|
|
6
|
+
*/
|
|
7
|
+
activeWorkspace: {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
} | null;
|
|
11
|
+
/**
|
|
12
|
+
* The list of all available workspaces.
|
|
13
|
+
* Used to render options for workspace switching and selection.
|
|
14
|
+
*/
|
|
15
|
+
workspaces: ScalarListboxOption[];
|
|
16
|
+
};
|
|
17
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
18
|
+
"create:workspace": (payload: {
|
|
19
|
+
name: string;
|
|
20
|
+
}) => any;
|
|
21
|
+
"select:workspace": (id?: string | undefined) => any;
|
|
22
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
23
|
+
"onCreate:workspace"?: ((payload: {
|
|
24
|
+
name: string;
|
|
25
|
+
}) => any) | undefined;
|
|
26
|
+
"onSelect:workspace"?: ((id?: string | undefined) => any) | undefined;
|
|
27
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
|
+
export default _default;
|
|
29
|
+
//# sourceMappingURL=WorkspaceSelector.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceSelector.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/import-listener/components/WorkspaceSelector.vue"],"names":[],"mappings":"AAkGA,OAAO,EAOL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAA;AAI3B,KAAK,WAAW,GAAG;IACjB;;;OAGG;IACH,eAAe,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACrD;;;OAGG;IACH,UAAU,EAAE,mBAAmB,EAAE,CAAA;CAClC,CAAC;;;cAOyC,MAAM;;;;;cAAN,MAAM;;;;AAwPjD,wBAOG"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { defineComponent as w, createElementBlock as p, openBlock as i, createVNode as t, unref as e, withCtx as l, createElementVNode as o, toDisplayString as m, Fragment as x, renderList as k, createBlock as h, withModifiers as v, normalizeClass as _ } from "vue";
|
|
2
|
+
import { useModal as g, ScalarDropdown as C, ScalarButton as b, ScalarIcon as n, ScalarDropdownItem as f, ScalarDropdownDivider as S } from "@scalar/components";
|
|
3
|
+
import y from "../../app/components/CreateWorkspaceModal.vue.js";
|
|
4
|
+
const D = { class: "flex w-[inherit] items-center text-base" }, W = { class: "m-0 flex items-center gap-1 text-sm font-medium" }, z = { class: "line-clamp-1 w-[calc(100%-10px)] text-left text-xs" }, B = { class: "overflow-hidden text-ellipsis" }, j = { class: "flex h-4 w-4 items-center justify-center" }, V = /* @__PURE__ */ w({
|
|
5
|
+
__name: "WorkspaceSelector",
|
|
6
|
+
props: {
|
|
7
|
+
activeWorkspace: {},
|
|
8
|
+
workspaces: {}
|
|
9
|
+
},
|
|
10
|
+
emits: ["select:workspace", "create:workspace"],
|
|
11
|
+
setup(r, { emit: u }) {
|
|
12
|
+
const c = u, d = g();
|
|
13
|
+
return (M, a) => (i(), p("div", D, [
|
|
14
|
+
t(e(C), null, {
|
|
15
|
+
items: l(() => [
|
|
16
|
+
(i(!0), p(x, null, k(r.workspaces, (s) => (i(), h(e(f), {
|
|
17
|
+
key: s.id,
|
|
18
|
+
class: "group/item flex w-full items-center gap-1.5 overflow-hidden text-ellipsis whitespace-nowrap",
|
|
19
|
+
onClick: v((N) => c("select:workspace", s.id), ["stop"])
|
|
20
|
+
}, {
|
|
21
|
+
default: l(() => [
|
|
22
|
+
o("div", {
|
|
23
|
+
class: _([
|
|
24
|
+
"flex h-4 w-4 items-center justify-center rounded-full p-[3px]",
|
|
25
|
+
r.activeWorkspace?.id === s.id ? "bg-c-accent text-b-1" : "shadow-border text-transparent"
|
|
26
|
+
])
|
|
27
|
+
}, [
|
|
28
|
+
t(e(n), {
|
|
29
|
+
class: "size-2.5",
|
|
30
|
+
icon: "Checkmark",
|
|
31
|
+
thickness: "3"
|
|
32
|
+
})
|
|
33
|
+
], 2),
|
|
34
|
+
o("span", B, m(s.label), 1)
|
|
35
|
+
]),
|
|
36
|
+
_: 2
|
|
37
|
+
}, 1032, ["onClick"]))), 128)),
|
|
38
|
+
t(e(S)),
|
|
39
|
+
t(e(f), {
|
|
40
|
+
class: "flex items-center gap-1.5",
|
|
41
|
+
onClick: a[0] || (a[0] = (s) => e(d).show())
|
|
42
|
+
}, {
|
|
43
|
+
default: l(() => [
|
|
44
|
+
o("div", j, [
|
|
45
|
+
t(e(n), {
|
|
46
|
+
icon: "Add",
|
|
47
|
+
size: "sm"
|
|
48
|
+
})
|
|
49
|
+
]),
|
|
50
|
+
a[2] || (a[2] = o("span", null, "New Workspace", -1))
|
|
51
|
+
]),
|
|
52
|
+
_: 1
|
|
53
|
+
})
|
|
54
|
+
]),
|
|
55
|
+
default: l(() => [
|
|
56
|
+
t(e(b), {
|
|
57
|
+
class: "hover:bg-b-2 text-c-3 line-clamp-1 h-full w-fit justify-start px-1.5 py-1 font-normal",
|
|
58
|
+
variant: "ghost"
|
|
59
|
+
}, {
|
|
60
|
+
default: l(() => [
|
|
61
|
+
o("div", W, [
|
|
62
|
+
o("h2", z, m(r.activeWorkspace?.label), 1),
|
|
63
|
+
t(e(n), {
|
|
64
|
+
icon: "ChevronDown",
|
|
65
|
+
size: "md"
|
|
66
|
+
})
|
|
67
|
+
])
|
|
68
|
+
]),
|
|
69
|
+
_: 1
|
|
70
|
+
})
|
|
71
|
+
]),
|
|
72
|
+
_: 1
|
|
73
|
+
}),
|
|
74
|
+
t(e(y), {
|
|
75
|
+
state: e(d),
|
|
76
|
+
"onCreate:workspace": a[1] || (a[1] = (s) => c("create:workspace", s))
|
|
77
|
+
}, null, 8, ["state"])
|
|
78
|
+
]));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
export {
|
|
82
|
+
V as default
|
|
83
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a unique slug for an imported document based on its title.
|
|
3
|
+
*
|
|
4
|
+
* This ensures the imported document does not conflict with existing documents
|
|
5
|
+
* by appending a number suffix if necessary (e.g., "my-api", "my-api-1", "my-api-2").
|
|
6
|
+
*
|
|
7
|
+
* The function will retry up to 100 times to find a unique slug. If all attempts fail,
|
|
8
|
+
* it returns null, which should be handled as an import error.
|
|
9
|
+
*
|
|
10
|
+
* @param defaultValue - The original document title to base the slug on
|
|
11
|
+
* @param currentDocuments - Set of existing document slugs to check against
|
|
12
|
+
*
|
|
13
|
+
* @returns Promise resolving to a unique slug, or null if unable to generate one
|
|
14
|
+
*/
|
|
15
|
+
export declare const generateUniqueSlug: (defaultValue: string | undefined, currentDocuments: Set<string>) => Promise<string | undefined>;
|
|
16
|
+
//# sourceMappingURL=generate-unique-slug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-unique-slug.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/import-listener/helpers/generate-unique-slug.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAAU,cAAc,MAAM,GAAG,SAAS,EAAE,kBAAkB,GAAG,CAAC,MAAM,CAAC,gCAOvG,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { generateUniqueValue as r } from "@scalar/workspace-store/helpers/generate-unique-value";
|
|
2
|
+
import { slugify as i } from "../../../helpers/slugify.js";
|
|
3
|
+
const u = async (e, a) => await r({
|
|
4
|
+
defaultValue: e,
|
|
5
|
+
validation: (t) => !a.has(t),
|
|
6
|
+
maxRetries: 100,
|
|
7
|
+
transformation: i
|
|
8
|
+
});
|
|
9
|
+
export {
|
|
10
|
+
u as generateUniqueSlug
|
|
11
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gets the value of a specific query parameter from the current URL.
|
|
3
|
+
*
|
|
4
|
+
* @param parameterName - The name of the query parameter to retrieve
|
|
5
|
+
* @returns The value of the query parameter, or null if it does not exist
|
|
6
|
+
*/
|
|
7
|
+
export declare const getUrlQueryParameter: (parameterName: string) => string | null;
|
|
8
|
+
//# sourceMappingURL=get-url-query-parameter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-url-query-parameter.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/import-listener/helpers/get-url-query-parameter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,eAAe,MAAM,KAAG,MAAM,GAAG,IAGrE,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { WorkspaceStore } from '@scalar/workspace-store/client';
|
|
2
|
+
import type { InMemoryWorkspace } from '@scalar/workspace-store/schemas/inmemory-workspace';
|
|
3
|
+
/**
|
|
4
|
+
* Imports a single document from a workspace state into the current workspace.
|
|
5
|
+
*
|
|
6
|
+
* This function handles the complete import process including slug generation,
|
|
7
|
+
* document loading, and sidebar updates. It ensures the imported document does not
|
|
8
|
+
* conflict with existing documents by generating a unique slug.
|
|
9
|
+
*
|
|
10
|
+
* The meta from the importing workspace is intentionally excluded to preserve
|
|
11
|
+
* the current workspace settings and avoid unintended configuration changes.
|
|
12
|
+
*
|
|
13
|
+
* @param workspaceStore - The active workspace store where the document will be imported
|
|
14
|
+
* @param workspaceState - The in-memory workspace containing the document to import
|
|
15
|
+
* @param name - The original slug/name of the document in the source workspace state
|
|
16
|
+
*
|
|
17
|
+
* @returns Promise that resolves to the slug of the imported document
|
|
18
|
+
*/
|
|
19
|
+
export declare const importDocumentToWorkspace: ({ workspaceStore, workspaceState, name, }: {
|
|
20
|
+
workspaceStore: WorkspaceStore | null;
|
|
21
|
+
workspaceState: InMemoryWorkspace;
|
|
22
|
+
name: string;
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
ok: true;
|
|
25
|
+
slug: string;
|
|
26
|
+
} | {
|
|
27
|
+
ok: false;
|
|
28
|
+
error: string;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=import-document-to-workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-document-to-workspace.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/import-listener/helpers/import-document-to-workspace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oDAAoD,CAAA;AAI3F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,yBAAyB,GAAU,2CAI7C;IACD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC,cAAc,EAAE,iBAAiB,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;CACb,KAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAsDpE,CAAA"}
|