@webqit/webflo 0.11.30 → 0.11.32
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/package.json +3 -3
- package/src/runtime-pi/Cookies.js +75 -0
- package/src/runtime-pi/Router.js +3 -3
- package/src/runtime-pi/client/Runtime.js +10 -5
- package/src/runtime-pi/client/RuntimeClient.js +2 -2
- package/src/runtime-pi/client/Workport.js +5 -2
- package/src/runtime-pi/client/worker/Worker.js +5 -10
- package/src/runtime-pi/server/Runtime.js +10 -4
- package/src/runtime-pi/server/RuntimeClient.js +1 -1
- package/src/runtime-pi/xHeaders.js +67 -0
- package/src/runtime-pi/xHttpEvent.js +11 -3
- package/src/runtime-pi/xHttpMessage.js +11 -19
- package/src/runtime-pi/xRequest.js +12 -2
- package/src/runtime-pi/xRequestHeaders.js +30 -17
- package/src/runtime-pi/xResponse.js +1 -1
- package/src/runtime-pi/xResponseHeaders.js +47 -42
- package/src/runtime-pi/xfetch.js +8 -1
- package/src/services-pi/{certbot → cert}/http-auth-hook.js +1 -1
- package/src/services-pi/{certbot → cert}/http-cleanup-hook.js +1 -1
- package/src/services-pi/{certbot → cert}/index.js +0 -0
- package/src/services-pi/index.js +2 -2
- package/src/webflo.js +1 -1
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"vanila-javascript"
|
|
13
13
|
],
|
|
14
14
|
"homepage": "https://webqit.io/tooling/webflo",
|
|
15
|
-
"version": "0.11.
|
|
15
|
+
"version": "0.11.32",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"bin": {
|
|
33
33
|
"webflo": "src/webflo.js",
|
|
34
|
-
"webflo-certbot-http-auth-hook": "src/services-pi/
|
|
35
|
-
"webflo-certbot-http-cleanup-hook": "src/services-pi/
|
|
34
|
+
"webflo-certbot-http-auth-hook": "src/services-pi/cert/http-auth-hook.js",
|
|
35
|
+
"webflo-certbot-http-cleanup-hook": "src/services-pi/cert/http-cleanup-hook.js"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@octokit/webhooks": "^7.15.1",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import { _isString, _isObject } from "@webqit/util/js/index.js";
|
|
6
|
+
|
|
7
|
+
export default class Cookies extends Map {
|
|
8
|
+
|
|
9
|
+
constructor(...args) {
|
|
10
|
+
super(...args);
|
|
11
|
+
Object.defineProperty(this, 'inLock', { value: false, writable: true });
|
|
12
|
+
Object.defineProperty(this, 'outLock', { value: false, writable: true });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
set(name, value) {
|
|
16
|
+
if (this.inLock) return;
|
|
17
|
+
if (this.has(name)) this.delete(name);
|
|
18
|
+
this.inLock = true;
|
|
19
|
+
// -----------------
|
|
20
|
+
let valueObj = value, valueStr = value, retrn;
|
|
21
|
+
if (_isString(value)) { valueObj = this.parseEntry(`=${ value }`)[1]; }
|
|
22
|
+
retrn = super.set(name, valueObj);
|
|
23
|
+
if (!this.outLock) {
|
|
24
|
+
if (_isObject(value)) { valueStr = this.stringifyEntry(value); }
|
|
25
|
+
this.headers.append(this.headers.cookieHeaderName, `${ name }=${ valueStr }`);
|
|
26
|
+
}
|
|
27
|
+
// -----------------
|
|
28
|
+
this.inLock = false;
|
|
29
|
+
return retrn;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
delete(name) {
|
|
33
|
+
if (this.inLock) return;
|
|
34
|
+
this.inLock = true;
|
|
35
|
+
// -----------------
|
|
36
|
+
let retrn = super.delete(name);
|
|
37
|
+
this.headers.delete(this.headers.cookieHeaderName);
|
|
38
|
+
for (let [ name, definition ] of this) {
|
|
39
|
+
this.headers.append(this.headers.cookieHeaderName, `${ name }=${ this.stringifyEntry(definition) }`);
|
|
40
|
+
}
|
|
41
|
+
// -----------------
|
|
42
|
+
this.inLock = false;
|
|
43
|
+
return retrn;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
clear() {
|
|
47
|
+
if (this.inLock) return;
|
|
48
|
+
this.inLock = true;
|
|
49
|
+
// -----------------
|
|
50
|
+
let retrn = super.clear();
|
|
51
|
+
this.headers.delete(this.headers.cookieHeaderName);
|
|
52
|
+
// -----------------
|
|
53
|
+
this.inLock = false;
|
|
54
|
+
return retrn;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
json(json = {}) {
|
|
58
|
+
if (arguments.length) {
|
|
59
|
+
this.clear();
|
|
60
|
+
for (let name in json) {
|
|
61
|
+
this.set(name, json[name])
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
for (let [ name, definition ] of this) {
|
|
66
|
+
json[name] = definition;
|
|
67
|
+
}
|
|
68
|
+
return json;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
toString() {
|
|
72
|
+
return this.headers.get(this.headers.cookieHeaderName);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
package/src/runtime-pi/Router.js
CHANGED
|
@@ -67,7 +67,7 @@ export default class Router {
|
|
|
67
67
|
const _next = async (..._args) => {
|
|
68
68
|
const nextTick = { ...thisTick, arg: _args[0] };
|
|
69
69
|
if (_args.length > 1) {
|
|
70
|
-
|
|
70
|
+
let _url = _args[1], _request, requestInit = { ...(_args[2] || {}) };
|
|
71
71
|
if (_args[1] instanceof nextTick.event.Request) {
|
|
72
72
|
_request = _args[1];
|
|
73
73
|
_url = _request.url;
|
|
@@ -85,9 +85,9 @@ export default class Router {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
if (_request) {
|
|
88
|
-
nextTick.event = thisTick.event.
|
|
88
|
+
nextTick.event = thisTick.event.with(newDestination, _request, requestInit);
|
|
89
89
|
} else {
|
|
90
|
-
nextTick.event = thisTick.event.
|
|
90
|
+
nextTick.event = thisTick.event.with(newDestination, requestInit);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
nextTick.source = thisTick.destination.join('/');
|
|
@@ -25,7 +25,7 @@ const RequestHeaders = xRequestHeaders(whatwag.Headers);
|
|
|
25
25
|
const ResponseHeaders = xResponseHeaders(whatwag.Headers);
|
|
26
26
|
const Request = xRequest(whatwag.Request, RequestHeaders, FormData, whatwag.Blob);
|
|
27
27
|
const Response = xResponse(whatwag.Response, ResponseHeaders, FormData, whatwag.Blob);
|
|
28
|
-
const fetch = xfetch(whatwag.fetch);
|
|
28
|
+
const fetch = xfetch(whatwag.fetch, Request);
|
|
29
29
|
const HttpEvent = xHttpEvent(Request, Response, URL);
|
|
30
30
|
|
|
31
31
|
export {
|
|
@@ -190,7 +190,7 @@ export default class Runtime {
|
|
|
190
190
|
// Check is-hash-action
|
|
191
191
|
isHashAction(urlObj) {
|
|
192
192
|
const isHashNav = _before(window.document.location.href, '#') === _before(urlObj.href, '#') && urlObj.href.includes('#');
|
|
193
|
-
return isHashNav && urlObj.hash.length > 1 && document.querySelector(urlObj.hash);
|
|
193
|
+
return isHashNav// && urlObj.hash.length > 1 && document.querySelector(urlObj.hash);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
// Check is-spa-route
|
|
@@ -298,7 +298,7 @@ export default class Runtime {
|
|
|
298
298
|
// ------------
|
|
299
299
|
// Rendering
|
|
300
300
|
// ------------
|
|
301
|
-
if (finalResponse.ok && finalResponse.headers.contentType === 'application/json') {
|
|
301
|
+
if (finalResponse.ok && (finalResponse.headers.contentType === 'application/json' || finalResponse.headers.contentType.startsWith('multipart/form-data'))) {
|
|
302
302
|
client.render && await client.render(httpEvent, finalResponse);
|
|
303
303
|
} else if (!finalResponse.ok) {
|
|
304
304
|
if ([404, 500].includes(finalResponse.status)) {
|
|
@@ -317,8 +317,13 @@ export default class Runtime {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
// Initiates remote fetch and sets the status
|
|
320
|
-
remoteFetch(request, ...args) {
|
|
321
|
-
let href =
|
|
320
|
+
async remoteFetch(request, ...args) {
|
|
321
|
+
let href = request;
|
|
322
|
+
if (request instanceof Request) {
|
|
323
|
+
href = request.url;
|
|
324
|
+
} else if (request instanceof self.URL) {
|
|
325
|
+
href = request.href;
|
|
326
|
+
}
|
|
322
327
|
Observer.set(this.network, 'remote', href);
|
|
323
328
|
let _response = fetch(request, ...args);
|
|
324
329
|
// This catch() is NOT intended to handle failure of the fetch
|
|
@@ -45,7 +45,7 @@ export default class RuntimeClient {
|
|
|
45
45
|
|
|
46
46
|
// Renderer
|
|
47
47
|
async render(httpEvent, response) {
|
|
48
|
-
let data = await response.
|
|
48
|
+
let data = await response.jsonfy();
|
|
49
49
|
const router = new Router(this.cx, httpEvent.url.pathname);
|
|
50
50
|
return router.route('render', httpEvent, data, async (httpEvent, data) => {
|
|
51
51
|
// --------
|
|
@@ -82,7 +82,7 @@ export default class RuntimeClient {
|
|
|
82
82
|
|
|
83
83
|
// Normalize scroll position
|
|
84
84
|
async scrollIntoView(httpEvent) {
|
|
85
|
-
if (!(httpEvent.detail.
|
|
85
|
+
if (!(httpEvent.detail.srcType === 'link')) return;
|
|
86
86
|
await new Promise(res => setTimeout(res, 10));
|
|
87
87
|
let viewportTop, urlTarget;
|
|
88
88
|
if (httpEvent.url.hash && (urlTarget = document.querySelector(httpEvent.url.hash))) {
|
|
@@ -9,12 +9,13 @@ import { Observer } from './Runtime.js';
|
|
|
9
9
|
export default class Workport {
|
|
10
10
|
|
|
11
11
|
constructor(file, params = {}) {
|
|
12
|
-
this.ready = navigator.serviceWorker.ready;
|
|
12
|
+
this.ready = navigator.serviceWorker ? navigator.serviceWorker.ready : new Promise;
|
|
13
13
|
|
|
14
14
|
// --------
|
|
15
15
|
// Registration and lifecycle
|
|
16
16
|
// --------
|
|
17
17
|
this.registration = new Promise((resolve, reject) => {
|
|
18
|
+
if (!navigator.serviceWorker) return;
|
|
18
19
|
const register = () => {
|
|
19
20
|
navigator.serviceWorker.register(file, { scope: params.scope || '/' }).then(async registration => {
|
|
20
21
|
|
|
@@ -81,7 +82,9 @@ export default class Workport {
|
|
|
81
82
|
return this.post;
|
|
82
83
|
},
|
|
83
84
|
listen: callback => {
|
|
84
|
-
navigator.serviceWorker
|
|
85
|
+
if (navigator.serviceWorker) {
|
|
86
|
+
navigator.serviceWorker.addEventListener('message', callback);
|
|
87
|
+
}
|
|
85
88
|
return this.post;
|
|
86
89
|
},
|
|
87
90
|
request: (message, onAvailability = 1) => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { _any } from '@webqit/util/arr/index.js';
|
|
6
6
|
import { urlPattern } from '../../util.js';
|
|
7
|
-
import { HttpEvent, Request, Response, Observer } from '../Runtime.js';
|
|
7
|
+
import { HttpEvent, Request, Response, fetch as xfetch, Observer } from '../Runtime.js';
|
|
8
8
|
import Workport from './Workport.js';
|
|
9
9
|
export {
|
|
10
10
|
URL,
|
|
@@ -99,12 +99,7 @@ export default class Worker {
|
|
|
99
99
|
event.respondWith((async (req, evt) => {
|
|
100
100
|
let requestingClient = await self.clients.get(event.clientId);
|
|
101
101
|
this.workport.setCurrentClient(requestingClient);
|
|
102
|
-
const requestInit =
|
|
103
|
-
'method', 'headers', 'mode', 'credentials', 'cache', 'redirect', 'referrer', 'integrity',
|
|
104
|
-
].reduce((init, prop) => ({ [prop]: req[prop], ...init }), {});
|
|
105
|
-
if (!['GET', 'HEAD'].includes(req.method)) {
|
|
106
|
-
requestInit.body = await req.text();
|
|
107
|
-
}
|
|
102
|
+
const [ url, requestInit ] = await Request.rip(req);
|
|
108
103
|
// Now, the following is key:
|
|
109
104
|
// The browser likes to use "force-cache" for "navigate" requests, when, e.g: re-entering your site with the back button
|
|
110
105
|
// Problem here, force-cache forces out JSON not HTML as per webflo's design.
|
|
@@ -112,7 +107,7 @@ export default class Worker {
|
|
|
112
107
|
if (req.cache === 'force-cache'/* && req.mode === 'navigate' - even webflo client init call also comes with that... needs investigation */) {
|
|
113
108
|
requestInit.cache = 'default';
|
|
114
109
|
}
|
|
115
|
-
return this.go(
|
|
110
|
+
return this.go(url, requestInit, { event: evt });
|
|
116
111
|
})(event.request, event));
|
|
117
112
|
});
|
|
118
113
|
|
|
@@ -233,9 +228,9 @@ export default class Worker {
|
|
|
233
228
|
networkFetch(request, params = {}) {
|
|
234
229
|
if (!params.cacheFallback) {
|
|
235
230
|
Observer.set(this.network, 'remote', true);
|
|
236
|
-
return
|
|
231
|
+
return xfetch(request);
|
|
237
232
|
}
|
|
238
|
-
return
|
|
233
|
+
return xfetch(request).then(response => {
|
|
239
234
|
if (params.cacheRefresh) this.refreshCache(request, response);
|
|
240
235
|
Observer.set(this.network, 'remote', true);
|
|
241
236
|
return response;
|
|
@@ -164,7 +164,7 @@ export default class Runtime {
|
|
|
164
164
|
const requestInit = { method: request.method, headers: request.headers };
|
|
165
165
|
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
|
166
166
|
requestInit.body = await new Promise((resolve, reject) => {
|
|
167
|
-
var formidable = new Formidable.IncomingForm({ multiples: true, allowEmptyFiles:
|
|
167
|
+
var formidable = new Formidable.IncomingForm({ multiples: true, allowEmptyFiles: true, keepExtensions: true });
|
|
168
168
|
formidable.parse(request, (error, fields, files) => {
|
|
169
169
|
if (error) {
|
|
170
170
|
reject(error);
|
|
@@ -340,7 +340,7 @@ export default class Runtime {
|
|
|
340
340
|
let baseObject;
|
|
341
341
|
if (!(e.detail.request && e.detail.response)) {
|
|
342
342
|
baseObject = this.mockSessionStore;
|
|
343
|
-
let cookieAvailability = e.request.headers.cookies
|
|
343
|
+
let cookieAvailability = e.request.headers.cookies.get(id); // We just want to know availability... not validity, as this is understood to be for testing purposes only
|
|
344
344
|
if (!(this.mockSessionStore[id] && cookieAvailability)) {
|
|
345
345
|
let cookieObj = {};
|
|
346
346
|
Object.defineProperty(this.mockSessionStore, id, {
|
|
@@ -371,7 +371,13 @@ export default class Runtime {
|
|
|
371
371
|
|
|
372
372
|
// Initiates remote fetch and sets the status
|
|
373
373
|
remoteFetch(request, ...args) {
|
|
374
|
-
|
|
374
|
+
let href = request;
|
|
375
|
+
if (request instanceof Request) {
|
|
376
|
+
href = request.url;
|
|
377
|
+
} else if (request instanceof self.URL) {
|
|
378
|
+
href = request.href;
|
|
379
|
+
}
|
|
380
|
+
Observer.set(this.network, 'remote', href);
|
|
375
381
|
let _response = fetch(request, ...args);
|
|
376
382
|
// This catch() is NOT intended to handle failure of the fetch
|
|
377
383
|
_response.catch(e => Observer.set(this.network, 'error', e.message));
|
|
@@ -393,7 +399,7 @@ export default class Runtime {
|
|
|
393
399
|
// Mock-Cookies?
|
|
394
400
|
if (!(e.detail.request && e.detail.response)) {
|
|
395
401
|
for (let cookieName of Object.getOwnPropertyNames(this.mockSessionStore)) {
|
|
396
|
-
response.headers.
|
|
402
|
+
response.headers.append('Set-Cookie', `${cookieName}=1`); // We just want to know availability... not validity, as this is understood to be for testing purposes only
|
|
397
403
|
}
|
|
398
404
|
}
|
|
399
405
|
|
|
@@ -70,7 +70,7 @@ export default class RuntimeClient {
|
|
|
70
70
|
|
|
71
71
|
// Renderer
|
|
72
72
|
async render(httpEvent, router, response) {
|
|
73
|
-
let data = await response.
|
|
73
|
+
let data = await response.jsonfy();
|
|
74
74
|
let rendering = await router.route('render', httpEvent, data, async (httpEvent, data) => {
|
|
75
75
|
var renderFile, pathnameSplit = httpEvent.url.pathname.split('/');
|
|
76
76
|
while ((renderFile = Path.join(this.cx.CWD, this.cx.layout.PUBLIC_DIR, './' + pathnameSplit.join('/'), 'index.html'))
|
|
@@ -13,6 +13,9 @@ const xHeaders = whatwagHeaders => class extends whatwagHeaders {
|
|
|
13
13
|
|
|
14
14
|
// construct
|
|
15
15
|
constructor(definition = {}) {
|
|
16
|
+
const cookies = definition.cookies;
|
|
17
|
+
delete definition.cookies;
|
|
18
|
+
// -----------------
|
|
16
19
|
if (definition instanceof whatwagHeaders) {
|
|
17
20
|
// It's another Headers instance
|
|
18
21
|
super(definition);
|
|
@@ -20,6 +23,59 @@ const xHeaders = whatwagHeaders => class extends whatwagHeaders {
|
|
|
20
23
|
super();
|
|
21
24
|
this.json(definition);
|
|
22
25
|
}
|
|
26
|
+
// -----------------
|
|
27
|
+
this.cookies = cookies;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
set(name, value) {
|
|
31
|
+
// Will sync forth to this._cookies if is cookie
|
|
32
|
+
this.catchCookies(name, value);
|
|
33
|
+
return super.set(name, value);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
append(name, value) {
|
|
37
|
+
// Will sync forth to this._cookies if is cookie
|
|
38
|
+
this.catchCookies(name, value, true);
|
|
39
|
+
return super.append(name, value);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
delete(name) {
|
|
43
|
+
// Will sync forth to this._cookies if is cookie
|
|
44
|
+
this.catchCookies(name);
|
|
45
|
+
return super.delete(name);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
set cookies(cookies) {
|
|
49
|
+
if (cookies instanceof Map) {
|
|
50
|
+
this.cookies.clear();
|
|
51
|
+
for (let [ name, value ] of cookies) {
|
|
52
|
+
this.cookies.set(name, value);
|
|
53
|
+
}
|
|
54
|
+
} else if (cookies) { this.set(this.cookieHeaderName, cookies); }
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get cookies() {
|
|
59
|
+
if (!this._cookies) {
|
|
60
|
+
this._cookies = new this.Cookies;
|
|
61
|
+
Object.defineProperty(this._cookies, 'headers', { value: this });
|
|
62
|
+
}
|
|
63
|
+
return this._cookies;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
catchCookies(name, value, append = false) {
|
|
67
|
+
if (!this.cookies || name.toLowerCase() !== this.cookieHeaderName.toLowerCase()) return;
|
|
68
|
+
this.cookies.outLock = true;
|
|
69
|
+
// -----------------
|
|
70
|
+
if (arguments.length > 1) {
|
|
71
|
+
if (!append) { this.cookies.clear(); }
|
|
72
|
+
const cookiesObj = this.cookies.parse(value);
|
|
73
|
+
for (let name in cookiesObj) {
|
|
74
|
+
this.cookies.set(name, cookiesObj[name]);
|
|
75
|
+
}
|
|
76
|
+
} else { this.cookies.clear(); }
|
|
77
|
+
// -----------------
|
|
78
|
+
this.cookies.outLock = false;
|
|
23
79
|
}
|
|
24
80
|
|
|
25
81
|
json(headers = {}, replace = true) {
|
|
@@ -71,6 +127,17 @@ const xHeaders = whatwagHeaders => class extends whatwagHeaders {
|
|
|
71
127
|
return this.get('Content-Type');
|
|
72
128
|
}
|
|
73
129
|
|
|
130
|
+
static compat(headers) {
|
|
131
|
+
if (!(headers instanceof this) && !headers.json) {
|
|
132
|
+
const descs = getAllPropertyDescriptors(new this);
|
|
133
|
+
Object.keys(descs).forEach(key => {
|
|
134
|
+
if (typeof key === 'symbol' || (key in headers)) return;
|
|
135
|
+
Object.defineProperty(headers, key, descs[key]);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return headers;
|
|
139
|
+
}
|
|
140
|
+
|
|
74
141
|
}
|
|
75
142
|
|
|
76
143
|
export default xHeaders;
|
|
@@ -69,15 +69,23 @@ const xHttpEvent = (Request, Response, URL) => {
|
|
|
69
69
|
return this._sessionFactory(...args);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
// Redirect Response
|
|
73
|
+
redirect(url, code = 302) {
|
|
74
|
+
return new this.Response(null, { status: code, headers: { Location: url } });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// "with()"
|
|
78
|
+
with(url, init = {}, _url = null) {
|
|
79
|
+
let request;
|
|
75
80
|
if (url instanceof Request) {
|
|
76
81
|
if (!_isEmpty(init)) {
|
|
77
82
|
request = new Request(url, init);
|
|
78
83
|
} else {
|
|
79
84
|
request = url;
|
|
80
85
|
}
|
|
86
|
+
if (_url) {
|
|
87
|
+
request.attrs.url = `${this.url.origin}${_url}`;
|
|
88
|
+
}
|
|
81
89
|
} else {
|
|
82
90
|
request = new Request(this._request, init);
|
|
83
91
|
request.attrs.url = `${this.url.origin}${url}`;
|
|
@@ -12,17 +12,8 @@ const xHttpMessage = (whatwagHttpMessage, Headers, FormData) => {
|
|
|
12
12
|
const HttpMessage = class extends whatwagHttpMessage {
|
|
13
13
|
|
|
14
14
|
constructor(input, init, bodyAttrs) {
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
init.headers = new Headers(init.headers);
|
|
18
|
-
arguments[1] = init;
|
|
19
|
-
}
|
|
20
|
-
if (_isEmpty(init)) {
|
|
21
|
-
super(input);
|
|
22
|
-
} else {
|
|
23
|
-
super(input, init);
|
|
24
|
-
}
|
|
25
|
-
this._headers = init.headers;
|
|
15
|
+
if (init.headers) { init = { ...init, headers: new Headers(init.headers) }; }
|
|
16
|
+
super(input, init);
|
|
26
17
|
if (bodyAttrs.headers) {
|
|
27
18
|
this.headers.json(bodyAttrs.headers);
|
|
28
19
|
}
|
|
@@ -36,10 +27,8 @@ const xHttpMessage = (whatwagHttpMessage, Headers, FormData) => {
|
|
|
36
27
|
}
|
|
37
28
|
|
|
38
29
|
get headers() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
return this._headers;
|
|
30
|
+
Headers.compat(super.headers);
|
|
31
|
+
return super.headers;
|
|
43
32
|
}
|
|
44
33
|
|
|
45
34
|
get attrs() {
|
|
@@ -126,10 +115,13 @@ export default xHttpMessage;
|
|
|
126
115
|
export function encodeBody(body, FormData, Blob) {
|
|
127
116
|
const detailsObj = { body, input: body };
|
|
128
117
|
const encodeFormData = (detailsObj, formData) => {
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
118
|
+
if (FormData.encode) {
|
|
119
|
+
let [ body, headers ] = FormData.encode(formData);
|
|
120
|
+
detailsObj.body = body;
|
|
121
|
+
detailsObj.headers = headers;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
detailsObj.body = formData;
|
|
133
125
|
}
|
|
134
126
|
if (_isString(body) || _isNumber(body)) {
|
|
135
127
|
detailsObj.inputType = 'text';
|
|
@@ -62,11 +62,21 @@ const xRequest = (whatwagRequest, Headers, FormData, Blob) => class extends xHtt
|
|
|
62
62
|
return 'referrer' in this.attrs ? this.attrs.referrer : super.referrer;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
static
|
|
65
|
+
static async rip(request) {
|
|
66
|
+
const requestInit = [
|
|
67
|
+
'method', 'headers', 'mode', 'credentials', 'cache', 'redirect', 'referrer', 'integrity',
|
|
68
|
+
].reduce((init, prop) => ({ [prop]: request[prop], ...init }), {});
|
|
69
|
+
if (!['GET', 'HEAD'].includes(request.method)) {
|
|
70
|
+
requestInit.body = await request.text();
|
|
71
|
+
}
|
|
72
|
+
return [ request.url, requestInit ];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static compat(request) {
|
|
76
|
+
if (request instanceof this) return request;
|
|
66
77
|
if (request instanceof whatwagRequest) {
|
|
67
78
|
return Object.setPrototypeOf(request, new this);
|
|
68
79
|
}
|
|
69
|
-
return new this(url, request);
|
|
70
80
|
}
|
|
71
81
|
|
|
72
82
|
};
|
|
@@ -5,13 +5,41 @@
|
|
|
5
5
|
import { _after } from "@webqit/util/str/index.js";
|
|
6
6
|
import { _from as _arrFrom } from "@webqit/util/arr/index.js";
|
|
7
7
|
import { _getType, _isObject } from "@webqit/util/js/index.js";
|
|
8
|
-
import { wwwFormUnserialize
|
|
8
|
+
import { wwwFormUnserialize } from './util.js';
|
|
9
9
|
import xHeaders from './xHeaders.js';
|
|
10
|
+
import xCookies from './Cookies.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Cookies
|
|
14
|
+
*/
|
|
15
|
+
class Cookies extends xCookies {
|
|
16
|
+
|
|
17
|
+
parse(str) {
|
|
18
|
+
return wwwFormUnserialize(str, {}, ';');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
parseEntry(str) {
|
|
22
|
+
return str.trim().split('=');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
stringifyEntry(cookieBody) {
|
|
26
|
+
return cookieBody;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
10
30
|
|
|
11
31
|
/**
|
|
12
32
|
* The xHeaders Mixin
|
|
13
33
|
*/
|
|
14
34
|
const xRequestHeaders = NativeHeaders => class extends xHeaders(NativeHeaders) {
|
|
35
|
+
|
|
36
|
+
get cookieHeaderName() {
|
|
37
|
+
return 'Cookie';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get Cookies() {
|
|
41
|
+
return Cookies;
|
|
42
|
+
}
|
|
15
43
|
|
|
16
44
|
set accept(value) {
|
|
17
45
|
return this.set('Accept', value);
|
|
@@ -34,22 +62,6 @@ const xRequestHeaders = NativeHeaders => class extends xHeaders(NativeHeaders) {
|
|
|
34
62
|
};
|
|
35
63
|
}
|
|
36
64
|
|
|
37
|
-
set cookies(cookieJar) {
|
|
38
|
-
if (!_isObject(cookieJar)) {
|
|
39
|
-
throw new Error(`Cookies must be of type object. Received type: ${_getType(cookieJar)}.`);
|
|
40
|
-
}
|
|
41
|
-
this.set('Cookie', wwwFormSerialize(cookieJar, ';'));
|
|
42
|
-
this._cookies = null;
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
get cookies() {
|
|
47
|
-
if (!this._cookies) {
|
|
48
|
-
this._cookies = wwwFormUnserialize(this.get('cookie'), {}, ';');
|
|
49
|
-
}
|
|
50
|
-
return this._cookies;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
65
|
set range(value) {
|
|
54
66
|
let rangeArr = [];
|
|
55
67
|
_arrFrom(value).forEach((range, i) => {
|
|
@@ -90,6 +102,7 @@ const xRequestHeaders = NativeHeaders => class extends xHeaders(NativeHeaders) {
|
|
|
90
102
|
return this.get('Access-Control-Allow-Origin');
|
|
91
103
|
}
|
|
92
104
|
|
|
105
|
+
|
|
93
106
|
}
|
|
94
107
|
|
|
95
108
|
export default xRequestHeaders;
|
|
@@ -58,10 +58,10 @@ const xResponse = (whatwagResponse, Headers, FormData, Blob) => class extends xH
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
static compat(response) {
|
|
61
|
+
if (response instanceof this) return response;
|
|
61
62
|
if (response instanceof whatwagResponse) {
|
|
62
63
|
return Object.setPrototypeOf(response, new this);
|
|
63
64
|
}
|
|
64
|
-
return new this(response);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
};
|
|
@@ -5,48 +5,61 @@
|
|
|
5
5
|
import { _after, _beforeLast } from "@webqit/util/str/index.js";
|
|
6
6
|
import { _isString, _getType, _isObject } from "@webqit/util/js/index.js";
|
|
7
7
|
import _Headers from './xHeaders.js';
|
|
8
|
+
import xCookies from './Cookies.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Cookies
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
+
class Cookies extends xCookies {
|
|
14
|
+
|
|
15
|
+
parse(cookieStr) {
|
|
16
|
+
const obj = {};
|
|
17
|
+
cookieStr && cookieStr.split(',').forEach(str => {
|
|
18
|
+
let [ cookieName, definition ] = this.parseEntry(str);
|
|
19
|
+
obj[cookieName] = definition;
|
|
20
|
+
});
|
|
21
|
+
return obj;
|
|
22
|
+
}
|
|
13
23
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (let attrName in cookieBody) {
|
|
23
|
-
if (attrName === 'value') continue;
|
|
24
|
-
let _attrName = attrName[0].toUpperCase() + attrName.substring(1);
|
|
25
|
-
if (_attrName === 'MaxAge') { _attrName = 'Max-Age' };
|
|
26
|
-
attrsArr.push(cookieBody[attrName] === true ? _attrName : `${_attrName}=${cookieBody[attrName]}`);
|
|
27
|
-
}
|
|
28
|
-
cookieBody = attrsArr.join('; ');
|
|
29
|
-
}
|
|
30
|
-
this.append('Set-Cookie', `${cookieName}=${cookieBody}`);
|
|
31
|
-
}
|
|
32
|
-
return true;
|
|
24
|
+
parseEntry(str) {
|
|
25
|
+
let [ cookieDefinition, attrsStr ] = str.split(';');
|
|
26
|
+
let [ cookieName, cookieValue ] = cookieDefinition.trim().split('=');
|
|
27
|
+
let attrs = { value: cookieValue, };
|
|
28
|
+
attrsStr && (attrsStr || '').split(/\;/g).map(attrStr => attrStr.trim().split('=')).forEach(attrsArr => {
|
|
29
|
+
attrs[attrsArr[0][0].toLowerCase() + attrsArr[0].substring(1).replace('-', '')] = attrsArr.length === 1 ? true : attrsArr[1];
|
|
30
|
+
});
|
|
31
|
+
return [ cookieName, attrs ];
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
(
|
|
43
|
-
cookieJar[cookieName][attrsArr[0][0].toLowerCase() + attrsArr[0].substring(1).replace('-', '')] = attrsArr.length === 1 ? true : attrsArr[1];
|
|
44
|
-
});
|
|
34
|
+
stringifyEntry(cookieBody) {
|
|
35
|
+
if (_isObject(cookieBody)) {
|
|
36
|
+
let attrsArr = [ cookieBody.value ];
|
|
37
|
+
for (let attrName in cookieBody) {
|
|
38
|
+
if (attrName === 'value') continue;
|
|
39
|
+
let _attrName = attrName[0].toUpperCase() + attrName.substring(1);
|
|
40
|
+
if (_attrName === 'MaxAge') { _attrName = 'Max-Age' };
|
|
41
|
+
attrsArr.push(cookieBody[attrName] === true ? _attrName : `${_attrName}=${cookieBody[attrName]}`);
|
|
45
42
|
}
|
|
46
|
-
|
|
47
|
-
}
|
|
43
|
+
cookieBody = attrsArr.join(';');
|
|
44
|
+
}
|
|
45
|
+
return cookieBody;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The _Headers Mixin
|
|
52
|
+
*/
|
|
53
|
+
const _ResponseHeaders = NativeHeaders => class extends _Headers(NativeHeaders) {
|
|
54
|
+
|
|
55
|
+
get cookieHeaderName() {
|
|
56
|
+
return 'Set-Cookie';
|
|
48
57
|
}
|
|
49
58
|
|
|
59
|
+
get Cookies() {
|
|
60
|
+
return Cookies;
|
|
61
|
+
}
|
|
62
|
+
|
|
50
63
|
set contentRange(value) {
|
|
51
64
|
if (Array.isArray(value)) {
|
|
52
65
|
if ((value.length === 2 && !value[0].includes('-')) || value.length < 2) {
|
|
@@ -97,14 +110,6 @@ const _ResponseHeaders = NativeHeaders => class extends _Headers(NativeHeaders)
|
|
|
97
110
|
return this.set('Location', value);
|
|
98
111
|
}
|
|
99
112
|
|
|
100
|
-
get redirect() {
|
|
101
|
-
return this.get('Location');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
set redirect(value) {
|
|
105
|
-
return this.set('Location', value);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
export default _ResponseHeaders;
|
|
115
|
+
export default _ResponseHeaders;
|
package/src/runtime-pi/xfetch.js
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The xfetch Mixin
|
|
4
4
|
*/
|
|
5
|
-
const xfetch = whatwagFetch =>
|
|
5
|
+
const xfetch = (whatwagFetch, xRequest) => {
|
|
6
|
+
return (url, init = {}) => {
|
|
7
|
+
if (init.body && (typeof init.body === 'object')) {
|
|
8
|
+
return whatwagFetch(new xRequest(url, init));
|
|
9
|
+
}
|
|
10
|
+
return whatwagFetch(url, init);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
6
13
|
|
|
7
14
|
export default xfetch;
|
|
File without changes
|
package/src/services-pi/index.js
CHANGED
package/src/webflo.js
CHANGED