neo.mjs 4.1.2 → 4.2.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/buildScripts/addConfig.mjs +398 -0
- package/package.json +2 -1
@@ -0,0 +1,398 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
import chalk from 'chalk';
|
4
|
+
import { Command } from 'commander/esm.mjs';
|
5
|
+
import envinfo from 'envinfo';
|
6
|
+
import fs from 'fs-extra';
|
7
|
+
import inquirer from 'inquirer';
|
8
|
+
import os from 'os';
|
9
|
+
import path from 'path';
|
10
|
+
|
11
|
+
const
|
12
|
+
__dirname = path.resolve(),
|
13
|
+
cwd = process.cwd(),
|
14
|
+
requireJson = path => JSON.parse(fs.readFileSync((path))),
|
15
|
+
packageJson = requireJson(path.join(__dirname, 'package.json')),
|
16
|
+
program = new Command(),
|
17
|
+
programName = `${packageJson.name} add-config`;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Adds a comma to the last element of the contentArray
|
21
|
+
* @param {String[]} contentArray
|
22
|
+
* @param {Number} index=contentArray.length - 1
|
23
|
+
* @returns {String[]}
|
24
|
+
*/
|
25
|
+
function addComma(contentArray, index=contentArray.length - 1) {
|
26
|
+
contentArray[index] += ',';
|
27
|
+
return contentArray;
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Adds a config to the given index of the contentArray
|
32
|
+
* @param {Object} opts
|
33
|
+
* @param {String} opts.configName
|
34
|
+
* @param {String} opts.defaultValue
|
35
|
+
* @param {String[]} opts.contentArray
|
36
|
+
* @param {Boolean} opts.isLastConfig
|
37
|
+
* @param {Number} opts.index
|
38
|
+
* @param {String} opts.type
|
39
|
+
* @returns {String[]}
|
40
|
+
*/
|
41
|
+
function addConfig(opts) {
|
42
|
+
if (opts.type === 'String' && opts.defaultValue !== 'null') {
|
43
|
+
opts.defaultValue = `'${opts.defaultValue}'`;
|
44
|
+
}
|
45
|
+
|
46
|
+
const config = [
|
47
|
+
' /**',
|
48
|
+
` * @member {${opts.type}} ${opts.configName}_=${opts.defaultValue}`,
|
49
|
+
' */',
|
50
|
+
` ${opts.configName}_: ${opts.defaultValue}`
|
51
|
+
];
|
52
|
+
|
53
|
+
!opts.isLastConfig && addComma(config);
|
54
|
+
|
55
|
+
opts.contentArray.splice(opts.index, 0, config.join(os.EOL));
|
56
|
+
return opts.contentArray;
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Adds a config hook at the matching index
|
61
|
+
* @param {Object} opts
|
62
|
+
* @param {String} opts.comment
|
63
|
+
* @param {String[]} opts.contentArray
|
64
|
+
* @param {String} opts.name
|
65
|
+
* @param {Boolean} opts.oldValueParam
|
66
|
+
* @param {Boolean} opts.returnValue
|
67
|
+
* @param {String} opts.type
|
68
|
+
* @returns {String[]}
|
69
|
+
*/
|
70
|
+
function addHook(opts) {
|
71
|
+
let contentArray = opts.contentArray,
|
72
|
+
i = 0,
|
73
|
+
inserted = false,
|
74
|
+
len = contentArray.length,
|
75
|
+
j, methodName, nextLine,
|
76
|
+
|
77
|
+
method = [
|
78
|
+
'',
|
79
|
+
' /**',
|
80
|
+
` * ${opts.comment}`,
|
81
|
+
` * @param {${opts.type}} value`
|
82
|
+
];
|
83
|
+
|
84
|
+
if (opts.oldValueParam) {
|
85
|
+
method.push(
|
86
|
+
` * @param {${opts.type}} oldValue`
|
87
|
+
);
|
88
|
+
}
|
89
|
+
|
90
|
+
if (opts.returnValue) {
|
91
|
+
method.push(
|
92
|
+
` * @returns {${opts.type}}`
|
93
|
+
);
|
94
|
+
}
|
95
|
+
|
96
|
+
method.push(
|
97
|
+
' * @protected',
|
98
|
+
' */'
|
99
|
+
);
|
100
|
+
|
101
|
+
if (opts.oldValueParam) {
|
102
|
+
method.push(
|
103
|
+
` ${opts.name}(value, oldValue) {`
|
104
|
+
);
|
105
|
+
} else {
|
106
|
+
method.push(
|
107
|
+
` ${opts.name}(value) {`
|
108
|
+
);
|
109
|
+
}
|
110
|
+
|
111
|
+
if (opts.returnValue) {
|
112
|
+
method.push(
|
113
|
+
' return value;'
|
114
|
+
);
|
115
|
+
} else {
|
116
|
+
method.push(
|
117
|
+
' '
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
121
|
+
method.push(
|
122
|
+
' }'
|
123
|
+
);
|
124
|
+
|
125
|
+
for (; i < len; i++) {
|
126
|
+
if (contentArray[i].includes('}}')) {
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
for (; i < len; i++) {
|
132
|
+
if (contentArray[i].includes('*/')) {
|
133
|
+
nextLine = contentArray[i + 1]
|
134
|
+
methodName = nextLine.substring(0, nextLine.indexOf('(')).trim();
|
135
|
+
|
136
|
+
if (methodName === 'construct') {
|
137
|
+
continue;
|
138
|
+
}
|
139
|
+
|
140
|
+
if (methodName > opts.name) {
|
141
|
+
for (j=i; j > 0; j--) {
|
142
|
+
if (contentArray[j].includes('/**')) {
|
143
|
+
contentArray.splice(j - 1, 0, method.join(os.EOL));
|
144
|
+
inserted = true;
|
145
|
+
break;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
break;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
if (!inserted) {
|
154
|
+
for (i=contentArray.length - 1; i > 0; i--) {
|
155
|
+
if (contentArray[i].includes('}')) {
|
156
|
+
contentArray.splice(i, 0, method.join(os.EOL));
|
157
|
+
break;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
return contentArray;
|
163
|
+
}
|
164
|
+
|
165
|
+
|
166
|
+
/**
|
167
|
+
* Makes the first character of a string uppercase
|
168
|
+
* @param {String} value
|
169
|
+
* @returns {Boolean|String} Returns false for non string inputs
|
170
|
+
*/
|
171
|
+
function capitalize(value) {
|
172
|
+
return value[0].toUpperCase() + value.slice(1);
|
173
|
+
}
|
174
|
+
|
175
|
+
program
|
176
|
+
.name(programName)
|
177
|
+
.version(packageJson.version)
|
178
|
+
.option('-i, --info', 'print environment debug info')
|
179
|
+
.option('-c, --className <value>')
|
180
|
+
.option('-d, --defaultValue <value>')
|
181
|
+
.option('-h, --hooks <value>')
|
182
|
+
.option('-n, --configName <value>')
|
183
|
+
.option('-t, --type <value>')
|
184
|
+
.allowUnknownOption()
|
185
|
+
.on('--help', () => {
|
186
|
+
console.log('\nIn case you have any issues, please create a ticket here:');
|
187
|
+
console.log(chalk.cyan(process.env.npm_package_bugs_url));
|
188
|
+
})
|
189
|
+
.parse(process.argv);
|
190
|
+
|
191
|
+
const programOpts = program.opts();
|
192
|
+
|
193
|
+
if (programOpts.info) {
|
194
|
+
console.log(chalk.bold('\nEnvironment Info:'));
|
195
|
+
console.log(`\n current version of ${packageJson.name}: ${packageJson.version}`);
|
196
|
+
console.log(` running from ${cwd}`);
|
197
|
+
|
198
|
+
envinfo
|
199
|
+
.run({
|
200
|
+
System : ['OS', 'CPU'],
|
201
|
+
Binaries : ['Node', 'npm', 'Yarn'],
|
202
|
+
Browsers : ['Chrome', 'Edge', 'Firefox', 'Safari'],
|
203
|
+
npmPackages: ['neo.mjs']
|
204
|
+
}, {
|
205
|
+
duplicates : true,
|
206
|
+
showNotFound: true
|
207
|
+
})
|
208
|
+
.then(console.log);
|
209
|
+
} else {
|
210
|
+
console.log(chalk.green(programName));
|
211
|
+
|
212
|
+
let answers = {},
|
213
|
+
answer;
|
214
|
+
|
215
|
+
if (!programOpts.className) {
|
216
|
+
answer = await inquirer.prompt({
|
217
|
+
type : 'input',
|
218
|
+
name : 'className',
|
219
|
+
message: 'Please choose the namespace of your class:',
|
220
|
+
default: 'Covid.view.MainContainer'
|
221
|
+
});
|
222
|
+
|
223
|
+
Object.assign(answers, answer);
|
224
|
+
}
|
225
|
+
|
226
|
+
let className = programOpts.className || answers.className,
|
227
|
+
ns = className.split('.'),
|
228
|
+
root = ns.shift().toLowerCase(),
|
229
|
+
classPath = path.resolve(cwd, root === 'neo' ? 'src' : `apps/${root}`, `${ns.join('/')}.mjs`);
|
230
|
+
|
231
|
+
if (!fs.existsSync(path.resolve(classPath))) {
|
232
|
+
console.log(chalk.red(`File not found for ${className} => ${classPath}`));
|
233
|
+
process.exit(1);
|
234
|
+
}
|
235
|
+
|
236
|
+
if (!programOpts.configName) {
|
237
|
+
answer = await inquirer.prompt({
|
238
|
+
type : 'input',
|
239
|
+
name : 'configName',
|
240
|
+
message: 'Please enter a name for your class config:'
|
241
|
+
});
|
242
|
+
|
243
|
+
Object.assign(answers, answer);
|
244
|
+
}
|
245
|
+
|
246
|
+
let configName = programOpts.configName || answers.configName;
|
247
|
+
|
248
|
+
if (configName.endsWith('_')) {
|
249
|
+
configName = configName.slice(0, -1);
|
250
|
+
}
|
251
|
+
|
252
|
+
let uConfigName = capitalize(configName);
|
253
|
+
|
254
|
+
if (!programOpts.type) {
|
255
|
+
answer = await inquirer.prompt({
|
256
|
+
type : 'list',
|
257
|
+
name : 'type',
|
258
|
+
message: 'Please choose a type for your class config:',
|
259
|
+
default: 'Custom',
|
260
|
+
choices: [
|
261
|
+
'Custom',
|
262
|
+
'Object',
|
263
|
+
'Object[]',
|
264
|
+
'Number',
|
265
|
+
'Number[]',
|
266
|
+
'String',
|
267
|
+
'String[]'
|
268
|
+
]
|
269
|
+
});
|
270
|
+
|
271
|
+
Object.assign(answers, answer);
|
272
|
+
}
|
273
|
+
|
274
|
+
if (answers.type === 'Custom') {
|
275
|
+
answer = await inquirer.prompt({
|
276
|
+
type : 'input',
|
277
|
+
name : 'type',
|
278
|
+
message: 'Please enter the type for your class config:'
|
279
|
+
});
|
280
|
+
|
281
|
+
Object.assign(answers, answer);
|
282
|
+
}
|
283
|
+
|
284
|
+
if (!programOpts.defaultValue) {
|
285
|
+
answer = await inquirer.prompt({
|
286
|
+
type : 'input',
|
287
|
+
name : 'defaultValue',
|
288
|
+
message: 'Please enter a defaultValue:',
|
289
|
+
default: 'null'
|
290
|
+
});
|
291
|
+
|
292
|
+
Object.assign(answers, answer);
|
293
|
+
}
|
294
|
+
|
295
|
+
if (!programOpts.hooks) {
|
296
|
+
answer = await inquirer.prompt({
|
297
|
+
type : 'checkbox',
|
298
|
+
name : 'hooks',
|
299
|
+
message: 'Please choose the hooks for your class config:',
|
300
|
+
choices: [`afterSet${uConfigName}()`, `beforeGet${uConfigName}()`, `beforeSet${uConfigName}()`],
|
301
|
+
default: [`afterSet${uConfigName}()`]
|
302
|
+
});
|
303
|
+
|
304
|
+
Object.assign(answers, answer);
|
305
|
+
}
|
306
|
+
|
307
|
+
let defaultValue = programOpts.defaultValue || answers.defaultValue,
|
308
|
+
hooks = programOpts.hooks || answers.hooks,
|
309
|
+
type = programOpts.type || answers.type,
|
310
|
+
contentArray = fs.readFileSync(classPath).toString().split(os.EOL),
|
311
|
+
i = 0,
|
312
|
+
len = contentArray.length,
|
313
|
+
codeLine, existingConfigName, j, nextLine;
|
314
|
+
|
315
|
+
for (; i < len; i++) {
|
316
|
+
if (contentArray[i].includes('static getConfig')) {
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
321
|
+
for (; i < len; i++) {
|
322
|
+
codeLine = contentArray[i];
|
323
|
+
|
324
|
+
if (codeLine.includes('}}')) {
|
325
|
+
addComma(contentArray, i - 1);
|
326
|
+
addConfig({
|
327
|
+
configName,
|
328
|
+
defaultValue,
|
329
|
+
contentArray,
|
330
|
+
index : i,
|
331
|
+
isLastConfig: true,
|
332
|
+
type
|
333
|
+
});
|
334
|
+
break;
|
335
|
+
}
|
336
|
+
|
337
|
+
if (codeLine.includes('*/')) {
|
338
|
+
nextLine = contentArray[i + 1]
|
339
|
+
existingConfigName = nextLine.substring(0, nextLine.indexOf(':')).trim();
|
340
|
+
|
341
|
+
if (existingConfigName === 'className' || existingConfigName === 'ntype') {
|
342
|
+
continue;
|
343
|
+
}
|
344
|
+
|
345
|
+
if (existingConfigName > configName) {
|
346
|
+
for (j=i; j > 0; j--) {
|
347
|
+
if (contentArray[j].includes('/**')) {
|
348
|
+
addConfig({
|
349
|
+
configName,
|
350
|
+
contentArray,
|
351
|
+
defaultValue,
|
352
|
+
index : j,
|
353
|
+
isLastConfig: false,
|
354
|
+
type
|
355
|
+
});
|
356
|
+
break;
|
357
|
+
}
|
358
|
+
}
|
359
|
+
break;
|
360
|
+
}
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
if (hooks.includes(`afterSet${uConfigName}()`)) {
|
365
|
+
addHook({
|
366
|
+
comment : `Triggered after the ${configName} config got changed`,
|
367
|
+
contentArray,
|
368
|
+
name : `afterSet${uConfigName}`,
|
369
|
+
oldValueParam: true,
|
370
|
+
returnValue : false,
|
371
|
+
type
|
372
|
+
});
|
373
|
+
}
|
374
|
+
|
375
|
+
if (hooks.includes(`beforeGet${uConfigName}()`)) {
|
376
|
+
addHook({
|
377
|
+
comment : `Gets triggered when accessing the value of the ${configName} config`,
|
378
|
+
contentArray,
|
379
|
+
name : `beforeGet${uConfigName}`,
|
380
|
+
oldValueParam: false,
|
381
|
+
returnValue : true,
|
382
|
+
type
|
383
|
+
});
|
384
|
+
}
|
385
|
+
|
386
|
+
if (hooks.includes(`beforeSet${uConfigName}()`)) {
|
387
|
+
addHook({
|
388
|
+
comment : `Triggered before the ${configName} config gets changed`,
|
389
|
+
contentArray,
|
390
|
+
name : `beforeSet${uConfigName}`,
|
391
|
+
oldValueParam: true,
|
392
|
+
returnValue : true,
|
393
|
+
type
|
394
|
+
});
|
395
|
+
}
|
396
|
+
|
397
|
+
fs.writeFileSync(classPath, contentArray.join(os.EOL));
|
398
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "neo.mjs",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.2.0",
|
4
4
|
"description": "The webworkers driven UI framework",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -11,6 +11,7 @@
|
|
11
11
|
"neo-cc": "./buildScripts/createClass.mjs"
|
12
12
|
},
|
13
13
|
"scripts": {
|
14
|
+
"add-config": "node ./buildScripts/addConfig.mjs",
|
14
15
|
"build-all": "node ./buildScripts/buildAll.mjs -f -n",
|
15
16
|
"build-all-questions": "node ./buildScripts/buildAll.mjs -f",
|
16
17
|
"build-my-apps": "node ./buildScripts/webpack/buildMyApps.mjs -f",
|