@owocow/saber-ui 0.0.5 → 0.0.6
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/dist/utils/http.d.ts +32 -0
- package/dist/utils/http.mjs +174 -90
- package/dist/utils/index.mjs +24 -22
- package/package.json +1 -1
package/dist/utils/http.d.ts
CHANGED
|
@@ -23,6 +23,29 @@ export interface HttpConfig {
|
|
|
23
23
|
/** 加密响应头的 key,默认 `'encrypt-key'` */
|
|
24
24
|
encryptHeaderKey?: string;
|
|
25
25
|
}
|
|
26
|
+
/** 二进制请求选项,适用于下载、导出以及文件预览。 */
|
|
27
|
+
export interface BlobRequestOptions {
|
|
28
|
+
/** 请求方法,默认 GET。 */
|
|
29
|
+
method?: HttpMethod;
|
|
30
|
+
/** 非 GET 请求体;普通对象会由 ofetch 序列化为 JSON。 */
|
|
31
|
+
data?: BodyInit | Record<string, unknown>;
|
|
32
|
+
/** URL 查询参数。 */
|
|
33
|
+
params?: Record<string, unknown>;
|
|
34
|
+
/** 是否携带 Bearer Token,默认 true。 */
|
|
35
|
+
withToken?: boolean;
|
|
36
|
+
/** 附加或覆盖请求头;显式 Authorization 优先于自动注入的 Token。 */
|
|
37
|
+
headers?: HeadersInit;
|
|
38
|
+
/** 用于主动取消下载或预览请求。 */
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
}
|
|
41
|
+
/** 二进制响应,以及服务端提供的可选文件元数据。 */
|
|
42
|
+
export interface BlobResponse {
|
|
43
|
+
blob: Blob;
|
|
44
|
+
/** 从 Content-Disposition 解析并去除路径片段后的文件名。 */
|
|
45
|
+
fileName?: string;
|
|
46
|
+
/** 响应 Content-Type;响应头缺失时回退到 Blob.type。 */
|
|
47
|
+
contentType?: string;
|
|
48
|
+
}
|
|
26
49
|
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
27
50
|
interface RequestOptions {
|
|
28
51
|
method?: HttpMethod;
|
|
@@ -39,6 +62,12 @@ interface UploadOptions {
|
|
|
39
62
|
}
|
|
40
63
|
export declare function setupHttp(config: HttpConfig): void;
|
|
41
64
|
export declare function request<T = unknown>(url: string, options?: RequestOptions): Promise<T>;
|
|
65
|
+
/**
|
|
66
|
+
* 请求二进制内容,但不触发浏览器下载。
|
|
67
|
+
*
|
|
68
|
+
* PDF/图片预览可直接消费返回的 blob;需要保存到本地时再调用 saveBlob()。
|
|
69
|
+
*/
|
|
70
|
+
export declare function requestBlob(url: string, options?: BlobRequestOptions): Promise<BlobResponse>;
|
|
42
71
|
export declare const http: {
|
|
43
72
|
get<T = unknown, P extends object = object>(url: string, params?: P, withToken?: boolean): Promise<ApiResponse<T>>;
|
|
44
73
|
list<T = unknown, P extends object = object>(url: string, params?: P, withToken?: boolean): Promise<ListResult<T>>;
|
|
@@ -46,5 +75,8 @@ export declare const http: {
|
|
|
46
75
|
put<T = unknown, D extends object = object>(url: string, data?: D, withToken?: boolean, encrypt?: boolean): Promise<ApiResponse<T>>;
|
|
47
76
|
patch<T = unknown, D extends object = object>(url: string, data?: D, withToken?: boolean, encrypt?: boolean): Promise<ApiResponse<T>>;
|
|
48
77
|
delete<T = unknown, D extends object = object>(url: string, data?: D, withToken?: boolean): Promise<ApiResponse<T>>;
|
|
78
|
+
blob(url: string, options?: BlobRequestOptions): Promise<BlobResponse>;
|
|
49
79
|
upload<T = unknown>(url: string, file: File | File[], options?: UploadOptions): Promise<T>;
|
|
50
80
|
};
|
|
81
|
+
/** 使用临时 Object URL 将 Blob 保存到本地。 */
|
|
82
|
+
export declare function saveBlob(blob: Blob, fileName: string): void;
|
package/dist/utils/http.mjs
CHANGED
|
@@ -1,147 +1,231 @@
|
|
|
1
1
|
import { ofetch as H } from "ofetch";
|
|
2
|
-
import { decryptBase64 as
|
|
3
|
-
import { rsaDecrypt as
|
|
4
|
-
import { storage as
|
|
5
|
-
import { getToast as
|
|
6
|
-
let
|
|
7
|
-
function
|
|
8
|
-
if (!
|
|
2
|
+
import { decryptBase64 as O, decryptWithAes as P, generateAesKey as N, encryptBase64 as _, encryptWithAes as S } from "./crypto.mjs";
|
|
3
|
+
import { rsaDecrypt as z, rsaEncrypt as G } from "./rsa.mjs";
|
|
4
|
+
import { storage as U } from "./storage.mjs";
|
|
5
|
+
import { getToast as b } from "./toast.mjs";
|
|
6
|
+
let T = "", A = "", v = "token", m = null, R = !1, L = "encrypt-key", B = null, k = null;
|
|
7
|
+
function K() {
|
|
8
|
+
if (!B)
|
|
9
9
|
throw new Error("[http] 尚未初始化,请先调用 setupHttp({ baseURL, clientId, onAuthError })");
|
|
10
|
-
return
|
|
10
|
+
return B;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
|
|
12
|
+
function q() {
|
|
13
|
+
if (!k)
|
|
14
|
+
throw new Error("[http] 尚未初始化,请先调用 setupHttp({ baseURL, clientId, onAuthError })");
|
|
15
|
+
return k;
|
|
16
|
+
}
|
|
17
|
+
function I(r) {
|
|
18
|
+
const e = new Headers({ Clientid: A });
|
|
19
|
+
return new Headers(r).forEach((t, o) => e.set(o, t)), e;
|
|
14
20
|
}
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
baseURL:
|
|
21
|
+
function V(r) {
|
|
22
|
+
T = r.baseURL, A = r.clientId, m = r.onAuthError, v = r.tokenKey ?? "token", R = r.encryptEnabled ?? !1, L = r.encryptHeaderKey ?? "encrypt-key", B = H.create({
|
|
23
|
+
baseURL: T,
|
|
18
24
|
timeout: r.timeout ?? 1e4,
|
|
19
|
-
async onResponse({ response:
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
const c =
|
|
23
|
-
|
|
24
|
-
} else if (typeof
|
|
25
|
+
async onResponse({ response: e }) {
|
|
26
|
+
const t = R ? e.headers.get(L) : null;
|
|
27
|
+
if (t) {
|
|
28
|
+
const c = O(String(z(t)));
|
|
29
|
+
e._data = JSON.parse(P(String(e._data), c));
|
|
30
|
+
} else if (typeof e._data == "string")
|
|
25
31
|
try {
|
|
26
|
-
|
|
32
|
+
e._data = JSON.parse(e._data);
|
|
27
33
|
} catch {
|
|
28
34
|
}
|
|
29
|
-
const o =
|
|
35
|
+
const o = e._data;
|
|
30
36
|
if (!o) return;
|
|
31
|
-
const { code: n, msg:
|
|
37
|
+
const { code: n, msg: a } = o;
|
|
32
38
|
if (n === 200) return;
|
|
33
|
-
const
|
|
39
|
+
const l = b();
|
|
34
40
|
if (n === 401) {
|
|
35
|
-
|
|
41
|
+
l.add({ title: a, color: "error" }), m == null || m();
|
|
36
42
|
return;
|
|
37
43
|
}
|
|
38
44
|
if (n === 402 || n === 403) {
|
|
39
|
-
|
|
45
|
+
l.add({ title: a ?? "无权限访问该资源", color: "error" });
|
|
40
46
|
return;
|
|
41
47
|
}
|
|
42
48
|
if (n === 404) {
|
|
43
|
-
|
|
49
|
+
l.add({ title: "后端 API 不存在", color: "error" });
|
|
44
50
|
return;
|
|
45
51
|
}
|
|
46
|
-
throw
|
|
52
|
+
throw l.add({ title: a ?? `请求失败,错误码:${n}`, color: "error" }), new Error(a ?? `请求失败,错误码:${n}`);
|
|
47
53
|
},
|
|
48
|
-
onResponseError({ response:
|
|
54
|
+
onResponseError({ response: e }) {
|
|
49
55
|
var n;
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
title: `请求错误 ${
|
|
56
|
+
const t = e.status, o = (n = e._data) == null ? void 0 : n.msg;
|
|
57
|
+
b().add({
|
|
58
|
+
title: `请求错误 ${t}${o ? `:${o}` : ""}`,
|
|
53
59
|
color: "error"
|
|
54
60
|
});
|
|
55
61
|
}
|
|
62
|
+
}), k = H.create({
|
|
63
|
+
baseURL: T,
|
|
64
|
+
timeout: r.timeout ?? 1e4
|
|
56
65
|
});
|
|
57
66
|
}
|
|
58
|
-
function
|
|
59
|
-
const { method:
|
|
60
|
-
if (
|
|
61
|
-
const
|
|
62
|
-
|
|
67
|
+
function E(r, e = {}) {
|
|
68
|
+
const { method: t = "GET", data: o, params: n, withToken: a = !0, encrypt: l = !1 } = e, c = I();
|
|
69
|
+
if (a) {
|
|
70
|
+
const s = U.get(v);
|
|
71
|
+
s && c.set("Authorization", `Bearer ${s}`);
|
|
63
72
|
}
|
|
64
|
-
let
|
|
65
|
-
if (
|
|
66
|
-
const
|
|
67
|
-
c.set(
|
|
73
|
+
let u = t !== "GET" ? o : void 0, f;
|
|
74
|
+
if (R && l && (t === "POST" || t === "PUT" || t === "PATCH") && u) {
|
|
75
|
+
const s = N();
|
|
76
|
+
c.set(L, String(G(_(s)))), u = S(typeof u == "object" ? JSON.stringify(u) : String(u), s), f = "text";
|
|
68
77
|
}
|
|
69
|
-
return
|
|
70
|
-
method:
|
|
78
|
+
return K()(r, {
|
|
79
|
+
method: t,
|
|
71
80
|
headers: c,
|
|
72
|
-
body:
|
|
73
|
-
query:
|
|
74
|
-
responseType:
|
|
81
|
+
body: u,
|
|
82
|
+
query: t === "GET" ? { ...n, _t: Date.now() } : void 0,
|
|
83
|
+
responseType: f
|
|
75
84
|
});
|
|
76
85
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
function $(r) {
|
|
87
|
+
var o;
|
|
88
|
+
return ((o = r.trim().replace(/^['"]|['"]$/g, "").replace(/[\r\n]/g, "").split(/[\\/]/).pop()) == null ? void 0 : o.trim()) || void 0;
|
|
89
|
+
}
|
|
90
|
+
function C(r) {
|
|
91
|
+
if (!r) return;
|
|
92
|
+
const e = r.match(/filename\*\s*=\s*(?:[^']*'[^']*')?([^;]+)/i);
|
|
93
|
+
if (e != null && e[1]) {
|
|
94
|
+
const o = e[1].trim().replace(/^['"]|['"]$/g, "");
|
|
95
|
+
try {
|
|
96
|
+
return $(decodeURIComponent(o));
|
|
97
|
+
} catch {
|
|
98
|
+
return $(o);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const t = r.match(/filename\s*=\s*(?:"([^"]*)"|([^;]*))/i);
|
|
102
|
+
return $((t == null ? void 0 : t[1]) ?? (t == null ? void 0 : t[2]) ?? "");
|
|
103
|
+
}
|
|
104
|
+
async function x(r, e) {
|
|
105
|
+
if (!e || !/(?:^|\/)json(?:;|$)|\+json(?:;|$)/i.test(e)) return null;
|
|
106
|
+
try {
|
|
107
|
+
const t = JSON.parse(await r.text());
|
|
108
|
+
if (!t || typeof t != "object") return null;
|
|
109
|
+
const o = t, n = typeof o.code == "number" ? o.code : void 0, a = typeof o.msg == "string" ? o.msg : void 0;
|
|
110
|
+
return n !== void 0 || a !== void 0 ? { code: n, msg: a } : null;
|
|
111
|
+
} catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function J(r, e) {
|
|
116
|
+
const t = (e == null ? void 0 : e.code) !== void 0 && e.code !== 200 ? e.code : r;
|
|
117
|
+
let o = e == null ? void 0 : e.msg;
|
|
118
|
+
throw t === 401 ? (o ?? (o = "登录状态已失效"), b().add({ title: o, color: "error" }), m == null || m(), new Error(o)) : (t === 402 || t === 403 ? o ?? (o = "无权限访问该资源") : t === 404 ? o ?? (o = "后端 API 不存在") : o ?? (o = r >= 400 ? `请求错误 ${r}` : `请求失败,错误码:${t}`), b().add({ title: o, color: "error" }), new Error(o));
|
|
119
|
+
}
|
|
120
|
+
async function D(r, e = {}) {
|
|
121
|
+
const { method: t = "GET", data: o, params: n, withToken: a = !0, headers: l, signal: c } = e, u = I(l);
|
|
122
|
+
if (a) {
|
|
123
|
+
const i = U.get(v);
|
|
124
|
+
i && !u.has("Authorization") && u.set("Authorization", `Bearer ${i}`);
|
|
125
|
+
}
|
|
126
|
+
let f;
|
|
127
|
+
try {
|
|
128
|
+
f = await q().raw(r, {
|
|
129
|
+
method: t,
|
|
130
|
+
headers: u,
|
|
131
|
+
body: t === "GET" ? void 0 : o,
|
|
132
|
+
query: t === "GET" ? { ...n, _t: Date.now() } : n,
|
|
133
|
+
responseType: "blob",
|
|
134
|
+
ignoreResponseError: !0,
|
|
135
|
+
signal: c
|
|
136
|
+
});
|
|
137
|
+
} catch (i) {
|
|
138
|
+
throw c != null && c.aborted || b().add({ title: "文件请求失败", color: "error" }), i;
|
|
139
|
+
}
|
|
140
|
+
const h = f._data ?? new Blob(), s = f.headers.get("content-type") || h.type || void 0, d = await x(h, s);
|
|
141
|
+
return (!f.ok || (d == null ? void 0 : d.code) !== void 0 && d.code !== 200) && J(f.status, d), {
|
|
142
|
+
blob: h,
|
|
143
|
+
fileName: C(f.headers.get("content-disposition")),
|
|
144
|
+
contentType: s
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const Y = {
|
|
148
|
+
get(r, e, t = !0) {
|
|
149
|
+
return E(r, { method: "GET", params: e, withToken: t });
|
|
150
|
+
},
|
|
151
|
+
list(r, e, t = !0) {
|
|
152
|
+
return E(r, { method: "GET", params: e, withToken: t });
|
|
80
153
|
},
|
|
81
|
-
|
|
82
|
-
return
|
|
154
|
+
post(r, e, t = !0, o = !1) {
|
|
155
|
+
return E(r, { method: "POST", data: e, withToken: t, encrypt: o });
|
|
83
156
|
},
|
|
84
|
-
|
|
85
|
-
return
|
|
157
|
+
put(r, e, t = !0, o = !1) {
|
|
158
|
+
return E(r, { method: "PUT", data: e, withToken: t, encrypt: o });
|
|
86
159
|
},
|
|
87
|
-
|
|
88
|
-
return
|
|
160
|
+
patch(r, e, t = !0, o = !1) {
|
|
161
|
+
return E(r, { method: "PATCH", data: e, withToken: t, encrypt: o });
|
|
89
162
|
},
|
|
90
|
-
|
|
91
|
-
return
|
|
163
|
+
delete(r, e, t = !0) {
|
|
164
|
+
return E(r, { method: "DELETE", data: e, withToken: t });
|
|
92
165
|
},
|
|
93
|
-
|
|
94
|
-
return
|
|
166
|
+
blob(r, e = {}) {
|
|
167
|
+
return D(r, e);
|
|
95
168
|
},
|
|
96
|
-
upload(r,
|
|
97
|
-
const { data: o, field: n = "file", onProgress:
|
|
98
|
-
(Array.isArray(
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
-
const
|
|
102
|
-
|
|
169
|
+
upload(r, e, t = {}) {
|
|
170
|
+
const { data: o, field: n = "file", onProgress: a, withToken: l = !0 } = t, c = new FormData();
|
|
171
|
+
(Array.isArray(e) ? e : [e]).forEach((s) => c.append(n, s)), o && Object.entries(o).forEach(([s, d]) => c.append(s, d));
|
|
172
|
+
const f = T, h = { Clientid: A };
|
|
173
|
+
if (l) {
|
|
174
|
+
const s = U.get(v);
|
|
175
|
+
s && (h.Authorization = `Bearer ${s}`);
|
|
103
176
|
}
|
|
104
|
-
return new Promise((
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}),
|
|
109
|
-
if (
|
|
110
|
-
|
|
177
|
+
return new Promise((s, d) => {
|
|
178
|
+
const i = new XMLHttpRequest();
|
|
179
|
+
i.open("POST", `${f}${r}`), Object.entries(h).forEach(([y, p]) => i.setRequestHeader(y, p)), a && i.upload.addEventListener("progress", (y) => {
|
|
180
|
+
y.lengthComputable && a(Math.round(y.loaded / y.total * 100));
|
|
181
|
+
}), i.addEventListener("load", () => {
|
|
182
|
+
if (i.status < 200 || i.status >= 300) {
|
|
183
|
+
b().add({ title: `请求错误 ${i.status}`, color: "error" }), d(new Error(`请求错误 ${i.status}`));
|
|
111
184
|
return;
|
|
112
185
|
}
|
|
113
|
-
let
|
|
186
|
+
let y;
|
|
114
187
|
try {
|
|
115
|
-
|
|
188
|
+
y = JSON.parse(i.responseText);
|
|
116
189
|
} catch {
|
|
117
|
-
|
|
190
|
+
d(new Error("响应解析失败"));
|
|
118
191
|
return;
|
|
119
192
|
}
|
|
120
|
-
const { code:
|
|
121
|
-
if (
|
|
122
|
-
|
|
193
|
+
const { code: p, msg: w } = y;
|
|
194
|
+
if (p === 200) {
|
|
195
|
+
s(y.data);
|
|
123
196
|
return;
|
|
124
197
|
}
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
127
|
-
|
|
198
|
+
const g = b();
|
|
199
|
+
if (p === 401) {
|
|
200
|
+
g.add({ title: w, color: "error" }), m == null || m(), d(new Error(w ?? `鉴权失败,错误码:${p}`));
|
|
128
201
|
return;
|
|
129
202
|
}
|
|
130
|
-
if (
|
|
131
|
-
|
|
203
|
+
if (p === 402 || p === 403) {
|
|
204
|
+
g.add({ title: w ?? "无权限访问该资源", color: "error" }), d(new Error(w ?? `无权限,错误码:${p}`));
|
|
132
205
|
return;
|
|
133
206
|
}
|
|
134
|
-
if (
|
|
135
|
-
|
|
207
|
+
if (p === 404) {
|
|
208
|
+
g.add({ title: "后端 API 不存在", color: "error" }), d(new Error("后端 API 不存在"));
|
|
136
209
|
return;
|
|
137
210
|
}
|
|
138
|
-
|
|
139
|
-
}),
|
|
211
|
+
g.add({ title: w ?? `上传失败,错误码:${p}`, color: "error" }), d(new Error(w ?? `上传失败,错误码:${p}`));
|
|
212
|
+
}), i.addEventListener("error", () => d(new Error("上传请求失败"))), i.send(c);
|
|
140
213
|
});
|
|
141
214
|
}
|
|
142
215
|
};
|
|
216
|
+
function Z(r, e) {
|
|
217
|
+
var a, l;
|
|
218
|
+
if (typeof document > "u" || typeof ((a = globalThis.URL) == null ? void 0 : a.createObjectURL) != "function")
|
|
219
|
+
throw new Error("[saveBlob] 仅支持浏览器环境");
|
|
220
|
+
const t = $(e);
|
|
221
|
+
if (!t) throw new Error("[saveBlob] fileName 不能为空");
|
|
222
|
+
const o = globalThis.URL.createObjectURL(r), n = document.createElement("a");
|
|
223
|
+
n.href = o, n.download = t, n.rel = "noopener", n.style.display = "none", (l = document.body) == null || l.append(n), n.click(), n.remove(), setTimeout(() => globalThis.URL.revokeObjectURL(o), 4e4);
|
|
224
|
+
}
|
|
143
225
|
export {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
226
|
+
Y as http,
|
|
227
|
+
E as request,
|
|
228
|
+
D as requestBlob,
|
|
229
|
+
Z as saveBlob,
|
|
230
|
+
V as setupHttp
|
|
147
231
|
};
|
package/dist/utils/index.mjs
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
|
-
import { canAccess as t, hasPermission as o, hasRole as s, setupPermission as
|
|
1
|
+
import { canAccess as t, hasPermission as o, hasRole as s, setupPermission as a } from "./permission.mjs";
|
|
2
2
|
import { formatCurrency as m } from "./format.mjs";
|
|
3
3
|
import { createFilterOptions as c } from "./filter.mjs";
|
|
4
4
|
import { createTreeFromList as x } from "./tree.mjs";
|
|
5
|
-
import { decryptBase64 as y, decryptWithAes as d, encryptBase64 as u, encryptWithAes as
|
|
6
|
-
import { getToast as
|
|
7
|
-
import { setupStorage as
|
|
8
|
-
import { rsaDecrypt as
|
|
9
|
-
import { http as
|
|
5
|
+
import { decryptBase64 as y, decryptWithAes as d, encryptBase64 as u, encryptWithAes as l, generateAesKey as h } from "./crypto.mjs";
|
|
6
|
+
import { getToast as g, setToast as B, tryGetToast as P } from "./toast.mjs";
|
|
7
|
+
import { setupStorage as b, storage as q } from "./storage.mjs";
|
|
8
|
+
import { rsaDecrypt as F, rsaEncrypt as R, setupRsa as W } from "./rsa.mjs";
|
|
9
|
+
import { http as k, request as v, requestBlob as D, saveBlob as E, setupHttp as G } from "./http.mjs";
|
|
10
10
|
import { klona as K } from "klona/json";
|
|
11
11
|
import { nanoid as O } from "nanoid";
|
|
12
|
-
import { addressParse as
|
|
12
|
+
import { addressParse as w, createAddressParser as z } from "./addressParse.mjs";
|
|
13
13
|
export {
|
|
14
|
-
|
|
14
|
+
w as addressParse,
|
|
15
15
|
t as canAccess,
|
|
16
|
-
|
|
16
|
+
z as createAddressParser,
|
|
17
17
|
c as createFilterOptions,
|
|
18
18
|
x as createTreeFromList,
|
|
19
19
|
y as decryptBase64,
|
|
20
20
|
d as decryptWithAes,
|
|
21
21
|
u as encryptBase64,
|
|
22
|
-
|
|
22
|
+
l as encryptWithAes,
|
|
23
23
|
m as formatCurrency,
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
h as generateAesKey,
|
|
25
|
+
g as getToast,
|
|
26
26
|
o as hasPermission,
|
|
27
27
|
s as hasRole,
|
|
28
|
-
|
|
28
|
+
k as http,
|
|
29
29
|
K as jsonClone,
|
|
30
30
|
O as nanoid,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
v as request,
|
|
32
|
+
D as requestBlob,
|
|
33
|
+
F as rsaDecrypt,
|
|
34
|
+
R as rsaEncrypt,
|
|
35
|
+
E as saveBlob,
|
|
36
|
+
B as setToast,
|
|
35
37
|
G as setupHttp,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
a as setupPermission,
|
|
39
|
+
W as setupRsa,
|
|
40
|
+
b as setupStorage,
|
|
41
|
+
q as storage,
|
|
42
|
+
P as tryGetToast
|
|
41
43
|
};
|