@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,18 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* i@mports
|
|
4
|
+
*/
|
|
5
|
+
import Env from './Env.js';
|
|
6
|
+
import Layout from './Layout.js';
|
|
7
|
+
import Origins from './Origins.js';
|
|
8
|
+
import Virtualization from './Virtualization.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @exports
|
|
12
|
+
*/
|
|
13
|
+
export {
|
|
14
|
+
Env,
|
|
15
|
+
Layout,
|
|
16
|
+
Origins,
|
|
17
|
+
Virtualization,
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import * as deployment from './deployment/index.js';
|
|
6
|
+
import * as runtime from './runtime/index.js';
|
|
7
|
+
import * as $static from './static/index.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @exports
|
|
11
|
+
*/
|
|
12
|
+
export {
|
|
13
|
+
deployment,
|
|
14
|
+
runtime,
|
|
15
|
+
$static as static,
|
|
16
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* imports
|
|
4
|
+
*/
|
|
5
|
+
import { _merge } from '@webqit/util/obj/index.js';
|
|
6
|
+
import { _isNumeric } from '@webqit/util/js/index.js';
|
|
7
|
+
import { _before, _after } from '@webqit/util/str/index.js';
|
|
8
|
+
import Configurator from '../../Configurator.js';
|
|
9
|
+
|
|
10
|
+
export default class Client extends Configurator {
|
|
11
|
+
|
|
12
|
+
// Base name
|
|
13
|
+
get name() {
|
|
14
|
+
return 'client';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// @desc
|
|
18
|
+
static get ['@desc']() {
|
|
19
|
+
return 'Client Runtime config.';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Defaults merger
|
|
23
|
+
withDefaults(config) {
|
|
24
|
+
return _merge(true, {
|
|
25
|
+
support_oohtml: true,
|
|
26
|
+
support_service_worker: true,
|
|
27
|
+
worker_scope: '/',
|
|
28
|
+
}, config);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Questions generator
|
|
32
|
+
questions(config, choices = {}) {
|
|
33
|
+
// Questions
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
name: 'support_oohtml',
|
|
37
|
+
type: 'toggle',
|
|
38
|
+
message: 'Support rendering with OOHTML? (Adds OOHTML to your app\'s bundle.)',
|
|
39
|
+
active: 'YES',
|
|
40
|
+
inactive: 'NO',
|
|
41
|
+
initial: config.support_oohtml,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'support_service_worker',
|
|
45
|
+
type: 'toggle',
|
|
46
|
+
message: 'Support Service Worker?',
|
|
47
|
+
active: 'YES',
|
|
48
|
+
inactive: 'NO',
|
|
49
|
+
initial: config.support_service_worker,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'worker_scope',
|
|
53
|
+
type: (prev, answers) => answers.support_service_worker ? 'text' : null,
|
|
54
|
+
message: 'Specify the Service Worker scope',
|
|
55
|
+
initial: config.worker_scope,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* imports
|
|
4
|
+
*/
|
|
5
|
+
import Path from 'path';
|
|
6
|
+
import { _merge } from '@webqit/util/obj/index.js';
|
|
7
|
+
import Configurator from '../../Configurator.js';
|
|
8
|
+
|
|
9
|
+
export default class Server extends Configurator {
|
|
10
|
+
|
|
11
|
+
// Base name
|
|
12
|
+
get name() {
|
|
13
|
+
return 'server';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// @desc
|
|
17
|
+
static get ['@desc']() {
|
|
18
|
+
return 'Server Runtime config.';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Defaults merger
|
|
22
|
+
withDefaults(config) {
|
|
23
|
+
return _merge(true, {
|
|
24
|
+
port: process.env.port || 3000,
|
|
25
|
+
https: {
|
|
26
|
+
port: 0,
|
|
27
|
+
keyfile: '',
|
|
28
|
+
certfile: '',
|
|
29
|
+
certdoms: ['*'],
|
|
30
|
+
force: false,
|
|
31
|
+
},
|
|
32
|
+
process: {
|
|
33
|
+
name: Path.basename(process.cwd()),
|
|
34
|
+
errfile: '',
|
|
35
|
+
outfile: '',
|
|
36
|
+
exec_mode: 'fork',
|
|
37
|
+
autorestart: true,
|
|
38
|
+
merge_logs: false,
|
|
39
|
+
},
|
|
40
|
+
force_www: '',
|
|
41
|
+
shared: false,
|
|
42
|
+
}, config);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Questions generator
|
|
46
|
+
questions(config, choices = {}) {
|
|
47
|
+
// Choices
|
|
48
|
+
const CHOICES = _merge({
|
|
49
|
+
exec_mode: [
|
|
50
|
+
{value: 'fork',},
|
|
51
|
+
{value: 'cluster',},
|
|
52
|
+
],
|
|
53
|
+
force_www: [
|
|
54
|
+
{value: '', title: 'do nothing'},
|
|
55
|
+
{value: 'add',},
|
|
56
|
+
{value: 'remove',},
|
|
57
|
+
],
|
|
58
|
+
}, choices);
|
|
59
|
+
// Questions
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
name: 'port',
|
|
63
|
+
type: 'number',
|
|
64
|
+
message: 'Enter port number',
|
|
65
|
+
initial: config.port,
|
|
66
|
+
validation: ['important'],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'https',
|
|
70
|
+
initial: config.https,
|
|
71
|
+
controls: {
|
|
72
|
+
name: 'https',
|
|
73
|
+
},
|
|
74
|
+
questions: [
|
|
75
|
+
{
|
|
76
|
+
name: 'port',
|
|
77
|
+
type: 'number',
|
|
78
|
+
message: 'Enter HTTPS port number',
|
|
79
|
+
validation: ['important'],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'keyfile',
|
|
83
|
+
type: 'text',
|
|
84
|
+
message: 'Enter SSL KEY file',
|
|
85
|
+
validation: ['important'],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'certfile',
|
|
89
|
+
type: 'text',
|
|
90
|
+
message: 'Enter SSL CERT file',
|
|
91
|
+
validation: ['important'],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'certdoms',
|
|
95
|
+
type: 'list',
|
|
96
|
+
message: 'Enter the CERT domains (comma-separated)',
|
|
97
|
+
validation: ['important'],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'force',
|
|
101
|
+
type: 'toggle',
|
|
102
|
+
message: 'Force HTTPS?',
|
|
103
|
+
active: 'YES',
|
|
104
|
+
inactive: 'NO',
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'process',
|
|
110
|
+
initial: config.process,
|
|
111
|
+
controls: {
|
|
112
|
+
name: 'background process',
|
|
113
|
+
},
|
|
114
|
+
questions: [
|
|
115
|
+
{
|
|
116
|
+
name: 'name',
|
|
117
|
+
type: 'text',
|
|
118
|
+
message: 'Enter a name for process',
|
|
119
|
+
validation: ['important'],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'errfile',
|
|
123
|
+
type: 'text',
|
|
124
|
+
message: 'Enter path to error file',
|
|
125
|
+
validation: ['important'],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'outfile',
|
|
129
|
+
type: 'text',
|
|
130
|
+
message: 'Enter path to output file',
|
|
131
|
+
validation: ['important'],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'exec_mode',
|
|
135
|
+
type: 'select',
|
|
136
|
+
message: 'Select exec mode',
|
|
137
|
+
choices: CHOICES.exec_mode,
|
|
138
|
+
validation: ['important'],
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'autorestart',
|
|
142
|
+
type: 'toggle',
|
|
143
|
+
message: 'Server autorestart on crash?',
|
|
144
|
+
active: 'YES',
|
|
145
|
+
inactive: 'NO',
|
|
146
|
+
initial: config.autorestart,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'merge_logs',
|
|
150
|
+
type: 'toggle',
|
|
151
|
+
message: 'Server merge logs?',
|
|
152
|
+
active: 'YES',
|
|
153
|
+
inactive: 'NO',
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'force_www',
|
|
159
|
+
type: 'select',
|
|
160
|
+
message: 'Force add/remove "www" on hostname?',
|
|
161
|
+
choices: CHOICES.force_www,
|
|
162
|
+
initial: this.indexOfInitial(CHOICES.force_www, config.force_www),
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: 'shared',
|
|
166
|
+
type: 'toggle',
|
|
167
|
+
message: 'Shared server?',
|
|
168
|
+
active: 'YES',
|
|
169
|
+
inactive: 'NO',
|
|
170
|
+
initial: config.shared,
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* imports
|
|
4
|
+
*/
|
|
5
|
+
import { _merge } from '@webqit/util/obj/index.js';
|
|
6
|
+
import { _isNumeric } from '@webqit/util/js/index.js';
|
|
7
|
+
import { _before, _after } from '@webqit/util/str/index.js';
|
|
8
|
+
import Configurator from '../../../Configurator.js';
|
|
9
|
+
|
|
10
|
+
export default class Worker extends Configurator {
|
|
11
|
+
|
|
12
|
+
// Base name
|
|
13
|
+
get name() {
|
|
14
|
+
return 'worker';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// @desc
|
|
18
|
+
static get ['@desc']() {
|
|
19
|
+
return 'Application Service Worker config.';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Defaults merger
|
|
23
|
+
withDefaults(config) {
|
|
24
|
+
return _merge(true, {
|
|
25
|
+
cache_name: 'cache_v0',
|
|
26
|
+
cache_only_urls: [],
|
|
27
|
+
cache_first_urls: [],
|
|
28
|
+
network_only_urls: [],
|
|
29
|
+
network_first_urls: [],
|
|
30
|
+
skip_waiting: false,
|
|
31
|
+
// -----------------
|
|
32
|
+
support_push: false,
|
|
33
|
+
push_registration_url: '',
|
|
34
|
+
push_deregistration_url: '',
|
|
35
|
+
push_public_key: '',
|
|
36
|
+
}, config);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Questions generator
|
|
40
|
+
questions(config, choices = {}) {
|
|
41
|
+
// Increment cache
|
|
42
|
+
if (config.cache_name && config.cache_name.indexOf('_v') > -1 && _isNumeric(_after(config.cache_name, '_v'))) {
|
|
43
|
+
config.cache_name = _before(config.cache_name, '_v') + '_v' + (parseInt(_after(config.cache_name, '_v')) + 1);
|
|
44
|
+
}
|
|
45
|
+
// Questions
|
|
46
|
+
return [
|
|
47
|
+
{
|
|
48
|
+
name: 'cache_name',
|
|
49
|
+
type: 'text',
|
|
50
|
+
message: 'Enter the Service Worker cache name',
|
|
51
|
+
initial: config.cache_name,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'cache_only_urls',
|
|
55
|
+
type: 'list',
|
|
56
|
+
message: 'Specify URLs for a "cache-only" fetching strategy (comma-separated, globe supported)',
|
|
57
|
+
initial: (config.cache_only_urls || []).join(', '),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'cache_first_urls',
|
|
61
|
+
type: 'list',
|
|
62
|
+
message: 'Specify URLs for a "cache-first-then-network" fetching strategy (comma-separated, globe supported)',
|
|
63
|
+
initial: (config.cache_first_urls || []).join(', '),
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'network_only_urls',
|
|
67
|
+
type: 'list',
|
|
68
|
+
message: 'Specify URLs for a "network-only" fetching strategy (comma-separated, globe supported)',
|
|
69
|
+
initial: (config.network_only_urls || []).join(', '),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'network_first_urls',
|
|
73
|
+
type: 'list',
|
|
74
|
+
message: 'Specify URLs for a "network-first-then-cache" fetching strategy (comma-separated, globe supported)',
|
|
75
|
+
initial: (config.network_first_urls || []).join(', '),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'skip_waiting',
|
|
79
|
+
type: 'toggle',
|
|
80
|
+
message: 'Choose whether to skip the "waiting" state for updated Service Workers',
|
|
81
|
+
active: 'YES',
|
|
82
|
+
inactive: 'NO',
|
|
83
|
+
initial: config.skip_waiting,
|
|
84
|
+
},
|
|
85
|
+
// ------------- notification --------------
|
|
86
|
+
{
|
|
87
|
+
name: 'support_push',
|
|
88
|
+
type: 'toggle',
|
|
89
|
+
message: 'Support push-notifications?',
|
|
90
|
+
active: 'YES',
|
|
91
|
+
inactive: 'NO',
|
|
92
|
+
initial: config.support_push,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'push_registration_url',
|
|
96
|
+
type: (prev, answers) => answers.support_push ? 'text' : null,
|
|
97
|
+
message: 'Enter the URL for push notification subscription',
|
|
98
|
+
initial: config.push_registration_url,
|
|
99
|
+
validation: ['important'],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'push_deregistration_url',
|
|
103
|
+
type: (prev, answers) => answers.support_push ? 'text' : null,
|
|
104
|
+
message: 'Enter the URL for push notification unsubscription',
|
|
105
|
+
initial: config.push_deregistration_url,
|
|
106
|
+
validation: ['important'],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'push_key',
|
|
110
|
+
type: (prev, answers) => answers.support_push ? 'text' : null,
|
|
111
|
+
message: 'Enter the Public Key for push notification subscription',
|
|
112
|
+
initial: config.push_key,
|
|
113
|
+
validation: ['important'],
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Client from './Client.js';
|
|
6
|
+
import Server from './Server.js';
|
|
7
|
+
import * as client from './client/index.js';
|
|
8
|
+
import * as server from './server/index.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @exports
|
|
12
|
+
*/
|
|
13
|
+
export {
|
|
14
|
+
Client,
|
|
15
|
+
Server,
|
|
16
|
+
client,
|
|
17
|
+
server,
|
|
18
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* imports
|
|
4
|
+
*/
|
|
5
|
+
import Url from 'url';
|
|
6
|
+
import Micromatch from 'micromatch';
|
|
7
|
+
import { _merge } from '@webqit/util/obj/index.js';
|
|
8
|
+
import { _isObject } from '@webqit/util/js/index.js';
|
|
9
|
+
import Configurator from '../../../Configurator.js';
|
|
10
|
+
|
|
11
|
+
export default class Headers extends Configurator {
|
|
12
|
+
|
|
13
|
+
// Base name
|
|
14
|
+
get name() {
|
|
15
|
+
return 'headers';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// @desc
|
|
19
|
+
static get ['@desc']() {
|
|
20
|
+
return 'Automatic headers config.';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Defaults merger
|
|
24
|
+
withDefaults(config) {
|
|
25
|
+
return _merge(true, {
|
|
26
|
+
entries: [],
|
|
27
|
+
}, config);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Match
|
|
31
|
+
async match(url) {
|
|
32
|
+
if (!_isObject(url)) {
|
|
33
|
+
url = Url.parse(url);
|
|
34
|
+
}
|
|
35
|
+
return ((await this.read()).entries || []).filter(header => {
|
|
36
|
+
var regex = Micromatch.makeRe(header.url, {dot: true});
|
|
37
|
+
var rootMatch = url.pathname.split('/').filter(seg => seg).map(seg => seg.trim()).reduce((str, seg) => str.endsWith(' ') ? str : ((str = str + '/' + seg) && str.match(regex) ? str + ' ' : str), '');
|
|
38
|
+
return rootMatch.endsWith(' ');
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Questions generator
|
|
43
|
+
questions(config, choices = {}) {
|
|
44
|
+
const CHOICES = _merge({
|
|
45
|
+
type: [
|
|
46
|
+
{value: 'request', title: 'Request Header'},
|
|
47
|
+
{value: 'response', title: 'Response Header'},
|
|
48
|
+
]
|
|
49
|
+
}, choices);
|
|
50
|
+
// Questions
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
name: 'entries',
|
|
54
|
+
type: 'recursive',
|
|
55
|
+
controls: {
|
|
56
|
+
name: 'header',
|
|
57
|
+
},
|
|
58
|
+
initial: config.entries,
|
|
59
|
+
questions: [
|
|
60
|
+
{
|
|
61
|
+
name: 'type',
|
|
62
|
+
type: 'text',
|
|
63
|
+
message: 'Choose header type',
|
|
64
|
+
validation: ['important'],
|
|
65
|
+
initial: function() { return this.indexOfInitial(CHOICES.type, this.value); },
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'url',
|
|
69
|
+
type: 'text',
|
|
70
|
+
message: 'Enter URL',
|
|
71
|
+
validation: ['important'],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'name',
|
|
75
|
+
type: 'text',
|
|
76
|
+
message: 'Enter header name',
|
|
77
|
+
validation: ['important'],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'value',
|
|
81
|
+
type: 'text',
|
|
82
|
+
message: 'Enter header value',
|
|
83
|
+
validation: ['important'],
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* imports
|
|
4
|
+
*/
|
|
5
|
+
import Url from 'url';
|
|
6
|
+
import { _merge } from '@webqit/util/obj/index.js';
|
|
7
|
+
import { _after } from '@webqit/util/str/index.js';
|
|
8
|
+
import { _isObject } from '@webqit/util/js/index.js';
|
|
9
|
+
import Micromatch from 'micromatch';
|
|
10
|
+
import Configurator from '../../../Configurator.js';
|
|
11
|
+
|
|
12
|
+
export default class Redirects extends Configurator {
|
|
13
|
+
|
|
14
|
+
// Base name
|
|
15
|
+
get name() {
|
|
16
|
+
return 'redirects';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// @desc
|
|
20
|
+
static get ['@desc']() {
|
|
21
|
+
return 'Automatic redirects config.';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Defaults merger
|
|
25
|
+
withDefaults(config) {
|
|
26
|
+
return _merge(true, {
|
|
27
|
+
entries: [],
|
|
28
|
+
}, config);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Match
|
|
32
|
+
async match(url) {
|
|
33
|
+
if (!_isObject(url)) {
|
|
34
|
+
url = Url.parse(url);
|
|
35
|
+
}
|
|
36
|
+
return ((await this.read()).entries || []).reduce((match, rdr) => {
|
|
37
|
+
if (match) {
|
|
38
|
+
return match;
|
|
39
|
+
}
|
|
40
|
+
var regex = Micromatch.makeRe(rdr.from, {dot: true});
|
|
41
|
+
var rootMatch = url.pathname.split('/').filter(seg => seg).map(seg => seg.trim()).reduce((str, seg) => str.endsWith(' ') ? str : ((str = str + '/' + seg) && str.match(regex) ? str + ' ' : str), '');
|
|
42
|
+
if (rootMatch.endsWith(' ')) {
|
|
43
|
+
var leaf = _after(url.pathname, rootMatch.trim());
|
|
44
|
+
var [ target, targetQuery ] = rdr.to.split('?');
|
|
45
|
+
if (rdr.reuseQuery) {
|
|
46
|
+
targetQuery = [(url.search || '').substr(1), targetQuery].filter(str => str).join('&');
|
|
47
|
+
}
|
|
48
|
+
// ---------------
|
|
49
|
+
return {
|
|
50
|
+
target: target + leaf + (targetQuery ? (leaf.endsWith('?') || leaf.endsWith('&') ? '' : (leaf.includes('?') ? '&' : '?')) + targetQuery : ''),
|
|
51
|
+
query: targetQuery,
|
|
52
|
+
code: rdr.code,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}, null);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Questions generator
|
|
59
|
+
questions(config, choices = {}) {
|
|
60
|
+
// Choices
|
|
61
|
+
const CHOICES = _merge({
|
|
62
|
+
code: [
|
|
63
|
+
{value: 302,},
|
|
64
|
+
{value: 301,},
|
|
65
|
+
],
|
|
66
|
+
}, choices);
|
|
67
|
+
// Questions
|
|
68
|
+
return [
|
|
69
|
+
{
|
|
70
|
+
name: 'entries',
|
|
71
|
+
type: 'recursive',
|
|
72
|
+
controls: {
|
|
73
|
+
name: 'redirect',
|
|
74
|
+
},
|
|
75
|
+
initial: config.entries,
|
|
76
|
+
questions: [
|
|
77
|
+
{
|
|
78
|
+
name: 'from',
|
|
79
|
+
type: 'text',
|
|
80
|
+
message: 'Enter "from" URL',
|
|
81
|
+
validation: ['important'],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'to',
|
|
85
|
+
type: 'text',
|
|
86
|
+
message: 'Enter "to" URL',
|
|
87
|
+
validation: ['important'],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'reuseQuery',
|
|
91
|
+
type: 'toggle',
|
|
92
|
+
message: 'Reuse query parameters from matched URL in destination URL?',
|
|
93
|
+
active: 'YES',
|
|
94
|
+
inactive: 'NO',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'code',
|
|
98
|
+
type: 'select',
|
|
99
|
+
choices: CHOICES.code,
|
|
100
|
+
message: 'Enter redirect code',
|
|
101
|
+
validation: ['number', 'important'],
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
}
|