@vtj/utils
Version:
VTJ 是一款基于 Vue3 + Typescript 的低代码页面可视化设计器。内置低代码引擎、渲染器和代码生成器,面向前端开发者,开箱即用。 无缝嵌入本地开发工程,不改变前端开发流程和编码习惯。
761 lines (760 loc) • 22.4 kB
JavaScript
var N = Object.defineProperty;
var $ = (n, e, t) => e in n ? N(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
var p = (n, e, t) => $(n, typeof e != "symbol" ? e + "" : e, t);
import { omit as O, merge as v, debounce as H, throttle as V, isUrl as T, pathToRegexpCompile as z, uuid as X, rURL as Y, template as K } from "@vtj/base";
export * from "@vtj/base";
import { ref as R } from "vue";
import A from "axios";
import { default as Ge } from "axios";
(function() {
if (typeof window > "u" || typeof EventTarget > "u")
return;
const n = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(e, t, o) {
typeof o != "boolean" && (o = o || {}, o.passive = !1), n.call(this, e, t, o);
};
})();
/**!
* Copyright (c) 2026, VTJ.PRO All rights reserved.
* @name @vtj/utils
* @author CHC chenhuachun1549@dingtalk.com
* @version 0.18.27
* @license <a href="https://vtj.pro/license.html">MIT License</a>
*/
const Le = "0.18.27", Q = {
form: "application/x-www-form-urlencoded",
json: "application/json",
data: "multipart/form-data"
}, G = ["put", "post", "patch"], P = "Local-Request-Id", Z = 100, ee = 300, te = "/api/proxy";
class ne {
constructor(e = {}) {
p(this, "axios");
p(this, "settings");
p(this, "records", {});
p(this, "isLoading", !1);
p(this, "stopSkipWarn");
p(this, "showLoading");
p(this, "showError");
this.settings = Object.assign({ type: "form" }, e.settings || {});
const t = O(e, [
"settings",
"query"
]);
this.axios = A.create(
v(
{
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
timeout: 120 * 1e3
},
t
)
), this.setupSkipWarn(this.settings), this.showLoading = H(this.openLoading.bind(this), Z), this.showError = V(this._showError.bind(this), ee, {
leading: !0,
trailing: !1
});
}
setConfig(e = {}) {
this.settings = v(this.settings, e.settings || {});
const t = O(e, [
"settings",
"query"
]);
this.axios.defaults = v(this.axios.defaults, t), this.setupSkipWarn(this.settings);
}
cancel(e, t = "请求已取消") {
if (e) {
const o = this.records[e];
if (!o) return;
o.source.cancel(t);
} else
for (const o of Object.values(this.records))
o.source.cancel(t);
}
createHeaders(e, t, o) {
const r = t.injectHeaders ? typeof t.headers == "function" ? t.headers(e, o, t) : t.headers || {} : {}, s = {
"Content-Type": Q[t.type || "form"],
...o.headers,
...r
};
return t.skipWarn && (s[P] = e), s;
}
isJsonType(e) {
return Object.entries(e).some(([t, o]) => t.toLowerCase() === "content-type" && String(o).includes("application/json"));
}
toFormData(e, t = "data") {
if (e instanceof FormData || e instanceof URLSearchParams)
return e;
const o = t === "data" ? new FormData() : new URLSearchParams();
return Object.entries(e).forEach(([r, s]) => {
o.append(r, s);
}), o;
}
createSendData(e, t, o, r, s = {}) {
const { type: i, skipWarn: c } = e, { name: a = "skipWarn" } = c || {};
let { data: d, params: l = {}, method: u = "get" } = t;
const h = r ? { [a]: !0 } : {};
return G.includes(u.toLowerCase()) ? (d = Object.assign(d || {}, h), d = i !== "json" || !this.isJsonType(o) ? this.toFormData(d, i) : d, l = {
...s
}) : i === "form" ? l = {
...d || {},
...s,
...h
} : (d && (i !== "json" || !this.isJsonType(o)) && (d = this.toFormData(d, i)), l = {
...s,
...h
}), {
data: d,
params: l
};
}
createUrl(e) {
let { url: t, params: o } = e;
if (t) {
let r = T(t) ? new URL(t).origin : "";
const s = r ? t.replace(r, "") : t;
try {
const i = z(s, {
encode: encodeURIComponent
});
return r + i(o || {});
} catch {
console.warn("createUrl", "pathToRegexpCompile error", t);
}
}
return t;
}
createProxy(e, t, o) {
if (!e.proxy)
return {
url: t,
headers: o
};
const r = e.proxyPath || te, { protocol: s, host: i } = location || {}, c = T(t) ? t : `${s}//${i}${t}`;
return o.Target = c, {
url: r,
headers: o
};
}
openLoading(e) {
const { loading: t, showLoading: o } = e;
t && o && Object.keys(this.records).length > 0 && (this.isLoading = !0, o());
}
closeLoading(e) {
const { hideLoading: t } = e;
this.isLoading = !1;
const o = Object.keys(this.records);
t && o.length === 0 && (this.isLoading = !1, t());
}
_showError(e, t) {
const { failMessage: o, showError: r } = e;
if (o && r) {
const s = t?.response?.data, i = s?.message || s?.msg || t?.message || t?.msg || "未知错误";
r(i, t);
}
}
validResponse(e, t) {
const { validSuccess: o, validate: r } = e;
return o && r ? !!r(t) : !0;
}
isSkipWarnResponse(e) {
return !!e.promise;
}
send(e = {}, t = !1) {
const o = v({}, this.settings, e.settings || {}), r = e.query || {}, s = O(e, [
"settings",
"query"
]), i = X(!1), c = A.CancelToken.source();
this.records[i] = { settings: o, config: s, source: c };
const a = this.createUrl(s) || "", d = this.createHeaders(i, o, s), { url: l, headers: u } = this.createProxy(o, a, d), { data: h, params: y } = this.createSendData(
o,
s,
u,
t,
r
);
return this.showLoading(o), new Promise((g, S) => {
this.axios({
cancelToken: c.token,
...s,
url: l,
headers: u,
data: h,
params: y
}).then((f) => this.isSkipWarnResponse(f) ? g(f.promise) : this.validResponse(o, f) ? g(o.originResponse ? f : f.data?.data) : (this.showError(o, f.data), S(f.data))).catch((f) => (this.showError(o, f), S(f))).finally(() => {
delete this.records[i], this.closeLoading(o);
});
});
}
useResponse(e, t) {
const { response: o } = this.axios.interceptors, r = o.use(e, t);
return () => o.eject(r);
}
useRequest(e, t) {
const { request: o } = this.axios.interceptors, r = o.use(e, t);
return () => o.eject(r);
}
setupSkipWarn(e) {
if (this.stopSkipWarn && (this.stopSkipWarn(), this.stopSkipWarn = void 0), !e.skipWarn) return;
const { code: t, executor: o, callback: r, complete: s } = e.skipWarn;
this.stopSkipWarn = this.useResponse((i) => {
const a = (i.config.headers || {})[P], d = this.records[a];
if (!d) return i;
const { data: l } = i;
if (!l || typeof l != "object") return i;
if (l?.code === t) {
r && r(i);
const u = new Promise(o).then(() => this.send(
{
...d.config,
settings: d.settings
},
!0
));
u.catch((h) => h).finally(() => {
s && s();
}), i.promise = u;
}
return i;
});
}
}
function oe(n = {}) {
const e = new ne(n), t = e.send.bind(e), o = e.cancel.bind(e), r = e.setConfig.bind(e), s = e.useRequest.bind(e), i = e.useResponse.bind(e);
return Object.assign(t, {
...e,
instance: e,
send: t,
cancel: o,
setConfig: r,
useRequest: s,
useResponse: i
});
}
const F = oe({
settings: {
injectHeaders: !0,
loading: !0,
originResponse: !0
}
});
function re(n, e = F) {
const t = typeof n == "string" ? { url: n } : n;
return (o, r) => e.send(v({}, t, r || {}, { data: o }));
}
function Te(n, e = F) {
const t = {};
for (const [o, r] of Object.entries(n))
t[o] = re(r, e);
return t;
}
function Ae(n, e) {
const t = R(null), o = R(), r = R(!0), s = () => {
r.value = !0, o.value = void 0, (typeof n == "function" ? n() : n).then((c) => {
t.value = e ? e(c) : c;
}).catch((c) => {
o.value = c;
}).finally(() => {
r.value = !1;
});
};
return s(), {
data: t,
error: o,
loading: r,
reload: s
};
}
const x = typeof window < "u", Pe = (n) => new Promise((e, t) => {
const o = new FileReader();
o.readAsDataURL(n), o.onload = () => {
e(o.result);
}, o.onerror = (r) => {
t(r);
};
});
function Ue(n) {
const e = {};
return n ? (n.forEach((t, o) => {
e[o] = typeof t == "string" ? decodeURIComponent(t) : t;
}), e) : {};
}
function Me(n) {
const e = n.split(","), t = e[0].match(/:(.*?);/)?.[1], o = atob(e[1]);
let r = o.length;
const s = new Uint8Array(r);
for (; r--; )
s[r] = o.charCodeAt(r);
return new Blob([s], { type: t });
}
function De(n, e) {
const t = n;
return t.lastModified = Date.now(), t.lastModifiedDate = /* @__PURE__ */ new Date(), t.name = e, t;
}
const Fe = (n) => x ? window.requestAnimationFrame(n) : setTimeout(n, 16), Ie = (n) => x ? window.cancelAnimationFrame(n) : clearTimeout(n);
class se {
constructor(e = {}) {
p(this, "options", {
type: "cache",
expired: 0,
prefix: "__VTJ_"
});
p(this, "caches", {});
p(this, "types");
this.types = {
local: x ? window.localStorage : this.caches,
session: x ? window.sessionStorage : this.caches,
cache: this.caches
}, this.config(e);
}
config(e = {}) {
this.options = Object.assign(this.options, e);
}
save(e, t, o = {}) {
const { type: r, expired: s, prefix: i } = { ...this.options, ...o }, c = Date.now(), a = i + e, d = this.types[r] || this.caches, l = {
value: t,
timestamp: c,
expired: s
};
d === this.caches ? d[a] = l : d.setItem(a, JSON.stringify(l));
}
get(e, t = {}) {
const { type: o, prefix: r } = { ...this.options, ...t }, s = r + e, i = this.types[o] || this.caches;
let c;
if (i === this.caches)
c = i[s];
else {
const h = i.getItem(s);
if (h)
try {
c = JSON.parse(h);
} catch (y) {
console.warn("[Storage] JSON.parse", y);
}
}
if (!c) return null;
const { value: a, timestamp: d, expired: l } = c;
return l > 0 && d + l < Date.now() ? (this.remove(e, t), null) : a;
}
remove(e, t = {}) {
const { type: o, prefix: r } = { ...this.options, ...t }, s = this.types[o] || this.caches, i = r + e;
s === this.caches ? delete s[i] : s.removeItem(i);
}
clear(e = {}) {
const { type: t } = { ...this.options, ...e }, o = this.types[t] || this.caches;
o === this.caches ? this.caches = {} : o.clear();
}
}
const Je = new se();
function I(n) {
return n && n.__esModule && Object.prototype.hasOwnProperty.call(n, "default") ? n.default : n;
}
var b = { exports: {} }, ie = b.exports, U;
function ce() {
return U || (U = 1, (function(n, e) {
(function(t, o) {
o(e, n);
})(ie, function(t, o) {
var r = {
timeout: 5e3,
jsonpCallback: "callback"
};
function s() {
return "jsonp_" + Date.now() + "_" + Math.ceil(Math.random() * 1e5);
}
function i(d) {
try {
delete window[d];
} catch {
window[d] = void 0;
}
}
function c(d) {
var l = document.getElementById(d);
l && document.getElementsByTagName("head")[0].removeChild(l);
}
function a(d) {
var l = arguments.length <= 1 || arguments[1] === void 0 ? {} : arguments[1], u = d, h = l.timeout || r.timeout, y = l.jsonpCallback || r.jsonpCallback, g = void 0;
return new Promise(function(S, f) {
var m = l.jsonpCallbackFunction || s(), j = y + "_" + m;
window[m] = function(q) {
S({
ok: !0,
// keep consistent with fetch API
json: function() {
return Promise.resolve(q);
}
}), g && clearTimeout(g), c(j), i(m);
}, u += u.indexOf("?") === -1 ? "?" : "&";
var w = document.createElement("script");
w.setAttribute("src", "" + u + y + "=" + m), l.charset && w.setAttribute("charset", l.charset), l.nonce && w.setAttribute("nonce", l.nonce), l.referrerPolicy && w.setAttribute("referrerPolicy", l.referrerPolicy), l.crossorigin && w.setAttribute("crossorigin", "true"), w.id = j, document.getElementsByTagName("head")[0].appendChild(w), g = setTimeout(function() {
f(new Error("JSONP request to " + d + " timed out")), i(m), c(j), window[m] = function() {
i(m);
};
}, h), w.onerror = function() {
f(new Error("JSONP request to " + d + " failed")), i(m), c(j), g && clearTimeout(g);
};
});
}
o.exports = a;
});
})(b, b.exports)), b.exports;
}
var ae = ce();
const le = /* @__PURE__ */ I(ae);
function de(n) {
if (x) {
const { protocol: e, host: t, pathname: o } = location;
return `${e}//${t}${n ? o : ""}`;
} else
return null;
}
function ue(n = "") {
const e = n.match(Y);
return e ? e[0] : "";
}
function J(n) {
const e = [];
for (const t in n)
Object.prototype.hasOwnProperty.call(n, t) && e.push([t, encodeURIComponent(n[t])].join("="));
return e.join("&");
}
function k(n, e, t) {
const o = {};
n = (n || location.search).replace(/^[^]*\?/, ""), e = e || "&", t = t || "=";
let r;
const s = new RegExp(
"(?:^|\\" + e + ")([^\\" + t + "\\" + e + "]+)(?:\\" + t + "([^\\" + e + "]*))?",
"g"
);
for (; (r = s.exec(n)) !== null; )
r[1] !== n && (o[decodeURIComponent(r[1])] = decodeURIComponent(r[2] || ""));
return o;
}
function W(n, e) {
e = typeof e == "string" ? k(e) : e;
const t = n.split("?")[0], o = k(n), r = Object.assign({}, o, e), s = J(r);
return s ? [t, s].join("?") : n;
}
const We = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
append: W,
getCurrentHost: de,
getHost: ue,
parse: k,
stringify: J
}, Symbol.toStringTag, { value: "Module" }));
async function Be(n, e = {}) {
const { query: t = {} } = e;
n.includes("${") && (n = K(n)(t || {}));
const o = W(n, t);
return await (await le(o, e)).json();
}
var E, M;
function fe() {
if (M) return E;
M = 1, E = function(r, s, i) {
var c = document.head || document.getElementsByTagName("head")[0], a = document.createElement("script");
typeof s == "function" && (i = s, s = {}), s = s || {}, i = i || function() {
}, a.type = s.type || "text/javascript", a.charset = s.charset || "utf8", a.async = "async" in s ? !!s.async : !0, a.src = r, s.attrs && n(a, s.attrs), s.text && (a.text = "" + s.text);
var d = "onload" in a ? e : t;
d(a, i), a.onload || e(a, i), c.appendChild(a);
};
function n(o, r) {
for (var s in r)
o.setAttribute(s, r[s]);
}
function e(o, r) {
o.onload = function() {
this.onerror = this.onload = null, r(null, o);
}, o.onerror = function() {
this.onerror = this.onload = null, r(new Error("Failed to load " + this.src), o);
};
}
function t(o, r) {
o.onreadystatechange = function() {
this.readyState != "complete" && this.readyState != "loaded" || (this.onreadystatechange = null, r(null, o));
};
}
return E;
}
var pe = fe();
const he = /* @__PURE__ */ I(pe);
function qe(n, e = {}) {
return new Promise((t, o) => {
const { library: r } = e;
he(n, e, (s, i) => {
s ? o(s) : t(r ? window[r] : void 0);
});
});
}
const D = { debug: -1, log: 0, info: 0, warn: 1, error: 2 }, ge = function(n, e, t, o) {
return function(...r) {
if (e && D[e] <= D[n] && // @ts-ignore
console[n].apply && (o === "*" || t.startsWith(o)))
return console[n].apply(console, me(r, t));
};
};
function me(n, e) {
return e !== "*" && (typeof n[0] == "string" ? n[0] = `[${e}] ${n[0]}` : n = ["[" + e + "]"].concat(n)), n;
}
function we(n, e) {
if (!n)
return {
targetLevel: e.level,
targetBizName: e.bizName
};
if (~n.indexOf(":")) {
const t = n.split(":");
return {
targetLevel: t[0],
targetBizName: t[1]
};
}
return {
targetLevel: n,
targetBizName: "*"
};
}
const ye = {
level: "warn",
bizName: "*"
};
class ve {
constructor(e) {
p(this, "config");
p(this, "options");
this.options = { ...ye, ...e };
const t = typeof location < "u" ? location : {}, o = (/__(?:logConf|logLevel)__=([^#/&]*)/.exec(
t.href
) || [])[1];
this.config = we(o, e);
}
_log(e) {
const { targetLevel: t, targetBizName: o } = this.config, { bizName: r } = this.options;
return ge(e, t, r, o);
}
debug(...e) {
return this._log("debug")(...e);
}
log(...e) {
return this._log("log")(...e);
}
info(...e) {
return this._log("info")(...e);
}
warn(...e) {
return this._log("warn")(...e);
}
error(...e) {
return this._log("error")(...e);
}
}
function be(n) {
return new ve(n);
}
const Ne = be({ level: "log", bizName: "VTJ" });
/*! js-cookie v3.0.8 | MIT */
function _(n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var o in t)
o !== "__proto__" && (n[o] = t[o]);
}
return n;
}
var xe = {
read: function(n) {
return n[0] === '"' && (n = n.slice(1, -1)), n.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
},
write: function(n) {
return encodeURIComponent(n).replace(
/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
decodeURIComponent
);
}
};
function C(n, e) {
function t(r, s, i) {
if (!(typeof document > "u")) {
i = _({}, e, i), typeof i.expires == "number" && (i.expires = new Date(Date.now() + i.expires * 864e5)), i.expires && (i.expires = i.expires.toUTCString()), r = encodeURIComponent(r).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
var c = "";
for (var a in i)
i[a] && (c += "; " + a, i[a] !== !0 && (c += "=" + i[a].split(";")[0]));
return document.cookie = r + "=" + n.write(s, r) + c;
}
}
function o(r) {
if (!(typeof document > "u" || arguments.length && !r)) {
for (var s = document.cookie ? document.cookie.split("; ") : [], i = {}, c = 0; c < s.length; c++) {
var a = s[c].split("="), d = a.slice(1).join("=");
try {
var l = decodeURIComponent(a[0]);
if (l in i || (i[l] = n.read(d, l)), r === l)
break;
} catch {
}
}
return r ? i[r] : i;
}
}
return Object.create(
{
set: t,
get: o,
remove: function(r, s) {
t(
r,
"",
_({}, s, {
expires: -1
})
);
},
withAttributes: function(r) {
return C(this.converter, _({}, this.attributes, r));
},
withConverter: function(r) {
return C(_({}, this.converter, r), this.attributes);
}
},
{
attributes: { value: Object.freeze(e) },
converter: { value: Object.freeze(n) }
}
);
}
var L = C(xe, { path: "/" });
function Se(n, e, t) {
L.set(n, e, t);
}
function je(n) {
return L.get(n);
}
function _e(n, e) {
L.remove(n, e);
}
const $e = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
get: je,
remove: _e,
set: Se
}, Symbol.toStringTag, { value: "Module" }));
function He(n, e = "") {
const t = document.createElement("a");
t.download = e, t.href = n, t.target = "_blank", t.click();
}
function B(n, e = "", t) {
const o = new Blob([n], { type: t }), r = document.createElement("a");
r.download = e, r.style.display = "none", r.href = URL.createObjectURL(o), r.click(), URL.revokeObjectURL(r.href);
}
async function Ve(n, e = "", t) {
return fetch(n, { credentials: "include" }).then(async (o) => {
const r = await o.blob();
return B(r, e, t), r;
});
}
function ze(n, e = "") {
const t = JSON.stringify(n);
B(t, e, "application/json");
}
function Xe() {
const n = navigator.userAgent;
let e = "Unknown", t = "Unknown", o = "Unknown", r = "Unknown", s = !1;
if (/Windows NT/i.test(n)) {
e = "Windows";
const c = {
"12.0": "12",
"11.0": "11",
"10.0": "10",
"6.3": "8.1",
"6.2": "8",
"6.1": "7",
"6.0": "Vista",
"5.2": "XP 64-bit",
"5.1": "XP"
}, a = n.match(/Windows NT (\d+\.\d+)/);
a && (t = c[a[1]] || a[1]);
} else if (/Mac OS X/i.test(n)) {
e = "Mac OS";
const c = n.match(/Mac OS X (\d+[._]\d+[._]?\d*)/);
c && (t = c[1].replace(/_/g, "."));
} else if (/(iPhone|iPad|iPod)/i.test(n)) {
e = "iOS";
const c = n.match(/OS (\d+[_\.]\d+[_\.]?\d*)/);
c && (t = c[1].replace(/_/g, "."));
} else if (/Android/i.test(n)) {
e = "Android";
const c = n.match(/Android (\d+\.\d+)/);
c && (t = c[1]);
} else /Linux/i.test(n) && (e = "Linux");
const i = n.match(/(Edge|Edg|Edga|EdgA)\/(\d+)/i);
if (i)
o = "Microsoft Edge", r = i[2];
else {
const c = n.match(/Firefox\/(\d+)/i);
if (c)
o = "Firefox", r = c[1];
else {
const a = n.match(/(Opera|OPR)\/(\d+)/i);
if (a)
o = "Opera", r = a[2];
else {
const d = n.match(/Chrome\/(\d+)/i);
if (d)
o = "Chrome", r = d[1];
else {
const l = n.match(/Version\/(\d+\.\d+)/i);
if (l && /Safari/i.test(n))
o = "Safari", r = l[1];
else {
const u = n.match(/(MSIE |Trident.*rv:)(\d+)/i);
u && (o = "Internet Explorer", r = u[2]);
}
}
}
}
}
return s = // 移动设备通用检测
/(iPhone|iPod|iPad|Android|Windows Phone|Mobile)/i.test(n) || // 根据已识别的操作系统补充判断
["iOS", "Android"].includes(e), /(iPad|Tablet|Android(?!.*Mobile))/i.test(n) && (s = !0), {
os: e,
osVersion: t,
browser: o,
browserVersion: r,
isMobile: s
};
}
export {
P as LOCAL_REQUEST_ID,
ve as Logger,
ne as Request,
se as Storage,
Le as VTJ_UTILS_VERSION,
Ge as axios,
De as blobToFile,
Ie as cAF,
$e as cookie,
re as createApi,
Te as createApis,
oe as createRequest,
Me as dataURLtoBlob,
B as downloadBlob,
ze as downloadJson,
Ve as downloadRemoteFile,
He as downloadUrl,
Pe as fileToBase64,
Ue as formDataToJson,
Xe as getClientInfo,
be as getLogger,
x as isClient,
Be as jsonp,
qe as loadScript,
Ne as logger,
Fe as rAF,
F as request,
Je as storage,
We as url,
Ae as useApi
};