spyne-cli 0.3.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 (70) hide show
  1. package/README.md +3 -0
  2. package/index-cli.js +56 -0
  3. package/index.js +14 -0
  4. package/lib/ansi.js +116 -0
  5. package/lib/combos.js +75 -0
  6. package/lib/completer.js +52 -0
  7. package/lib/interpolate.js +266 -0
  8. package/lib/keypress.js +243 -0
  9. package/lib/placeholder.js +63 -0
  10. package/lib/prompt.js +485 -0
  11. package/lib/prompts/autocomplete.js +113 -0
  12. package/lib/prompts/basicauth.js +41 -0
  13. package/lib/prompts/confirm.js +13 -0
  14. package/lib/prompts/editable.js +136 -0
  15. package/lib/prompts/form.js +196 -0
  16. package/lib/prompts/index.js +28 -0
  17. package/lib/prompts/input.js +55 -0
  18. package/lib/prompts/invisible.js +11 -0
  19. package/lib/prompts/list.js +36 -0
  20. package/lib/prompts/multiselect.js +11 -0
  21. package/lib/prompts/numeral.js +1 -0
  22. package/lib/prompts/password.js +18 -0
  23. package/lib/prompts/quiz.js +37 -0
  24. package/lib/prompts/scale.js +237 -0
  25. package/lib/prompts/select.js +139 -0
  26. package/lib/prompts/snippet.js +185 -0
  27. package/lib/prompts/sort.js +37 -0
  28. package/lib/prompts/survey.js +163 -0
  29. package/lib/prompts/text.js +1 -0
  30. package/lib/prompts/toggle.js +109 -0
  31. package/lib/render.js +33 -0
  32. package/lib/roles.js +46 -0
  33. package/lib/state.js +69 -0
  34. package/lib/styles.js +144 -0
  35. package/lib/symbols.js +66 -0
  36. package/lib/theme.js +11 -0
  37. package/lib/timer.js +38 -0
  38. package/lib/types/array.js +658 -0
  39. package/lib/types/auth.js +29 -0
  40. package/lib/types/boolean.js +88 -0
  41. package/lib/types/index.js +7 -0
  42. package/lib/types/number.js +86 -0
  43. package/lib/types/string.js +185 -0
  44. package/lib/utils.js +268 -0
  45. package/package.json +45 -0
  46. package/src/app/channels/.gitkeep +0 -0
  47. package/src/app/components/.gitkeep +0 -0
  48. package/src/app/traits/.gitkeep +0 -0
  49. package/src/spyne-file-prompt.js +63 -0
  50. package/src/spyne-template-prompts.js +171 -0
  51. package/src/templates/generate-file-string.js +131 -0
  52. package/src/templates/generate-prompt-input-fields.js +256 -0
  53. package/src/templates/generate-prompt-input-object.js +46 -0
  54. package/src/templates/generate-prompt-output.js +109 -0
  55. package/src/ui.js +16 -0
  56. package/src/utils/color-utils.js +36 -0
  57. package/src/utils/error-logger.js +15 -0
  58. package/src/utils/file-utils.js +69 -0
  59. package/tests/generate-file-prompt.test.js +47 -0
  60. package/tests/generate-file-string.test.js +68 -0
  61. package/tests/generate-prompt-input-fields-methods.test.js +178 -0
  62. package/tests/generate-prompt-input-fields.test.js +181 -0
  63. package/tests/generate-prompt-input-object.test.js +41 -0
  64. package/tests/generate-prompt-output.test.js +60 -0
  65. package/tests/index.test.js +13 -0
  66. package/tests/mocks/answers.js +33 -0
  67. package/tests/mocks/answers.json +33 -0
  68. package/tests/mocks/enquirer-data.js +411 -0
  69. package/tests/mocks/enquirer-data.json +409 -0
  70. package/tests/utils/file-utils.test.js +70 -0
@@ -0,0 +1,88 @@
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;
@@ -0,0 +1,7 @@
1
+ module.exports = {
2
+ ArrayPrompt: require('./array'),
3
+ AuthPrompt: require('./auth'),
4
+ BooleanPrompt: require('./boolean'),
5
+ NumberPrompt: require('./number'),
6
+ StringPrompt: require('./string')
7
+ };
@@ -0,0 +1,86 @@
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;
@@ -0,0 +1,185 @@
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 ADDED
@@ -0,0 +1,268 @@
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/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "spyne-cli",
3
+ "bin": {
4
+ "spyne-cli": "index.js"
5
+ },
6
+ "type": "module",
7
+ "version": "0.3.0",
8
+ "description": "Generates spyne objects and saves them to standard spyne.",
9
+ "main": "index.js",
10
+ "scripts": {
11
+ "debug": "nodemon --no-stdin index.js",
12
+ "resetApp": "node ./index-cli resetAppDir",
13
+ "resetAll": "npm run resetApp && clear && npm start",
14
+ "start": "node index.js",
15
+ "test": "echo \"Error: no test specified\" && exit 1"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+ssh://git@github.com/spynejs/spyne-cli.git"
20
+ },
21
+ "author": "Frank Batista",
22
+ "license": "AGPL-3.0-or-later",
23
+ "bugs": {
24
+ "url": "https://github.com/spynejs/spyne-cli/issues"
25
+ },
26
+ "homepage": "https://github.com/spynejs/spyne-cli#readme",
27
+ "dependencies": {
28
+ "ansi-colors": "^4.1.1",
29
+ "boxen": "^6.2.1",
30
+ "chalk": "^5.0.0",
31
+ "change-case": "^4.1.2",
32
+ "clear": "^0.1.0",
33
+ "enquirer": "^2.3.6",
34
+ "figlet": "^1.5.2",
35
+ "json-stringify-safe": "^5.0.1"
36
+ },
37
+ "devDependencies": {
38
+ "chai": "^4.3.4",
39
+ "mocha": "^9.1.3",
40
+ "nodemon": "^2.0.15"
41
+ },
42
+ "directories": {
43
+ "lib": "lib"
44
+ }
45
+ }
File without changes
File without changes
File without changes