@webqit/webflo 0.8.75 → 0.9.0-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 (96) 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/server/NavigationEvent.js → runtime-pi/server/whatwag.js} +16 -17
  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 +61 -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/Runtime.js +0 -586
  94. package/src/runtime/server/index.js +0 -183
  95. package/src/runtime/server/index.mjs +0 -10
  96. package/src/services/index.js +0 -6
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "vanila-javascript"
13
13
  ],
14
14
  "homepage": "https://webqit.io/tooling/webflo",
15
- "version": "0.8.75",
15
+ "version": "0.9.0-0",
16
16
  "license": "MIT",
17
17
  "repository": {
18
18
  "type": "git",
@@ -24,6 +24,8 @@
24
24
  "type": "module",
25
25
  "main": "./src/index.js",
26
26
  "scripts": {
27
+ "test": "mocha --extension .test.js --exit",
28
+ "test:coverage": "c8 --reporter=text-lcov npm run test | coveralls",
27
29
  "postversion": "npm publish",
28
30
  "postpublish": "git push && git push --tags"
29
31
  },
@@ -33,16 +35,11 @@
33
35
  "webflo-certbot-http-cleanup-hook": "src/services/certbot/http-cleanup-hook.js"
34
36
  },
35
37
  "dependencies": {
36
- "@octokit/auth-basic": "^1.4.6",
37
- "@octokit/rest": "^17.11.2",
38
38
  "@octokit/webhooks": "^7.15.1",
39
39
  "@webqit/backpack": "^0.0.37",
40
- "@webqit/browser-pie": "^0.0.16",
41
- "@webqit/observer": "^1.7.5",
42
- "@webqit/pseudo-browser": "^1.0.0",
43
- "@webqit/util": "^0.8.7",
40
+ "@webqit/oohtml-ssr": "^1.0.2",
41
+ "@webqit/util": "^0.8.9",
44
42
  "client-sessions": "^0.8.0",
45
- "cookie": "^0.4.1",
46
43
  "form-data-encoder": "^1.6.0",
47
44
  "formdata-node": "^4.3.0",
48
45
  "formidable": "^2.0.0-dev.20200131.2",
@@ -51,12 +48,8 @@
51
48
  "mime-types": "^2.1.33",
52
49
  "minimatch": "^3.0.4",
53
50
  "node-fetch": "^2.6.1",
54
- "pm2": "^5.2.0",
55
51
  "simple-git": "^2.20.1",
56
52
  "stream-slice": "^0.1.2",
57
- "touch": "^3.1.0",
58
- "undici": "^4.3.1",
59
- "uuid": "^8.3.2",
60
53
  "webpack": "^5.50.0"
61
54
  },
62
55
  "author": "Oxford Harrison <oxharris.dev@gmail.com>",
package/src/Cli.js ADDED
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @imports
5
+ */
6
+ import { _toTitle } from '@webqit/util/str/index.js';
7
+ import { _merge, _set, _get } from '@webqit/util/obj/index.js';
8
+ import { _isClass, _isFunction, _isObject, _isEmpty, _isString } from '@webqit/util/js/index.js';
9
+ import { Promptx } from '@webqit/backpack/src/cli/Promptx.js';
10
+ import parseArgs from '@webqit/backpack/src/cli/parseArgs.js';
11
+
12
+ export default class Cli {
13
+
14
+ /**
15
+ * @constructor
16
+ *
17
+ * @param Object api
18
+ */
19
+ constructor(api) {
20
+ this.api = api;
21
+ this.nsSeparator = '::';
22
+ // Generate available options
23
+ this.availableConfigs = {};
24
+ this.availableCommands = {};
25
+ const discoverConfigs = (namespace, piObj) => Object.keys(piObj).forEach(name => {
26
+ let pathname = `${name}${this.nsSeparator}${namespace}`.toLowerCase();
27
+ if (_isClass(piObj[name])) {
28
+ if (piObj[name]['@desc']) this.availableConfigs[pathname] = piObj[name]['@desc'];
29
+ } else if (_isObject(piObj[name])) discoverConfigs(pathname, piObj[name]);
30
+ });
31
+ const discoverCommands = (namespace, piObj) => Object.keys(piObj).forEach(name => {
32
+ let pathname = `${name}${this.nsSeparator}${namespace}`.toLowerCase();
33
+ if (!_isClass(piObj[name]) && _isFunction(piObj[name])) {
34
+ if (!piObj[name]['@desc']) this.availableCommands[pathname] = piObj[name]['@desc'];
35
+ } else if (_isObject(piObj[name])) discoverCommands(pathname, piObj[name]);
36
+ });
37
+ Object.keys(this.api).forEach(name => {
38
+ if (name === 'config') discoverConfigs(name, this.api[name]);
39
+ else discoverCommands(name, this.api[name]);
40
+ });
41
+ }
42
+
43
+ /**
44
+ * @exec
45
+ */
46
+ async exec(cx) {
47
+ const { command, keywords, flags, options, ellipsis } = parseArgs(process.argv);
48
+ cx.flags = flags;
49
+ // ------------
50
+ if (cx.webflo.version) {
51
+ cx.logger.log('');
52
+ cx.logger.banner(cx.webflo.title, cx.webflo.version || '');
53
+ cx.logger.log('');
54
+ }
55
+ // ------------
56
+ if (command === 'help') {
57
+ cx.logger.title(`> COMMAND LINE HELP`);
58
+ cx.logger.log('');
59
+ // ------------
60
+ cx.logger.log(cx.logger.f`Say "webflo <${'command'}>"`);
61
+ cx.logger.log(cx.logger.f`Where <${'command'}> is one of:`);
62
+ cx.logger.log(cx.logger.f`${this.availableCommands}`);
63
+ cx.logger.log('');
64
+ // ------------
65
+ cx.logger.log(cx.logger.f`Or say "webflo config", or "webflo config <${'path'}>"`);
66
+ cx.logger.log(cx.logger.f`Where <${'path'}> is one of:`);
67
+ cx.logger.log(cx.logger.f`${this.availableConfigs}`);
68
+ cx.logger.log('');
69
+ // ------------
70
+ cx.logger.log(cx.logger.f`You may also refer to the Webflo DOCS as ${'https://webqit.io/tooling/webflo'}`);
71
+ return;
72
+ }
73
+ // ------------
74
+ const keywordList = Object.keys(keywords);
75
+ const fcn = keywordList[0];
76
+ const resolveIdentifier = (fcn, isConfig) => {
77
+ let namespaceObj = isConfig ? this.availableConfigs : this.availableCommands;
78
+ let matches = Object.keys(namespaceObj).filter(path => `${path}${this.nsSeparator}`.startsWith(`${fcn}${this.nsSeparator}`));
79
+ if (matches.length === 1) {
80
+ return matches[0];
81
+ }
82
+ return matches;
83
+ };
84
+ const pathNisplayName = path => path.split(this.nsSeparator).slice(0, -1).join(this.nsSeparator);
85
+ const promptIdentifier = async (preselection, isConfig) => {
86
+ let namespaceObj = isConfig ? this.availableConfigs : this.availableCommands;
87
+ let selection = await Promptx({
88
+ name: 'fcn',
89
+ type: 'select',
90
+ choices: (!_isEmpty(preselection) ? preselection : Object.keys(namespaceObj)).map(path => ({ value: path, title: pathNisplayName(path) })).concat({ value: '<' }),
91
+ message: 'Please select a function to continue, or "<" to exit',
92
+ }).then(d => d.fcn);
93
+ if (selection === '<') process.exit();
94
+ return selection;
95
+ };
96
+ // ------------
97
+ let isConfig = command === 'config', _fcn = isConfig ? fcn : command, resolvedFcn;
98
+ if (!(_fcn && _isString(resolvedFcn = resolveIdentifier(_fcn, isConfig))) || ellipsis) {
99
+ cx.logger.title(`> webflo ${isConfig ? 'config ' : ''}${_fcn || ''}...`);
100
+ cx.logger.log('');
101
+ resolvedFcn = await promptIdentifier(resolvedFcn, isConfig);
102
+ }
103
+ cx.logger.title(`> webflo ${isConfig ? 'config ' : ''}${pathNisplayName(resolvedFcn)}`);
104
+ cx.logger.log('');
105
+ // ------------
106
+ // Process command
107
+ if (isConfig) {
108
+ const configClass = _get(this.api, _toTitle(resolvedFcn).split(this.nsSeparator).reverse());
109
+ const configurator = new configClass(cx);
110
+ const config = await configurator.read();
111
+ const givenOptionsList = Object.keys(options);
112
+ if (givenOptionsList.length) {
113
+ const optionsStructured = {};
114
+ givenOptionsList.forEach(path => {
115
+ _set(optionsStructured, path.split('.'), options[path]);
116
+ });
117
+ await configurator.write(_merge(true, config, optionsStructured));
118
+ } else {
119
+ await Promptx(configurator.questions(config)).then(async _config => {
120
+ await configurator.write(_merge(true, config, _config));
121
+ });
122
+ }
123
+ } else {
124
+ const func = _get(this.api, resolvedFcn.split(this.nsSeparator).reverse());
125
+ await func.call(cx, ...keywordList);
126
+ }
127
+
128
+ cx.logger.log('');
129
+ }
130
+
131
+ }
@@ -0,0 +1,97 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import Path from 'path';
6
+ import { _merge } from '@webqit/util/obj/index.js';
7
+ import { initialGetIndex } from '@webqit/backpack/src/cli/Promptx.js';
8
+ import { DotJson, DotEnv, anyExists } from '@webqit/backpack/src/dotfiles/index.js';
9
+
10
+ /**
11
+ * @exports
12
+ */
13
+ export default class Configurator {
14
+
15
+ /**
16
+ * The default initializer.
17
+ *
18
+ * @param Context cx
19
+ */
20
+ constructor(cx) {
21
+ this.cx = cx;
22
+ this.givenExt = this.cx.flags.mode ? `.${this.cx.flags.mode}` : '';
23
+ this.availableExt = anyExists([ this.givenExt, '', '.example' ], ext => this.resolveFileName(ext));
24
+ if (this.isEnv) {
25
+ this.availableEnvExt = anyExists([ this.givenExt, '', '.example' ], ext => this.resolveEnvFileName(ext));
26
+ }
27
+ }
28
+
29
+ // ------------
30
+
31
+ get configDir() {
32
+ return Path.join(this.cx.CWD || ``, `./.webqit/webflo/config/`);
33
+ }
34
+
35
+ get envDir() {
36
+ return Path.resolve(this.cx.CWD || '');
37
+ }
38
+
39
+ // ------------
40
+
41
+ static read(...args) {
42
+ let instance = new this(...args);
43
+ return instance.read();
44
+ }
45
+
46
+
47
+ static write(config, ...args) {
48
+ let instance = new this(...args);
49
+ return instance.write(config);
50
+ }
51
+
52
+ // ------------
53
+
54
+ async read() {
55
+ let config = DotJson.read(this.resolveFileName(this.availableExt));
56
+ if (this.isEnv) {
57
+ let config2 = { entries: DotEnv.read(this.resolveEnvFileName(this.availableEnvExt)) || {}, };
58
+ // The rewrite below is because entries should not also appear in json
59
+ //config.entries = _merge(config.entries || {}, config2.entries);
60
+ config = _merge(config, config2);
61
+ }
62
+ return this.withDefaults(config);
63
+ }
64
+
65
+ async write(config) {
66
+ if (this.isEnv) {
67
+ config = { ...config };
68
+ DotEnv.write(config.entries, this.resolveEnvFileName(this.givenExt));
69
+ // The delete below is because entries should not also appear in json
70
+ delete config.entries;
71
+ }
72
+ DotJson.write(config, this.resolveFileName(this.givenExt));
73
+ }
74
+
75
+ questions() {
76
+ return [];
77
+ }
78
+
79
+ // ------------
80
+
81
+ resolveFileName(ext) {
82
+ return `${this.configDir}/${this.name}${ext}.json`;
83
+ }
84
+
85
+ resolveEnvFileName(ext) {
86
+ return `${this.envDir}/.${this.name}${ext}`;
87
+ }
88
+
89
+ withDefaults(config) {
90
+ return config;
91
+ }
92
+
93
+ indexOfInitial(options, initial) {
94
+ return initialGetIndex(options, initial);
95
+ }
96
+
97
+ }
package/src/Context.js ADDED
@@ -0,0 +1,76 @@
1
+
2
+ export default class Context {
3
+
4
+ /**
5
+ * Initializes a context.
6
+ *
7
+ * @param Object dict
8
+ * @param String CD
9
+ */
10
+ constructor(dict, CD = null) {
11
+ // dict can be plain object or some Context instance itself
12
+ // Using it as only a prototype protects it from being mutated down here
13
+ Object.defineProperty(this, 'dict', { value: Object.create(dict), });
14
+ // Now, for enumerable props thet need to be enumerable, where no getter/setter on both instances
15
+ for (let prop in this.dict) {
16
+ if (prop in this) continue;
17
+ this[prop] = this.dict[prop];
18
+ }
19
+ if (arguments.length > 1) {
20
+ this.dict.CWD = CD;
21
+ }
22
+ }
23
+
24
+ // create
25
+ static create(...args) {
26
+ return new this(...args);
27
+ }
28
+
29
+ // CWD
30
+ get CWD() {
31
+ return this.dict.CWD || '';
32
+ }
33
+
34
+ // webflo
35
+ get webflo() {
36
+ return this.dict.webflo || {};
37
+ }
38
+
39
+ // app
40
+ get app() {
41
+ return this.dict.app || {};
42
+ }
43
+
44
+ // config
45
+ get config() {
46
+ return this.dict.config || {};
47
+ }
48
+
49
+ // flags
50
+ get flags() {
51
+ return this.dict.flags || {};
52
+ }
53
+
54
+ set flags(value) {
55
+ this.dict.flags = value;
56
+ }
57
+
58
+ // layout
59
+ get layout() {
60
+ return this.dict.layout || {};
61
+ }
62
+
63
+ set layout(value) {
64
+ this.dict.layout = value;
65
+ }
66
+
67
+ // logger
68
+ get logger() {
69
+ return this.dict.logger;
70
+ }
71
+
72
+ set logger(value) {
73
+ this.dict.logger = value;
74
+ }
75
+
76
+ }
@@ -0,0 +1,69 @@
1
+
2
+ /**
3
+ * imports
4
+ */
5
+ import { _merge } from '@webqit/util/obj/index.js';
6
+ import Configurator from '../../Configurator.js';
7
+
8
+ export default class Env extends Configurator {
9
+
10
+ // Base name
11
+ get name() {
12
+ return 'env';
13
+ }
14
+
15
+ // @desc
16
+ static get ['@desc']() {
17
+ return 'Environmental variables config.';
18
+ }
19
+
20
+ // isEnv
21
+ get isEnv() {
22
+ return true;
23
+ }
24
+
25
+ // Defaults merger
26
+ withDefaults(config) {
27
+ return _merge({
28
+ autoload: true,
29
+ }, config);
30
+ }
31
+
32
+ // Questions generator
33
+ questions(config, choices = {}) {
34
+ // Questions
35
+ return [
36
+ {
37
+ name: 'entries',
38
+ type: 'recursive',
39
+ controls: {
40
+ name: 'variable',
41
+ combomode: true,
42
+ },
43
+ initial: config.entries,
44
+ questions: [
45
+ {
46
+ name: 'name',
47
+ type: 'text',
48
+ message: 'Name',
49
+ validation: ['important'],
50
+ },
51
+ {
52
+ name: 'value',
53
+ type: 'text',
54
+ message: 'Value',
55
+ validation: ['important'],
56
+ },
57
+ ],
58
+ },
59
+ {
60
+ name: 'autoload',
61
+ type: 'toggle',
62
+ message: 'Choose whether to autoload variables into "process.env"',
63
+ active: 'YES',
64
+ inactive: 'NO',
65
+ initial: config.autoload,
66
+ },
67
+ ];
68
+ }
69
+ }
@@ -0,0 +1,65 @@
1
+
2
+ /**
3
+ * imports
4
+ */
5
+ import { _merge } from '@webqit/util/obj/index.js';
6
+ import Configurator from '../../Configurator.js';
7
+
8
+ export default class Layout extends Configurator {
9
+
10
+ // Base name
11
+ get name() {
12
+ return 'layout';
13
+ }
14
+
15
+ // @desc
16
+ static get ['@desc']() {
17
+ return 'Project layout config.';
18
+ }
19
+
20
+ // Defaults merger
21
+ withDefaults(config) {
22
+ return _merge({
23
+ ROOT: process.cwd(),
24
+ PUBLIC_DIR: './public',
25
+ SERVER_DIR: './server',
26
+ CLIENT_DIR: './client',
27
+ WORKER_DIR: './worker',
28
+ }, config);
29
+ }
30
+
31
+ // Questions generator
32
+ questions(config, choices = {}) {
33
+ // Questions
34
+ return [
35
+ {
36
+ name: 'PUBLIC_DIR',
37
+ type: 'text',
38
+ message: 'Enter the application\'s public directory',
39
+ initial: config.PUBLIC_DIR,
40
+ validation: ['important'],
41
+ },
42
+ {
43
+ name: 'SERVER_DIR',
44
+ type: 'text',
45
+ message: 'Enter the directory for the application\'s server-side route handlers',
46
+ initial: config.SERVER_DIR,
47
+ validation: ['important'],
48
+ },
49
+ {
50
+ name: 'CLIENT_DIR',
51
+ type: 'text',
52
+ message: 'Enter the directory for the application\'s client-side route handlers',
53
+ initial: config.CLIENT_DIR,
54
+ validation: ['important'],
55
+ },
56
+ {
57
+ name: 'WORKER_DIR',
58
+ type: 'text',
59
+ message: 'Enter the directory for the application\'s offline route handlers',
60
+ initial: config.WORKER_DIR,
61
+ validation: ['important'],
62
+ },
63
+ ];
64
+ }
65
+ }
@@ -0,0 +1,133 @@
1
+
2
+ /**
3
+ * imports
4
+ */
5
+ import Url from 'url';
6
+ import { _merge } from '@webqit/util/obj/index.js';
7
+ import { _before } from '@webqit/util/str/index.js';
8
+ import { _isObject, _isTypeObject } from '@webqit/util/js/index.js';
9
+ import Configurator from '../../Configurator.js';
10
+
11
+ export default class Origins extends Configurator {
12
+
13
+ // Base name
14
+ get name() {
15
+ return 'origins';
16
+ }
17
+
18
+ // @desc
19
+ static get ['@desc']() {
20
+ return 'Remote origins config.';
21
+ }
22
+
23
+ // Defaults merger
24
+ withDefaults(config) {
25
+ let hostname = '', origin = '';
26
+ if (this.cx.PKG && this.cx.PKG.repository) {
27
+ var inferredRepo = Url.parse(_isTypeObject(this.cx.PKG.repository) ? this.cx.PKG.repository.url : this.cx.PKG.repository);
28
+ hostname = _before(inferredRepo.hostname, '.');
29
+ origin = _before(inferredRepo.pathname, '.');
30
+ }
31
+ // Params
32
+ return _merge({
33
+ entries: [{
34
+ host: hostname,
35
+ repo: origin,
36
+ branch: 'master',
37
+ tag: 'root',
38
+ deploy_path: '.',
39
+ autodeploy: true,
40
+ autodeploy_secret: '',
41
+ ondeploy: 'npm install',
42
+ ondeploy_autoexit: true,
43
+ }],
44
+ }, config);
45
+ }
46
+
47
+ // Match
48
+ async match(url) {
49
+ return ((await this.read()).entries || []).filter(_origin => _origin.tag.toLowerCase() === url.toLowerCase() || _origin.repo.toLowerCase() === url.toLowerCase());
50
+ }
51
+
52
+ // Questions generator
53
+ questions(config, choices = {}) {
54
+ // Choices
55
+ const CHOICES = _merge({
56
+ host: [
57
+ {value: 'github',},
58
+ {value: 'bitbucket',},
59
+ ],
60
+ }, choices);
61
+ // Questions
62
+ return [
63
+ {
64
+ name: 'entries',
65
+ type: 'recursive',
66
+ controls: {
67
+ name: 'repository',
68
+ },
69
+ initial: config.entries,
70
+ questions: [
71
+ {
72
+ name: 'host',
73
+ type: 'select',
74
+ message: 'Host name',
75
+ choices: CHOICES.host,
76
+ validation: ['input', 'important'],
77
+ },
78
+ {
79
+ name: 'repo',
80
+ type: 'text',
81
+ message: 'Enter a repository name (in the format: user-or-org/origin)',
82
+ validation: ['input', 'important'],
83
+ },
84
+ {
85
+ name: 'branch',
86
+ type: 'text',
87
+ message: 'Specifiy the git branch within the given repository',
88
+ validation: ['input', 'important'],
89
+ },
90
+ {
91
+ name: 'tag',
92
+ type: 'text',
93
+ message: 'Enter a local name for this origin',
94
+ validation: ['input', 'important'],
95
+ },
96
+ {
97
+ name: 'deploy_path',
98
+ type: 'text',
99
+ message: 'Enter the relative local path that this origin deploys to',
100
+ validation: ['important'],
101
+ },
102
+ {
103
+ name: 'autodeploy',
104
+ type: 'toggle',
105
+ message: 'Auto-deploy this origin on every push to branch?',
106
+ active: 'YES',
107
+ inactive: 'NO',
108
+ },
109
+ {
110
+ name: 'autodeploy_secret',
111
+ type: (prev, ans) => ans.autodeploy ? 'text' : null,
112
+ message: 'Enter the "secret" for validating the auto-deploy webhook event',
113
+ validation: ['input', 'important'],
114
+ },
115
+ {
116
+ name: 'ondeploy',
117
+ type: 'text',
118
+ message: 'Enter an optional "command" to run on deploy',
119
+ validation: ['input', 'important'],
120
+ },
121
+ {
122
+ name: 'ondeploy_autoexit',
123
+ type: (prev, ans) => ans.autodeploy ? 'toggle' : null,
124
+ message: 'Auto exit process on deploy?',
125
+ active: 'YES',
126
+ inactive: 'NO',
127
+ },
128
+ ],
129
+ },
130
+
131
+ ];
132
+ }
133
+ }
@@ -0,0 +1,65 @@
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 Configurator from '../../Configurator.js';
8
+
9
+ export default class Virtualization extends Configurator {
10
+
11
+ // Base name
12
+ get name() {
13
+ return 'virtualization';
14
+ }
15
+
16
+ // @desc
17
+ static get ['@desc']() {
18
+ return 'Layout virtualization config.';
19
+ }
20
+
21
+ // Defaults merger
22
+ withDefaults(config) {
23
+ return _merge(true, {
24
+ entries: [],
25
+ }, config);
26
+ }
27
+
28
+ // Match
29
+ async match(hostname) {
30
+ if (_isObject(hostname)) {
31
+ hostname = hostname.hostname;
32
+ }
33
+ return ((await this.read()).entries || []).filter(vh => vh.host === hostname);
34
+ }
35
+
36
+ // Questions generator
37
+ questions(config, choices = {}) {
38
+ // Questions
39
+ return [
40
+ {
41
+ name: 'entries',
42
+ type: 'recursive',
43
+ controls: {
44
+ name: 'vhost',
45
+ },
46
+ initial: config.entries,
47
+ questions: [
48
+ {
49
+ name: 'host',
50
+ type: 'text',
51
+ message: 'Enter Host name',
52
+ validation: ['important'],
53
+ },
54
+ {
55
+ name: 'path',
56
+ type: 'text',
57
+ message: 'Enter local path',
58
+ validation: ['important'],
59
+ },
60
+ ],
61
+ },
62
+
63
+ ];
64
+ }
65
+ }