@php-wasm/web-service-worker 3.1.5 → 3.1.8
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/index.cjs +1 -1
- package/index.js +81 -73
- package/package.json +7 -6
package/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("@php-wasm/scopes"),P=require("@php-wasm/universal"),T=25e3;let C=0;function x(e,t,...r){const s=R();return e.postMessage({...t,requestId:s},...r),s}function R(){return++C}function m(e,t,r=T){return new Promise((s,a)=>{const o=i=>{i.data.type==="response"&&i.data.requestId===t&&(e.removeEventListener("message",o),clearTimeout(n),s(i.data.response))},n=setTimeout(()=>{a(new Error("Request timed out")),e.removeEventListener("message",o)},r);e.addEventListener("message",o)})}function q(e,t){return{type:"response",requestId:e,response:t}}async function v(e){let t=new URL(e.request.url);if(!u.isURLScoped(t))try{const c=new URL(e.request.referrer);t=u.setURLScope(t,u.getURLScope(c))}catch{}const r=e.request.headers.get("content-type"),s=e.request.method==="POST"?new Uint8Array(await e.request.clone().arrayBuffer()):void 0,a={};for(const c of e.request.headers.entries())a[c[0]]=c[1];let o;try{const c={method:"request",args:[{body:s,url:t.toString(),method:e.request.method,headers:{...a,Host:t.host,"User-agent":self.navigator.userAgent,"Content-type":r}}]},l=u.getURLScope(t);if(l===null)throw new Error(`The URL ${t.toString()} is not scoped. This should not happen.`);const y=await g(c,l);if(o=await m(self,y),delete o.headers["x-frame-options"],o.headers["content-security-policy"]){const d=o.headers["content-security-policy"].map(h=>b("frame-ancestors",h)).filter(h=>h.trim().length>0);d.length>0?o.headers["content-security-policy"]=d:delete o.headers["content-security-policy"]}}catch(c){throw console.error(c,{url:t.toString()}),c}if(o.httpStatusCode>=300&&o.httpStatusCode<=399&&o.headers.location){const c=u.getURLScope(t);let l=new URL(o.headers.location[0],t.toString());return c&&!u.isURLScoped(l)&&(l=u.setURLScope(l,c)),Response.redirect(l.toString(),o.httpStatusCode)}const n=[101,103,204,205,304].includes(o.httpStatusCode);let i=null;return n||(o.bodyPort?i=P.portToStream(o.bodyPort):i=o.bytes),new Response(i,{headers:o.headers,status:o.httpStatusCode})}async function g(e,t){const r=R();for(const s of await self.clients.matchAll({includeUncontrolled:!0}))s.postMessage({...e,scope:t,requestId:r});return r}async function p(e,t){let r;return["GET","HEAD"].includes(e.method)||"body"in t?r=void 0:!e.bodyUsed&&e.body?r=e.body:r=await e.arrayBuffer(),new Request(t.url||e.url,{body:r,method:e.method,headers:e.headers,referrer:e.referrer,referrerPolicy:e.referrerPolicy,mode:e.mode==="navigate"?"same-origin":e.mode,credentials:e.credentials,cache:e.cache,redirect:e.redirect,integrity:e.integrity,...r instanceof ReadableStream&&{duplex:"half"},...t})}async function S(e){if(!e.body)return[e,e];const[t,r]=e.body.tee();return[await p(e,{body:t,duplex:"half"}),await p(e,{body:r,duplex:"half"})]}function H(e){const t={};return e.headers.forEach((r,s)=>{t[s]=r}),t}function b(e,t){const r=/^[\u{9}\u{A}\u{C}\u{D}\u{20}]+/u,s=/[\u{9}\u{A}\u{C}\u{D}\u{20}]+$/u,a=/[\u{9}\u{A}\u{C}\u{D}\u{20}]/u;return t.split(";").filter(o=>{const n=o.replace(r,"").replace(s,""),[i]=n.split(a,1);return i.toLowerCase()!==e.toLowerCase()}).join(";")}class E extends Error{constructor(t,r,s){super(`Could not fetch ${t} – your network appears to be blocking this request (HTTP ${r}). This often happens on school, university, or corporate networks. Try switching to a different network or using a VPN.`),this.name="FirewallInterferenceError",this.url=t,this.status=r,this.statusText=s}}const A="X-Playground-Cors-Proxy";async function I(e,t,r,s){var y;let a=typeof e=="string"?new Request(e,t):e;const o=s?new URL(s):null;let n=o?new URL(a.url,o):new URL(a.url);if(n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]"||n.hostname==="::1")return await f(a);if(n.protocol==="http:"){n.protocol="https:";const d=n.toString();a=await p(a,{url:d}),n=new URL(d)}if(!r)return await f(a);if(o&&n.protocol===o.protocol&&n.hostname===o.hostname&&n.port===o.port&&n.pathname.startsWith(o.pathname))return await f(a);const[c,l]=await S(a);try{return await f(c)}catch{const h=((y=new Headers(l.headers).get("x-cors-proxy-allowed-request-headers"))==null?void 0:y.split(","))||[],L=h.includes("authorization")||h.includes("cookie"),U=await p(l,{url:`${r}${a.url}`,...L&&{credentials:"include"}}),w=await f(U,t);if(!w.headers.has(A))throw new E(a.url,w.status,w.statusText);return w}}async function f(e,t){let r=t?new Request(e,t):e;if(new URL(r.url).protocol==="http:"&&r.body){const s=await new Response(r.body).arrayBuffer();r=await p(r,{body:s})}return fetch(r)}exports.FirewallInterferenceError=E;exports.awaitReply=m;exports.broadcastMessageExpectReply=g;exports.cloneRequest=p;exports.convertFetchEventToPHPRequest=v;exports.fetchWithCorsProxy=I;exports.getNextRequestId=R;exports.getRequestHeaders=H;exports.postMessageExpectReply=x;exports.removeContentSecurityPolicyDirective=b;exports.responseTo=q;exports.teeRequest=S;
|
package/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { isURLScoped as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { isURLScoped as m, setURLScope as R, getURLScope as w } from "@php-wasm/scopes";
|
|
2
|
+
import { portToStream as E } from "@php-wasm/universal";
|
|
3
|
+
const L = 25e3;
|
|
4
|
+
let U = 0;
|
|
5
|
+
function O(e, t, ...r) {
|
|
6
|
+
const s = g();
|
|
6
7
|
return e.postMessage(
|
|
7
8
|
{
|
|
8
9
|
...t,
|
|
@@ -11,37 +12,37 @@ function H(e, t, ...r) {
|
|
|
11
12
|
...r
|
|
12
13
|
), s;
|
|
13
14
|
}
|
|
14
|
-
function
|
|
15
|
-
return ++
|
|
15
|
+
function g() {
|
|
16
|
+
return ++U;
|
|
16
17
|
}
|
|
17
|
-
function
|
|
18
|
-
return new Promise((s,
|
|
18
|
+
function C(e, t, r = L) {
|
|
19
|
+
return new Promise((s, a) => {
|
|
19
20
|
const o = (c) => {
|
|
20
|
-
c.data.type === "response" && c.data.requestId === t && (e.removeEventListener("message", o), clearTimeout(
|
|
21
|
-
},
|
|
22
|
-
|
|
21
|
+
c.data.type === "response" && c.data.requestId === t && (e.removeEventListener("message", o), clearTimeout(n), s(c.data.response));
|
|
22
|
+
}, n = setTimeout(() => {
|
|
23
|
+
a(new Error("Request timed out")), e.removeEventListener("message", o);
|
|
23
24
|
}, r);
|
|
24
25
|
e.addEventListener("message", o);
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
+
function D(e, t) {
|
|
28
29
|
return {
|
|
29
30
|
type: "response",
|
|
30
31
|
requestId: e,
|
|
31
32
|
response: t
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
|
-
async function
|
|
35
|
+
async function v(e) {
|
|
35
36
|
let t = new URL(e.request.url);
|
|
36
|
-
if (!
|
|
37
|
+
if (!m(t))
|
|
37
38
|
try {
|
|
38
39
|
const i = new URL(e.request.referrer);
|
|
39
|
-
t =
|
|
40
|
+
t = R(t, w(i));
|
|
40
41
|
} catch {
|
|
41
42
|
}
|
|
42
|
-
const r = e.request.headers.get("content-type"), s = e.request.method === "POST" ? new Uint8Array(await e.request.clone().arrayBuffer()) : void 0,
|
|
43
|
+
const r = e.request.headers.get("content-type"), s = e.request.method === "POST" ? new Uint8Array(await e.request.clone().arrayBuffer()) : void 0, a = {};
|
|
43
44
|
for (const i of e.request.headers.entries())
|
|
44
|
-
|
|
45
|
+
a[i[0]] = i[1];
|
|
45
46
|
let o;
|
|
46
47
|
try {
|
|
47
48
|
const i = {
|
|
@@ -52,7 +53,7 @@ async function O(e) {
|
|
|
52
53
|
url: t.toString(),
|
|
53
54
|
method: e.request.method,
|
|
54
55
|
headers: {
|
|
55
|
-
...
|
|
56
|
+
...a,
|
|
56
57
|
Host: t.host,
|
|
57
58
|
// Safari and Firefox don't make the User-Agent header
|
|
58
59
|
// available in the fetch event. Let's add it manually:
|
|
@@ -61,39 +62,46 @@ async function O(e) {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
]
|
|
64
|
-
},
|
|
65
|
-
if (
|
|
65
|
+
}, l = w(t);
|
|
66
|
+
if (l === null)
|
|
66
67
|
throw new Error(
|
|
67
68
|
`The URL ${t.toString()} is not scoped. This should not happen.`
|
|
68
69
|
);
|
|
69
|
-
const f = await
|
|
70
|
-
if (o = await
|
|
71
|
-
const
|
|
72
|
-
(
|
|
70
|
+
const f = await T(i, l);
|
|
71
|
+
if (o = await C(self, f), delete o.headers["x-frame-options"], o.headers["content-security-policy"]) {
|
|
72
|
+
const u = o.headers["content-security-policy"].map(
|
|
73
|
+
(d) => x(
|
|
73
74
|
"frame-ancestors",
|
|
74
|
-
|
|
75
|
+
d
|
|
75
76
|
)
|
|
76
|
-
).filter((
|
|
77
|
-
|
|
77
|
+
).filter((d) => d.trim().length > 0);
|
|
78
|
+
u.length > 0 ? o.headers["content-security-policy"] = u : delete o.headers["content-security-policy"];
|
|
78
79
|
}
|
|
79
80
|
} catch (i) {
|
|
80
81
|
throw console.error(i, { url: t.toString() }), i;
|
|
81
82
|
}
|
|
82
|
-
if (o.httpStatusCode >= 300 && o.httpStatusCode <= 399 && o.headers.location)
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
if (o.httpStatusCode >= 300 && o.httpStatusCode <= 399 && o.headers.location) {
|
|
84
|
+
const i = w(t);
|
|
85
|
+
let l = new URL(
|
|
86
|
+
o.headers.location[0],
|
|
87
|
+
t.toString()
|
|
88
|
+
);
|
|
89
|
+
return i && !m(l) && (l = R(l, i)), Response.redirect(
|
|
90
|
+
l.toString(),
|
|
85
91
|
o.httpStatusCode
|
|
86
92
|
);
|
|
87
|
-
|
|
93
|
+
}
|
|
94
|
+
const n = [101, 103, 204, 205, 304].includes(
|
|
88
95
|
o.httpStatusCode
|
|
89
|
-
)
|
|
90
|
-
|
|
96
|
+
);
|
|
97
|
+
let c = null;
|
|
98
|
+
return n || (o.bodyPort ? c = E(o.bodyPort) : c = o.bytes), new Response(c, {
|
|
91
99
|
headers: o.headers,
|
|
92
100
|
status: o.httpStatusCode
|
|
93
101
|
});
|
|
94
102
|
}
|
|
95
|
-
async function
|
|
96
|
-
const r =
|
|
103
|
+
async function T(e, t) {
|
|
104
|
+
const r = g();
|
|
97
105
|
for (const s of await self.clients.matchAll({
|
|
98
106
|
// Sometimes the client that triggered the current fetch()
|
|
99
107
|
// event is considered uncontrolled in Google Chrome. This
|
|
@@ -132,7 +140,7 @@ async function p(e, t) {
|
|
|
132
140
|
...t
|
|
133
141
|
});
|
|
134
142
|
}
|
|
135
|
-
async function
|
|
143
|
+
async function P(e) {
|
|
136
144
|
if (!e.body)
|
|
137
145
|
return [e, e];
|
|
138
146
|
const [t, r] = e.body.tee();
|
|
@@ -141,58 +149,58 @@ async function T(e) {
|
|
|
141
149
|
await p(e, { body: r, duplex: "half" })
|
|
142
150
|
];
|
|
143
151
|
}
|
|
144
|
-
function
|
|
152
|
+
function $(e) {
|
|
145
153
|
const t = {};
|
|
146
154
|
return e.headers.forEach((r, s) => {
|
|
147
155
|
t[s] = r;
|
|
148
156
|
}), t;
|
|
149
157
|
}
|
|
150
158
|
function x(e, t) {
|
|
151
|
-
const r = /^[\u{9}\u{A}\u{C}\u{D}\u{20}]+/u, s = /[\u{9}\u{A}\u{C}\u{D}\u{20}]+$/u,
|
|
159
|
+
const r = /^[\u{9}\u{A}\u{C}\u{D}\u{20}]+/u, s = /[\u{9}\u{A}\u{C}\u{D}\u{20}]+$/u, a = /[\u{9}\u{A}\u{C}\u{D}\u{20}]/u;
|
|
152
160
|
return t.split(";").filter((o) => {
|
|
153
|
-
const
|
|
154
|
-
|
|
161
|
+
const n = o.replace(r, "").replace(s, ""), [c] = n.split(
|
|
162
|
+
a,
|
|
155
163
|
// The directive name is the first token.
|
|
156
164
|
1
|
|
157
165
|
);
|
|
158
166
|
return c.toLowerCase() !== e.toLowerCase();
|
|
159
167
|
}).join(";");
|
|
160
168
|
}
|
|
161
|
-
class
|
|
169
|
+
class A extends Error {
|
|
162
170
|
constructor(t, r, s) {
|
|
163
171
|
super(
|
|
164
172
|
`Could not fetch ${t} – your network appears to be blocking this request (HTTP ${r}). This often happens on school, university, or corporate networks. Try switching to a different network or using a VPN.`
|
|
165
173
|
), this.name = "FirewallInterferenceError", this.url = t, this.status = r, this.statusText = s;
|
|
166
174
|
}
|
|
167
175
|
}
|
|
168
|
-
const
|
|
169
|
-
async function
|
|
176
|
+
const q = "X-Playground-Cors-Proxy";
|
|
177
|
+
async function k(e, t, r, s) {
|
|
170
178
|
var f;
|
|
171
|
-
let
|
|
179
|
+
let a = typeof e == "string" ? new Request(e, t) : e;
|
|
172
180
|
const o = s ? new URL(s) : null;
|
|
173
|
-
let
|
|
174
|
-
if (
|
|
175
|
-
return await h(
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
181
|
+
let n = o ? new URL(a.url, o) : new URL(a.url);
|
|
182
|
+
if (n.hostname === "localhost" || n.hostname === "127.0.0.1" || n.hostname === "[::1]" || n.hostname === "::1")
|
|
183
|
+
return await h(a);
|
|
184
|
+
if (n.protocol === "http:") {
|
|
185
|
+
n.protocol = "https:";
|
|
186
|
+
const u = n.toString();
|
|
187
|
+
a = await p(a, { url: u }), n = new URL(u);
|
|
180
188
|
}
|
|
181
189
|
if (!r)
|
|
182
|
-
return await h(
|
|
183
|
-
if (o &&
|
|
184
|
-
return await h(
|
|
185
|
-
const [i,
|
|
190
|
+
return await h(a);
|
|
191
|
+
if (o && n.protocol === o.protocol && n.hostname === o.hostname && n.port === o.port && n.pathname.startsWith(o.pathname))
|
|
192
|
+
return await h(a);
|
|
193
|
+
const [i, l] = await P(a);
|
|
186
194
|
try {
|
|
187
195
|
return await h(i);
|
|
188
196
|
} catch {
|
|
189
|
-
const
|
|
190
|
-
url: `${r}${
|
|
191
|
-
...
|
|
192
|
-
}), y = await h(
|
|
193
|
-
if (!y.headers.has(
|
|
194
|
-
throw new
|
|
195
|
-
|
|
197
|
+
const d = ((f = new Headers(l.headers).get("x-cors-proxy-allowed-request-headers")) == null ? void 0 : f.split(",")) || [], b = d.includes("authorization") || d.includes("cookie"), S = await p(l, {
|
|
198
|
+
url: `${r}${a.url}`,
|
|
199
|
+
...b && { credentials: "include" }
|
|
200
|
+
}), y = await h(S, t);
|
|
201
|
+
if (!y.headers.has(q))
|
|
202
|
+
throw new A(
|
|
203
|
+
a.url,
|
|
196
204
|
y.status,
|
|
197
205
|
y.statusText
|
|
198
206
|
);
|
|
@@ -210,16 +218,16 @@ async function h(e, t) {
|
|
|
210
218
|
return fetch(r);
|
|
211
219
|
}
|
|
212
220
|
export {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
221
|
+
A as FirewallInterferenceError,
|
|
222
|
+
C as awaitReply,
|
|
223
|
+
T as broadcastMessageExpectReply,
|
|
216
224
|
p as cloneRequest,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
v as convertFetchEventToPHPRequest,
|
|
226
|
+
k as fetchWithCorsProxy,
|
|
227
|
+
g as getNextRequestId,
|
|
228
|
+
$ as getRequestHeaders,
|
|
229
|
+
O as postMessageExpectReply,
|
|
222
230
|
x as removeContentSecurityPolicyDirective,
|
|
223
|
-
|
|
224
|
-
|
|
231
|
+
D as responseTo,
|
|
232
|
+
P as teeRequest
|
|
225
233
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/web-service-worker",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
4
4
|
"description": "PHP.wasm – service worker utils",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,11 +31,16 @@
|
|
|
31
31
|
"main": "./index.cjs",
|
|
32
32
|
"module": "./index.js",
|
|
33
33
|
"license": "GPL-2.0-or-later",
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "ba6a9509c9db4e0b7af6f155cf31162a6b659b5f",
|
|
35
35
|
"engines": {
|
|
36
36
|
"node": ">=20.10.0",
|
|
37
37
|
"npm": ">=10.2.3"
|
|
38
38
|
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"ini": "4.1.2",
|
|
41
|
+
"@php-wasm/scopes": "3.1.8",
|
|
42
|
+
"@php-wasm/universal": "3.1.8"
|
|
43
|
+
},
|
|
39
44
|
"packageManager": "npm@10.9.2",
|
|
40
45
|
"overrides": {
|
|
41
46
|
"rollup": "^4.34.6",
|
|
@@ -43,13 +48,9 @@
|
|
|
43
48
|
"react-dom": "18.3.1",
|
|
44
49
|
"typescript": "5.4.5",
|
|
45
50
|
"@playwright/test": "1.55.1",
|
|
46
|
-
"ws": "8.18.3",
|
|
47
51
|
"tmp": "0.2.5",
|
|
48
52
|
"form-data": "^4.0.4",
|
|
49
53
|
"lodash": "^4.17.23",
|
|
50
54
|
"glob": "^9.3.0"
|
|
51
|
-
},
|
|
52
|
-
"dependencies": {
|
|
53
|
-
"@php-wasm/scopes": "3.1.5"
|
|
54
55
|
}
|
|
55
56
|
}
|