spyne-cli 0.6.8 → 0.7.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/LICENSE +661 -0
- package/README.md +80 -30
- package/index.js +123 -21
- package/package.json +24 -6
- package/src/cli/args.js +197 -0
- package/src/cli/render.js +184 -0
- package/src/core/create-app.js +232 -0
- package/src/core/generate-module.js +146 -0
- package/src/registry.js +174 -0
- package/src/spyne-file-prompt.js +77 -30
- package/src/templates/generate-prompt-input-fields.js +1 -1
- package/src/ui.js +5 -1
- package/lib/ansi.js +0 -116
- package/lib/combos.js +0 -75
- package/lib/completer.js +0 -52
- package/lib/interpolate.js +0 -266
- package/lib/keypress.js +0 -243
- package/lib/placeholder.js +0 -63
- package/lib/prompt.js +0 -485
- package/lib/prompts/autocomplete.js +0 -113
- package/lib/prompts/basicauth.js +0 -41
- package/lib/prompts/confirm.js +0 -13
- package/lib/prompts/editable.js +0 -136
- package/lib/prompts/form.js +0 -196
- package/lib/prompts/index.js +0 -28
- package/lib/prompts/input.js +0 -55
- package/lib/prompts/invisible.js +0 -11
- package/lib/prompts/list.js +0 -36
- package/lib/prompts/multiselect.js +0 -11
- package/lib/prompts/numeral.js +0 -1
- package/lib/prompts/password.js +0 -18
- package/lib/prompts/quiz.js +0 -37
- package/lib/prompts/scale.js +0 -237
- package/lib/prompts/select.js +0 -139
- package/lib/prompts/snippet.js +0 -185
- package/lib/prompts/sort.js +0 -37
- package/lib/prompts/survey.js +0 -163
- package/lib/prompts/text.js +0 -1
- package/lib/prompts/toggle.js +0 -109
- package/lib/render.js +0 -33
- package/lib/roles.js +0 -46
- package/lib/state.js +0 -69
- package/lib/styles.js +0 -144
- package/lib/symbols.js +0 -66
- package/lib/theme.js +0 -11
- package/lib/timer.js +0 -38
- package/lib/types/array.js +0 -658
- package/lib/types/auth.js +0 -29
- package/lib/types/boolean.js +0 -88
- package/lib/types/index.js +0 -7
- package/lib/types/number.js +0 -86
- package/lib/types/string.js +0 -185
- package/lib/utils.js +0 -268
- package/mocha.conf.cjs +0 -16
- package/src/app/channels/.gitkeep +0 -0
- package/src/app/channels/channel-custom.js +0 -1
- package/src/app/components/.gitkeep +0 -0
- package/src/app/traits/.gitkeep +0 -0
- package/src/hello-world-app-source/README.md +0 -15
- package/src/hello-world-app-source/apache-htaccess +0 -20
- package/src/hello-world-app-source/karma.conf.js +0 -75
- package/src/hello-world-app-source/package.json +0 -50
- package/src/hello-world-app-source/src/app/app-view.js +0 -38
- package/src/hello-world-app-source/src/app/channels/.gitkeep +0 -0
- package/src/hello-world-app-source/src/app/components/.gitkeep +0 -0
- package/src/hello-world-app-source/src/app/traits/.gitkeep +0 -0
- package/src/hello-world-app-source/src/index.js +0 -16
- package/src/hello-world-app-source/src/index.tmpl.html +0 -12
- package/src/hello-world-app-source/src/scss/01-vendors/normalize.css +0 -349
- package/src/hello-world-app-source/src/scss/02-variables/mixins.scss +0 -0
- package/src/hello-world-app-source/src/scss/03-components/.gitkeep +0 -0
- package/src/hello-world-app-source/src/scss/main.scss +0 -15
- package/src/hello-world-app-source/src/static/data/.gitkeep +0 -0
- package/src/hello-world-app-source/src/static/fonts/.gitkeep +0 -0
- package/src/hello-world-app-source/src/static/imgs/.gitkeep +0 -0
- package/src/hello-world-app-source/src/tests/unit-tests/index.test.js +0 -10
- package/src/hello-world-app-source/webpack.config.js +0 -178
- package/src/spyne-app-create.js +0 -209
- package/src/spyne-app-creator.js +0 -119
- package/src/spyne-starter-app-create.js +0 -147
- package/tests/create-spyne-app.test.js +0 -63
- package/tests/generate-file-prompt.test.js +0 -45
- package/tests/generate-file-string.test.js +0 -66
- package/tests/generate-prompt-input-fields-methods.test.js +0 -177
- package/tests/generate-prompt-input-fields.test.js +0 -179
- package/tests/generate-prompt-input-object.test.js +0 -39
- package/tests/generate-prompt-output.test.js +0 -58
- package/tests/index.test.js +0 -11
- package/tests/mocks/answers.js +0 -33
- package/tests/mocks/answers.json +0 -33
- package/tests/mocks/enquirer-data.js +0 -411
- package/tests/mocks/enquirer-data.json +0 -409
- package/tests/utils/file-utils.test.js +0 -84
package/lib/types/boolean.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Prompt = require('../prompt');
|
|
4
|
-
const { isPrimitive, hasColor } = require('../utils');
|
|
5
|
-
|
|
6
|
-
class BooleanPrompt extends Prompt {
|
|
7
|
-
constructor(options) {
|
|
8
|
-
super(options);
|
|
9
|
-
this.cursorHide();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async initialize() {
|
|
13
|
-
let initial = await this.resolve(this.initial, this.state);
|
|
14
|
-
this.input = await this.cast(initial);
|
|
15
|
-
await super.initialize();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
dispatch(ch) {
|
|
19
|
-
if (!this.isValue(ch)) return this.alert();
|
|
20
|
-
this.input = ch;
|
|
21
|
-
return this.submit();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
format(value) {
|
|
25
|
-
let { styles, state } = this;
|
|
26
|
-
return !state.submitted ? styles.primary(value) : styles.success(value);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
cast(input) {
|
|
30
|
-
return this.isTrue(input);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
isTrue(input) {
|
|
34
|
-
return /^[ty1]/i.test(input);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
isFalse(input) {
|
|
38
|
-
return /^[fn0]/i.test(input);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
isValue(value) {
|
|
42
|
-
return isPrimitive(value) && (this.isTrue(value) || this.isFalse(value));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async hint() {
|
|
46
|
-
if (this.state.status === 'pending') {
|
|
47
|
-
let hint = await this.element('hint');
|
|
48
|
-
if (!hasColor(hint)) {
|
|
49
|
-
return this.styles.muted(hint);
|
|
50
|
-
}
|
|
51
|
-
return hint;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async render() {
|
|
56
|
-
let { input, size } = this.state;
|
|
57
|
-
|
|
58
|
-
let prefix = await this.prefix();
|
|
59
|
-
let sep = await this.separator();
|
|
60
|
-
let msg = await this.message();
|
|
61
|
-
let hint = this.styles.muted(this.default);
|
|
62
|
-
|
|
63
|
-
let promptLine = [prefix, msg, hint, sep].filter(Boolean).join(' ');
|
|
64
|
-
this.state.prompt = promptLine;
|
|
65
|
-
|
|
66
|
-
let header = await this.header();
|
|
67
|
-
let value = this.value = this.cast(input);
|
|
68
|
-
let output = await this.format(value);
|
|
69
|
-
let help = (await this.error()) || (await this.hint());
|
|
70
|
-
let footer = await this.footer();
|
|
71
|
-
|
|
72
|
-
if (help && !promptLine.includes(help)) output += ' ' + help;
|
|
73
|
-
promptLine += ' ' + output;
|
|
74
|
-
|
|
75
|
-
this.clear(size);
|
|
76
|
-
this.write([header, promptLine, footer].filter(Boolean).join('\n'));
|
|
77
|
-
this.restore();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
set value(value) {
|
|
81
|
-
super.value = value;
|
|
82
|
-
}
|
|
83
|
-
get value() {
|
|
84
|
-
return this.cast(super.value);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
module.exports = BooleanPrompt;
|
package/lib/types/index.js
DELETED
package/lib/types/number.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const StringPrompt = require('./string');
|
|
4
|
-
|
|
5
|
-
class NumberPrompt extends StringPrompt {
|
|
6
|
-
constructor(options = {}) {
|
|
7
|
-
super({ style: 'number', ...options });
|
|
8
|
-
this.min = this.isValue(options.min) ? this.toNumber(options.min) : -Infinity;
|
|
9
|
-
this.max = this.isValue(options.max) ? this.toNumber(options.max) : Infinity;
|
|
10
|
-
this.delay = options.delay != null ? options.delay : 1000;
|
|
11
|
-
this.float = options.float !== false;
|
|
12
|
-
this.round = options.round === true || options.float === false;
|
|
13
|
-
this.major = options.major || 10;
|
|
14
|
-
this.minor = options.minor || 1;
|
|
15
|
-
this.initial = options.initial != null ? options.initial : '';
|
|
16
|
-
this.input = String(this.initial);
|
|
17
|
-
this.cursor = this.input.length;
|
|
18
|
-
this.cursorShow();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
append(ch) {
|
|
22
|
-
if (!/[-+.]/.test(ch) || (ch === '.' && this.input.includes('.'))) {
|
|
23
|
-
return this.alert('invalid number');
|
|
24
|
-
}
|
|
25
|
-
return super.append(ch);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
number(ch) {
|
|
29
|
-
return super.append(ch);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
next() {
|
|
33
|
-
if (this.input && this.input !== this.initial) return this.alert();
|
|
34
|
-
if (!this.isValue(this.initial)) return this.alert();
|
|
35
|
-
this.input = this.initial;
|
|
36
|
-
this.cursor = String(this.initial).length;
|
|
37
|
-
return this.render();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
up(number) {
|
|
41
|
-
let step = number || this.minor;
|
|
42
|
-
let num = this.toNumber(this.input);
|
|
43
|
-
if (num > this.max + step) return this.alert();
|
|
44
|
-
this.input = `${num + step}`;
|
|
45
|
-
return this.render();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
down(number) {
|
|
49
|
-
let step = number || this.minor;
|
|
50
|
-
let num = this.toNumber(this.input);
|
|
51
|
-
if (num < this.min - step) return this.alert();
|
|
52
|
-
this.input = `${num - step}`;
|
|
53
|
-
return this.render();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
shiftDown() {
|
|
57
|
-
return this.down(this.major);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
shiftUp() {
|
|
61
|
-
return this.up(this.major);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
format(input = this.input) {
|
|
65
|
-
if (typeof this.options.format === 'function') {
|
|
66
|
-
return this.options.format.call(this, input);
|
|
67
|
-
}
|
|
68
|
-
return this.styles.info(input);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
toNumber(value = '') {
|
|
72
|
-
return this.float ? +value : Math.round(+value);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
isValue(value) {
|
|
76
|
-
return /^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(value);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
submit() {
|
|
80
|
-
let value = [this.input, this.initial].find(v => this.isValue(v));
|
|
81
|
-
this.value = this.toNumber(value || 0);
|
|
82
|
-
return super.submit();
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
module.exports = NumberPrompt;
|
package/lib/types/string.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Prompt = require('../prompt');
|
|
4
|
-
const placeholder = require('../placeholder');
|
|
5
|
-
const { isPrimitive } = require('../utils');
|
|
6
|
-
|
|
7
|
-
class StringPrompt extends Prompt {
|
|
8
|
-
constructor(options) {
|
|
9
|
-
super(options);
|
|
10
|
-
this.initial = isPrimitive(this.initial) ? String(this.initial) : '';
|
|
11
|
-
if (this.initial) this.cursorHide();
|
|
12
|
-
this.state.prevCursor = 0;
|
|
13
|
-
this.state.clipboard = [];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async keypress(input, key = {}) {
|
|
17
|
-
let prev = this.state.prevKeypress;
|
|
18
|
-
this.state.prevKeypress = key;
|
|
19
|
-
if (this.options.multiline === true && key.name === 'return') {
|
|
20
|
-
if (!prev || prev.name !== 'return') {
|
|
21
|
-
return this.append('\n', key);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return super.keypress(input, key);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
moveCursor(n) {
|
|
28
|
-
this.cursor += n;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
reset() {
|
|
32
|
-
this.input = this.value = '';
|
|
33
|
-
this.cursor = 0;
|
|
34
|
-
return this.render();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
dispatch(ch, key) {
|
|
38
|
-
if (!ch || key.ctrl || key.code) return this.alert();
|
|
39
|
-
this.append(ch);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
append(ch) {
|
|
43
|
-
let { cursor, input } = this.state;
|
|
44
|
-
this.input = `${input}`.slice(0, cursor) + ch + `${input}`.slice(cursor);
|
|
45
|
-
this.moveCursor(String(ch).length);
|
|
46
|
-
this.render();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
insert(str) {
|
|
50
|
-
this.append(str);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
delete() {
|
|
54
|
-
let { cursor, input } = this.state;
|
|
55
|
-
if (cursor <= 0) return this.alert();
|
|
56
|
-
this.input = `${input}`.slice(0, cursor - 1) + `${input}`.slice(cursor);
|
|
57
|
-
this.moveCursor(-1);
|
|
58
|
-
this.render();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
deleteForward() {
|
|
62
|
-
let { cursor, input } = this.state;
|
|
63
|
-
if (input[cursor] === void 0) return this.alert();
|
|
64
|
-
this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
|
|
65
|
-
this.render();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
cutForward() {
|
|
69
|
-
let pos = this.cursor;
|
|
70
|
-
if (this.input.length <= pos) return this.alert();
|
|
71
|
-
this.state.clipboard.push(this.input.slice(pos));
|
|
72
|
-
this.input = this.input.slice(0, pos);
|
|
73
|
-
this.render();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
cutLeft() {
|
|
77
|
-
let pos = this.cursor;
|
|
78
|
-
if (pos === 0) return this.alert();
|
|
79
|
-
let before = this.input.slice(0, pos);
|
|
80
|
-
let after = this.input.slice(pos);
|
|
81
|
-
let words = before.split(' ');
|
|
82
|
-
this.state.clipboard.push(words.pop());
|
|
83
|
-
this.input = words.join(' ');
|
|
84
|
-
this.cursor = this.input.length;
|
|
85
|
-
this.input += after;
|
|
86
|
-
this.render();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
paste() {
|
|
90
|
-
if (!this.state.clipboard.length) return this.alert();
|
|
91
|
-
this.insert(this.state.clipboard.pop());
|
|
92
|
-
this.render();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
toggleCursor() {
|
|
96
|
-
if (this.state.prevCursor) {
|
|
97
|
-
this.cursor = this.state.prevCursor;
|
|
98
|
-
this.state.prevCursor = 0;
|
|
99
|
-
} else {
|
|
100
|
-
this.state.prevCursor = this.cursor;
|
|
101
|
-
this.cursor = 0;
|
|
102
|
-
}
|
|
103
|
-
this.render();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
first() {
|
|
107
|
-
this.cursor = 0;
|
|
108
|
-
this.render();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
last() {
|
|
112
|
-
this.cursor = this.input.length - 1;
|
|
113
|
-
this.render();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
next() {
|
|
117
|
-
let init = this.initial != null ? String(this.initial) : '';
|
|
118
|
-
if (!init || !init.startsWith(this.input)) return this.alert();
|
|
119
|
-
this.input = this.initial;
|
|
120
|
-
this.cursor = this.initial.length;
|
|
121
|
-
this.render();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
prev() {
|
|
125
|
-
if (!this.input) return this.alert();
|
|
126
|
-
this.reset();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
backward() {
|
|
130
|
-
return this.left();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
forward() {
|
|
134
|
-
return this.right();
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
right() {
|
|
138
|
-
if (this.cursor >= this.input.length) return this.alert();
|
|
139
|
-
this.moveCursor(1);
|
|
140
|
-
return this.render();
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
left() {
|
|
144
|
-
if (this.cursor <= 0) return this.alert();
|
|
145
|
-
this.moveCursor(-1);
|
|
146
|
-
return this.render();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
isValue(value) {
|
|
150
|
-
return !!value;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async format(input = this.value) {
|
|
154
|
-
let initial = await this.resolve(this.initial, this.state);
|
|
155
|
-
if (!this.state.submitted) {
|
|
156
|
-
return placeholder(this, { input, initial, pos: this.cursor });
|
|
157
|
-
}
|
|
158
|
-
return this.styles.submitted(input || initial);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async render() {
|
|
162
|
-
let size = this.state.size;
|
|
163
|
-
|
|
164
|
-
let prefix = await this.prefix();
|
|
165
|
-
let separator = await this.separator();
|
|
166
|
-
let message = await this.message();
|
|
167
|
-
|
|
168
|
-
let prompt = [prefix, message, separator].filter(Boolean).join(' ');
|
|
169
|
-
this.state.prompt = prompt;
|
|
170
|
-
|
|
171
|
-
let header = await this.header();
|
|
172
|
-
let output = await this.format();
|
|
173
|
-
let help = (await this.error()) || (await this.hint());
|
|
174
|
-
let footer = await this.footer();
|
|
175
|
-
|
|
176
|
-
if (help && !output.includes(help)) output += ' ' + help;
|
|
177
|
-
prompt += ' ' + output;
|
|
178
|
-
|
|
179
|
-
this.clear(size);
|
|
180
|
-
this.write([header, prompt, footer].filter(Boolean).join('\n'));
|
|
181
|
-
this.restore();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
module.exports = StringPrompt;
|
package/lib/utils.js
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const toString = Object.prototype.toString;
|
|
4
|
-
const colors = require('ansi-colors');
|
|
5
|
-
let called = false;
|
|
6
|
-
let fns = [];
|
|
7
|
-
|
|
8
|
-
const complements = {
|
|
9
|
-
'yellow': 'blue',
|
|
10
|
-
'cyan': 'red',
|
|
11
|
-
'green': 'magenta',
|
|
12
|
-
'black': 'white',
|
|
13
|
-
'blue': 'yellow',
|
|
14
|
-
'red': 'cyan',
|
|
15
|
-
'magenta': 'green',
|
|
16
|
-
'white': 'black'
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
exports.longest = (arr, prop) => {
|
|
20
|
-
return arr.reduce((a, v) => Math.max(a, prop ? v[prop].length : v.length), 0);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
exports.hasColor = str => !!str && colors.hasColor(str);
|
|
24
|
-
|
|
25
|
-
const isObject = exports.isObject = val => {
|
|
26
|
-
return val !== null && typeof val === 'object' && !Array.isArray(val);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
exports.nativeType = val => {
|
|
30
|
-
return toString.call(val).slice(8, -1).toLowerCase().replace(/\s/g, '');
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
exports.isAsyncFn = val => {
|
|
34
|
-
return exports.nativeType(val) === 'asyncfunction';
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
exports.isPrimitive = val => {
|
|
38
|
-
return val != null && typeof val !== 'object' && typeof val !== 'function';
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
exports.resolve = (context, value, ...rest) => {
|
|
42
|
-
if (typeof value === 'function') {
|
|
43
|
-
return value.call(context, ...rest);
|
|
44
|
-
}
|
|
45
|
-
return value;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
exports.scrollDown = (choices = []) => [...choices.slice(1), choices[0]];
|
|
49
|
-
exports.scrollUp = (choices = []) => [choices.pop(), ...choices];
|
|
50
|
-
|
|
51
|
-
exports.reorder = (arr = []) => {
|
|
52
|
-
let res = arr.slice();
|
|
53
|
-
res.sort((a, b) => {
|
|
54
|
-
if (a.index > b.index) return 1;
|
|
55
|
-
if (a.index < b.index) return -1;
|
|
56
|
-
return 0;
|
|
57
|
-
});
|
|
58
|
-
return res;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
exports.swap = (arr, index, pos) => {
|
|
62
|
-
let len = arr.length;
|
|
63
|
-
let idx = pos === len ? 0 : pos < 0 ? len - 1 : pos;
|
|
64
|
-
let choice = arr[index];
|
|
65
|
-
arr[index] = arr[idx];
|
|
66
|
-
arr[idx] = choice;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
exports.width = (stream, fallback = 80) => {
|
|
70
|
-
let columns = (stream && stream.columns) ? stream.columns : fallback;
|
|
71
|
-
if (stream && typeof stream.getWindowSize === 'function') {
|
|
72
|
-
columns = stream.getWindowSize()[0];
|
|
73
|
-
}
|
|
74
|
-
if (process.platform === 'win32') {
|
|
75
|
-
return columns - 1;
|
|
76
|
-
}
|
|
77
|
-
return columns;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
exports.height = (stream, fallback = 20) => {
|
|
81
|
-
let rows = (stream && stream.rows) ? stream.rows : fallback;
|
|
82
|
-
if (stream && typeof stream.getWindowSize === 'function') {
|
|
83
|
-
rows = stream.getWindowSize()[1];
|
|
84
|
-
}
|
|
85
|
-
return rows;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
exports.wordWrap = (str, options = {}) => {
|
|
89
|
-
if (!str) return str;
|
|
90
|
-
|
|
91
|
-
if (typeof options === 'number') {
|
|
92
|
-
options = { width: options };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let { indent = '', newline = ('\n' + indent), width = 80 } = options;
|
|
96
|
-
let spaces = (newline + indent).match(/[^\S\n]/g) || [];
|
|
97
|
-
width -= spaces.length;
|
|
98
|
-
let source = `.{1,${width}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`;
|
|
99
|
-
let output = str.trim();
|
|
100
|
-
let regex = new RegExp(source, 'g');
|
|
101
|
-
let lines = output.match(regex) || [];
|
|
102
|
-
lines = lines.map(line => line.replace(/\n$/, ''));
|
|
103
|
-
if (options.padEnd) lines = lines.map(line => line.padEnd(width, ' '));
|
|
104
|
-
if (options.padStart) lines = lines.map(line => line.padStart(width, ' '));
|
|
105
|
-
return indent + lines.join(newline);
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
exports.unmute = color => {
|
|
109
|
-
let name = color.stack.find(n => colors.keys.color.includes(n));
|
|
110
|
-
if (name) {
|
|
111
|
-
return colors[name];
|
|
112
|
-
}
|
|
113
|
-
let bg = color.stack.find(n => n.slice(2) === 'bg');
|
|
114
|
-
if (bg) {
|
|
115
|
-
return colors[name.slice(2)];
|
|
116
|
-
}
|
|
117
|
-
return str => str;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
exports.pascal = str => str ? str[0].toUpperCase() + str.slice(1) : '';
|
|
121
|
-
|
|
122
|
-
exports.inverse = color => {
|
|
123
|
-
if (!color || !color.stack) return color;
|
|
124
|
-
let name = color.stack.find(n => colors.keys.color.includes(n));
|
|
125
|
-
if (name) {
|
|
126
|
-
let col = colors['bg' + exports.pascal(name)];
|
|
127
|
-
return col ? col.black : color;
|
|
128
|
-
}
|
|
129
|
-
let bg = color.stack.find(n => n.slice(0, 2) === 'bg');
|
|
130
|
-
if (bg) {
|
|
131
|
-
return colors[bg.slice(2).toLowerCase()] || color;
|
|
132
|
-
}
|
|
133
|
-
return colors.none;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
exports.complement = color => {
|
|
137
|
-
if (!color || !color.stack) return color;
|
|
138
|
-
let name = color.stack.find(n => colors.keys.color.includes(n));
|
|
139
|
-
let bg = color.stack.find(n => n.slice(0, 2) === 'bg');
|
|
140
|
-
if (name && !bg) {
|
|
141
|
-
return colors[complements[name] || name];
|
|
142
|
-
}
|
|
143
|
-
if (bg) {
|
|
144
|
-
let lower = bg.slice(2).toLowerCase();
|
|
145
|
-
let comp = complements[lower];
|
|
146
|
-
if (!comp) return color;
|
|
147
|
-
return colors['bg' + exports.pascal(comp)] || color;
|
|
148
|
-
}
|
|
149
|
-
return colors.none;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
exports.meridiem = date => {
|
|
153
|
-
let hours = date.getHours();
|
|
154
|
-
let minutes = date.getMinutes();
|
|
155
|
-
let ampm = hours >= 12 ? 'pm' : 'am';
|
|
156
|
-
hours = hours % 12;
|
|
157
|
-
let hrs = hours === 0 ? 12 : hours;
|
|
158
|
-
let min = minutes < 10 ? '0' + minutes : minutes;
|
|
159
|
-
return hrs + ':' + min + ' ' + ampm;
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Set a value on the given object.
|
|
164
|
-
* @param {Object} obj
|
|
165
|
-
* @param {String} prop
|
|
166
|
-
* @param {any} value
|
|
167
|
-
*/
|
|
168
|
-
|
|
169
|
-
exports.set = (obj = {}, prop = '', val) => {
|
|
170
|
-
return prop.split('.').reduce((acc, k, i, arr) => {
|
|
171
|
-
let value = arr.length - 1 > i ? (acc[k] || {}) : val;
|
|
172
|
-
if (!exports.isObject(value) && i < arr.length - 1) value = {};
|
|
173
|
-
return (acc[k] = value);
|
|
174
|
-
}, obj);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Get a value from the given object.
|
|
179
|
-
* @param {Object} obj
|
|
180
|
-
* @param {String} prop
|
|
181
|
-
*/
|
|
182
|
-
|
|
183
|
-
exports.get = (obj = {}, prop = '', fallback) => {
|
|
184
|
-
let value = obj[prop] == null
|
|
185
|
-
? prop.split('.').reduce((acc, k) => acc && acc[k], obj)
|
|
186
|
-
: obj[prop];
|
|
187
|
-
return value == null ? fallback : value;
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
exports.mixin = (target, b) => {
|
|
191
|
-
if (!isObject(target)) return b;
|
|
192
|
-
if (!isObject(b)) return target;
|
|
193
|
-
for (let key of Object.keys(b)) {
|
|
194
|
-
let desc = Object.getOwnPropertyDescriptor(b, key);
|
|
195
|
-
if (desc.hasOwnProperty('value')) {
|
|
196
|
-
if (target.hasOwnProperty(key) && isObject(desc.value)) {
|
|
197
|
-
let existing = Object.getOwnPropertyDescriptor(target, key);
|
|
198
|
-
if (isObject(existing.value) && existing.value !== desc.value) {
|
|
199
|
-
target[key] = exports.merge({}, target[key], b[key]);
|
|
200
|
-
} else {
|
|
201
|
-
Reflect.defineProperty(target, key, desc);
|
|
202
|
-
}
|
|
203
|
-
} else {
|
|
204
|
-
Reflect.defineProperty(target, key, desc);
|
|
205
|
-
}
|
|
206
|
-
} else {
|
|
207
|
-
Reflect.defineProperty(target, key, desc);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return target;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
exports.merge = (...args) => {
|
|
214
|
-
let target = {};
|
|
215
|
-
for (let ele of args) exports.mixin(target, ele);
|
|
216
|
-
return target;
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
exports.mixinEmitter = (obj, emitter) => {
|
|
220
|
-
let proto = emitter.constructor.prototype;
|
|
221
|
-
for (let key of Object.keys(proto)) {
|
|
222
|
-
let val = proto[key];
|
|
223
|
-
if (typeof val === 'function') {
|
|
224
|
-
exports.define(obj, key, val.bind(emitter));
|
|
225
|
-
} else {
|
|
226
|
-
exports.define(obj, key, val);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
exports.onExit = callback => {
|
|
232
|
-
const onExit = (quit, code) => {
|
|
233
|
-
if (called) return;
|
|
234
|
-
|
|
235
|
-
called = true;
|
|
236
|
-
fns.forEach(fn => fn());
|
|
237
|
-
|
|
238
|
-
if (quit === true) {
|
|
239
|
-
process.exit(128 + code);
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
if (fns.length === 0) {
|
|
244
|
-
process.once('SIGTERM', onExit.bind(null, true, 15));
|
|
245
|
-
process.once('SIGINT', onExit.bind(null, true, 2));
|
|
246
|
-
process.once('exit', onExit);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
fns.push(callback);
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
exports.define = (obj, key, value) => {
|
|
253
|
-
Reflect.defineProperty(obj, key, { value });
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
exports.defineExport = (obj, key, fn) => {
|
|
257
|
-
let custom;
|
|
258
|
-
Reflect.defineProperty(obj, key, {
|
|
259
|
-
enumerable: true,
|
|
260
|
-
configurable: true,
|
|
261
|
-
set(val) {
|
|
262
|
-
custom = val;
|
|
263
|
-
},
|
|
264
|
-
get() {
|
|
265
|
-
return custom ? custom() : fn();
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
};
|
package/mocha.conf.cjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// mocha.conf.js
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
// Look for test files in the `tests` folder
|
|
5
|
-
spec: 'tests/**/*.test.js',
|
|
6
|
-
|
|
7
|
-
exclude: [
|
|
8
|
-
'tests/create-spyne-app-test.js'
|
|
9
|
-
|
|
10
|
-
],
|
|
11
|
-
// You can also specify mocha options here
|
|
12
|
-
extension: ['js'], // The file extensions Mocha should look for
|
|
13
|
-
ui: 'bdd', // BDD-style (describe/it)
|
|
14
|
-
timeout: 5000, // Test timeout in milliseconds
|
|
15
|
-
reporter: 'spec', // The built-in "spec" reporter
|
|
16
|
-
};
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Some content for tests/utils/file-utils-test -- should test saving to file
|
|
File without changes
|
package/src/app/traits/.gitkeep
DELETED
|
File without changes
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
## Spynejs Hello World Application
|
|
2
|
-
barebones app preconfigured for building, testing and adding content using the spyne-cli tool
|
|
3
|
-
|
|
4
|
-
App includes
|
|
5
|
-
* AppView
|
|
6
|
-
* Application Folder Structure
|
|
7
|
-
* Build, production setup using webpack and sass
|
|
8
|
-
* Spyne Console plugin
|
|
9
|
-
* Unit testing
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
npm run init or npm install
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### Build better web experiences, faster
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# html5 pushstate (history) support:
|
|
2
|
-
<ifModule mod_rewrite.c>
|
|
3
|
-
RewriteEngine On
|
|
4
|
-
|
|
5
|
-
# the final correct redirect
|
|
6
|
-
RewriteEngine on
|
|
7
|
-
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
|
|
8
|
-
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
RewriteCond %{REQUEST_FILENAME} !-f
|
|
12
|
-
RewriteCond %{REQUEST_FILENAME} !-d
|
|
13
|
-
RewriteCond %{REQUEST_URI} !index
|
|
14
|
-
RewriteRule (.*) index.html [L,QSA]
|
|
15
|
-
</ifModule>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<IfModule mod_headers.c>
|
|
19
|
-
Header add Access-Control-Allow-Origin: *
|
|
20
|
-
</IfModule>
|