@webqit/webflo 0.8.76 → 0.9.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.
Files changed (97) hide show
  1. package/package.json +5 -12
  2. package/src/Cli.js +131 -0
  3. package/src/Configurator.js +97 -0
  4. package/src/Context.js +76 -0
  5. package/src/config-pi/deployment/Env.js +69 -0
  6. package/src/config-pi/deployment/Layout.js +65 -0
  7. package/src/config-pi/deployment/Origins.js +133 -0
  8. package/src/config-pi/deployment/Virtualization.js +65 -0
  9. package/src/config-pi/deployment/index.js +18 -0
  10. package/src/config-pi/index.js +16 -0
  11. package/src/config-pi/runtime/Client.js +59 -0
  12. package/src/config-pi/runtime/Server.js +174 -0
  13. package/src/config-pi/runtime/client/Worker.js +117 -0
  14. package/src/config-pi/runtime/client/index.js +12 -0
  15. package/src/config-pi/runtime/index.js +18 -0
  16. package/src/config-pi/runtime/server/Headers.js +90 -0
  17. package/src/config-pi/runtime/server/Redirects.js +108 -0
  18. package/src/config-pi/runtime/server/index.js +14 -0
  19. package/src/config-pi/static/Manifest.js +321 -0
  20. package/src/config-pi/static/Ssg.js +72 -0
  21. package/src/config-pi/static/index.js +14 -0
  22. package/src/deployment-pi/index.js +10 -0
  23. package/src/{services → deployment-pi}/origins/index.js +88 -58
  24. package/src/index.js +14 -147
  25. package/src/{runtime → runtime-pi}/Router.js +19 -19
  26. package/src/runtime-pi/client/Context.js +7 -0
  27. package/src/{runtime → runtime-pi}/client/Router.js +2 -2
  28. package/src/{runtime/client/Navigator.js → runtime-pi/client/Runtime.js} +143 -102
  29. package/src/runtime-pi/client/RuntimeClient.js +114 -0
  30. package/src/{runtime → runtime-pi}/client/Storage.js +8 -7
  31. package/src/{runtime → runtime-pi}/client/Url.js +2 -6
  32. package/src/{runtime/client/WorkerClient.js → runtime-pi/client/WorkerComm.js} +2 -2
  33. package/src/runtime-pi/client/generate.js +242 -0
  34. package/src/runtime-pi/client/generate.oohtml.js +7 -0
  35. package/src/runtime-pi/client/index.js +18 -0
  36. package/src/runtime-pi/client/whatwag.js +27 -0
  37. package/src/runtime-pi/client/worker/Context.js +7 -0
  38. package/src/runtime-pi/client/worker/Worker.js +243 -0
  39. package/src/runtime-pi/client/worker/WorkerClient.js +46 -0
  40. package/src/runtime-pi/client/worker/index.js +18 -0
  41. package/src/runtime-pi/index.js +14 -0
  42. package/src/runtime-pi/server/Context.js +16 -0
  43. package/src/{runtime → runtime-pi}/server/Router.js +6 -6
  44. package/src/runtime-pi/server/Runtime.js +531 -0
  45. package/src/runtime-pi/server/RuntimeClient.js +102 -0
  46. package/src/runtime-pi/server/index.js +41 -0
  47. package/src/runtime-pi/server/whatwag.js +35 -0
  48. package/src/{runtime → runtime-pi}/util.js +0 -0
  49. package/src/{runtime/_FormData.js → runtime-pi/xFormData.js} +2 -2
  50. package/src/{runtime/_Headers.js → runtime-pi/xHeaders.js} +4 -4
  51. package/src/runtime-pi/xHttpEvent.js +93 -0
  52. package/src/runtime-pi/xHttpMessage.js +179 -0
  53. package/src/runtime-pi/xRequest.js +67 -0
  54. package/src/runtime-pi/xRequestHeaders.js +95 -0
  55. package/src/runtime-pi/xResponse.js +62 -0
  56. package/src/{runtime/_ResponseHeaders.js → runtime-pi/xResponseHeaders.js} +38 -18
  57. package/src/{runtime/_URL.js → runtime-pi/xURL.js} +4 -4
  58. package/src/runtime-pi/xfetch.js +7 -0
  59. package/src/{services → services-pi}/certbot/http-auth-hook.js +0 -0
  60. package/src/{services → services-pi}/certbot/http-cleanup-hook.js +0 -0
  61. package/src/{services → services-pi}/certbot/index.js +21 -15
  62. package/src/services-pi/index.js +9 -0
  63. package/src/static-pi/index.js +11 -0
  64. package/src/webflo.js +33 -0
  65. package/test/index.test.js +26 -0
  66. package/src/build/client/index.js +0 -261
  67. package/src/build/index.js +0 -5
  68. package/src/config/client.js +0 -191
  69. package/src/config/headers.js +0 -121
  70. package/src/config/index.js +0 -14
  71. package/src/config/layout.js +0 -83
  72. package/src/config/manifest.js +0 -341
  73. package/src/config/origins.js +0 -165
  74. package/src/config/prerendering.js +0 -100
  75. package/src/config/redirects.js +0 -137
  76. package/src/config/server.js +0 -201
  77. package/src/config/variables.js +0 -102
  78. package/src/config/vhosts.js +0 -93
  79. package/src/runtime/_MessageStream.js +0 -195
  80. package/src/runtime/_NavigationEvent.js +0 -91
  81. package/src/runtime/_Request.js +0 -61
  82. package/src/runtime/_RequestHeaders.js +0 -72
  83. package/src/runtime/_Response.js +0 -56
  84. package/src/runtime/client/Cache.js +0 -38
  85. package/src/runtime/client/Http.js +0 -225
  86. package/src/runtime/client/NavigationEvent.js +0 -21
  87. package/src/runtime/client/Runtime.js +0 -126
  88. package/src/runtime/client/StdRequest.js +0 -74
  89. package/src/runtime/client/Worker.js +0 -312
  90. package/src/runtime/client/WorkerComm.js +0 -183
  91. package/src/runtime/client/effects/sounds.js +0 -64
  92. package/src/runtime/index.js +0 -5
  93. package/src/runtime/server/NavigationEvent.js +0 -39
  94. package/src/runtime/server/Runtime.js +0 -593
  95. package/src/runtime/server/index.js +0 -183
  96. package/src/runtime/server/index.mjs +0 -10
  97. package/src/services/index.js +0 -6
@@ -0,0 +1,62 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import xHttpMessage, { encodeBody } from './xHttpMessage.js';
6
+
7
+ /**
8
+ * The xResponse Mixin
9
+ */
10
+ const xResponse = (whatwagResponse, Headers, FormData) => class extends xHttpMessage(whatwagResponse, Headers, FormData) {
11
+
12
+ // construct
13
+ constructor(body = null, init = {}) {
14
+ let bodyAttrs = {}, isResponseInput;
15
+ if (arguments.length) {
16
+ if (body instanceof whatwagResponse) {
17
+ isResponseInput = body;
18
+ // Inherit init
19
+ init = { status: body.status, statusText: body.statusText, headers: body.headers, ...init };
20
+ if (body.status === 0) delete init.status;
21
+ // Inherit bodyAttrs and body
22
+ bodyAttrs = body.bodyAttrs || {};
23
+ body = body.body;
24
+ } else {
25
+ bodyAttrs = encodeBody(body, FormData);
26
+ body = bodyAttrs.body;
27
+ }
28
+ }
29
+ super(body, init, bodyAttrs);
30
+ if (isResponseInput) {
31
+ // Through the backdoor
32
+ this.attrs.url = isResponseInput.url;
33
+ this.attrs.ok = isResponseInput.ok;
34
+ this.attrs.status = isResponseInput.status; // In case it was earlier deleted
35
+ this.attrs.type = isResponseInput.type;
36
+ this.attrs.redirected = isResponseInput.redirected;
37
+ }
38
+ }
39
+
40
+ get ok() {
41
+ return 'ok' in this.attrs ? this.attrs.ok : super.ok;
42
+ }
43
+
44
+ get status() {
45
+ return 'status' in this.attrs ? this.attrs.status : super.status;
46
+ }
47
+
48
+ get statusText() {
49
+ return 'statusText' in this.attrs ? this.attrs.statusText : super.statusText;
50
+ }
51
+
52
+ get type() {
53
+ return 'type' in this.attrs ? this.attrs.type : super.type;
54
+ }
55
+
56
+ get redirected() {
57
+ return 'redirected' in this.attrs ? this.attrs.redirected : super.redirected;
58
+ }
59
+
60
+ };
61
+
62
+ export default xResponse;
@@ -4,13 +4,49 @@
4
4
  */
5
5
  import { _after, _beforeLast } from "@webqit/util/str/index.js";
6
6
  import { _isString, _getType, _isObject } from "@webqit/util/js/index.js";
7
- import _Headers from './_Headers.js';
7
+ import _Headers from './xHeaders.js';
8
8
 
9
9
  /**
10
10
  * The _Headers Mixin
11
11
  */
12
12
  const _ResponseHeaders = NativeHeaders => class extends _Headers(NativeHeaders) {
13
13
 
14
+ set cookies(cookieJar) {
15
+ if (!_isObject(cookieJar)) {
16
+ throw new Error(`The "cookies" response directive cannot be of type: ${_getType(cookieJar)}`);
17
+ }
18
+ for (let cookieName in cookieJar) {
19
+ let cookieBody = cookieJar[cookieName];
20
+ if (_isObject(cookieBody)) {
21
+ let attrsArr = [ cookieBody.value ];
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;
33
+ }
34
+
35
+ get cookies() {
36
+ const cookiesStr = this.get('Set-Cookie');
37
+ return cookiesStr && cookiesStr.split(',').reduce((cookieJar, str) => {
38
+ let [ cookieDefinition, attrsStr ] = str.split(';');
39
+ let [ cookieName, cookieValue ] = cookieDefinition.trim().split('=');
40
+ cookieJar[cookieName] = { value: cookieValue, };
41
+ if (attrsStr) {
42
+ (attrsStr || '').split(/\;/g).map(attrStr => attrStr.trim().split('=')).forEach(attrsArr => {
43
+ cookieJar[cookieName][attrsArr[0][0].toLowerCase() + attrsArr[0].substring(1).replace('-', '')] = attrsArr.length === 1 ? true : attrsArr[1];
44
+ });
45
+ }
46
+ return cookieJar;
47
+ }, {});
48
+ }
49
+
14
50
  set contentRange(value) {
15
51
  if (Array.isArray(value)) {
16
52
  if ((value.length === 2 && !value[0].includes('-')) || value.length < 2) {
@@ -18,28 +54,12 @@ const _ResponseHeaders = NativeHeaders => class extends _Headers(NativeHeaders)
18
54
  }
19
55
  return this.set('Content-Range', `bytes ${value.join('/')}`);
20
56
  }
21
- if (!this.has('Accept-Ranges')) {
22
- this.set('Accept-Ranges', 'bytes');
23
- }
24
57
  return this.set('Content-Range', value);
25
58
  }
26
59
 
27
60
  get contentRange() {
28
61
  const value = this.get('Content-Range');
29
- if (!value) return;
30
- return _after(value, 'bytes ').split('/');
31
- }
32
-
33
- set cookies(cookieStr) {
34
- if (!_isObject(cookieJar)) {
35
- throw new Error(`The "cookies" response directive does not support the type: ${_getType(cookieStr)}`);
36
- }
37
- this.set('Set-Cookie', cookieStr);
38
- return true;
39
- }
40
-
41
- get cookies() {
42
- return this.get('Set-Cookie');
62
+ return value && _after(value, 'bytes ').split('/');
43
63
  }
44
64
 
45
65
  set cors(value) {
@@ -8,11 +8,11 @@ import { wwwFormUnserialize, wwwFormSerialize } from './util.js';
8
8
 
9
9
  /**
10
10
  * ---------------------------
11
- * The _URL Mixin
11
+ * The xURL Mixin
12
12
  * ---------------------------
13
13
  */
14
- const _URL = NativeURL => {
15
- const URL = class extends NativeURL {
14
+ const xURL = whatwagURL => {
15
+ const URL = class extends whatwagURL {
16
16
 
17
17
  // constructor
18
18
  constructor(...args) {
@@ -108,4 +108,4 @@ var _strictEven = (a, b) => {
108
108
  return a === b;
109
109
  };
110
110
 
111
- export default _URL;
111
+ export default xURL;
@@ -0,0 +1,7 @@
1
+
2
+ /**
3
+ * The xfetch Mixin
4
+ */
5
+ const xfetch = whatwagFetch => whatwagFetch;
6
+
7
+ export default xfetch;
@@ -4,27 +4,27 @@
4
4
  */
5
5
  import Fs from 'fs';
6
6
  import { spawn } from 'child_process';
7
- import _arrFrom from '@webqit/util/arr/from.js';
8
- import * as _server from '../../config/server.js';
7
+ import { _from as _arrFrom } from '@webqit/util/arr/index.js';
9
8
 
10
9
  /**
11
10
  * @description
12
11
  */
13
12
  export const desc = {
14
- generate: 'Deploys a remote origin into the local directory.',
13
+ generate: 'Generate an SSL cert for a domain or list of domains.',
15
14
  };
16
15
 
17
16
  /**
18
17
  * Reads SSL from file.
19
18
  *
20
- * @param Ui Ui
21
19
  * @param string allDomains
22
- * @param object flags
23
- * @param object layout
24
20
  *
25
21
  * @return object
26
22
  */
27
- export async function generate(Ui, allDomains, flags = {}, layout = {}) {
23
+ export async function generate(allDomains) {
24
+ const cx = this || {};
25
+ if (!cx.config.runtime?.Server) {
26
+ throw new Error(`The Server configurator "config.runtime.Server" is required in context.`);
27
+ }
28
28
  const domains = _arrFrom(allDomains).reduce((all, d) => all.concat(d.split(',')), []).filter(d => d.trim());
29
29
  const args = [
30
30
  'certonly',
@@ -41,34 +41,40 @@ export async function generate(Ui, allDomains, flags = {}, layout = {}) {
41
41
  process.stdin.pipe(child.stdin);
42
42
 
43
43
  child.stdout.on('data', data => {
44
- Ui.log('[' + Ui.style.keyword('CERTBOT') + '][' + Ui.style.var('OUT') + ']:', data + '');
44
+ if (cx.logger) {
45
+ cx.logger.log('[' + cx.logger.style.keyword('CERTBOT') + '][' + cx.logger.style.var('OUT') + ']:', data + '');
46
+ }
45
47
  });
46
48
 
47
49
  child.stderr.on('data', data => {
48
- Ui.log('[' + Ui.style.keyword('CERTBOT') + '][' + Ui.style.err('ERR') + ']:', (data + '').trim());
50
+ if (cx.logger) {
51
+ cx.logger.log('[' + cx.logger.style.keyword('CERTBOT') + '][' + cx.logger.style.err('ERR') + ']:', (data + '').trim());
52
+ }
49
53
  });
50
54
 
51
55
  child.on('error', data => {
52
- Ui.error(data);
56
+ cx.logger && cx.logger.error(data);
53
57
  process.exit();
54
58
  });
55
59
 
56
60
  child.on('exit', async exitCode => {
57
- const server = await _server.read(flags, layout);
61
+ const serverConfig = new cx.config.runtime.Server(cx);
62
+ const server = await serverConfig.read();
58
63
  const domain = domains[0], certDir = `/etc/letsencrypt/live/${domain}`;
59
- if (!exitCode && (flags['auto-config'] || flags.c)) {
64
+ if (!exitCode && cx.flags && (cx.flags['auto-config'] || cx.flags.c)) {
60
65
  if (Fs.existsSync(certDir)) {
61
- Ui.log('Automatically configuring the server with the generated cert.');
66
+ cx.logger && cx.logger.log('Automatically configuring the server with the generated cert.');
62
67
  if (!server.https) {
63
68
  server.https = {};
64
69
  }
65
70
  server.https.keyfile = `${certDir}/privkey.pem`;
66
71
  server.https.certfile = `${certDir}/fullchain.pem`;
67
- await _server.write(server);
72
+ await serverConfig.write(server);
68
73
  } else {
69
- Ui.log(`Generated cert files not found in ${certDir}; be sure to configure the server with the valid cert files.`);
74
+ cx.logger && cx.logger.log(`Generated cert files not found in ${certDir}; be sure to configure the server with the valid cert files.`);
70
75
  }
71
76
  }
72
77
  process.exit();
73
78
  });
79
+
74
80
  }
@@ -0,0 +1,9 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import * as certbot from './certbot/index.js';
6
+
7
+ export {
8
+ certbot,
9
+ }
@@ -0,0 +1,11 @@
1
+
2
+ /**
3
+ * @imports
4
+ import * as client from './client/index.js';
5
+ import * as server from './server/index.js';
6
+ */
7
+
8
+ export {
9
+ //client,
10
+ //server,
11
+ }
package/src/webflo.js ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @imports
5
+ */
6
+ import Url from 'url';
7
+ import Path from 'path';
8
+ import { read as readJsonFile } from '@webqit/backpack/src/dotfiles/DotJson.js';
9
+ import logger from '@webqit/backpack/src/cli/Ui.js';
10
+ import * as WebfloPI from './index.js';
11
+ import Context from './Context.js';
12
+ import Cli from './Cli.js';
13
+
14
+ const dirSelf = Path.dirname(Url.fileURLToPath(import.meta.url));
15
+ const webfloJson = readJsonFile(Path.join(dirSelf, '../package.json'));
16
+ const appJson = readJsonFile('./package.json');
17
+
18
+ /**
19
+ * @cx
20
+ */
21
+ const cx = Context.create({
22
+ webflo: { title: webfloJson.title, version: webfloJson.version },
23
+ app: { title: appJson.title, version: appJson.version },
24
+ logger,
25
+ config: WebfloPI.config,
26
+ middlewares: [ WebfloPI.deployment.origins.webhook, ],
27
+ });
28
+
29
+ /**
30
+ * @cli
31
+ */
32
+ const cli = new Cli(WebfloPI);
33
+ await cli.exec(cx);
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @imports
3
+ */
4
+ import Context from "../src/Context.js";
5
+ import * as WebfloPI from '../src/index.js';
6
+
7
+ let client = {
8
+ handle: function(httpEvent) {
9
+ return new httpEvent.Response({ abcd: '1234' }, {
10
+ status: 302,
11
+ headers: {
12
+ //location: '/dddd',
13
+ cookies: {
14
+ cookie1: { value: 'value1' },
15
+ cookie2: { value: 'value2' },
16
+ }
17
+ }
18
+ });
19
+ },
20
+ };
21
+
22
+ const cx = Context.create({ config: WebfloPI.config, });
23
+ const clientCallback = (_cx, hostName, defaultClientCallback) => client;
24
+ const app = await WebfloPI.runtime.server.start.call(cx, clientCallback);
25
+
26
+ const response = await app.go('http://localhost/', { headers: { range: 'bytes=0-5, 6' } } );
@@ -1,261 +0,0 @@
1
-
2
- /**
3
- * imports
4
- */
5
- import Fs from 'fs';
6
- import Url from 'url';
7
- import Path from 'path';
8
- import Webpack from 'webpack';
9
- import { _beforeLast } from '@webqit/util/str/index.js';
10
- import { _isObject, _isArray, _isEmpty } from '@webqit/util/js/index.js';
11
- import * as DotJs from '@webqit/backpack/src/dotfiles/DotJs.js';
12
- import * as client from '../../config/client.js'
13
-
14
-
15
- /**
16
- * @description
17
- */
18
- export const desc = {
19
- build: 'Creates the application Client Build.',
20
- };
21
-
22
- /**
23
- * @build
24
- */
25
- export async function build(Ui, flags = {}, layout = {}) {
26
-
27
- const config = await client.read(flags, layout);
28
- // Consistent forward slashing
29
- const forwardSlash = str => str.replace(/\\/g, '/');
30
- var modulesDir = forwardSlash(Url.fileURLToPath(Path.join(import.meta.url, '../../../runtime/client')));
31
-
32
- var workerDirSplit = Path.resolve(layout.WORKER_DIR).replace(/\\/g, '/').split('/');
33
- var workerParams = config.worker || {};
34
- const workerBundlingConfig = workerParams.bundling || {};
35
-
36
- var clientDirSplit = Path.resolve(layout.CLIENT_DIR).replace(/\\/g, '/').split('/');
37
- var clientParams = config; // Yes root config object
38
- const clientBundlingConfig = clientParams.bundling || {};
39
-
40
- var waiting;
41
-
42
- // -------------------
43
- // Create the Service Worker file
44
- // -------------------
45
-
46
- if (!_isEmpty(workerParams)) {
47
-
48
- Ui.log('');
49
- Ui.title(`SERVICE WORKER BUILD`);
50
-
51
- const workerBuild = { imports: {}, code: [], };
52
- workerBuild.imports[modulesDir + '/Worker.js'] = 'Worker';
53
-
54
- // ------------------
55
- // >> Routes mapping
56
- buildRoutes(workerBuild, Ui, Path.resolve(layout.WORKER_DIR), 'Worker-Side Routing:');
57
- workerBuild.code.push(``);
58
- workerBuild.code.push(`// >> Worker Params`);
59
- buildParams(workerBuild, workerParams, 'params');
60
- workerBuild.code.push(``);
61
- workerBuild.code.push(`// >> Worker Instantiation`);
62
- workerBuild.code.push(`Worker.call(null, layout, params);`);
63
- // ------------------
64
-
65
- // ------------------
66
- // >> Write to file...
67
- workerBundlingConfig.intermediate = workerBundlingConfig.intermediate || `${clientDirSplit.join('/')}/worker.js`;
68
- workerBundlingConfig.output = workerBundlingConfig.output || {
69
- filename: 'worker.js',
70
- path: Path.resolve(layout.PUBLIC_DIR),
71
- };
72
- waiting = Ui.waiting(Ui.f`Writing the Service Worker file: ${workerBundlingConfig.intermediate}`);
73
- waiting.start();
74
- DotJs.write(workerBuild, workerBundlingConfig.intermediate, 'Service Worker File');
75
- waiting.stop();
76
- Ui.info(Ui.f`Service Worker file: ${workerBundlingConfig.intermediate}`);
77
- // ------------------
78
- }
79
-
80
- // -------------------
81
- // Create the Client file
82
- // -------------------
83
-
84
- Ui.log('');
85
- Ui.title(`CLIENT BUILD`);
86
-
87
- const clientBuild = { imports: {}, code: [], };
88
- clientBuild.imports[modulesDir + '/Runtime.js'] = 'Runtime';
89
-
90
- // ------------------
91
- // >> Routes mapping
92
- buildRoutes(clientBuild, Ui, Path.resolve(layout.CLIENT_DIR), 'Client-Side Routing:');
93
- clientBuild.code.push(``);
94
- clientBuild.code.push(`// >> Runtime Params`);
95
- buildParams(clientBuild, clientParams, 'params');
96
- clientBuild.code.push(``);
97
- clientBuild.code.push(`// >> Runtime Instantiation`);
98
- clientBuild.code.push(`Runtime.call(null, layout, params);`);
99
- // ------------------
100
-
101
- // ------------------
102
- // >> Write to file...
103
- clientBundlingConfig.intermediate = clientBundlingConfig.intermediate || clientDirSplit.join('/') + '/bundle.js';
104
- clientBundlingConfig.output = clientBundlingConfig.output || {
105
- filename: 'bundle.js',
106
- path: Path.resolve(layout.PUBLIC_DIR),
107
- };
108
- waiting = Ui.waiting(`Writing the client entry file: ${clientBundlingConfig.intermediate}`);
109
- waiting.start();
110
- DotJs.write(clientBuild, clientBundlingConfig.intermediate, 'Runtime Build File');
111
- waiting.stop();
112
- Ui.info(Ui.f`Runtime Build file: ${clientBundlingConfig.intermediate}`);
113
- // ------------------
114
-
115
- // -------------------
116
- // Run webpack
117
- // -------------------
118
-
119
- if (clientParams.bundling || workerParams.bundling) {
120
- Ui.log('');
121
- Ui.title(`BUNDLES`);
122
- }
123
- if (workerParams.bundling !== false) {
124
- await createBundle(Ui, workerBundlingConfig, 'Bundling the Service Worker Build file');
125
- }
126
- if (clientParams.bundling !== false) {
127
- clientBundlingConfig.experiments = clientBundlingConfig.experiments || {};
128
- if (!('outputModule' in clientBundlingConfig.experiments)) {
129
- clientBundlingConfig.experiments.outputModule = true;
130
- clientBundlingConfig.externalsType = 'module';
131
- }
132
- if (clientBundlingConfig.experiments.outputModule !== false) {
133
- clientBundlingConfig.output = clientBundlingConfig.output || {};
134
- clientBundlingConfig.output.environment = clientBundlingConfig.output.environment || {};
135
- if (!('module' in clientBundlingConfig.output)) {
136
- clientBundlingConfig.output.module = true;
137
- clientBundlingConfig.output.environment.module = true;
138
- }
139
- }
140
- await createBundle(Ui, clientBundlingConfig, 'Bundling the Runtime Build file');
141
- }
142
-
143
- }
144
-
145
- /**
146
- * Creates a bundle using webpack
147
- *
148
- * @param {object} config
149
- * @param {string} desc
150
- *
151
- * @return void
152
- */
153
- const createBundle = (Ui, config, desc) => {
154
- const intermediateFile = config.intermediate;
155
- config = { ...config };
156
- if (!config.entry) {
157
- config.entry = config.intermediate;
158
- }
159
- delete config.intermediate;
160
- return new Promise(resolve => {
161
- var waiting = Ui.waiting(`${desc} ...`);
162
- Ui.log('');
163
- Ui.info(Ui.f`FROM: ${config.entry}`);
164
- Ui.info(Ui.f`TO: ${config.output.path + '/' + config.output.filename}`);
165
- Ui.log('');
166
- waiting.start();
167
-
168
- // Run
169
- var compiler = Webpack(config);
170
- compiler.run((err, stats) => {
171
- waiting.stop();
172
- if (err) {
173
- Ui.title(`Errors!`);
174
- Ui.error(err);
175
- }
176
- Ui.log(stats.toString({
177
- colors: true,
178
- }));
179
- // Remove intermediate build
180
- Fs.unlinkSync(intermediateFile);
181
- resolve();
182
- });
183
- });
184
- };
185
-
186
- /**
187
- * Initializes a server on the given working directory.
188
- *
189
- * @param object params
190
- *
191
- * @return void
192
- */
193
- const buildRoutes = (build, Ui, entry, desc) => {
194
- // -------------------
195
- // Helper functions
196
- // -------------------
197
- // Directory walking
198
- const walk = (dir, callback) => {
199
- Fs.readdirSync(dir).forEach(f => {
200
- let resource = Path.join(dir, f);
201
- if (Fs.statSync(resource).isDirectory()) {
202
- walk(resource, callback);
203
- } else {
204
- var ext = Path.extname(resource) || '';
205
- callback(resource, ext);
206
- }
207
- });
208
- };
209
-
210
- Ui.log('');
211
- Ui.title(desc);
212
-
213
- // >> Routes mapping
214
- build.code.push(`// >> ` + desc);
215
- build.code.push(`const layout = {};`);
216
-
217
- var indexCount = 0;
218
- if (entry && Fs.existsSync(entry)) {
219
- var clientDirname = entry.replace(/\\/g, '/').split('/').pop();
220
- walk(entry, (file, ext) => {
221
- //relativePath = relativePath.replace(/\\/g, '/');
222
- if (file.replace(/\\/g, '/').endsWith('/index.js')) {
223
- var relativePath = Path.relative(entry, file).replace(/\\/g, '/');
224
- // Import code
225
- var routeName = 'index' + (++ indexCount);
226
- // IMPORTANT: we;re taking a step back here so that the parent-child relationship for
227
- // the directories be involved
228
- build.imports[`../${clientDirname}/${relativePath}`] = '* as ' + routeName;
229
- // Definition code
230
- var routePath = _beforeLast('/' + relativePath, '/index.js');
231
- build.code.push(`layout['${routePath || '/'}'] = ${routeName};`);
232
- // Show
233
- Ui.log(`> ./${relativePath}`);
234
- }
235
- });
236
- }
237
- if (!indexCount) {
238
- Ui.log(`> (none)`);
239
- }
240
- };
241
-
242
- const buildParams = (build, params, varName = null, indentation = 0) => {
243
- if (varName) build.code.push(`const ${varName} = {`);
244
- Object.keys(params).forEach(name => {
245
- var _name = ` ${' '.repeat(indentation)}${(_isArray(params) ? '' : (name.includes(' ') ? `'${name}'` : name) + ': ')}`;
246
- if ([ 'boolean', 'number' ].includes(typeof params[name])) {
247
- build.code.push(`${_name}${params[name]},`);
248
- } else if (_isArray(params[name])) {
249
- build.code.push(`${_name}[`);
250
- buildParams(build, params[name], null, indentation + 1);
251
- build.code.push(` ${' '.repeat(indentation)}],`);
252
- } else if (_isObject(params[name])) {
253
- build.code.push(`${_name}{`);
254
- buildParams(build, params[name], null, indentation + 1);
255
- build.code.push(` ${' '.repeat(indentation)}},`);
256
- } else {
257
- build.code.push(`${_name}'${params[name]}',`);
258
- }
259
- });
260
- if (varName) build.code.push(`};`);
261
- };
@@ -1,5 +0,0 @@
1
-
2
- /**
3
- * exports
4
- */
5
- export * as client from './client/index.js';