@webqit/webflo 0.11.21 → 0.11.24
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/.gitignore +7 -7
- package/LICENSE +20 -20
- package/README.md +2074 -2071
- package/package.json +82 -82
- package/src/Context.js +79 -79
- package/src/config-pi/deployment/Env.js +69 -69
- package/src/config-pi/deployment/Layout.js +65 -65
- package/src/config-pi/deployment/Origins.js +133 -133
- package/src/config-pi/deployment/Virtualization.js +65 -65
- package/src/config-pi/deployment/index.js +17 -17
- package/src/config-pi/index.js +15 -15
- package/src/config-pi/runtime/Client.js +101 -101
- package/src/config-pi/runtime/Server.js +128 -128
- package/src/config-pi/runtime/client/Worker.js +135 -135
- package/src/config-pi/runtime/client/index.js +11 -11
- package/src/config-pi/runtime/index.js +17 -17
- package/src/config-pi/runtime/server/Headers.js +77 -77
- package/src/config-pi/runtime/server/Redirects.js +73 -73
- package/src/config-pi/runtime/server/index.js +13 -13
- package/src/config-pi/static/Manifest.js +321 -321
- package/src/config-pi/static/Ssg.js +51 -51
- package/src/config-pi/static/index.js +13 -13
- package/src/deployment-pi/index.js +10 -10
- package/src/deployment-pi/origins/index.js +215 -215
- package/src/index.js +19 -19
- package/src/runtime-pi/Router.js +131 -131
- package/src/runtime-pi/client/Context.js +6 -6
- package/src/runtime-pi/client/Router.js +47 -47
- package/src/runtime-pi/client/Runtime.js +357 -341
- package/src/runtime-pi/client/RuntimeClient.js +98 -98
- package/src/runtime-pi/client/Storage.js +56 -56
- package/src/runtime-pi/client/Url.js +205 -205
- package/src/runtime-pi/client/Workport.js +163 -163
- package/src/runtime-pi/client/generate.js +467 -467
- package/src/runtime-pi/client/index.js +23 -23
- package/src/runtime-pi/client/oohtml/full.js +6 -6
- package/src/runtime-pi/client/oohtml/namespacing.js +6 -6
- package/src/runtime-pi/client/oohtml/scripting.js +7 -7
- package/src/runtime-pi/client/oohtml/templating.js +7 -7
- package/src/runtime-pi/client/whatwag.js +27 -27
- package/src/runtime-pi/client/worker/Context.js +6 -6
- package/src/runtime-pi/client/worker/Worker.js +291 -291
- package/src/runtime-pi/client/worker/WorkerClient.js +46 -46
- package/src/runtime-pi/client/worker/Workport.js +79 -79
- package/src/runtime-pi/client/worker/index.js +23 -23
- package/src/runtime-pi/index.js +13 -13
- package/src/runtime-pi/server/Context.js +15 -15
- package/src/runtime-pi/server/Router.js +157 -157
- package/src/runtime-pi/server/Runtime.js +547 -547
- package/src/runtime-pi/server/RuntimeClient.js +112 -112
- package/src/runtime-pi/server/index.js +23 -23
- package/src/runtime-pi/server/whatwag.js +35 -35
- package/src/runtime-pi/util.js +162 -162
- package/src/runtime-pi/xFormData.js +59 -59
- package/src/runtime-pi/xHeaders.js +87 -87
- package/src/runtime-pi/xHttpEvent.js +92 -92
- package/src/runtime-pi/xHttpMessage.js +179 -179
- package/src/runtime-pi/xRequest.js +73 -73
- package/src/runtime-pi/xRequestHeaders.js +94 -94
- package/src/runtime-pi/xResponse.js +68 -68
- package/src/runtime-pi/xResponseHeaders.js +109 -109
- package/src/runtime-pi/xURL.js +110 -110
- package/src/runtime-pi/xfetch.js +6 -6
- package/src/services-pi/certbot/http-auth-hook.js +22 -22
- package/src/services-pi/certbot/http-cleanup-hook.js +22 -22
- package/src/services-pi/certbot/index.js +79 -79
- package/src/services-pi/index.js +8 -8
- package/src/static-pi/index.js +10 -10
- package/src/webflo.js +31 -31
- package/test/index.test.js +26 -25
- package/test/site/package.json +9 -9
- package/test/site/public/bundle.html +5 -5
- package/test/site/public/bundle.html.json +3 -3
- package/test/site/public/bundle.js +2 -2
- package/test/site/public/bundle.webflo.js +15 -15
- package/test/site/public/index.html +29 -29
- package/test/site/public/index1.html +34 -34
- package/test/site/public/page-2/bundle.html +4 -4
- package/test/site/public/page-2/bundle.js +2 -2
- package/test/site/public/page-2/index.html +45 -45
- package/test/site/public/page-2/main.html +2 -2
- package/test/site/public/page-4/subpage/bundle.js +2 -2
- package/test/site/public/page-4/subpage/index.html +30 -30
- package/test/site/public/sparoots.json +4 -4
- package/test/site/public/worker.js +3 -3
- package/test/site/server/index.js +15 -15
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Fs from 'fs';
|
|
6
|
-
import Url from 'url';
|
|
7
|
-
import Path from 'path';
|
|
8
|
-
import Mime from 'mime-types';
|
|
9
|
-
import _Router from '../Router.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* ---------------------------
|
|
13
|
-
* The Router class
|
|
14
|
-
* ---------------------------
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export default class Router extends _Router {
|
|
18
|
-
|
|
19
|
-
async readTick(thisTick) {
|
|
20
|
-
if (thisTick.trail) {
|
|
21
|
-
thisTick.currentSegment = thisTick.destination[thisTick.trail.length];
|
|
22
|
-
thisTick.currentSegmentOnFile = [ thisTick.currentSegment, '-' ].reduce((_segmentOnFile, _seg) => {
|
|
23
|
-
if (_segmentOnFile.index) return _segmentOnFile;
|
|
24
|
-
var _currentPath = thisTick.trailOnFile.concat(_seg).join('/'),
|
|
25
|
-
routeHandlerFile;
|
|
26
|
-
return Fs.existsSync(routeHandlerFile = Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, _currentPath, 'index.js')) ? { seg: _seg, index: routeHandlerFile } : (
|
|
27
|
-
Fs.existsSync(Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, _currentPath)) ? { seg: _seg, dirExists: true } : _segmentOnFile
|
|
28
|
-
);
|
|
29
|
-
}, { seg: null });
|
|
30
|
-
thisTick.trail.push(thisTick.currentSegment);
|
|
31
|
-
thisTick.trailOnFile.push(thisTick.currentSegmentOnFile.seg);
|
|
32
|
-
thisTick.exports = thisTick.currentSegmentOnFile.index ? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index)) : undefined;
|
|
33
|
-
} else {
|
|
34
|
-
thisTick.trail = [];
|
|
35
|
-
thisTick.trailOnFile = [];
|
|
36
|
-
thisTick.currentSegmentOnFile = { index: Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, 'index.js') };
|
|
37
|
-
thisTick.exports = Fs.existsSync(thisTick.currentSegmentOnFile.index)
|
|
38
|
-
? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index))
|
|
39
|
-
: null;
|
|
40
|
-
}
|
|
41
|
-
return thisTick;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
finalizeHandlerContext(context, thisTick) {
|
|
45
|
-
if (thisTick.currentSegmentOnFile.index) {
|
|
46
|
-
context.dirname = Path.dirname(thisTick.currentSegmentOnFile.index);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
pathJoin(...args) {
|
|
51
|
-
return Path.join(...args);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Reads a static file from the public directory.
|
|
56
|
-
*
|
|
57
|
-
* @param ServerNavigationEvent httpEvent
|
|
58
|
-
*
|
|
59
|
-
* @return Promise
|
|
60
|
-
*/
|
|
61
|
-
file(httpEvent) {
|
|
62
|
-
let filename = Path.join(this.cx.CWD, this.cx.layout.PUBLIC_DIR, decodeURIComponent(httpEvent.url.pathname));
|
|
63
|
-
let index, ext = Path.parse(httpEvent.url.pathname).ext;
|
|
64
|
-
// if is a directory search for index file matching the extention
|
|
65
|
-
if (!ext && Fs.existsSync(filename) && Fs.lstatSync(filename).isDirectory()) {
|
|
66
|
-
ext = '.html';
|
|
67
|
-
index = `index${ext}`;
|
|
68
|
-
filename = Path.join(filename, index);
|
|
69
|
-
}
|
|
70
|
-
let enc, acceptEncs = [], supportedEncs = { gzip: '.gz', br: '.br' };
|
|
71
|
-
// based on the URL path, extract the file extention. e.g. .js, .doc, ...
|
|
72
|
-
// and process encoding
|
|
73
|
-
if ((acceptEncs = (httpEvent.request.headers.get('Accept-Encoding') || '').split(',').map(e => e.trim())).length
|
|
74
|
-
&& (enc = acceptEncs.reduce((prev, _enc) => prev || (Fs.existsSync(filename + supportedEncs[_enc]) && _enc), null))) {
|
|
75
|
-
filename = filename + supportedEncs[enc];
|
|
76
|
-
} else {
|
|
77
|
-
if (!Fs.existsSync(filename)) return;
|
|
78
|
-
if (Object.values(supportedEncs).includes(ext)) {
|
|
79
|
-
enc = Object.keys(supportedEncs).reduce((prev, _enc) => prev || (supportedEncs[_enc] === ext && _enc), null);
|
|
80
|
-
ext = Path.parse(filename.substring(0, filename.length - ext.length)).ext;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// read file from file system
|
|
84
|
-
return new Promise(resolve => {
|
|
85
|
-
Fs.readFile(filename, function(err, data) {
|
|
86
|
-
let response;
|
|
87
|
-
if (err) {
|
|
88
|
-
response = new httpEvent.Response(null, { status: 500, statusText: `Error reading static file: ${filename}` } );
|
|
89
|
-
} else {
|
|
90
|
-
// if the file is found, set Content-type and send data
|
|
91
|
-
let mime = Mime.lookup(ext);
|
|
92
|
-
response = new httpEvent.Response(data, { headers: {
|
|
93
|
-
contentType: mime === 'application/javascript' ? 'text/javascript' : mime,
|
|
94
|
-
contentLength: Buffer.byteLength(data),
|
|
95
|
-
} });
|
|
96
|
-
if (enc) {
|
|
97
|
-
response.headers.set('Content-Encoding', enc);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
response.attrs.filename = filename;
|
|
101
|
-
response.attrs.static = true;
|
|
102
|
-
response.attrs.index = index;
|
|
103
|
-
resolve(response);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Writes a file to the public directory.
|
|
110
|
-
*
|
|
111
|
-
* @param object filename
|
|
112
|
-
* @param string content
|
|
113
|
-
*
|
|
114
|
-
* @return bool
|
|
115
|
-
*/
|
|
116
|
-
putPreRendered(filename, content) {
|
|
117
|
-
var _filename = Path.join(this.cx.layout.PUBLIC_DIR, '.', filename);
|
|
118
|
-
if (!Path.parse(filename).ext && filename.lastIndexOf('.') < filename.lastIndexOf('/')) {
|
|
119
|
-
_filename = Path.join(_filename, '/index.html');
|
|
120
|
-
}
|
|
121
|
-
var dir = Path.dirname(_filename);
|
|
122
|
-
if (!Fs.existsSync(dir)) {
|
|
123
|
-
Fs.mkdirSync(dir, {recursive:true});
|
|
124
|
-
}
|
|
125
|
-
return Fs.writeFileSync(_filename, content);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Deletes a file from the public directory.
|
|
130
|
-
*
|
|
131
|
-
* @param object filename
|
|
132
|
-
*
|
|
133
|
-
* @return bool
|
|
134
|
-
*/
|
|
135
|
-
deletePreRendered(filename) {
|
|
136
|
-
return Fs.unlinkSync(filename);
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
// maps file extention to MIME typere
|
|
141
|
-
const mimeTypes = {
|
|
142
|
-
'.ico': 'image/x-icon',
|
|
143
|
-
'.html': 'text/html',
|
|
144
|
-
'.js': 'text/javascript',
|
|
145
|
-
'.json': 'application/json',
|
|
146
|
-
'.css': 'text/css',
|
|
147
|
-
'.png': 'image/png',
|
|
148
|
-
'.jpeg': 'image/jpeg',
|
|
149
|
-
'.jpg': 'image/jpeg',
|
|
150
|
-
'.wav': 'audio/wav',
|
|
151
|
-
'.mp3': 'audio/mpeg',
|
|
152
|
-
'.svg': 'image/svg+xml',
|
|
153
|
-
'.pdf': 'application/pdf',
|
|
154
|
-
'.doc': 'application/msword'
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
export { mimeTypes };
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Fs from 'fs';
|
|
6
|
+
import Url from 'url';
|
|
7
|
+
import Path from 'path';
|
|
8
|
+
import Mime from 'mime-types';
|
|
9
|
+
import _Router from '../Router.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ---------------------------
|
|
13
|
+
* The Router class
|
|
14
|
+
* ---------------------------
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export default class Router extends _Router {
|
|
18
|
+
|
|
19
|
+
async readTick(thisTick) {
|
|
20
|
+
if (thisTick.trail) {
|
|
21
|
+
thisTick.currentSegment = thisTick.destination[thisTick.trail.length];
|
|
22
|
+
thisTick.currentSegmentOnFile = [ thisTick.currentSegment, '-' ].reduce((_segmentOnFile, _seg) => {
|
|
23
|
+
if (_segmentOnFile.index) return _segmentOnFile;
|
|
24
|
+
var _currentPath = thisTick.trailOnFile.concat(_seg).join('/'),
|
|
25
|
+
routeHandlerFile;
|
|
26
|
+
return Fs.existsSync(routeHandlerFile = Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, _currentPath, 'index.js')) ? { seg: _seg, index: routeHandlerFile } : (
|
|
27
|
+
Fs.existsSync(Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, _currentPath)) ? { seg: _seg, dirExists: true } : _segmentOnFile
|
|
28
|
+
);
|
|
29
|
+
}, { seg: null });
|
|
30
|
+
thisTick.trail.push(thisTick.currentSegment);
|
|
31
|
+
thisTick.trailOnFile.push(thisTick.currentSegmentOnFile.seg);
|
|
32
|
+
thisTick.exports = thisTick.currentSegmentOnFile.index ? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index)) : undefined;
|
|
33
|
+
} else {
|
|
34
|
+
thisTick.trail = [];
|
|
35
|
+
thisTick.trailOnFile = [];
|
|
36
|
+
thisTick.currentSegmentOnFile = { index: Path.join(this.cx.CWD, this.cx.layout.SERVER_DIR, 'index.js') };
|
|
37
|
+
thisTick.exports = Fs.existsSync(thisTick.currentSegmentOnFile.index)
|
|
38
|
+
? await import(Url.pathToFileURL(thisTick.currentSegmentOnFile.index))
|
|
39
|
+
: null;
|
|
40
|
+
}
|
|
41
|
+
return thisTick;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
finalizeHandlerContext(context, thisTick) {
|
|
45
|
+
if (thisTick.currentSegmentOnFile.index) {
|
|
46
|
+
context.dirname = Path.dirname(thisTick.currentSegmentOnFile.index);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
pathJoin(...args) {
|
|
51
|
+
return Path.join(...args);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Reads a static file from the public directory.
|
|
56
|
+
*
|
|
57
|
+
* @param ServerNavigationEvent httpEvent
|
|
58
|
+
*
|
|
59
|
+
* @return Promise
|
|
60
|
+
*/
|
|
61
|
+
file(httpEvent) {
|
|
62
|
+
let filename = Path.join(this.cx.CWD, this.cx.layout.PUBLIC_DIR, decodeURIComponent(httpEvent.url.pathname));
|
|
63
|
+
let index, ext = Path.parse(httpEvent.url.pathname).ext;
|
|
64
|
+
// if is a directory search for index file matching the extention
|
|
65
|
+
if (!ext && Fs.existsSync(filename) && Fs.lstatSync(filename).isDirectory()) {
|
|
66
|
+
ext = '.html';
|
|
67
|
+
index = `index${ext}`;
|
|
68
|
+
filename = Path.join(filename, index);
|
|
69
|
+
}
|
|
70
|
+
let enc, acceptEncs = [], supportedEncs = { gzip: '.gz', br: '.br' };
|
|
71
|
+
// based on the URL path, extract the file extention. e.g. .js, .doc, ...
|
|
72
|
+
// and process encoding
|
|
73
|
+
if ((acceptEncs = (httpEvent.request.headers.get('Accept-Encoding') || '').split(',').map(e => e.trim())).length
|
|
74
|
+
&& (enc = acceptEncs.reduce((prev, _enc) => prev || (Fs.existsSync(filename + supportedEncs[_enc]) && _enc), null))) {
|
|
75
|
+
filename = filename + supportedEncs[enc];
|
|
76
|
+
} else {
|
|
77
|
+
if (!Fs.existsSync(filename)) return;
|
|
78
|
+
if (Object.values(supportedEncs).includes(ext)) {
|
|
79
|
+
enc = Object.keys(supportedEncs).reduce((prev, _enc) => prev || (supportedEncs[_enc] === ext && _enc), null);
|
|
80
|
+
ext = Path.parse(filename.substring(0, filename.length - ext.length)).ext;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// read file from file system
|
|
84
|
+
return new Promise(resolve => {
|
|
85
|
+
Fs.readFile(filename, function(err, data) {
|
|
86
|
+
let response;
|
|
87
|
+
if (err) {
|
|
88
|
+
response = new httpEvent.Response(null, { status: 500, statusText: `Error reading static file: ${filename}` } );
|
|
89
|
+
} else {
|
|
90
|
+
// if the file is found, set Content-type and send data
|
|
91
|
+
let mime = Mime.lookup(ext);
|
|
92
|
+
response = new httpEvent.Response(data, { headers: {
|
|
93
|
+
contentType: mime === 'application/javascript' ? 'text/javascript' : mime,
|
|
94
|
+
contentLength: Buffer.byteLength(data),
|
|
95
|
+
} });
|
|
96
|
+
if (enc) {
|
|
97
|
+
response.headers.set('Content-Encoding', enc);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
response.attrs.filename = filename;
|
|
101
|
+
response.attrs.static = true;
|
|
102
|
+
response.attrs.index = index;
|
|
103
|
+
resolve(response);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Writes a file to the public directory.
|
|
110
|
+
*
|
|
111
|
+
* @param object filename
|
|
112
|
+
* @param string content
|
|
113
|
+
*
|
|
114
|
+
* @return bool
|
|
115
|
+
*/
|
|
116
|
+
putPreRendered(filename, content) {
|
|
117
|
+
var _filename = Path.join(this.cx.layout.PUBLIC_DIR, '.', filename);
|
|
118
|
+
if (!Path.parse(filename).ext && filename.lastIndexOf('.') < filename.lastIndexOf('/')) {
|
|
119
|
+
_filename = Path.join(_filename, '/index.html');
|
|
120
|
+
}
|
|
121
|
+
var dir = Path.dirname(_filename);
|
|
122
|
+
if (!Fs.existsSync(dir)) {
|
|
123
|
+
Fs.mkdirSync(dir, {recursive:true});
|
|
124
|
+
}
|
|
125
|
+
return Fs.writeFileSync(_filename, content);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Deletes a file from the public directory.
|
|
130
|
+
*
|
|
131
|
+
* @param object filename
|
|
132
|
+
*
|
|
133
|
+
* @return bool
|
|
134
|
+
*/
|
|
135
|
+
deletePreRendered(filename) {
|
|
136
|
+
return Fs.unlinkSync(filename);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// maps file extention to MIME typere
|
|
141
|
+
const mimeTypes = {
|
|
142
|
+
'.ico': 'image/x-icon',
|
|
143
|
+
'.html': 'text/html',
|
|
144
|
+
'.js': 'text/javascript',
|
|
145
|
+
'.json': 'application/json',
|
|
146
|
+
'.css': 'text/css',
|
|
147
|
+
'.png': 'image/png',
|
|
148
|
+
'.jpeg': 'image/jpeg',
|
|
149
|
+
'.jpg': 'image/jpeg',
|
|
150
|
+
'.wav': 'audio/wav',
|
|
151
|
+
'.mp3': 'audio/mpeg',
|
|
152
|
+
'.svg': 'image/svg+xml',
|
|
153
|
+
'.pdf': 'application/pdf',
|
|
154
|
+
'.doc': 'application/msword'
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export { mimeTypes };
|