@cbjwwwcode/common 0.1.0 → 0.1.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.
@@ -0,0 +1,5 @@
1
+ import { ClassValue } from "clsx";
2
+ //#region src/cn.d.ts
3
+ declare function cn(...inputs: ClassValue[]): string;
4
+ //#endregion
5
+ export { cn };
package/dist/es/cn.mjs ADDED
@@ -0,0 +1,8 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ //#region src/cn.ts
4
+ function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+ //#endregion
8
+ export { cn };
@@ -17,4 +17,5 @@ export declare function makeUuid(): string;
17
17
  export declare function createFunction<T extends object = any>(code: string, scope: T): any;
18
18
  export declare function makeVueId(prefix?: string, suffix?: string): string;
19
19
  export declare function isHttpUrl<T extends string>(str: T): boolean;
20
+ export declare function isVueComponent(val: unknown): val is Component;
20
21
  //#endregion
@@ -108,5 +108,15 @@ function isHttpUrl(str) {
108
108
  return false;
109
109
  }
110
110
  }
111
+ /**
112
+ * 判断是否为Vue组件定义
113
+ */
114
+ function isVueComponent(val) {
115
+ if (typeof val !== "object" || val === null) return false;
116
+ const hasRender = "render" in val && typeof val.render === "function";
117
+ const hasSetup = "setup" in val && typeof val.setup === "function";
118
+ if (typeof val === "function" && "__asyncLoader" in val) return true;
119
+ return hasRender || hasSetup;
120
+ }
111
121
  //#endregion
112
- export { createFunction, determineTextColor, hasProperty, isComponentRegistered, isHttpUrl, isStringNumber, keepProps, makeRawComponent, makeUuid, makeVueId, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, randomId, transformPx };
122
+ export { createFunction, determineTextColor, hasProperty, isComponentRegistered, isHttpUrl, isStringNumber, isVueComponent, keepProps, makeRawComponent, makeUuid, makeVueId, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, randomId, transformPx };
@@ -11,4 +11,5 @@ export declare function useCopy(options?: UseCopyOptions): {
11
11
  copied: Readonly<import("vue").ShallowRef<boolean>>;
12
12
  isSupported: import("vue").ComputedRef<boolean>;
13
13
  };
14
- //#endregion
14
+ //#endregion
15
+ export {};
package/dist/es/copy.mjs CHANGED
@@ -1,31 +1,51 @@
1
1
  import { toast } from "./toastify.mjs";
2
2
  import { useClipboard } from "@vueuse/core";
3
3
  //#region src/copy.ts
4
+ function fallbackCopy(text) {
5
+ return new Promise((resolve) => {
6
+ const textarea = document.createElement("textarea");
7
+ textarea.value = text;
8
+ textarea.style.position = "fixed";
9
+ textarea.style.opacity = "0";
10
+ document.body.appendChild(textarea);
11
+ textarea.select();
12
+ const result = document.execCommand("copy");
13
+ document.body.removeChild(textarea);
14
+ resolve(result);
15
+ });
16
+ }
4
17
  function useCopy(options = {}) {
5
18
  const { successMessage = "复制成功", errorMessage = "复制失败", showMessage = true, onSuccess, onError } = options;
6
19
  const { copy, copied, isSupported } = useClipboard();
20
+ const doFallbackCopy = async (content, errorMessage) => {
21
+ try {
22
+ await fallbackCopy(content);
23
+ showMessage && toast.success(successMessage);
24
+ onSuccess?.(content);
25
+ return true;
26
+ } catch (error) {
27
+ showMessage && toast.warning(errorMessage);
28
+ onError?.(error);
29
+ return false;
30
+ }
31
+ };
7
32
  /**
8
33
  * 复制文本
9
34
  */
10
35
  const handleCopy = async (text) => {
11
- if (!isSupported.value) {
12
- showMessage && toast.warning("当前环境不支持复制");
13
- return false;
14
- }
15
36
  const content = String(text ?? "");
16
37
  if (!content) {
17
38
  showMessage && toast.warning("复制内容为空");
18
39
  return false;
19
40
  }
41
+ if (!isSupported.value) return await doFallbackCopy(content, "当前环境不支持复制");
20
42
  try {
21
43
  await copy(content);
22
44
  showMessage && toast.success(successMessage);
23
45
  onSuccess?.(content);
24
46
  return true;
25
47
  } catch (error) {
26
- showMessage && toast.error(errorMessage);
27
- onError?.(error);
28
- return false;
48
+ return await doFallbackCopy(content, errorMessage);
29
49
  }
30
50
  };
31
51
  return {
@@ -0,0 +1,16 @@
1
+ //#region src/download.d.ts
2
+ interface DownloadOptions<T = string> {
3
+ fileName?: string;
4
+ source: T;
5
+ target?: string;
6
+ }
7
+ export declare function downloadImageFromCanvas(canvas: HTMLCanvasElement, name: string, type?: string, quality?: number): void;
8
+ export declare function downloadFileFromUrl({ fileName, source, target }: DownloadOptions): Promise<void>;
9
+ export declare function downloadFileFromBase64({ fileName, source }: DownloadOptions): void;
10
+ export declare function downloadFileFromImageUrl({ fileName, source }: DownloadOptions): Promise<void>;
11
+ export declare function downloadFileFromBlob({ fileName, source }: DownloadOptions<Blob>): void;
12
+ export declare function downloadFileFromBlobPart({ fileName, source }: DownloadOptions<BlobPart>): void;
13
+ export declare function urlToBase64(url: string, mineType?: string): Promise<string>;
14
+ export declare function triggerDownload(href: string, fileName: string | undefined, revokeDelay?: number): void;
15
+ //#endregion
16
+ export {};
@@ -0,0 +1,103 @@
1
+ import { openWindow } from "./window.mjs";
2
+ //#region src/download.ts
3
+ const DEFAULT_FILENAME = "downloaded_file";
4
+ function downloadImageFromCanvas(canvas, name, type, quality) {
5
+ downloadFileFromUrl({
6
+ fileName: name,
7
+ source: canvas.toDataURL(type, quality)
8
+ });
9
+ }
10
+ /**
11
+ * 通过 URL 下载文件,支持跨域
12
+ * @throws {Error} - 当下载失败时抛出错误
13
+ */
14
+ async function downloadFileFromUrl({ fileName, source, target = "_blank" }) {
15
+ if (!source || typeof source !== "string") throw new Error("Invalid URL.");
16
+ const isChrome = window.navigator.userAgent.toLowerCase().includes("chrome");
17
+ const isSafari = window.navigator.userAgent.toLowerCase().includes("safari");
18
+ if (/iP/.test(window.navigator.userAgent)) {
19
+ console.error("Your browser does not support download!");
20
+ return;
21
+ }
22
+ if (isChrome || isSafari) {
23
+ triggerDownload(source, resolveFileName(source, fileName));
24
+ return;
25
+ }
26
+ if (!source.includes("?")) source += "?download";
27
+ openWindow(source, { target });
28
+ }
29
+ /**
30
+ * 通过 Base64 下载文件
31
+ */
32
+ function downloadFileFromBase64({ fileName, source }) {
33
+ if (!source || typeof source !== "string") throw new Error("Invalid Base64 data.");
34
+ triggerDownload(source, fileName || DEFAULT_FILENAME);
35
+ }
36
+ /**
37
+ * 通过图片 URL 下载图片文件
38
+ */
39
+ async function downloadFileFromImageUrl({ fileName, source }) {
40
+ downloadFileFromBase64({
41
+ fileName,
42
+ source: await urlToBase64(source)
43
+ });
44
+ }
45
+ /**
46
+ * 通过 Blob 下载文件
47
+ */
48
+ function downloadFileFromBlob({ fileName = DEFAULT_FILENAME, source }) {
49
+ if (!(source instanceof Blob)) throw new TypeError("Invalid Blob data.");
50
+ triggerDownload(URL.createObjectURL(source), fileName);
51
+ }
52
+ /**
53
+ * 下载文件,支持 Blob、字符串和其他 BlobPart 类型
54
+ */
55
+ function downloadFileFromBlobPart({ fileName = DEFAULT_FILENAME, source }) {
56
+ const blob = source instanceof Blob ? source : new Blob([source], { type: "application/octet-stream" });
57
+ triggerDownload(URL.createObjectURL(blob), fileName);
58
+ }
59
+ /**
60
+ * img url to base64
61
+ * @param url
62
+ */
63
+ function urlToBase64(url, mineType) {
64
+ return new Promise((resolve, reject) => {
65
+ let canvas = document.createElement("CANVAS");
66
+ const ctx = canvas?.getContext("2d");
67
+ const img = new Image();
68
+ img.crossOrigin = "";
69
+ img.addEventListener("load", () => {
70
+ if (!canvas || !ctx) return reject(/* @__PURE__ */ new Error("Failed to create canvas."));
71
+ canvas.height = img.height;
72
+ canvas.width = img.width;
73
+ ctx.drawImage(img, 0, 0);
74
+ const dataURL = canvas.toDataURL(mineType || "image/png");
75
+ canvas = null;
76
+ resolve(dataURL);
77
+ });
78
+ img.src = url;
79
+ });
80
+ }
81
+ /**
82
+ * 通用下载触发函数
83
+ * @param href - 文件下载的 URL
84
+ * @param fileName - 下载文件的名称,如果未提供则自动识别
85
+ * @param revokeDelay - 清理 URL 的延迟时间 (毫秒)
86
+ */
87
+ function triggerDownload(href, fileName, revokeDelay = 100) {
88
+ const finalFileName = fileName || "downloaded_file";
89
+ const link = document.createElement("a");
90
+ link.href = href;
91
+ link.download = finalFileName;
92
+ link.style.display = "none";
93
+ if (link.download === void 0) link.setAttribute("target", "_blank");
94
+ document.body.append(link);
95
+ link.click();
96
+ link.remove();
97
+ setTimeout(() => URL.revokeObjectURL(href), revokeDelay);
98
+ }
99
+ function resolveFileName(url, fileName) {
100
+ return fileName || url.slice(url.lastIndexOf("/") + 1) || DEFAULT_FILENAME;
101
+ }
102
+ //#endregion
103
+ export { downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageFromCanvas, triggerDownload, urlToBase64 };
@@ -1,5 +1,5 @@
1
1
  import { $http, AlovaAxiosRequestConfig, ApiConfig, createClientTokenAuthentication, setupRequest, useCaptcha, useRequest, useUploader } from "./api.mjs";
2
- import { createFunction, determineTextColor, hasProperty, isComponentRegistered, isHttpUrl, isStringNumber, keepProps, makeRawComponent, makeUuid, makeVueId, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, randomId, transformPx } from "./common.mjs";
2
+ import { createFunction, determineTextColor, hasProperty, isComponentRegistered, isHttpUrl, isStringNumber, isVueComponent, keepProps, makeRawComponent, makeUuid, makeVueId, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, randomId, transformPx } from "./common.mjs";
3
3
  import { CryptoJS, md5 } from "./crypto.mjs";
4
4
  import { dayjs, setDayjsLocale } from "./dayjs.mjs";
5
5
  import { Toolkit, isNotNil, isPromise } from "./es-toolkit.mjs";
@@ -11,15 +11,17 @@ import { VeeValidate } from "./vee-validate.mjs";
11
11
  import { Vue } from "./vue.mjs";
12
12
  import { VueRouter } from "./vue-router.mjs";
13
13
  import { VueUse, createGlobalState, createReusableTemplate, onClickOutside, useClipboard, useScriptTag, useStorage, useStyleTag, useToggle } from "./vueuse.mjs";
14
- import { $mitt, axios, isModuleObject, registerWindow } from "./window.mjs";
14
+ import { $mitt, axios, isModuleObject, openRouteInNewWindow, openWindow, registerWindow } from "./window.mjs";
15
15
  import { zod } from "./zod.mjs";
16
16
  import { JsonNodeProps, setupJsonNode, useJsonNode } from "./vtj/node.mjs";
17
17
  import { BlockSchema, ContextMode, initProvider, useGlobalProvider, vtjSymbol } from "./vtj/provider.mjs";
18
18
  import { VtjCore, VtjRenderer, VtjUtils } from "./vtj/index.mjs";
19
- import hljs from "./lowlight/hljs.mjs";
19
+ import core_default from "./lowlight/hljs.mjs";
20
20
  import { Lowlight, VueLowlight, highlightLanguages, lowlight } from "./lowlight/index.mjs";
21
21
  import { Hucre } from "./hucre.mjs";
22
22
  import { useCopy } from "./copy.mjs";
23
23
  import { FormatRule as Rules, esthetic, formatCode } from "./format.mjs";
24
24
  import { DOMConfig as Config, DOMPurify, toSafeHtml } from "./dompurify.mjs";
25
- export { $http, $mitt, AlovaAxiosRequestConfig, ApiConfig, type BlockSchema, ContextMode, CryptoJS, type Config as DOMConfig, DOMPurify, type Rules as FormatRule, Hucre, IDBKeyValReturn, IDBOptions, JsonNodeProps, Lowlight, type NProgress, type NProgressOptions, type Toast, ToastApi, type ToastOptions, Toolkit, type UseStore, VeeValidate, VtjCore, VtjRenderer, VtjUtils, Vue, VueLowlight, VueRouter, VueUse, axios, createClientTokenAuthentication, createFunction, createGlobalState, createNaiveStore, createReusableTemplate, dayjs, determineTextColor, esthetic, formatCode, hasProperty, highlightLanguages, hljs, idb, initProvider, isComponentRegistered, isHttpUrl, isModuleObject, isNotNil, isPromise, isStringNumber, keepProps, loadJsStore, loadRemoteModule, loaderScript, lowlight, makeRawComponent, makeUuid, makeVueId, md5, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, onClickOutside, randomId, registerWindow, setDayjsLocale, setupJsonNode, setupRequest, setupToast, toSafeHtml, toast, transformPx, useCaptcha, useClipboard, useCopy, useGlobalProvider, useIdb, useJsonNode, useProgress, useRequest, useScriptTag, useStorage, useStyleLink, useStyleTag, useToggle, useUploader, vtjSymbol, zod };
25
+ import { downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageFromCanvas, triggerDownload, urlToBase64 } from "./download.mjs";
26
+ import { cn } from "./cn.mjs";
27
+ export { $http, $mitt, AlovaAxiosRequestConfig, ApiConfig, type BlockSchema, ContextMode, CryptoJS, type Config as DOMConfig, DOMPurify, type Rules as FormatRule, Hucre, IDBKeyValReturn, IDBOptions, JsonNodeProps, Lowlight, type NProgress, type NProgressOptions, type Toast, ToastApi, type ToastOptions, Toolkit, type UseStore, VeeValidate, VtjCore, VtjRenderer, VtjUtils, Vue, VueLowlight, VueRouter, VueUse, axios, cn, createClientTokenAuthentication, createFunction, createGlobalState, createNaiveStore, createReusableTemplate, dayjs, determineTextColor, downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageFromCanvas, esthetic, formatCode, hasProperty, highlightLanguages, core_default as hljs, idb, initProvider, isComponentRegistered, isHttpUrl, isModuleObject, isNotNil, isPromise, isStringNumber, isVueComponent, keepProps, loadJsStore, loadRemoteModule, loaderScript, lowlight, makeRawComponent, makeUuid, makeVueId, md5, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, onClickOutside, openRouteInNewWindow, openWindow, randomId, registerWindow, setDayjsLocale, setupJsonNode, setupRequest, setupToast, toSafeHtml, toast, transformPx, triggerDownload, urlToBase64, useCaptcha, useClipboard, useCopy, useGlobalProvider, useIdb, useJsonNode, useProgress, useRequest, useScriptTag, useStorage, useStyleLink, useStyleTag, useToggle, useUploader, vtjSymbol, zod };
package/dist/es/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { $http, createClientTokenAuthentication, setupRequest, useCaptcha, useRequest, useUploader } from "./api.mjs";
2
- import { createFunction, determineTextColor, hasProperty, isComponentRegistered, isHttpUrl, isStringNumber, keepProps, makeRawComponent, makeUuid, makeVueId, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, randomId, transformPx } from "./common.mjs";
2
+ import { createFunction, determineTextColor, hasProperty, isComponentRegistered, isHttpUrl, isStringNumber, isVueComponent, keepProps, makeRawComponent, makeUuid, makeVueId, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, randomId, transformPx } from "./common.mjs";
3
3
  import { CryptoJS, md5 } from "./crypto.mjs";
4
4
  import { Vue } from "./vue.mjs";
5
5
  import { VueRouter } from "./vue-router.mjs";
@@ -7,7 +7,7 @@ import { VueUse, createGlobalState, createReusableTemplate, onClickOutside, useC
7
7
  import { zod } from "./zod.mjs";
8
8
  import hljs_default from "./lowlight/hljs.mjs";
9
9
  import { VueLowlight, highlightLanguages, lowlight } from "./lowlight/index.mjs";
10
- import { $mitt, axios, isModuleObject, registerWindow } from "./window.mjs";
10
+ import { $mitt, axios, isModuleObject, openRouteInNewWindow, openWindow, registerWindow } from "./window.mjs";
11
11
  import { dayjs, setDayjsLocale } from "./dayjs.mjs";
12
12
  import { Toolkit, isNotNil, isPromise } from "./es-toolkit.mjs";
13
13
  import { createNaiveStore, idb, loadJsStore, useIdb } from "./idb-keyval.mjs";
@@ -22,4 +22,6 @@ import { Hucre } from "./hucre.mjs";
22
22
  import { useCopy } from "./copy.mjs";
23
23
  import { esthetic, formatCode } from "./format.mjs";
24
24
  import { DOMPurify, toSafeHtml } from "./dompurify.mjs";
25
- export { $http, $mitt, ContextMode, CryptoJS, DOMPurify, Hucre, ToastApi, Toolkit, VeeValidate, VtjCore, VtjRenderer, VtjUtils, Vue, VueLowlight, VueRouter, VueUse, axios, createClientTokenAuthentication, createFunction, createGlobalState, createNaiveStore, createReusableTemplate, dayjs, determineTextColor, esthetic, formatCode, hasProperty, highlightLanguages, hljs_default as hljs, idb, initProvider, isComponentRegistered, isHttpUrl, isModuleObject, isNotNil, isPromise, isStringNumber, keepProps, loadJsStore, loadRemoteModule, loaderScript, lowlight, makeRawComponent, makeUuid, makeVueId, md5, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, onClickOutside, randomId, registerWindow, setDayjsLocale, setupJsonNode, setupRequest, setupToast, toSafeHtml, toast, transformPx, useCaptcha, useClipboard, useCopy, useGlobalProvider, useIdb, useJsonNode, useProgress, useRequest, useScriptTag, useStorage, useStyleLink, useStyleTag, useToggle, useUploader, vtjSymbol, zod };
25
+ import { downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageFromCanvas, triggerDownload, urlToBase64 } from "./download.mjs";
26
+ import { cn } from "./cn.mjs";
27
+ export { $http, $mitt, ContextMode, CryptoJS, DOMPurify, Hucre, ToastApi, Toolkit, VeeValidate, VtjCore, VtjRenderer, VtjUtils, Vue, VueLowlight, VueRouter, VueUse, axios, cn, createClientTokenAuthentication, createFunction, createGlobalState, createNaiveStore, createReusableTemplate, dayjs, determineTextColor, downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageFromCanvas, esthetic, formatCode, hasProperty, highlightLanguages, hljs_default as hljs, idb, initProvider, isComponentRegistered, isHttpUrl, isModuleObject, isNotNil, isPromise, isStringNumber, isVueComponent, keepProps, loadJsStore, loadRemoteModule, loaderScript, lowlight, makeRawComponent, makeUuid, makeVueId, md5, mergeOmitBy, mergePropsOmitBy, mergeUrlWithParams, onClickOutside, openRouteInNewWindow, openWindow, randomId, registerWindow, setDayjsLocale, setupJsonNode, setupRequest, setupToast, toSafeHtml, toast, transformPx, triggerDownload, urlToBase64, useCaptcha, useClipboard, useCopy, useGlobalProvider, useIdb, useJsonNode, useProgress, useRequest, useScriptTag, useStorage, useStyleLink, useStyleTag, useToggle, useUploader, vtjSymbol, zod };
@@ -1,2 +1,2 @@
1
- import hljs$1 from "highlight.js/lib/core";
2
- export { hljs$1 as default };
1
+ import core_default from "highlight.js/lib/core";
2
+ export { core_default as default };
@@ -1,5 +1,5 @@
1
1
  import { createLowlight } from "./lowlights.mjs";
2
- import hljs from "./hljs.mjs";
2
+ import core_default from "./hljs.mjs";
3
3
  import "highlight.js/styles/atom-one-dark.min.css";
4
4
  //#region src/lowlight/index.d.ts
5
5
  export declare const highlightLanguages: string[];
@@ -156,4 +156,4 @@ export declare const VueLowlight: {
156
156
  };
157
157
  export type Lowlight = typeof lowlight;
158
158
  //#endregion
159
- export { hljs };
159
+ export { core_default as hljs };
@@ -30,4 +30,5 @@ export declare const setupJsonNode: (props: JsonNodeProps) => {
30
30
  };
31
31
  declare type JsonNodeType = ReturnType<typeof setupJsonNode>;
32
32
  export declare const useJsonNode: () => JsonNodeType;
33
- //#endregion
33
+ //#endregion
34
+ export {};
@@ -3,5 +3,12 @@ import axios$1 from "axios";
3
3
  export declare const $mitt: import("mitt").Emitter<Record<import("mitt").EventType, unknown>>;
4
4
  export declare function isModuleObject(value: unknown): value is Record<string, any>;
5
5
  export declare function registerWindow<T extends any>(key: string, value: T): void;
6
+ interface OpenWindowOptions {
7
+ noopener?: boolean;
8
+ noreferrer?: boolean;
9
+ target?: '_blank' | '_parent' | '_self' | '_top' | string;
10
+ }
11
+ declare function openWindow(url: string, options?: OpenWindowOptions): void;
12
+ declare function openRouteInNewWindow(path: string): void;
6
13
  //#endregion
7
- export { axios$1 as axios };
14
+ export { axios$1 as axios, openRouteInNewWindow, openWindow };
@@ -35,5 +35,25 @@ registerWindow("CryptoJS", CryptoJS);
35
35
  registerWindow("VueLowlight", VueLowlight);
36
36
  registerWindow("hljs", hljs_default);
37
37
  registerWindow("process", { env: { NODE_ENV: "production" } });
38
+ /**
39
+ * 新窗口打开URL。
40
+ *
41
+ * @param url - 需要打开的网址。
42
+ * @param options - 打开窗口的选项。
43
+ */
44
+ function openWindow(url, options = {}) {
45
+ const { noopener = true, noreferrer = true, target = "_blank" } = options;
46
+ const features = [noopener && "noopener=yes", noreferrer && "noreferrer=yes"].filter(Boolean).join(",");
47
+ window.open(url, target, features);
48
+ }
49
+ /**
50
+ * 在新窗口中打开路由。
51
+ * @param path
52
+ */
53
+ function openRouteInNewWindow(path) {
54
+ const { hash, origin } = location;
55
+ const fullPath = path.startsWith("/") ? path : `/${path}`;
56
+ openWindow(`${origin}${hash && !fullPath.startsWith("/#") ? "/#" : ""}${fullPath}`, { target: "_blank" });
57
+ }
38
58
  //#endregion
39
- export { $mitt, axios$1 as axios, isModuleObject, registerWindow };
59
+ export { $mitt, axios$1 as axios, isModuleObject, openRouteInNewWindow, openWindow, registerWindow };