@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,321 @@
1
+
2
+ /**
3
+ * imports
4
+ */
5
+ import Path from 'path';
6
+ import { _all } from '@webqit/util/arr/index.js';
7
+ import { _merge } from '@webqit/util/obj/index.js';
8
+ import { _isNumeric } from '@webqit/util/js/index.js';
9
+ import { _before, _after } from '@webqit/util/str/index.js';
10
+ import { initialGetIndex } from '@webqit/backpack/src/cli/Promptx.js';
11
+ import Configurator from '../../Configurator.js';
12
+
13
+ export default class Manifest extends Configurator {
14
+
15
+ // Base name
16
+ get name() {
17
+ return 'manifest';
18
+ }
19
+
20
+ // @desc
21
+ static get ['@desc']() {
22
+ return 'Application Manifest config.';
23
+ }
24
+
25
+ // Config dir
26
+ get configDir() {
27
+ return Path.join(this.cx.CWD || ``, this.cx.layout.PUBLIC_DIR || '');
28
+ }
29
+
30
+ // Defaults merger
31
+ withDefaults(config) {
32
+ const pkg = this.cx.PKG || {};
33
+ return _merge(true, {
34
+ // -----------------
35
+ name: pkg.value,
36
+ short_name: pkg.value,
37
+ description: pkg.description,
38
+ categories: pkg.keywords,
39
+ theme_color: 'transparent',
40
+ background_color: 'transparent',
41
+ icons: [],
42
+ display: 'browser',
43
+ orientation: 'any',
44
+ // advanced
45
+ screenshots: [],
46
+ shortcuts: [],
47
+ scope: '/',
48
+ start_url: '/',
49
+ lang: 'en-us',
50
+ dir: 'ltr',
51
+ related_applications: '',
52
+ prefer_related_applications: false,
53
+ }, config);
54
+ }
55
+
56
+ // Questions generator
57
+ questions(config, choices = {}) {
58
+ // Choices hash...
59
+ const CHOICES = _merge({
60
+ display: [
61
+ {value: 'browser',},
62
+ {value: 'fullscreen',},
63
+ {value: 'standalone',},
64
+ {value: 'minimal-ui',},
65
+ ],
66
+ orientation: [
67
+ {value: 'any',},
68
+ {value: 'natural',},
69
+ {value: '::::::::::::::::', disabled: true,},
70
+ {value: 'landscape',},
71
+ {value: 'landscape-primary',},
72
+ {value: 'landscape-secondary',},
73
+ {value: '::::::::::::::::', disabled: true,},
74
+ {value: 'portrait',},
75
+ {value: 'portrait-primary',},
76
+ {value: 'portrait-secondary',},
77
+ ],
78
+ }, choices);
79
+
80
+ // Gets index...
81
+ const getSize = src => Path.basename(src).split(/[_\.\-]/g).reduce((size, chunk) => size || (_all(chunk.split('x'), c => _isNumeric(c)) ? chunk : ''), null);
82
+ const getMime = src => extensions[Path.extname(src)];
83
+ // extensions
84
+ const extensions = {
85
+ '.png': 'image/png',
86
+ '.jpg': 'image/jpg',
87
+ '.jpeg': 'image/jpeg',
88
+ '.ico': 'image/ico',
89
+ };
90
+
91
+ // Questions
92
+ return [
93
+ {
94
+ name: 'name',
95
+ type: 'text',
96
+ message: 'Enter the application name',
97
+ initial: config.name,
98
+ validation: ['important'],
99
+ },
100
+ {
101
+ name: 'short_name',
102
+ type: 'text',
103
+ message: 'Enter the application short name',
104
+ initial: prev => config.short_name || prev,
105
+ validation: ['important'],
106
+ },
107
+ {
108
+ name: 'description',
109
+ type: 'text',
110
+ message: 'Enter the application description',
111
+ initial: config.description,
112
+ validation: ['important'],
113
+ },
114
+ {
115
+ name: 'categories',
116
+ type: 'list',
117
+ message: 'Specify applications categories (comma-separated)',
118
+ initial: (config.categories || []).join(', '),
119
+ },
120
+ {
121
+ name: 'theme_color',
122
+ type: 'text',
123
+ message: 'Enter the application theme color',
124
+ initial: config.theme_color,
125
+ },
126
+ {
127
+ name: 'background_color',
128
+ type: 'text',
129
+ message: 'Enter the application background color',
130
+ initial: config.background_color,
131
+ },
132
+ {
133
+ name: 'icons',
134
+ type: 'recursive',
135
+ initial: config.icons,
136
+ controls: {
137
+ name: 'icon',
138
+ },
139
+ questions: [
140
+ {
141
+ name: 'src',
142
+ type: 'text',
143
+ message: 'Enter icon URL',
144
+ validation: ['important'],
145
+ },
146
+ {
147
+ name: 'type',
148
+ type: 'text',
149
+ message: 'Enter icon MIME type',
150
+ initial: prev => getMime(prev),
151
+ validation: ['important'],
152
+ },
153
+ {
154
+ name: 'sizes',
155
+ type: 'text',
156
+ message: 'Enter icon sizes',
157
+ initial: (prev, answers) => getSize(answers.src),
158
+ validation: ['important'],
159
+ },
160
+ ],
161
+ },
162
+ {
163
+ name: 'display',
164
+ type: 'select',
165
+ message: 'Enter the application display mode',
166
+ choices: CHOICES.display,
167
+ initial: initialGetIndex(CHOICES.display, config.display),
168
+ },
169
+ {
170
+ name: 'orientation',
171
+ type: 'select',
172
+ message: 'Enter the application orientation mode',
173
+ choices: CHOICES.orientation,
174
+ initial: initialGetIndex(CHOICES.orientation, config.orientation),
175
+ },
176
+ // ------------- advanced --------------
177
+ {
178
+ name: '__advanced',
179
+ type: 'toggle',
180
+ message: 'Show advanced options?',
181
+ active: 'YES',
182
+ inactive: 'NO',
183
+ initial: config.__advanced,
184
+ exclude: true,
185
+ },
186
+ // ------------- advanced --------------
187
+ {
188
+ name: 'screenshots',
189
+ type: (prev, answers) => answers.__advanced ? 'recursive' : null,
190
+ initial: config.screenshots,
191
+ controls: {
192
+ name: 'screenshot',
193
+ },
194
+ questions: [
195
+ {
196
+ name: 'src',
197
+ type: 'text',
198
+ message: 'Enter screenshot URL',
199
+ validation: ['important'],
200
+ },
201
+ {
202
+ name: 'type',
203
+ type: 'text',
204
+ message: 'Enter screenshot MIME type',
205
+ initial: prev => getMime(prev),
206
+ validation: ['important'],
207
+ },
208
+ {
209
+ name: 'sizes',
210
+ type: 'text',
211
+ message: 'Enter screenshot sizes',
212
+ initial: (prev, answers) => getSize(answers.src),
213
+ validation: ['important'],
214
+ },
215
+ ],
216
+ },
217
+ {
218
+ name: 'shortcuts',
219
+ type: (prev, answers) => answers.__advanced ? 'recursive' : null,
220
+ initial: config.shortcuts,
221
+ controls: {
222
+ name: 'shortcut',
223
+ },
224
+ questions: [
225
+ {
226
+ name: 'name',
227
+ type: 'text',
228
+ message: 'Enter shortcut name',
229
+ validation: ['important'],
230
+ },
231
+ {
232
+ name: 'short_name',
233
+ type: 'text',
234
+ message: 'Enter shortcut short name',
235
+ validation: ['important'],
236
+ },
237
+ {
238
+ name: 'description',
239
+ type: 'text',
240
+ message: 'Enter shortcut description',
241
+ validation: ['important'],
242
+ },
243
+ {
244
+ name: 'url',
245
+ type: 'text',
246
+ message: 'Enter shortcut URL',
247
+ validation: ['important'],
248
+ },
249
+ {
250
+ name: 'icons',
251
+ type: 'recursive',
252
+ controls: {
253
+ name: 'shortcut icon',
254
+ },
255
+ questions: [
256
+ {
257
+ name: 'src',
258
+ type: 'text',
259
+ message: 'Enter icon URL',
260
+ validation: ['important'],
261
+ },
262
+ {
263
+ name: 'type',
264
+ type: 'text',
265
+ message: 'Enter icon MIME type',
266
+ initial: prev => getMime(prev),
267
+ validation: ['important'],
268
+ },
269
+ {
270
+ name: 'sizes',
271
+ type: 'text',
272
+ message: 'Enter icon sizes',
273
+ initial: (prev, answers) => getSize(answers.src),
274
+ validation: ['important'],
275
+ },
276
+ ],
277
+ },
278
+ ],
279
+ },
280
+ {
281
+ name: 'scope',
282
+ type: (prev, answers) => answers.__advanced ? 'text' : null,
283
+ message: 'Specify the manifest scope',
284
+ initial: config.scope,
285
+ },
286
+ {
287
+ name: 'start_url',
288
+ type: (prev, answers) => answers.__advanced ? 'text' : null,
289
+ message: 'Specify the application start URL',
290
+ initial: config.start_url,
291
+ },
292
+ {
293
+ name: 'lang',
294
+ type: (prev, answers) => answers.__advanced ? 'text' : null,
295
+ message: 'Specify the application language',
296
+ initial: config.lang,
297
+ },
298
+ {
299
+ name: 'dir',
300
+ type: (prev, answers) => answers.__advanced ? 'text' : null,
301
+ message: 'Specify the application writing mode',
302
+ initial: config.dir,
303
+ },
304
+ {
305
+ name: 'related_applications',
306
+ type: (prev, answers) => answers.__advanced ? 'list' : null,
307
+ message: 'Specify related applications (comma-separated)',
308
+ initial: (config.related_applications || []).join(', '),
309
+ },
310
+ {
311
+ name: 'prefer_related_applications',
312
+ type: (prev, answers) => answers.related_applications ? 'toggle' : null,
313
+ message: 'Specify whether to "prefer" related applications',
314
+ active: 'YES',
315
+ inactive: 'NO',
316
+ initial: config.prefer_related_applications,
317
+ },
318
+
319
+ ];
320
+ }
321
+ }
@@ -0,0 +1,72 @@
1
+
2
+ /**
3
+ * imports
4
+ */
5
+ import { _merge } from '@webqit/util/obj/index.js';
6
+ import { _isObject } from '@webqit/util/js/index.js';
7
+ import Micromatch from 'micromatch';
8
+ import Configurator from '../../Configurator.js';
9
+
10
+ export default class Ssg extends Configurator {
11
+
12
+ // Base name
13
+ get name() {
14
+ return 'ssg';
15
+ }
16
+
17
+ // @desc
18
+ static get ['@desc']() {
19
+ return 'Server-Side Generation (SSG) config.';
20
+ }
21
+
22
+ // Defaults merger
23
+ withDefaults(config) {
24
+ return _merge(true, {
25
+ entries: [],
26
+ }, config);
27
+ }
28
+
29
+ // Match
30
+ async match(url) {
31
+ var pathname = url;
32
+ if (_isObject(url)) {
33
+ pathname = url.pathname;
34
+ }
35
+ return ((await this.read()).entries || []).reduce((match, prerend) => {
36
+ if (match) {
37
+ return match;
38
+ }
39
+ var regex = Micromatch.makeRe(prerend.page, {dot: true});
40
+ var rootMatch = pathname.split('/').filter(seg => seg).map(seg => seg.trim()).reduce((str, seg) => str.endsWith(' ') ? str : ((str = str + '/' + seg) && str.match(regex) ? str + ' ' : str), '');
41
+ if (rootMatch.endsWith(' ')) {
42
+ return {
43
+ url: prerend.page,
44
+ };
45
+ }
46
+ }, null);
47
+ }
48
+
49
+ // Questions generator
50
+ questions(config, choices = {}) {
51
+ // Questions
52
+ return [
53
+ {
54
+ name: 'entries',
55
+ type: 'recursive',
56
+ controls: {
57
+ name: 'page',
58
+ },
59
+ initial: config.entries,
60
+ questions: [
61
+ {
62
+ name: 'page',
63
+ type: 'text',
64
+ message: 'Page URL',
65
+ validation: ['important'],
66
+ },
67
+ ],
68
+ },
69
+
70
+ ];
71
+ }
72
+ }
@@ -0,0 +1,14 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import Manifest from './Manifest.js';
6
+ import Ssg from './Ssg.js';
7
+
8
+ /**
9
+ * @exports
10
+ */
11
+ export {
12
+ Manifest,
13
+ Ssg,
14
+ }
@@ -0,0 +1,10 @@
1
+
2
+ /**
3
+ * imports
4
+ */
5
+ import * as origins from './origins/index.js';
6
+
7
+ /**
8
+ * @exports
9
+ */
10
+ export { origins }
@@ -1,28 +1,31 @@
1
1
 
2
2
  /**
3
- * imports
3
+ * @imports
4
4
  */
5
5
  import Fs from 'fs';
6
6
  import Path from 'path';
7
- import { spawn } from 'child_process';
8
- import _any from '@webqit/util/arr/any.js';
9
- import _beforeLast from '@webqit/util/str/beforeLast.js';
10
- import _isObject from '@webqit/util/js/isObject.js';
11
7
  import SimpleGit from 'simple-git';
8
+ import { spawn } from 'child_process';
9
+ import { _any } from '@webqit/util/arr/index.js';
10
+ import { _beforeLast } from '@webqit/util/str/index.js';
11
+ import { _isObject } from '@webqit/util/js/index.js';
12
12
  import Webhooks from '@octokit/webhooks';
13
- import * as origins from '../../config/origins.js';
14
13
 
15
14
  /**
16
- * @description
15
+ * @desc
17
16
  */
18
17
  export const desc = {
19
- deploy: 'Deploys a remote origin into the local directory.',
18
+ deploy: 'Deploy project from a remote origin.',
20
19
  };
21
20
 
22
21
  /**
23
22
  * @deploy
24
23
  */
25
- export async function deploy(Ui, origin, flags = {}, layout = {}) {
24
+ export async function deploy(origin) {
25
+ const cx = this || {};
26
+ if (!cx.config.deployment?.Origins) {
27
+ throw new Error(`The Origins configurator "config.deployment.Origins" is required in context.`);
28
+ }
26
29
  if (!_isObject(origin)) {
27
30
  if (!origin) {
28
31
  throw new Error(`Please provide a repository name.`);
@@ -41,7 +44,7 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
41
44
  tag: repo.replace('/', '-'),
42
45
  };
43
46
  } else {
44
- const matches = await origins.match(origin, flags, layout);
47
+ const matches = await (new cx.config.deployment.Origins(cx)).match(origin);
45
48
  if (matches.length > 1) {
46
49
  throw new Error(`Cannot deploy ${origin}: Multiple deploy settings found.`);
47
50
  }
@@ -53,7 +56,7 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
53
56
  }
54
57
  // ---------------
55
58
  const isDeployPathSet = origin.deploy_path;
56
- origin.deploy_path = Path.join(layout.ROOT, origin.deploy_path || '.');
59
+ origin.deploy_path = Path.join(cx.CWD || '', origin.deploy_path || '.');
57
60
  // ---------------
58
61
  // Instance
59
62
  const git = SimpleGit();
@@ -61,7 +64,7 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
61
64
  var isNewDeployPath = !Fs.existsSync((origin.deploy_path || '') + '/.git');
62
65
  if (isDeployPathSet) {
63
66
  if (!Fs.existsSync(origin.deploy_path)) {
64
- Fs.mkdirSync(origin.deploy_path, {recursive: true});
67
+ Fs.mkdirSync(origin.deploy_path, { recursive: true });
65
68
  }
66
69
  }
67
70
  await git.cwd(origin.deploy_path);
@@ -76,18 +79,23 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
76
79
 
77
80
  // Deployment
78
81
  const pull = async () => {
79
- Ui.log('');
80
- const waiting = Ui.waiting(Ui.f`Deploying ${origin.tag}`);
81
- waiting.start();
82
+ let waiting;
83
+ if (cx.logger) {
84
+ cx.logger.log('');
85
+ waiting = cx.logger.waiting(cx.logger.f`Deploying ${origin.tag}`);
86
+ waiting.start();
87
+ }
82
88
  await git.reset('hard');
83
89
  return git.pull(origin.tag, origin.branch)
84
90
  .then(() => {
85
- waiting.stop();
86
- Ui.log('');
87
- var _date = (new Date).toUTCString();
88
- Ui.success(Ui.f`[${Ui.style.comment(_date)}][AUTODEPLOY] Successfully deployed: ${origin.tag + '@' + origin.branch} - ${url} to ${origin.deploy_path}!`);
89
- Ui.success(Ui.f`[${Ui.style.comment(_date)}][AUTODEPLOY] On-deploy script: ${origin.ondeploy}!`);
90
- Ui.log('');
91
+ if (cx.logger) {
92
+ waiting.stop();
93
+ cx.logger.log('');
94
+ var _date = (new Date).toUTCString();
95
+ cx.logger.success(cx.logger.f`[${cx.logger.style.comment(_date)}][AUTODEPLOY] Successfully deployed: ${origin.tag + '@' + origin.branch} - ${url} to ${origin.deploy_path}!`);
96
+ cx.logger.success(cx.logger.f`[${cx.logger.style.comment(_date)}][AUTODEPLOY] On-deploy script: ${origin.ondeploy}!`);
97
+ cx.logger.log('');
98
+ }
91
99
  if (origin.ondeploy) {
92
100
  const run = cmd => new Promise((resolve, reject) => {
93
101
  cmd = cmd.split(' ').map(a => a.trim()).filter(a => a);
@@ -96,14 +104,14 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
96
104
  stdio: [ process.stdin, process.stdout, process.stderr ],
97
105
  });
98
106
 
99
- child.on('error', data => {
100
- Ui.error(data);
101
- reject(data);
107
+ child.on('error', error => {
108
+ cx.logger && cx.logger.error(error);
109
+ reject(error);
102
110
  });
103
111
 
104
112
  child.on('exit', async exitCode => {
105
113
  resolve(exitCode);
106
- Ui.log('');
114
+ cx.logger && cx.logger.log('');
107
115
  });
108
116
  });
109
117
  return origin.ondeploy.split('&&').map(cmd => cmd.trim()).reduce(
@@ -111,8 +119,10 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
111
119
  , 0);
112
120
  }
113
121
  }).catch(err => {
114
- waiting.stop();
115
- Ui.error(err);
122
+ if (cx.logger) {
123
+ waiting.stop();
124
+ cx.logger.error(err);
125
+ }
116
126
  });
117
127
  };
118
128
 
@@ -124,28 +134,35 @@ export async function deploy(Ui, origin, flags = {}, layout = {}) {
124
134
  || isNewDeployPath) {
125
135
  return git.addRemote(origin.tag, url)
126
136
  .then(() => {
127
- Ui.log('');
128
- Ui.info(Ui.f`Added new origin - ${origin.tag}: ${url}`);
137
+ if (cx.logger) {
138
+ cx.logger.log('');
139
+ cx.logger.info(cx.logger.f`Added new origin - ${origin.tag}: ${url}`);
140
+ }
129
141
  return pull();
130
142
  })
131
- .catch(err => Ui.error(err));
143
+ .catch(err => cx.logger && cx.logger.error(err));
132
144
  } else {
133
145
  return pull();
134
146
  }
135
147
  });
148
+
136
149
  }
137
150
 
138
151
  /**
139
152
  * @hook
140
153
  */
141
- export async function hook(Ui, event, deployCallback, flags = {}, layout = {}) {
142
- const eventHandler = Webhooks.createEventHandler();
143
- if (event.request.headers.has('user-agent') && event.request.headers.get('user-agent').startsWith('GitHub-Hookshot/')) {
144
- const payload = await event.request.json();
145
- const matches = (await origins.match(payload.repository.full_name, flags, layout)).filter(o => o.autodeploy);
154
+ export async function webhook(httpEvent, router, next) {
155
+ const cx = this || {};
156
+ if (!cx.config.deployment?.Origins) {
157
+ throw new Error(`The Origins configurator "config.deployment.Origins" is required in context.`);
158
+ }
159
+ const webhookEventHandler = Webhooks.createEventHandler();
160
+ if (httpEvent.request.headers.has('user-agent') && httpEvent.request.headers.get('user-agent').startsWith('GitHub-Hookshot/')) {
161
+ const payload = await httpEvent.request.json();
162
+ const matches = (await (new cx.config.deployment.Origins(cx)).match(payload.repository.full_name)).filter(o => o.autodeploy);
146
163
  var deployParams;
147
164
  if (!(deployParams = matches[0])) {
148
- return;
165
+ return next();
149
166
  }
150
167
  if (matches.length > 1) {
151
168
  throw new Error(`Failed deploy attempt (${payload.repository.full_name}): Multiple deploy settings found.`);
@@ -153,34 +170,47 @@ export async function hook(Ui, event, deployCallback, flags = {}, layout = {}) {
153
170
  if (!deployParams.autodeploy_secret) {
154
171
  throw new Error(`Failed deploy attempt (${payload.repository.full_name}): The deploy settings do not contain a secret.`);
155
172
  }
156
- if (!Webhooks.verify(deployParams.autodeploy_secret, payload, event.request.headers.get('x-hub-signature'))) {
173
+ if (!Webhooks.verify(deployParams.autodeploy_secret, payload, httpEvent.request.headers.get('x-hub-signature'))) {
157
174
  throw new Error(`Failed deploy attempt (${payload.repository.full_name}): Signature mismatch.`);
158
175
  }
159
176
  if (payload.repository.disabled || payload.repository.archived) {
160
177
  throw new Error(`Failed deploy attempt (${payload.repository.full_name}): Repository disabled or archived.`);
161
178
  }
162
- eventHandler.on('push', async ({ name, payload }) => {
163
- Ui.log('---------------------------');
164
- Ui.log('');
165
- var exitCode = await deployCallback(payload, _payload => {
166
- return deploy(Ui, deployParams, flags, layout);
179
+ return new Promise(resolve => {
180
+ webhookEventHandler.on('push', async ({ name, payload }) => {
181
+ if (cx.logger) {
182
+ cx.logger.log('---------------------------');
183
+ cx.logger.log('');
184
+ }
185
+ var exitCode = await router.route('deploy', navigationEvent, payload, _payload => {
186
+ return deploy.call(cx, deployParams);
187
+ });
188
+ if (cx.logger) {
189
+ cx.logger.log('');
190
+ cx.logger.log('---------------------------');
191
+ }
192
+ if (exitCode === 0) {
193
+ if (cx.logger) {
194
+ cx.logger.log('');
195
+ var _date = (new Date).toUTCString();
196
+ cx.logger.success(cx.logger.f`[${cx.logger.style.comment(_date)}][AUTODEPLOY] Auto-exit: ${true}; exiting...`);
197
+ cx.logger.log('');
198
+ }
199
+ if (deployParams.ondeploy_autoexit) {
200
+ process.exit();
201
+ }
202
+ }
203
+ resolve(
204
+ new navigationEvent.Response(null, { status: exitCode === 0 ? 200 : 500 })
205
+ );
206
+ });
207
+ webhookEventHandler.receive({
208
+ id: httpEvent.request.headers.get('x-github-delivery'),
209
+ name: httpEvent.request.headers.get('x-github-httpEvent'),
210
+ payload: payload /* JSON object */,
167
211
  });
168
- Ui.log('');
169
- Ui.log('---------------------------');
170
- if (exitCode === 0 && deployParams.ondeploy_autoexit) {
171
- Ui.log('');
172
- var _date = (new Date).toUTCString();
173
- Ui.success(Ui.f`[${Ui.style.comment(_date)}][AUTODEPLOY] Auto-exit: ${true}; exiting...`);
174
- Ui.log('');
175
- // -----------
176
- process.exit();
177
- // -----------
178
- }
179
- });
180
- return eventHandler.receive({
181
- id: event.request.headers.get('x-github-delivery'),
182
- name: event.request.headers.get('x-github-event'),
183
- payload: payload /* JSON object */,
184
212
  });
185
213
  }
214
+
215
+ return next();
186
216
  }