@skillbuilder/miniapp-simulator 0.0.0-beta-20261023084421 → 0.2.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/README.md +52 -2
- package/dist/sw/miniapp-simulator-service-worker.js +487 -371
- package/dist/sw/miniapp-simulator-service-worker.min.js +1 -1
- package/docs/external-cli-workbench.md +5 -7
- package/docs/npm-integration-verification.md +1 -11
- package/docs/remote-architecture.md +3 -2
- package/docs/worker-runtime.md +62 -0
- package/lib/{client-BZtD2VtP.mjs → client-CO-UjIY3.mjs} +141 -138
- package/lib/index-B5oixYXr.mjs +574 -0
- package/lib/index.js +1152 -1075
- package/lib/remote-client.js +2 -2
- package/lib/types/capabilities/constants.d.ts +1 -0
- package/lib/types/capabilities/csp-snippet.d.ts +2 -0
- package/lib/types/capabilities/security-head-snippet.d.ts +3 -2
- package/lib/types/index.d.ts +8 -1
- package/lib/types/injection/types.d.ts +2 -0
- package/lib/types/remote/protocol.d.ts +7 -2
- package/lib/types/renderer/content-host/iframe-content-host.d.ts +1 -0
- package/lib/types/sw/protocol.d.ts +3 -1
- package/lib/types/sw/served-entry.d.ts +1 -1
- package/lib/types/sw/service-worker-host.d.ts +1 -0
- package/lib/types/sw/worker/globals.d.ts +1 -0
- package/lib/types/sw/worker/mount-store.d.ts +5 -0
- package/lib/types/types/options.d.ts +8 -1
- package/lib/types/workbench/server/index.d.ts +1 -1
- package/lib/types/worker/adapters/csp-policy.d.ts +7 -0
- package/lib/types/worker/adapters/host-lifecycle.d.ts +5 -0
- package/lib/types/worker/adapters/mount-recovery.d.ts +2 -0
- package/lib/types/worker/adapters/package-policy.d.ts +12 -0
- package/lib/types/worker/adapters/page-lifecycle.d.ts +1 -0
- package/lib/types/worker/adapters/protocol.d.ts +49 -0
- package/lib/types/worker/adapters/scripts.d.ts +2 -0
- package/lib/types/worker/adapters/service-worker.d.ts +2 -0
- package/lib/workbench-server.mjs +1 -1
- package/lib/workbench.js +1 -1
- package/package.json +1 -1
- package/lib/index-BW85h7kT.mjs +0 -505
|
@@ -1,4 +1,148 @@
|
|
|
1
|
-
const
|
|
1
|
+
const h = self, pe = "index.html", me = "default-src 'none'; script-src 'none'; connect-src 'none'; worker-src 'none'; child-src 'none'", ge = {
|
|
2
|
+
workerCsp: me
|
|
3
|
+
}, G = ge.workerCsp, ye = ["default-src", "script-src", "connect-src", "worker-src", "child-src"];
|
|
4
|
+
function Z(e) {
|
|
5
|
+
if (!e || typeof e != "object" || Array.isArray(e)) return;
|
|
6
|
+
const t = {};
|
|
7
|
+
for (const [n, r] of Object.entries(e)) {
|
|
8
|
+
if (!ye.includes(n) || typeof r != "string" || !r.trim() || /[;,]|[^\x20-\x7e]/u.test(r))
|
|
9
|
+
return;
|
|
10
|
+
t[n] = r.trim();
|
|
11
|
+
}
|
|
12
|
+
return Object.keys(t).length ? t : void 0;
|
|
13
|
+
}
|
|
14
|
+
function we(e) {
|
|
15
|
+
const t = Z(e);
|
|
16
|
+
return t ? G.split("; ").map((n) => {
|
|
17
|
+
const r = n.slice(0, n.indexOf(" "));
|
|
18
|
+
return t[r] === void 0 ? n : `${r} ${t[r]}`;
|
|
19
|
+
}).join("; ") : G;
|
|
20
|
+
}
|
|
21
|
+
const be = {
|
|
22
|
+
html: "text/html; charset=utf-8",
|
|
23
|
+
htm: "text/html; charset=utf-8",
|
|
24
|
+
js: "text/javascript; charset=utf-8",
|
|
25
|
+
mjs: "text/javascript; charset=utf-8",
|
|
26
|
+
cjs: "text/javascript; charset=utf-8",
|
|
27
|
+
css: "text/css; charset=utf-8",
|
|
28
|
+
json: "application/json; charset=utf-8",
|
|
29
|
+
xml: "application/xml; charset=utf-8",
|
|
30
|
+
txt: "text/plain; charset=utf-8",
|
|
31
|
+
csv: "text/csv; charset=utf-8",
|
|
32
|
+
svg: "image/svg+xml",
|
|
33
|
+
wasm: "application/wasm",
|
|
34
|
+
map: "application/json; charset=utf-8"
|
|
35
|
+
}, _e = {
|
|
36
|
+
png: "image/png",
|
|
37
|
+
jpg: "image/jpeg",
|
|
38
|
+
jpeg: "image/jpeg",
|
|
39
|
+
gif: "image/gif",
|
|
40
|
+
webp: "image/webp",
|
|
41
|
+
avif: "image/avif",
|
|
42
|
+
ico: "image/x-icon",
|
|
43
|
+
bmp: "image/bmp",
|
|
44
|
+
woff: "font/woff",
|
|
45
|
+
woff2: "font/woff2",
|
|
46
|
+
ttf: "font/ttf",
|
|
47
|
+
otf: "font/otf",
|
|
48
|
+
eot: "application/vnd.ms-fontobject",
|
|
49
|
+
mp4: "video/mp4",
|
|
50
|
+
webm: "video/webm",
|
|
51
|
+
ogg: "video/ogg",
|
|
52
|
+
mp3: "audio/mpeg",
|
|
53
|
+
wav: "audio/wav",
|
|
54
|
+
m4a: "audio/mp4"
|
|
55
|
+
};
|
|
56
|
+
function Re(e) {
|
|
57
|
+
const t = e.split(".").pop()?.toLowerCase() ?? "";
|
|
58
|
+
return be[t] ?? _e[t] ?? "application/octet-stream";
|
|
59
|
+
}
|
|
60
|
+
function b(e) {
|
|
61
|
+
try {
|
|
62
|
+
return decodeURIComponent(e);
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function W(e) {
|
|
68
|
+
const t = [];
|
|
69
|
+
for (const n of e.replace(/\\/g, "/").split("/"))
|
|
70
|
+
if (!(n === "" || n === ".")) {
|
|
71
|
+
if (n === "..") return "";
|
|
72
|
+
t.push(n);
|
|
73
|
+
}
|
|
74
|
+
return t.join("/");
|
|
75
|
+
}
|
|
76
|
+
const g = /* @__PURE__ */ new Map(), Y = 16;
|
|
77
|
+
function ve(e) {
|
|
78
|
+
if (!g.has(e.id) && g.size >= Y) {
|
|
79
|
+
const r = new Error(`too many active simulator mounts (max ${Y})`);
|
|
80
|
+
throw r.code = "ERR_MOUNT_LIMIT", r;
|
|
81
|
+
}
|
|
82
|
+
const t = /* @__PURE__ */ new Map();
|
|
83
|
+
for (const [r, i] of Object.entries(e.files)) {
|
|
84
|
+
const s = W(r);
|
|
85
|
+
s && t.set(s, { bytes: i, mime: Re(s) });
|
|
86
|
+
}
|
|
87
|
+
let n;
|
|
88
|
+
if (e.worker) {
|
|
89
|
+
if (e.remoteBase || e.worker.sessionId !== e.id)
|
|
90
|
+
throw new TypeError("Invalid package Worker mount policy");
|
|
91
|
+
n = {
|
|
92
|
+
sessionId: e.id,
|
|
93
|
+
csp: Z(e.worker.csp)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return g.set(e.id, {
|
|
97
|
+
worker: n,
|
|
98
|
+
workerResponses: /* @__PURE__ */ new Map(),
|
|
99
|
+
files: t,
|
|
100
|
+
injectHead: e.injectHead,
|
|
101
|
+
csp: e.csp,
|
|
102
|
+
remoteBase: e.remoteBase ?? "",
|
|
103
|
+
fsScope: e.fsScope ?? "",
|
|
104
|
+
ownerClientId: e.ownerClientId ?? ""
|
|
105
|
+
}), t.size;
|
|
106
|
+
}
|
|
107
|
+
function xe(e) {
|
|
108
|
+
g.delete(e);
|
|
109
|
+
}
|
|
110
|
+
function Ee(e) {
|
|
111
|
+
let t = 0;
|
|
112
|
+
for (const [n, r] of g)
|
|
113
|
+
!r.ownerClientId || e.has(r.ownerClientId) || (g.delete(n), t += 1);
|
|
114
|
+
return t;
|
|
115
|
+
}
|
|
116
|
+
function P(e) {
|
|
117
|
+
let t;
|
|
118
|
+
try {
|
|
119
|
+
t = new URL(e).pathname;
|
|
120
|
+
} catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
for (const [n, r] of g) {
|
|
124
|
+
const i = `/${n}/`, s = t.indexOf(i);
|
|
125
|
+
if (s === -1) continue;
|
|
126
|
+
let a = b(t.slice(s + i.length));
|
|
127
|
+
if (a === null) return null;
|
|
128
|
+
(a === "" || a.endsWith("/")) && (a += pe);
|
|
129
|
+
const o = W(a);
|
|
130
|
+
return o ? { app: r, filePath: o } : null;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
function Q(e) {
|
|
135
|
+
let t;
|
|
136
|
+
try {
|
|
137
|
+
t = new URL(e).pathname;
|
|
138
|
+
} catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
for (const [n, r] of g)
|
|
142
|
+
if (t.includes(`/${n}/`)) return r;
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const Se = 5, Pe = "miniapp:restore-worker-mount", De = [
|
|
2
146
|
"fsWriteTempFile",
|
|
3
147
|
"fsSaveFile",
|
|
4
148
|
"fsWriteFile",
|
|
@@ -9,7 +153,88 @@ const ue = [
|
|
|
9
153
|
"fsUnlink",
|
|
10
154
|
"fsMkdir",
|
|
11
155
|
"fsGetStorageInfo"
|
|
12
|
-
],
|
|
156
|
+
], F = /* @__PURE__ */ new Map();
|
|
157
|
+
async function Ie(e, t) {
|
|
158
|
+
const n = new URL(h.registration.scope), r = new URL(e.url);
|
|
159
|
+
if (r.origin !== n.origin || !r.pathname.startsWith(n.pathname)) return;
|
|
160
|
+
const i = r.pathname.slice(n.pathname.length), s = i.indexOf("/");
|
|
161
|
+
if (s < 1) return;
|
|
162
|
+
const a = i.slice(0, s);
|
|
163
|
+
if (!/^[a-zA-Z0-9_-]{1,128}$/.test(a)) return;
|
|
164
|
+
const o = await h.clients.get(t);
|
|
165
|
+
if (!o) return;
|
|
166
|
+
const c = new URL(o.url);
|
|
167
|
+
if (c.origin !== n.origin || !c.pathname.startsWith(`${n.pathname}${a}/`))
|
|
168
|
+
return;
|
|
169
|
+
let u = F.get(a);
|
|
170
|
+
u || (u = Te(a, n.origin).finally(() => F.delete(a)), F.set(a, u)), await u;
|
|
171
|
+
}
|
|
172
|
+
async function Te(e, t) {
|
|
173
|
+
const n = (await h.clients.matchAll({ type: "window", includeUncontrolled: !0 })).filter(
|
|
174
|
+
(r) => new URL(r.url).origin === t
|
|
175
|
+
);
|
|
176
|
+
n.length && await new Promise((r) => {
|
|
177
|
+
const i = [];
|
|
178
|
+
let s = n.length, a = !1;
|
|
179
|
+
const o = () => {
|
|
180
|
+
if (!a) {
|
|
181
|
+
a = !0, clearTimeout(c);
|
|
182
|
+
for (const u of i) u.close();
|
|
183
|
+
r();
|
|
184
|
+
}
|
|
185
|
+
}, c = setTimeout(o, 5e3);
|
|
186
|
+
for (const u of n) {
|
|
187
|
+
const f = new MessageChannel();
|
|
188
|
+
i.push(f.port1), f.port1.onmessage = ({ data: d }) => {
|
|
189
|
+
(d?.ok === !0 || --s === 0) && o();
|
|
190
|
+
};
|
|
191
|
+
try {
|
|
192
|
+
u.postMessage({ type: Pe, id: e }, [f.port2]);
|
|
193
|
+
} catch {
|
|
194
|
+
f.port2.close(), --s === 0 && o();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async function ke(e, t) {
|
|
200
|
+
const n = () => new Response("Worker entry denied", {
|
|
201
|
+
status: 403,
|
|
202
|
+
headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-store" }
|
|
203
|
+
});
|
|
204
|
+
if (e.method !== "GET" || e.destination !== "worker" || !t) return n();
|
|
205
|
+
let r = P(e.url);
|
|
206
|
+
if (!r)
|
|
207
|
+
try {
|
|
208
|
+
await Ie(e, t), r = P(e.url);
|
|
209
|
+
} catch {
|
|
210
|
+
return n();
|
|
211
|
+
}
|
|
212
|
+
if (!r?.app.worker) return n();
|
|
213
|
+
const { app: i, filePath: s } = r, a = i.worker, o = new URL(h.registration.scope), c = new URL(e.url);
|
|
214
|
+
if (c.origin !== o.origin || !c.pathname.startsWith(`${o.pathname}${a.sessionId}/`))
|
|
215
|
+
return n();
|
|
216
|
+
try {
|
|
217
|
+
const u = await h.clients.get(t);
|
|
218
|
+
if (!u || Q(u.url) !== i || P(e.url)?.app !== i)
|
|
219
|
+
return n();
|
|
220
|
+
const f = i.workerResponses.get(s);
|
|
221
|
+
if (f) return f.clone();
|
|
222
|
+
const d = i.files.get(s);
|
|
223
|
+
if (!d) return n();
|
|
224
|
+
const y = new Response(d.bytes, {
|
|
225
|
+
headers: {
|
|
226
|
+
"Content-Type": "text/javascript; charset=utf-8",
|
|
227
|
+
"Cache-Control": "no-store",
|
|
228
|
+
"X-Content-Type-Options": "nosniff",
|
|
229
|
+
"Content-Security-Policy": we(a.csp)
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
return i.workerResponses.set(s, y), y.clone();
|
|
233
|
+
} catch {
|
|
234
|
+
return n();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const Ce = {
|
|
13
238
|
"image/png": "png",
|
|
14
239
|
"image/jpeg": "jpg",
|
|
15
240
|
"image/webp": "webp",
|
|
@@ -18,24 +243,24 @@ const ue = [
|
|
|
18
243
|
"video/quicktime": "mov",
|
|
19
244
|
"video/webm": "webm"
|
|
20
245
|
};
|
|
21
|
-
function
|
|
246
|
+
function J(e) {
|
|
22
247
|
const t = new Uint8Array(e);
|
|
23
|
-
if (
|
|
248
|
+
if (U(t, [137, 80, 78, 71, 13, 10, 26, 10]))
|
|
24
249
|
return "image/png";
|
|
25
|
-
if (
|
|
26
|
-
if (
|
|
27
|
-
if (
|
|
28
|
-
if (
|
|
29
|
-
return
|
|
30
|
-
if (
|
|
31
|
-
}
|
|
32
|
-
function
|
|
250
|
+
if (U(t, [255, 216, 255])) return "image/jpeg";
|
|
251
|
+
if (x(t, 0, "GIF87a") || x(t, 0, "GIF89a")) return "image/gif";
|
|
252
|
+
if (x(t, 0, "RIFF") && x(t, 8, "WEBP")) return "image/webp";
|
|
253
|
+
if (x(t, 4, "ftyp"))
|
|
254
|
+
return ee(t, 8, 12) === "qt " ? "video/quicktime" : "video/mp4";
|
|
255
|
+
if (U(t, [26, 69, 223, 163])) return "video/webm";
|
|
256
|
+
}
|
|
257
|
+
function Me(e) {
|
|
33
258
|
if (typeof e != "string" || e.length === 0)
|
|
34
259
|
return { error: "data is required", code: "ERR_INVALID_ARGS" };
|
|
35
260
|
const t = /^data:([^;,]+);base64,(.*)$/s.exec(e);
|
|
36
261
|
if (!t)
|
|
37
262
|
return { error: "only base64 data: URI is accepted", code: "ERR_INVALID_ARGS" };
|
|
38
|
-
const n = t[1].toLowerCase(), r =
|
|
263
|
+
const n = t[1].toLowerCase(), r = Ce[n];
|
|
39
264
|
if (!r)
|
|
40
265
|
return { error: `unsupported mime "${n}"`, code: "ERR_UNSUPPORTED_MIME" };
|
|
41
266
|
let i;
|
|
@@ -48,47 +273,47 @@ function fe(e) {
|
|
|
48
273
|
for (let a = 0; a < i.length; a++) s[a] = i.charCodeAt(a);
|
|
49
274
|
return { bytes: s.buffer, mime: n, ext: r };
|
|
50
275
|
}
|
|
51
|
-
function
|
|
276
|
+
function U(e, t) {
|
|
52
277
|
return t.every((n, r) => e[r] === n);
|
|
53
278
|
}
|
|
54
|
-
function
|
|
55
|
-
return
|
|
279
|
+
function x(e, t, n) {
|
|
280
|
+
return ee(e, t, t + n.length) === n;
|
|
56
281
|
}
|
|
57
|
-
function
|
|
282
|
+
function ee(e, t, n) {
|
|
58
283
|
if (e.length < n) return "";
|
|
59
284
|
let r = "";
|
|
60
285
|
for (let i = t; i < n; i++) r += String.fromCharCode(e[i]);
|
|
61
286
|
return r;
|
|
62
287
|
}
|
|
63
|
-
const
|
|
64
|
-
let
|
|
65
|
-
function
|
|
66
|
-
return
|
|
67
|
-
const n = indexedDB.open(
|
|
288
|
+
const Fe = "miniapp-simulator-fs", Ue = 1, p = "files";
|
|
289
|
+
let _ = null;
|
|
290
|
+
function R() {
|
|
291
|
+
return _ || (_ = new Promise((e, t) => {
|
|
292
|
+
const n = indexedDB.open(Fe, Ue);
|
|
68
293
|
n.onupgradeneeded = () => {
|
|
69
294
|
const r = n.result;
|
|
70
|
-
if (!r.objectStoreNames.contains(
|
|
71
|
-
const i = r.createObjectStore(
|
|
295
|
+
if (!r.objectStoreNames.contains(p)) {
|
|
296
|
+
const i = r.createObjectStore(p, { keyPath: ["scope", "path"] });
|
|
72
297
|
i.createIndex("by_scope", "scope", { unique: !1 }), i.createIndex("by_createdAt", "createdAt", { unique: !1 });
|
|
73
298
|
}
|
|
74
299
|
}, n.onsuccess = () => e(n.result), n.onerror = () => {
|
|
75
|
-
|
|
300
|
+
_ = null, t(n.error ?? new Error("indexedDB open failed"));
|
|
76
301
|
}, n.onblocked = () => {
|
|
77
|
-
|
|
302
|
+
_ = null, t(new Error("indexedDB open blocked"));
|
|
78
303
|
};
|
|
79
|
-
}),
|
|
304
|
+
}), _);
|
|
80
305
|
}
|
|
81
|
-
function
|
|
306
|
+
function te(e) {
|
|
82
307
|
return new Promise((t, n) => {
|
|
83
308
|
e.onsuccess = () => t(e.result), e.onerror = () => n(e.error ?? new Error("indexedDB request failed"));
|
|
84
309
|
});
|
|
85
310
|
}
|
|
86
|
-
function
|
|
311
|
+
function T(e) {
|
|
87
312
|
return new Promise((t, n) => {
|
|
88
313
|
e.oncomplete = () => t(), e.onerror = () => n(e.error ?? new Error("indexedDB transaction failed")), e.onabort = () => n(e.error ?? new Error("indexedDB transaction aborted"));
|
|
89
314
|
});
|
|
90
315
|
}
|
|
91
|
-
function
|
|
316
|
+
function N(e, t, n, r, i) {
|
|
92
317
|
const s = Date.now();
|
|
93
318
|
return {
|
|
94
319
|
scope: e,
|
|
@@ -100,16 +325,16 @@ function B(e, t, n, r, i) {
|
|
|
100
325
|
lastModified: s
|
|
101
326
|
};
|
|
102
327
|
}
|
|
103
|
-
async function
|
|
104
|
-
const s = (await
|
|
105
|
-
s.objectStore(
|
|
328
|
+
async function ne(e, t, n, r = "application/octet-stream") {
|
|
329
|
+
const s = (await R()).transaction(p, "readwrite");
|
|
330
|
+
s.objectStore(p).put(N(e, t, n, r, !1)), await T(s);
|
|
106
331
|
}
|
|
107
|
-
async function
|
|
108
|
-
const r = (await
|
|
109
|
-
r.objectStore(
|
|
332
|
+
async function A(e, t) {
|
|
333
|
+
const r = (await R()).transaction(p, "readwrite");
|
|
334
|
+
r.objectStore(p).put(N(e, t, new ArrayBuffer(0), "application/x-directory", !0)), await T(r);
|
|
110
335
|
}
|
|
111
336
|
async function S(e, t) {
|
|
112
|
-
const r = (await
|
|
337
|
+
const r = (await R()).transaction(p, "readonly").objectStore(p), i = await te(r.get([e, t]));
|
|
113
338
|
return i ? {
|
|
114
339
|
path: i.path,
|
|
115
340
|
bytes: await i.bytes.arrayBuffer(),
|
|
@@ -119,9 +344,9 @@ async function S(e, t) {
|
|
|
119
344
|
} : null;
|
|
120
345
|
}
|
|
121
346
|
async function v(e) {
|
|
122
|
-
const t = await
|
|
123
|
-
return (await
|
|
124
|
-
t.transaction(
|
|
347
|
+
const t = await R();
|
|
348
|
+
return (await te(
|
|
349
|
+
t.transaction(p, "readonly").objectStore(p).index("by_scope").getAll(e)
|
|
125
350
|
)).map((r) => ({
|
|
126
351
|
path: r.path,
|
|
127
352
|
mime: r.mime,
|
|
@@ -130,147 +355,34 @@ async function v(e) {
|
|
|
130
355
|
lastModified: r.lastModified ?? r.createdAt ?? 0
|
|
131
356
|
}));
|
|
132
357
|
}
|
|
133
|
-
async function
|
|
134
|
-
const r = (await
|
|
135
|
-
r.objectStore(
|
|
136
|
-
}
|
|
137
|
-
async function me(e, t, n, r) {
|
|
138
|
-
const s = (await _()).transaction(d, "readwrite"), a = s.objectStore(d);
|
|
139
|
-
a.put(B(e, n, r.bytes, r.mime, !1)), a.delete([e, t]), await I(s);
|
|
140
|
-
}
|
|
141
|
-
const g = self, ge = "index.html", ye = {
|
|
142
|
-
html: "text/html; charset=utf-8",
|
|
143
|
-
htm: "text/html; charset=utf-8",
|
|
144
|
-
js: "text/javascript; charset=utf-8",
|
|
145
|
-
mjs: "text/javascript; charset=utf-8",
|
|
146
|
-
cjs: "text/javascript; charset=utf-8",
|
|
147
|
-
css: "text/css; charset=utf-8",
|
|
148
|
-
json: "application/json; charset=utf-8",
|
|
149
|
-
xml: "application/xml; charset=utf-8",
|
|
150
|
-
txt: "text/plain; charset=utf-8",
|
|
151
|
-
csv: "text/csv; charset=utf-8",
|
|
152
|
-
svg: "image/svg+xml",
|
|
153
|
-
wasm: "application/wasm",
|
|
154
|
-
map: "application/json; charset=utf-8"
|
|
155
|
-
}, we = {
|
|
156
|
-
png: "image/png",
|
|
157
|
-
jpg: "image/jpeg",
|
|
158
|
-
jpeg: "image/jpeg",
|
|
159
|
-
gif: "image/gif",
|
|
160
|
-
webp: "image/webp",
|
|
161
|
-
avif: "image/avif",
|
|
162
|
-
ico: "image/x-icon",
|
|
163
|
-
bmp: "image/bmp",
|
|
164
|
-
woff: "font/woff",
|
|
165
|
-
woff2: "font/woff2",
|
|
166
|
-
ttf: "font/ttf",
|
|
167
|
-
otf: "font/otf",
|
|
168
|
-
eot: "application/vnd.ms-fontobject",
|
|
169
|
-
mp4: "video/mp4",
|
|
170
|
-
webm: "video/webm",
|
|
171
|
-
ogg: "video/ogg",
|
|
172
|
-
mp3: "audio/mpeg",
|
|
173
|
-
wav: "audio/wav",
|
|
174
|
-
m4a: "audio/mp4"
|
|
175
|
-
};
|
|
176
|
-
function be(e) {
|
|
177
|
-
const t = e.split(".").pop()?.toLowerCase() ?? "";
|
|
178
|
-
return ye[t] ?? we[t] ?? "application/octet-stream";
|
|
179
|
-
}
|
|
180
|
-
function w(e) {
|
|
181
|
-
try {
|
|
182
|
-
return decodeURIComponent(e);
|
|
183
|
-
} catch {
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
function k(e) {
|
|
188
|
-
const t = [];
|
|
189
|
-
for (const n of e.replace(/\\/g, "/").split("/"))
|
|
190
|
-
if (!(n === "" || n === ".")) {
|
|
191
|
-
if (n === "..") return "";
|
|
192
|
-
t.push(n);
|
|
193
|
-
}
|
|
194
|
-
return t.join("/");
|
|
195
|
-
}
|
|
196
|
-
const m = /* @__PURE__ */ new Map(), q = 16;
|
|
197
|
-
function _e(e) {
|
|
198
|
-
if (!m.has(e.id) && m.size >= q) {
|
|
199
|
-
const n = new Error(`too many active simulator mounts (max ${q})`);
|
|
200
|
-
throw n.code = "ERR_MOUNT_LIMIT", n;
|
|
201
|
-
}
|
|
202
|
-
const t = /* @__PURE__ */ new Map();
|
|
203
|
-
for (const [n, r] of Object.entries(e.files)) {
|
|
204
|
-
const i = k(n);
|
|
205
|
-
i && t.set(i, { bytes: r, mime: be(i) });
|
|
206
|
-
}
|
|
207
|
-
return m.set(e.id, {
|
|
208
|
-
files: t,
|
|
209
|
-
injectHead: e.injectHead,
|
|
210
|
-
csp: e.csp,
|
|
211
|
-
remoteBase: e.remoteBase ?? "",
|
|
212
|
-
fsScope: e.fsScope ?? "",
|
|
213
|
-
ownerClientId: e.ownerClientId ?? ""
|
|
214
|
-
}), t.size;
|
|
215
|
-
}
|
|
216
|
-
function ve(e) {
|
|
217
|
-
m.delete(e);
|
|
358
|
+
async function Ae(e, t) {
|
|
359
|
+
const r = (await R()).transaction(p, "readwrite");
|
|
360
|
+
r.objectStore(p).delete([e, t]), await T(r);
|
|
218
361
|
}
|
|
219
|
-
function
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
!r.ownerClientId || e.has(r.ownerClientId) || (m.delete(n), t += 1);
|
|
223
|
-
return t;
|
|
224
|
-
}
|
|
225
|
-
function Ee(e) {
|
|
226
|
-
let t;
|
|
227
|
-
try {
|
|
228
|
-
t = new URL(e).pathname;
|
|
229
|
-
} catch {
|
|
230
|
-
return null;
|
|
231
|
-
}
|
|
232
|
-
for (const [n, r] of m) {
|
|
233
|
-
const i = `/${n}/`, s = t.indexOf(i);
|
|
234
|
-
if (s === -1) continue;
|
|
235
|
-
let a = w(t.slice(s + i.length));
|
|
236
|
-
if (a === null) return null;
|
|
237
|
-
(a === "" || a.endsWith("/")) && (a += ge);
|
|
238
|
-
const o = k(a);
|
|
239
|
-
return o ? { app: r, filePath: o } : null;
|
|
240
|
-
}
|
|
241
|
-
return null;
|
|
362
|
+
async function Le(e, t, n, r) {
|
|
363
|
+
const s = (await R()).transaction(p, "readwrite"), a = s.objectStore(p);
|
|
364
|
+
a.put(N(e, n, r.bytes, r.mime, !1)), a.delete([e, t]), await T(s);
|
|
242
365
|
}
|
|
243
|
-
function
|
|
244
|
-
|
|
245
|
-
try {
|
|
246
|
-
t = new URL(e).pathname;
|
|
247
|
-
} catch {
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
for (const [n, r] of m)
|
|
251
|
-
if (t.includes(`/${n}/`)) return r;
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
function Se(e, t, n) {
|
|
255
|
-
if (e.files.has(t)) return O(e, t);
|
|
366
|
+
function Oe(e, t, n) {
|
|
367
|
+
if (e.files.has(t)) return L(e, t);
|
|
256
368
|
if (e.remoteBase) {
|
|
257
369
|
const r = new URL(t, e.remoteBase);
|
|
258
|
-
return r.search = new URL(n.url).search,
|
|
370
|
+
return r.search = new URL(n.url).search, ie(r.href);
|
|
259
371
|
}
|
|
260
|
-
return
|
|
372
|
+
return L(e, t);
|
|
261
373
|
}
|
|
262
|
-
async function
|
|
374
|
+
async function Be(e, t) {
|
|
263
375
|
try {
|
|
264
|
-
const n = await
|
|
376
|
+
const n = await h.clients.get(e);
|
|
265
377
|
if (n) {
|
|
266
|
-
const r =
|
|
378
|
+
const r = Q(n.url);
|
|
267
379
|
if (r) {
|
|
268
|
-
const i = new URL(t.url), s =
|
|
380
|
+
const i = new URL(t.url), s = b(i.pathname), a = s === null ? "" : W(s);
|
|
269
381
|
if (a && r.files.has(a))
|
|
270
|
-
return
|
|
382
|
+
return L(r, a);
|
|
271
383
|
if (r.remoteBase) {
|
|
272
384
|
const o = new URL(i.pathname + i.search, new URL(r.remoteBase).origin);
|
|
273
|
-
return
|
|
385
|
+
return ie(o.href);
|
|
274
386
|
}
|
|
275
387
|
}
|
|
276
388
|
}
|
|
@@ -278,7 +390,7 @@ async function De(e, t) {
|
|
|
278
390
|
}
|
|
279
391
|
return fetch(t);
|
|
280
392
|
}
|
|
281
|
-
function
|
|
393
|
+
function re(e, t) {
|
|
282
394
|
return new Response(e, {
|
|
283
395
|
status: 200,
|
|
284
396
|
headers: {
|
|
@@ -290,7 +402,7 @@ function Q(e, t) {
|
|
|
290
402
|
}
|
|
291
403
|
});
|
|
292
404
|
}
|
|
293
|
-
function
|
|
405
|
+
function L(e, t) {
|
|
294
406
|
const n = e.files.get(t);
|
|
295
407
|
if (!n)
|
|
296
408
|
return new Response(`Not Found: ${t}`, {
|
|
@@ -298,7 +410,7 @@ function O(e, t) {
|
|
|
298
410
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
299
411
|
});
|
|
300
412
|
if (n.mime.startsWith("text/html")) {
|
|
301
|
-
const r =
|
|
413
|
+
const r = We(new TextDecoder("utf-8").decode(n.bytes), e.injectHead), i = {
|
|
302
414
|
"Content-Type": "text/html; charset=utf-8",
|
|
303
415
|
"Cache-Control": "no-store",
|
|
304
416
|
// 与 Runtime 文档取同一值:guest 与 Runtime 同 origin,agent cluster 归属按 origin
|
|
@@ -307,9 +419,9 @@ function O(e, t) {
|
|
|
307
419
|
};
|
|
308
420
|
return e.csp && (i["Content-Security-Policy"] = e.csp), new Response(r, { status: 200, headers: i });
|
|
309
421
|
}
|
|
310
|
-
return
|
|
422
|
+
return re(n.bytes, n.mime);
|
|
311
423
|
}
|
|
312
|
-
async function
|
|
424
|
+
async function ie(e) {
|
|
313
425
|
try {
|
|
314
426
|
return await fetch(e, { method: "GET", credentials: "omit" });
|
|
315
427
|
} catch {
|
|
@@ -319,7 +431,7 @@ async function J(e) {
|
|
|
319
431
|
});
|
|
320
432
|
}
|
|
321
433
|
}
|
|
322
|
-
function
|
|
434
|
+
function We(e, t) {
|
|
323
435
|
if (!t) return e;
|
|
324
436
|
const n = /<head\b[^>]*>/i.exec(e);
|
|
325
437
|
if (n) {
|
|
@@ -333,21 +445,21 @@ function Pe(e, t) {
|
|
|
333
445
|
}
|
|
334
446
|
return `<head>${t}</head>${e}`;
|
|
335
447
|
}
|
|
336
|
-
const
|
|
337
|
-
let
|
|
338
|
-
function
|
|
339
|
-
const t =
|
|
340
|
-
return
|
|
448
|
+
const se = 50 * 1024 * 1024, D = 2 * 1024 * 1024, O = 2 * 1024 * 1024, Ne = 200 * 1024 * 1024, je = 4, $e = 255, K = 1e3, j = /* @__PURE__ */ new Set(["tmp", "usr"]), k = /* @__PURE__ */ new Set(["usr"]), qe = /^[A-Za-z0-9._-]{1,64}$/, I = /* @__PURE__ */ new Map();
|
|
449
|
+
let H = Promise.resolve();
|
|
450
|
+
function C(e) {
|
|
451
|
+
const t = H.then(e, e);
|
|
452
|
+
return H = t.then(
|
|
341
453
|
() => {
|
|
342
454
|
},
|
|
343
455
|
() => {
|
|
344
456
|
}
|
|
345
457
|
), t;
|
|
346
458
|
}
|
|
347
|
-
function
|
|
348
|
-
|
|
459
|
+
function ze(e) {
|
|
460
|
+
I.delete(e);
|
|
349
461
|
}
|
|
350
|
-
async function
|
|
462
|
+
async function Ge(e) {
|
|
351
463
|
const t = (n) => ({
|
|
352
464
|
type: "FS_ACK",
|
|
353
465
|
op: e.op,
|
|
@@ -355,38 +467,38 @@ async function Le(e) {
|
|
|
355
467
|
reqId: e.reqId,
|
|
356
468
|
...n
|
|
357
469
|
});
|
|
358
|
-
if (!
|
|
470
|
+
if (!g.has(e.id))
|
|
359
471
|
return t({ ok: !1, error: "simulator not ready", code: "ERR_NOT_MOUNTED" });
|
|
360
472
|
try {
|
|
361
|
-
const n = await
|
|
473
|
+
const n = await Ye(e);
|
|
362
474
|
return t(n);
|
|
363
475
|
} catch {
|
|
364
476
|
return t({ ok: !1, code: 50101, error: "storage io error" });
|
|
365
477
|
}
|
|
366
478
|
}
|
|
367
|
-
async function
|
|
479
|
+
async function Ye(e) {
|
|
368
480
|
const t = e.fsScope || e.id;
|
|
369
481
|
switch (e.op) {
|
|
370
482
|
case "fsWriteTempFile":
|
|
371
|
-
return
|
|
483
|
+
return Ke(t, e);
|
|
372
484
|
case "fsSaveFile":
|
|
373
|
-
return
|
|
485
|
+
return He(t, e);
|
|
374
486
|
case "fsWriteFile":
|
|
375
|
-
return
|
|
487
|
+
return V(t, e, !1);
|
|
376
488
|
case "fsAppendFile":
|
|
377
|
-
return
|
|
489
|
+
return V(t, e, !0);
|
|
378
490
|
case "fsReadFile":
|
|
379
|
-
return
|
|
491
|
+
return Ve(t, e);
|
|
380
492
|
case "fsReadDir":
|
|
381
|
-
return
|
|
493
|
+
return Xe(t, e);
|
|
382
494
|
case "fsStatFile":
|
|
383
|
-
return
|
|
495
|
+
return Ze(t, e);
|
|
384
496
|
case "fsUnlink":
|
|
385
|
-
return
|
|
497
|
+
return Qe(t, e);
|
|
386
498
|
case "fsMkdir":
|
|
387
|
-
return
|
|
499
|
+
return Je(t, e);
|
|
388
500
|
case "fsGetStorageInfo":
|
|
389
|
-
return
|
|
501
|
+
return et(t);
|
|
390
502
|
default:
|
|
391
503
|
return {
|
|
392
504
|
ok: !1,
|
|
@@ -395,139 +507,139 @@ async function Oe(e) {
|
|
|
395
507
|
};
|
|
396
508
|
}
|
|
397
509
|
}
|
|
398
|
-
async function
|
|
399
|
-
const n =
|
|
510
|
+
async function Ke(e, t) {
|
|
511
|
+
const n = Me(t.data);
|
|
400
512
|
if ("error" in n) return { ok: !1, error: n.error, code: n.code };
|
|
401
|
-
const r = `tmp/${
|
|
402
|
-
return await
|
|
513
|
+
const r = `tmp/${de()}.${n.ext}`;
|
|
514
|
+
return await ne(e, r, n.bytes, n.mime), { ok: !0, result: { path: r, url: he(e, r) } };
|
|
403
515
|
}
|
|
404
|
-
async function
|
|
405
|
-
const n =
|
|
516
|
+
async function He(e, t) {
|
|
517
|
+
const n = m(t.tempFilePath, "tempFilePath");
|
|
406
518
|
if (n) return n;
|
|
407
519
|
if (t.filePath !== void 0 && t.filePath !== null) {
|
|
408
|
-
const s =
|
|
520
|
+
const s = m(t.filePath, "filePath");
|
|
409
521
|
if (s) return s;
|
|
410
522
|
}
|
|
411
|
-
const r =
|
|
412
|
-
if ("code" in r) return
|
|
413
|
-
const i = t.filePath === void 0 || t.filePath === null ?
|
|
414
|
-
return "code" in i ?
|
|
523
|
+
const r = w(t.tempFilePath, e, /* @__PURE__ */ new Set(["tmp"]), !1);
|
|
524
|
+
if ("code" in r) return l(r);
|
|
525
|
+
const i = t.filePath === void 0 || t.filePath === null ? it(r.path) : w(t.filePath, e, k, !1);
|
|
526
|
+
return "code" in i ? l(i) : C(async () => {
|
|
415
527
|
const s = await S(e, r.path);
|
|
416
|
-
if (!s) return
|
|
417
|
-
if (s.isDir) return
|
|
418
|
-
const a = await v(e), o =
|
|
528
|
+
if (!s) return l({ code: 50202, message: "file not found; reason=not_found" });
|
|
529
|
+
if (s.isDir) return l({ code: 50205, message: "not a file" });
|
|
530
|
+
const a = await v(e), o = q(a);
|
|
419
531
|
if (o.has(i.path))
|
|
420
|
-
return
|
|
421
|
-
const c =
|
|
422
|
-
if ("code" in c) return
|
|
423
|
-
const
|
|
424
|
-
return
|
|
532
|
+
return l({ code: 50204, message: "file already exists" });
|
|
533
|
+
const c = ue(i.path, o);
|
|
534
|
+
if ("code" in c) return l(c);
|
|
535
|
+
const u = ae(t.id, a, s.bytes.byteLength, 0);
|
|
536
|
+
return u ? l(u) : (await le(e, c.missing), await Le(e, r.path, i.path, s), ce(t.id, s.bytes.byteLength), { ok: !0, result: { savedFilePath: he(e, i.path) } });
|
|
425
537
|
});
|
|
426
538
|
}
|
|
427
|
-
async function
|
|
428
|
-
const r =
|
|
539
|
+
async function V(e, t, n) {
|
|
540
|
+
const r = m(t.filePath, "filePath");
|
|
429
541
|
if (r) return r;
|
|
430
|
-
const i =
|
|
542
|
+
const i = oe(t.data, "data", !0);
|
|
431
543
|
if (i) return i;
|
|
432
|
-
const s =
|
|
544
|
+
const s = m(t.encoding, "encoding");
|
|
433
545
|
if (s) return s;
|
|
434
|
-
const a =
|
|
435
|
-
if ("code" in a) return
|
|
546
|
+
const a = w(t.filePath, e, k, !1);
|
|
547
|
+
if ("code" in a) return l(a);
|
|
436
548
|
if (t.encoding !== "base64" && t.encoding !== "utf8")
|
|
437
|
-
return
|
|
438
|
-
const o =
|
|
439
|
-
return "code" in o ?
|
|
549
|
+
return l({ code: 10001, message: "invalid parameter; reason=encoding_unsupported" });
|
|
550
|
+
const o = nt(t.data, t.encoding);
|
|
551
|
+
return "code" in o ? l(o) : o.bytes.byteLength > D ? l({
|
|
440
552
|
code: 50201,
|
|
441
553
|
message: "storage quota exceeded; reason=single_over_limit"
|
|
442
|
-
}) :
|
|
443
|
-
const c = await v(e),
|
|
444
|
-
if (f?.isDir) return
|
|
445
|
-
const
|
|
446
|
-
if ("code" in
|
|
447
|
-
const
|
|
554
|
+
}) : C(async () => {
|
|
555
|
+
const c = await v(e), u = q(c), f = await S(e, a.path);
|
|
556
|
+
if (f?.isDir) return l({ code: 50205, message: "not a file" });
|
|
557
|
+
const d = ue(a.path, u);
|
|
558
|
+
if ("code" in d) return l(d);
|
|
559
|
+
const y = n ? 0 : f?.bytes.byteLength ?? 0, z = ae(
|
|
448
560
|
t.id,
|
|
449
561
|
c,
|
|
450
562
|
o.bytes.byteLength,
|
|
451
|
-
|
|
563
|
+
y
|
|
452
564
|
);
|
|
453
|
-
if (
|
|
454
|
-
await
|
|
565
|
+
if (z) return l(z);
|
|
566
|
+
await le(e, d.missing);
|
|
455
567
|
let M = o.bytes;
|
|
456
|
-
return n && f && (M =
|
|
568
|
+
return n && f && (M = st(f.bytes, o.bytes)), await ne(e, a.path, M, at(M, t.encoding)), ce(t.id, o.bytes.byteLength), { ok: !0, result: { writtenBytes: o.bytes.byteLength } };
|
|
457
569
|
});
|
|
458
570
|
}
|
|
459
|
-
async function
|
|
460
|
-
const n =
|
|
571
|
+
async function Ve(e, t) {
|
|
572
|
+
const n = m(t.filePath, "filePath");
|
|
461
573
|
if (n) return n;
|
|
462
|
-
const r =
|
|
574
|
+
const r = m(t.encoding, "encoding");
|
|
463
575
|
if (r) return r;
|
|
464
|
-
const i =
|
|
576
|
+
const i = X(t.position, "position");
|
|
465
577
|
if (i) return i;
|
|
466
|
-
const s =
|
|
578
|
+
const s = X(t.length, "length");
|
|
467
579
|
if (s) return s;
|
|
468
|
-
const a =
|
|
469
|
-
if ("code" in a) return
|
|
580
|
+
const a = w(t.filePath, e, j, !1);
|
|
581
|
+
if ("code" in a) return l(a);
|
|
470
582
|
if (t.encoding !== "base64" && t.encoding !== "utf8")
|
|
471
|
-
return
|
|
472
|
-
const o = t.position === void 0 ? 0 : t.position, c = t.length === void 0 ?
|
|
473
|
-
if (!Number.isSafeInteger(o) || o < 0 || !Number.isSafeInteger(c) || c < 0 || c >
|
|
474
|
-
return
|
|
475
|
-
const
|
|
476
|
-
if (!
|
|
477
|
-
if (
|
|
478
|
-
const f = Math.min(
|
|
479
|
-
let
|
|
583
|
+
return l({ code: 10001, message: "invalid parameter; reason=encoding_unsupported" });
|
|
584
|
+
const o = t.position === void 0 ? 0 : t.position, c = t.length === void 0 ? O : t.length;
|
|
585
|
+
if (!Number.isSafeInteger(o) || o < 0 || !Number.isSafeInteger(c) || c < 0 || c > O)
|
|
586
|
+
return l({ code: 10001, message: "invalid parameter; reason=range_invalid" });
|
|
587
|
+
const u = await S(e, a.path);
|
|
588
|
+
if (!u) return l({ code: 50202, message: "file not found" });
|
|
589
|
+
if (u.isDir) return l({ code: 50205, message: "not a file" });
|
|
590
|
+
const f = Math.min(u.bytes.byteLength, o + c), d = o >= u.bytes.byteLength ? new ArrayBuffer(0) : u.bytes.slice(o, f);
|
|
591
|
+
let y;
|
|
480
592
|
if (t.encoding === "base64")
|
|
481
|
-
|
|
593
|
+
y = ot(d);
|
|
482
594
|
else
|
|
483
595
|
try {
|
|
484
|
-
|
|
596
|
+
y = new TextDecoder("utf-8", { fatal: !0 }).decode(d);
|
|
485
597
|
} catch {
|
|
486
|
-
return
|
|
598
|
+
return l({ code: 10001, message: "invalid parameter; reason=decode_failed" });
|
|
487
599
|
}
|
|
488
600
|
return {
|
|
489
601
|
ok: !0,
|
|
490
602
|
result: {
|
|
491
|
-
data:
|
|
492
|
-
bytesRead:
|
|
493
|
-
eof: o +
|
|
603
|
+
data: y,
|
|
604
|
+
bytesRead: d.byteLength,
|
|
605
|
+
eof: o + d.byteLength >= u.bytes.byteLength
|
|
494
606
|
}
|
|
495
607
|
};
|
|
496
608
|
}
|
|
497
|
-
async function
|
|
498
|
-
const n =
|
|
609
|
+
async function Xe(e, t) {
|
|
610
|
+
const n = m(t.dirPath, "dirPath");
|
|
499
611
|
if (n) return n;
|
|
500
|
-
const r =
|
|
501
|
-
if ("code" in r) return
|
|
612
|
+
const r = w(t.dirPath, e, j, !0);
|
|
613
|
+
if ("code" in r) return l(r);
|
|
502
614
|
const i = await v(e);
|
|
503
615
|
if (r.relativePath) {
|
|
504
616
|
const o = i.find((c) => c.path === r.path);
|
|
505
|
-
if (!o) return
|
|
506
|
-
if (!o.isDir) return
|
|
617
|
+
if (!o) return l({ code: 50202, message: "file not found" });
|
|
618
|
+
if (!o.isDir) return l({ code: 50206, message: "not a directory" });
|
|
507
619
|
}
|
|
508
620
|
const s = `${r.path}/`, a = i.filter((o) => {
|
|
509
621
|
if (!o.path.startsWith(s)) return !1;
|
|
510
622
|
const c = o.path.slice(s.length);
|
|
511
|
-
return c.length > 0 && !c.includes("/") && !
|
|
623
|
+
return c.length > 0 && !c.includes("/") && !E(o.path);
|
|
512
624
|
}).sort((o, c) => o.path.localeCompare(c.path));
|
|
513
625
|
return {
|
|
514
626
|
ok: !0,
|
|
515
627
|
result: {
|
|
516
|
-
files: a.slice(0,
|
|
628
|
+
files: a.slice(0, K).map((o) => ({
|
|
517
629
|
name: o.path.slice(s.length),
|
|
518
630
|
size: o.isDir ? 0 : o.size,
|
|
519
631
|
lastModified: o.lastModified,
|
|
520
632
|
isDir: o.isDir
|
|
521
633
|
})),
|
|
522
|
-
truncated: a.length >
|
|
634
|
+
truncated: a.length > K
|
|
523
635
|
}
|
|
524
636
|
};
|
|
525
637
|
}
|
|
526
|
-
async function
|
|
527
|
-
const n =
|
|
638
|
+
async function Ze(e, t) {
|
|
639
|
+
const n = m(t.filePath, "filePath");
|
|
528
640
|
if (n) return n;
|
|
529
|
-
const r =
|
|
530
|
-
if ("code" in r) return
|
|
641
|
+
const r = w(t.filePath, e, j, !1);
|
|
642
|
+
if ("code" in r) return l(r);
|
|
531
643
|
const i = (await v(e)).find((s) => s.path === r.path);
|
|
532
644
|
return i ? {
|
|
533
645
|
ok: !0,
|
|
@@ -536,80 +648,80 @@ async function Ne(e, t) {
|
|
|
536
648
|
lastModified: i.lastModified,
|
|
537
649
|
isDir: i.isDir
|
|
538
650
|
}
|
|
539
|
-
} :
|
|
651
|
+
} : l({ code: 50202, message: "file not found" });
|
|
540
652
|
}
|
|
541
|
-
async function
|
|
542
|
-
const n =
|
|
653
|
+
async function Qe(e, t) {
|
|
654
|
+
const n = m(t.filePath, "filePath");
|
|
543
655
|
if (n) return n;
|
|
544
|
-
const r =
|
|
545
|
-
return "code" in r ?
|
|
656
|
+
const r = w(t.filePath, e, k, !1);
|
|
657
|
+
return "code" in r ? l(r) : C(async () => {
|
|
546
658
|
const i = await S(e, r.path);
|
|
547
|
-
return i ? i.isDir ?
|
|
659
|
+
return i ? i.isDir ? l({ code: 50205, message: "not a file" }) : (await Ae(e, r.path), { ok: !0, result: {} }) : l({ code: 50202, message: "file not found" });
|
|
548
660
|
});
|
|
549
661
|
}
|
|
550
|
-
async function
|
|
551
|
-
const n =
|
|
662
|
+
async function Je(e, t) {
|
|
663
|
+
const n = m(t.dirPath, "dirPath");
|
|
552
664
|
if (n) return n;
|
|
553
665
|
if (t.recursive !== void 0 && typeof t.recursive != "boolean")
|
|
554
|
-
return
|
|
555
|
-
const r =
|
|
556
|
-
if ("code" in r) return
|
|
666
|
+
return $("recursive");
|
|
667
|
+
const r = w(t.dirPath, e, k, !1);
|
|
668
|
+
if ("code" in r) return l(r);
|
|
557
669
|
const i = t.recursive === !0;
|
|
558
|
-
return
|
|
559
|
-
const s = await v(e), a =
|
|
670
|
+
return C(async () => {
|
|
671
|
+
const s = await v(e), a = q(s), o = a.get(r.path);
|
|
560
672
|
if (o)
|
|
561
|
-
return o.isDir ? i ? { ok: !0, result: {} } :
|
|
562
|
-
const c =
|
|
563
|
-
for (const
|
|
564
|
-
const f = a.get(
|
|
673
|
+
return o.isDir ? i ? { ok: !0, result: {} } : l({ code: 50204, message: "file already exists" }) : l({ code: 50205, message: "not a file" });
|
|
674
|
+
const c = fe(r.path);
|
|
675
|
+
for (const u of c) {
|
|
676
|
+
const f = a.get(u);
|
|
565
677
|
if (f && !f.isDir)
|
|
566
|
-
return
|
|
678
|
+
return l({ code: 50205, message: "not a file" });
|
|
567
679
|
if (!f && !i)
|
|
568
|
-
return
|
|
680
|
+
return l({ code: 50202, message: "file not found" });
|
|
569
681
|
}
|
|
570
682
|
if (i)
|
|
571
|
-
for (const
|
|
572
|
-
a.has(
|
|
573
|
-
return await
|
|
683
|
+
for (const u of c)
|
|
684
|
+
a.has(u) || await A(e, u);
|
|
685
|
+
return await A(e, r.path), { ok: !0, result: {} };
|
|
574
686
|
});
|
|
575
687
|
}
|
|
576
|
-
async function
|
|
688
|
+
async function et(e) {
|
|
577
689
|
const t = await v(e), n = t.filter(
|
|
578
|
-
(i) => !i.isDir && i.path.startsWith("usr/") && !
|
|
690
|
+
(i) => !i.isDir && i.path.startsWith("usr/") && !E(i.path)
|
|
579
691
|
), r = t.filter(
|
|
580
|
-
(i) => !i.isDir && i.path.startsWith("tmp/") && !
|
|
692
|
+
(i) => !i.isDir && i.path.startsWith("tmp/") && !E(i.path)
|
|
581
693
|
);
|
|
582
694
|
return {
|
|
583
695
|
ok: !0,
|
|
584
696
|
result: {
|
|
585
|
-
usedBytes:
|
|
586
|
-
limitBytes:
|
|
697
|
+
usedBytes: B(n),
|
|
698
|
+
limitBytes: se,
|
|
587
699
|
fileCount: n.length,
|
|
588
|
-
tmpUsedBytes:
|
|
700
|
+
tmpUsedBytes: B(r),
|
|
589
701
|
writeChunkMaxBytes: D,
|
|
590
|
-
readChunkMaxBytes:
|
|
702
|
+
readChunkMaxBytes: O
|
|
591
703
|
}
|
|
592
704
|
};
|
|
593
705
|
}
|
|
594
|
-
function
|
|
595
|
-
return
|
|
706
|
+
function m(e, t) {
|
|
707
|
+
return oe(e, t, !1);
|
|
596
708
|
}
|
|
597
|
-
function
|
|
709
|
+
function oe(e, t, n) {
|
|
598
710
|
if (!(typeof e == "string" && (n || e.length > 0)))
|
|
599
|
-
return
|
|
711
|
+
return $(t);
|
|
600
712
|
}
|
|
601
|
-
function
|
|
713
|
+
function X(e, t) {
|
|
602
714
|
if (!(e === void 0 || typeof e == "number"))
|
|
603
|
-
return
|
|
715
|
+
return $(t);
|
|
604
716
|
}
|
|
605
|
-
function
|
|
717
|
+
function $(e) {
|
|
606
718
|
return { ok: !1, code: 10001, error: `invalid parameter; param=${e}` };
|
|
607
719
|
}
|
|
608
|
-
function
|
|
720
|
+
function l(e) {
|
|
609
721
|
return { ok: !1, code: e.code, error: e.message };
|
|
610
722
|
}
|
|
611
|
-
function
|
|
612
|
-
const i =
|
|
723
|
+
function w(e, t, n, r) {
|
|
724
|
+
const i = tt(e, t);
|
|
613
725
|
if (i === null)
|
|
614
726
|
return { code: 50203, message: "invalid path; reason=dir_not_allowed" };
|
|
615
727
|
if (i === "__DECODE_ERROR__")
|
|
@@ -619,17 +731,17 @@ function y(e, t, n, r) {
|
|
|
619
731
|
return { code: 50203, message: "invalid path; reason=dir_not_allowed" };
|
|
620
732
|
if (i.includes("\0") || i.includes("\\") || c.split("/").includes(".."))
|
|
621
733
|
return { code: 50203, message: "invalid path; reason=traversal" };
|
|
622
|
-
if (new TextEncoder().encode(c).byteLength >
|
|
734
|
+
if (new TextEncoder().encode(c).byteLength > $e)
|
|
623
735
|
return { code: 50203, message: "invalid path; reason=name_too_long" };
|
|
624
|
-
const
|
|
625
|
-
return
|
|
736
|
+
const u = c ? c.split("/") : [];
|
|
737
|
+
return u.length > je ? { code: 50203, message: "invalid path; reason=depth_exceeded" } : u.some((f) => f === "." || !qe.test(f)) ? { code: 50203, message: "invalid path; reason=name_invalid" } : u.some((f) => f.startsWith("__xhs")) ? { code: 50203, message: "invalid path; reason=reserved_name" } : {
|
|
626
738
|
dir: o,
|
|
627
739
|
relativePath: c,
|
|
628
740
|
path: c ? `${o}/${c}` : o
|
|
629
741
|
};
|
|
630
742
|
}
|
|
631
|
-
function
|
|
632
|
-
const n =
|
|
743
|
+
function tt(e, t) {
|
|
744
|
+
const n = b(e);
|
|
633
745
|
if (n === null) return "__DECODE_ERROR__";
|
|
634
746
|
const r = n.split(/[?#]/, 1)[0];
|
|
635
747
|
if (r.includes("\0") || r.includes("\\") || r.split("/").includes(".."))
|
|
@@ -647,19 +759,19 @@ function qe(e, t) {
|
|
|
647
759
|
if (a.protocol !== "http:" && a.protocol !== "https:") return null;
|
|
648
760
|
const o = "/_xhsfile_/", c = a.pathname.indexOf(o);
|
|
649
761
|
if (c === -1) return null;
|
|
650
|
-
const
|
|
651
|
-
if (f <= 0 ||
|
|
652
|
-
i =
|
|
762
|
+
const u = a.pathname.slice(c + o.length), f = u.indexOf("/");
|
|
763
|
+
if (f <= 0 || b(u.slice(0, f)) !== t) return null;
|
|
764
|
+
i = u.slice(f + 1);
|
|
653
765
|
}
|
|
654
|
-
const s =
|
|
766
|
+
const s = b(i);
|
|
655
767
|
return s === null ? "__DECODE_ERROR__" : s;
|
|
656
768
|
}
|
|
657
|
-
function
|
|
769
|
+
function nt(e, t) {
|
|
658
770
|
if (t === "utf8")
|
|
659
771
|
return e.length > D ? { code: 50201, message: "storage quota exceeded; reason=single_over_limit" } : { bytes: new TextEncoder().encode(e).buffer };
|
|
660
772
|
if (e.length > Math.ceil(D * 4 / 3) + 4)
|
|
661
773
|
return { code: 50201, message: "storage quota exceeded; reason=single_over_limit" };
|
|
662
|
-
if (!
|
|
774
|
+
if (!rt(e))
|
|
663
775
|
return { code: 10001, message: "invalid parameter; reason=decode_failed" };
|
|
664
776
|
try {
|
|
665
777
|
const n = atob(e), r = new Uint8Array(n.length);
|
|
@@ -669,78 +781,78 @@ function ze(e, t) {
|
|
|
669
781
|
return { code: 10001, message: "invalid parameter; reason=decode_failed" };
|
|
670
782
|
}
|
|
671
783
|
}
|
|
672
|
-
function
|
|
784
|
+
function rt(e) {
|
|
673
785
|
return e.length % 4 !== 0 ? !1 : /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e);
|
|
674
786
|
}
|
|
675
|
-
function
|
|
676
|
-
if ((
|
|
787
|
+
function ae(e, t, n, r) {
|
|
788
|
+
if ((I.get(e) ?? 0) + n > Ne)
|
|
677
789
|
return { code: 50201, message: "storage quota exceeded; reason=session_limit" };
|
|
678
|
-
if (
|
|
790
|
+
if (B(
|
|
679
791
|
t.filter(
|
|
680
|
-
(s) => !s.isDir && s.path.startsWith("usr/") && !
|
|
792
|
+
(s) => !s.isDir && s.path.startsWith("usr/") && !E(s.path)
|
|
681
793
|
)
|
|
682
|
-
) - r + n >
|
|
794
|
+
) - r + n > se)
|
|
683
795
|
return { code: 50201, message: "storage quota exceeded; reason=total_over_limit" };
|
|
684
796
|
}
|
|
685
|
-
function
|
|
686
|
-
|
|
797
|
+
function ce(e, t) {
|
|
798
|
+
I.set(e, (I.get(e) ?? 0) + t);
|
|
687
799
|
}
|
|
688
|
-
function
|
|
800
|
+
function q(e) {
|
|
689
801
|
return new Map(e.map((t) => [t.path, t]));
|
|
690
802
|
}
|
|
691
|
-
function
|
|
803
|
+
function ue(e, t) {
|
|
692
804
|
const n = [];
|
|
693
|
-
for (const r of
|
|
805
|
+
for (const r of fe(e)) {
|
|
694
806
|
const i = t.get(r);
|
|
695
807
|
if (i && !i.isDir) return { code: 50205, message: "not a file" };
|
|
696
808
|
i || n.push(r);
|
|
697
809
|
}
|
|
698
810
|
return { missing: n };
|
|
699
811
|
}
|
|
700
|
-
async function
|
|
701
|
-
for (const n of t) await
|
|
812
|
+
async function le(e, t) {
|
|
813
|
+
for (const n of t) await A(e, n);
|
|
702
814
|
}
|
|
703
|
-
function
|
|
815
|
+
function fe(e) {
|
|
704
816
|
const t = e.split("/"), n = [];
|
|
705
817
|
for (let r = 2; r < t.length; r++)
|
|
706
818
|
n.push(t.slice(0, r).join("/"));
|
|
707
819
|
return n;
|
|
708
820
|
}
|
|
709
|
-
function
|
|
710
|
-
const t = e.slice(e.lastIndexOf("/") + 1), n = t.lastIndexOf("."), r = n > 0 ? t.slice(n) : "", i = `${
|
|
821
|
+
function it(e) {
|
|
822
|
+
const t = e.slice(e.lastIndexOf("/") + 1), n = t.lastIndexOf("."), r = n > 0 ? t.slice(n) : "", i = `${de()}${r}`;
|
|
711
823
|
return { dir: "usr", relativePath: i, path: `usr/${i}` };
|
|
712
824
|
}
|
|
713
|
-
function
|
|
825
|
+
function st(e, t) {
|
|
714
826
|
const n = new Uint8Array(e.byteLength + t.byteLength);
|
|
715
827
|
return n.set(new Uint8Array(e), 0), n.set(new Uint8Array(t), e.byteLength), n.buffer;
|
|
716
828
|
}
|
|
717
|
-
function
|
|
829
|
+
function ot(e) {
|
|
718
830
|
const t = new Uint8Array(e), n = 32768;
|
|
719
831
|
let r = "";
|
|
720
832
|
for (let i = 0; i < t.length; i += n)
|
|
721
833
|
r += String.fromCharCode(...t.subarray(i, i + n));
|
|
722
834
|
return btoa(r);
|
|
723
835
|
}
|
|
724
|
-
function
|
|
725
|
-
return
|
|
836
|
+
function at(e, t) {
|
|
837
|
+
return J(e) ?? (t === "utf8" ? "text/plain; charset=utf-8" : "application/octet-stream");
|
|
726
838
|
}
|
|
727
|
-
function
|
|
839
|
+
function B(e) {
|
|
728
840
|
return e.reduce((t, n) => t + n.size, 0);
|
|
729
841
|
}
|
|
730
|
-
function
|
|
842
|
+
function E(e) {
|
|
731
843
|
return e.split("/").some((t) => t.startsWith("__xhs"));
|
|
732
844
|
}
|
|
733
|
-
function
|
|
845
|
+
function de() {
|
|
734
846
|
if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
|
|
735
847
|
return crypto.randomUUID().replace(/-/g, "");
|
|
736
848
|
let e = "";
|
|
737
849
|
for (let t = 0; t < 32; t++) e += Math.floor(Math.random() * 16).toString(16);
|
|
738
850
|
return e;
|
|
739
851
|
}
|
|
740
|
-
function
|
|
741
|
-
return `${
|
|
852
|
+
function he(e, t) {
|
|
853
|
+
return `${h.registration.scope}_xhsfile_/${encodeURIComponent(e)}/${t}`;
|
|
742
854
|
}
|
|
743
|
-
function
|
|
855
|
+
function ct(e) {
|
|
744
856
|
let t;
|
|
745
857
|
try {
|
|
746
858
|
t = new URL(e).pathname;
|
|
@@ -751,15 +863,15 @@ function Xe(e) {
|
|
|
751
863
|
if (r === -1) return null;
|
|
752
864
|
const i = t.slice(r + n.length), s = i.indexOf("/");
|
|
753
865
|
if (s <= 0) return null;
|
|
754
|
-
const a =
|
|
866
|
+
const a = b(i.slice(0, s)), o = b(i.slice(s + 1));
|
|
755
867
|
return !a || !o || o.includes("\0") || o.includes("\\") || o.split("/").includes("..") ? null : { scope: a, path: o };
|
|
756
868
|
}
|
|
757
|
-
async function
|
|
869
|
+
async function ut(e, t) {
|
|
758
870
|
try {
|
|
759
871
|
const n = await S(e, t);
|
|
760
|
-
if (n && !n.isDir && !
|
|
761
|
-
const r =
|
|
762
|
-
if (r) return
|
|
872
|
+
if (n && !n.isDir && !E(t)) {
|
|
873
|
+
const r = J(n.bytes);
|
|
874
|
+
if (r) return re(n.bytes, r);
|
|
763
875
|
}
|
|
764
876
|
} catch {
|
|
765
877
|
}
|
|
@@ -768,25 +880,25 @@ async function Ze(e, t) {
|
|
|
768
880
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
769
881
|
});
|
|
770
882
|
}
|
|
771
|
-
|
|
772
|
-
|
|
883
|
+
h.addEventListener("install", () => {
|
|
884
|
+
h.skipWaiting();
|
|
773
885
|
});
|
|
774
|
-
|
|
775
|
-
e.waitUntil(
|
|
886
|
+
h.addEventListener("activate", (e) => {
|
|
887
|
+
e.waitUntil(h.clients.claim());
|
|
776
888
|
});
|
|
777
|
-
|
|
889
|
+
h.addEventListener("message", (e) => {
|
|
778
890
|
const t = e.data;
|
|
779
891
|
if (!t || typeof t.type != "string") return;
|
|
780
892
|
const n = (r) => e.ports?.[0]?.postMessage(r);
|
|
781
893
|
if (t.type === "MOUNT") {
|
|
782
|
-
const r =
|
|
894
|
+
const r = lt(t, ft(e.source)).then(
|
|
783
895
|
(i) => n({
|
|
784
896
|
type: "MOUNT_ACK",
|
|
785
897
|
id: t.id,
|
|
786
898
|
ok: !0,
|
|
787
899
|
count: i,
|
|
788
|
-
swVersion:
|
|
789
|
-
fsOps:
|
|
900
|
+
swVersion: Se,
|
|
901
|
+
fsOps: De
|
|
790
902
|
}),
|
|
791
903
|
(i) => {
|
|
792
904
|
const s = i;
|
|
@@ -803,7 +915,7 @@ g.addEventListener("message", (e) => {
|
|
|
803
915
|
return;
|
|
804
916
|
}
|
|
805
917
|
if (t.type === "FS") {
|
|
806
|
-
const r = t, i =
|
|
918
|
+
const r = t, i = Ge(r).then(
|
|
807
919
|
n,
|
|
808
920
|
(s) => (
|
|
809
921
|
// handleFsOp 内部已对已知错误 resolve 出准确 code;走到这里只可能是未预期的运行时异常,
|
|
@@ -822,33 +934,37 @@ g.addEventListener("message", (e) => {
|
|
|
822
934
|
e.waitUntil?.(i);
|
|
823
935
|
return;
|
|
824
936
|
}
|
|
825
|
-
t.type === "UNMOUNT" && (
|
|
937
|
+
t.type === "UNMOUNT" && (ze(t.id), xe(t.id));
|
|
826
938
|
});
|
|
827
|
-
|
|
939
|
+
h.addEventListener("fetch", (e) => {
|
|
940
|
+
if (e.request.destination === "worker" || e.request.destination === "sharedworker") {
|
|
941
|
+
e.respondWith(ke(e.request, e.clientId));
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
828
944
|
if (e.request.method !== "GET") return;
|
|
829
|
-
const t =
|
|
945
|
+
const t = ct(e.request.url);
|
|
830
946
|
if (t) {
|
|
831
|
-
e.respondWith(
|
|
947
|
+
e.respondWith(ut(t.scope, t.path));
|
|
832
948
|
return;
|
|
833
949
|
}
|
|
834
|
-
const n =
|
|
950
|
+
const n = P(e.request.url);
|
|
835
951
|
if (n) {
|
|
836
|
-
e.respondWith(
|
|
952
|
+
e.respondWith(Oe(n.app, n.filePath, e.request));
|
|
837
953
|
return;
|
|
838
954
|
}
|
|
839
955
|
const r = e.clientId || e.resultingClientId;
|
|
840
|
-
r && e.respondWith(
|
|
956
|
+
r && e.respondWith(Be(r, e.request));
|
|
841
957
|
});
|
|
842
|
-
async function
|
|
958
|
+
async function lt(e, t) {
|
|
843
959
|
if (t)
|
|
844
960
|
try {
|
|
845
|
-
const n = await
|
|
846
|
-
|
|
961
|
+
const n = await h.clients.matchAll({ type: "window", includeUncontrolled: !0 });
|
|
962
|
+
Ee(new Set(n.map((r) => r.id)));
|
|
847
963
|
} catch {
|
|
848
964
|
}
|
|
849
|
-
return
|
|
965
|
+
return ve({ ...e, ownerClientId: t });
|
|
850
966
|
}
|
|
851
|
-
function
|
|
967
|
+
function ft(e) {
|
|
852
968
|
if (!e || typeof e != "object" || !("id" in e)) return "";
|
|
853
969
|
const t = e.id;
|
|
854
970
|
return typeof t == "string" ? t : "";
|