@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.
- package/package.json +5 -12
- package/src/Cli.js +131 -0
- package/src/Configurator.js +97 -0
- package/src/Context.js +76 -0
- package/src/config-pi/deployment/Env.js +69 -0
- package/src/config-pi/deployment/Layout.js +65 -0
- package/src/config-pi/deployment/Origins.js +133 -0
- package/src/config-pi/deployment/Virtualization.js +65 -0
- package/src/config-pi/deployment/index.js +18 -0
- package/src/config-pi/index.js +16 -0
- package/src/config-pi/runtime/Client.js +59 -0
- package/src/config-pi/runtime/Server.js +174 -0
- package/src/config-pi/runtime/client/Worker.js +117 -0
- package/src/config-pi/runtime/client/index.js +12 -0
- package/src/config-pi/runtime/index.js +18 -0
- package/src/config-pi/runtime/server/Headers.js +90 -0
- package/src/config-pi/runtime/server/Redirects.js +108 -0
- package/src/config-pi/runtime/server/index.js +14 -0
- package/src/config-pi/static/Manifest.js +321 -0
- package/src/config-pi/static/Ssg.js +72 -0
- package/src/config-pi/static/index.js +14 -0
- package/src/deployment-pi/index.js +10 -0
- package/src/{services → deployment-pi}/origins/index.js +88 -58
- package/src/index.js +14 -147
- package/src/{runtime → runtime-pi}/Router.js +19 -19
- package/src/runtime-pi/client/Context.js +7 -0
- package/src/{runtime → runtime-pi}/client/Router.js +2 -2
- package/src/{runtime/client/Navigator.js → runtime-pi/client/Runtime.js} +143 -102
- package/src/runtime-pi/client/RuntimeClient.js +114 -0
- package/src/{runtime → runtime-pi}/client/Storage.js +8 -7
- package/src/{runtime → runtime-pi}/client/Url.js +2 -6
- package/src/{runtime/client/WorkerClient.js → runtime-pi/client/WorkerComm.js} +2 -2
- package/src/runtime-pi/client/generate.js +242 -0
- package/src/runtime-pi/client/generate.oohtml.js +7 -0
- package/src/runtime-pi/client/index.js +18 -0
- package/src/runtime-pi/client/whatwag.js +27 -0
- package/src/runtime-pi/client/worker/Context.js +7 -0
- package/src/runtime-pi/client/worker/Worker.js +243 -0
- package/src/runtime-pi/client/worker/WorkerClient.js +46 -0
- package/src/runtime-pi/client/worker/index.js +18 -0
- package/src/runtime-pi/index.js +14 -0
- package/src/runtime-pi/server/Context.js +16 -0
- package/src/{runtime → runtime-pi}/server/Router.js +6 -6
- package/src/runtime-pi/server/Runtime.js +531 -0
- package/src/runtime-pi/server/RuntimeClient.js +102 -0
- package/src/runtime-pi/server/index.js +41 -0
- package/src/runtime-pi/server/whatwag.js +35 -0
- package/src/{runtime → runtime-pi}/util.js +0 -0
- package/src/{runtime/_FormData.js → runtime-pi/xFormData.js} +2 -2
- package/src/{runtime/_Headers.js → runtime-pi/xHeaders.js} +4 -4
- package/src/runtime-pi/xHttpEvent.js +93 -0
- package/src/runtime-pi/xHttpMessage.js +179 -0
- package/src/runtime-pi/xRequest.js +67 -0
- package/src/runtime-pi/xRequestHeaders.js +95 -0
- package/src/runtime-pi/xResponse.js +62 -0
- package/src/{runtime/_ResponseHeaders.js → runtime-pi/xResponseHeaders.js} +38 -18
- package/src/{runtime/_URL.js → runtime-pi/xURL.js} +4 -4
- package/src/runtime-pi/xfetch.js +7 -0
- package/src/{services → services-pi}/certbot/http-auth-hook.js +0 -0
- package/src/{services → services-pi}/certbot/http-cleanup-hook.js +0 -0
- package/src/{services → services-pi}/certbot/index.js +21 -15
- package/src/services-pi/index.js +9 -0
- package/src/static-pi/index.js +11 -0
- package/src/webflo.js +33 -0
- package/test/index.test.js +26 -0
- package/src/build/client/index.js +0 -261
- package/src/build/index.js +0 -5
- package/src/config/client.js +0 -191
- package/src/config/headers.js +0 -121
- package/src/config/index.js +0 -14
- package/src/config/layout.js +0 -83
- package/src/config/manifest.js +0 -341
- package/src/config/origins.js +0 -165
- package/src/config/prerendering.js +0 -100
- package/src/config/redirects.js +0 -137
- package/src/config/server.js +0 -201
- package/src/config/variables.js +0 -102
- package/src/config/vhosts.js +0 -93
- package/src/runtime/_MessageStream.js +0 -195
- package/src/runtime/_NavigationEvent.js +0 -91
- package/src/runtime/_Request.js +0 -61
- package/src/runtime/_RequestHeaders.js +0 -72
- package/src/runtime/_Response.js +0 -56
- package/src/runtime/client/Cache.js +0 -38
- package/src/runtime/client/Http.js +0 -225
- package/src/runtime/client/NavigationEvent.js +0 -21
- package/src/runtime/client/Runtime.js +0 -126
- package/src/runtime/client/StdRequest.js +0 -74
- package/src/runtime/client/Worker.js +0 -312
- package/src/runtime/client/WorkerComm.js +0 -183
- package/src/runtime/client/effects/sounds.js +0 -64
- package/src/runtime/index.js +0 -5
- package/src/runtime/server/NavigationEvent.js +0 -39
- package/src/runtime/server/Runtime.js +0 -593
- package/src/runtime/server/index.js +0 -183
- package/src/runtime/server/index.mjs +0 -10
- 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
|
+
}
|
|
@@ -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
|
-
* @
|
|
15
|
+
* @desc
|
|
17
16
|
*/
|
|
18
17
|
export const desc = {
|
|
19
|
-
deploy: '
|
|
18
|
+
deploy: 'Deploy project from a remote origin.',
|
|
20
19
|
};
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* @deploy
|
|
24
23
|
*/
|
|
25
|
-
export async function deploy(
|
|
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
|
|
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(
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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',
|
|
100
|
-
|
|
101
|
-
reject(
|
|
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
|
-
|
|
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
|
-
|
|
115
|
-
|
|
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
|
-
|
|
128
|
-
|
|
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 =>
|
|
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
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
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,
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
}
|