neo.mjs 4.0.62 → 4.0.65
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/README.md +3 -3
- package/buildScripts/createClass.mjs +214 -34
- package/package.json +1 -1
- package/src/core/Util.mjs +4 -4
package/README.md
CHANGED
@@ -236,12 +236,12 @@ More infos: <a href="./BACKERS.md">Sponsors & Backers</a>
|
|
236
236
|
</br></br>
|
237
237
|
<h2 id="jobs">14. Jobs</h2>
|
238
238
|
Accenture is hiring multiple neo.mjs developers for the new Cloud Technology Studio in Kaiserslauern (Germany):</br>
|
239
|
-
|
240
|
-
|
239
|
+
</br>
|
241
240
|
These full-time roles are based on German contracts, so they require living in (or relocating to) Germany.
|
241
|
+
Ping us on LinkedIn or Slack for details.
|
242
242
|
|
243
243
|
</br></br>
|
244
|
-
Logo contributed by <a href="https://www.linkedin.com/in/dinkheller/">Torsten Dinkheller</a>.
|
244
|
+
Logo contributed by <a href="https://www.linkedin.com/in/torsten-dinkheller-614516231/">Torsten Dinkheller</a>.
|
245
245
|
|
246
246
|
</br></br>
|
247
247
|
Build with :heart: in Germany.
|
@@ -14,7 +14,7 @@ const
|
|
14
14
|
cwd = process.cwd(),
|
15
15
|
requireJson = path => JSON.parse(fs.readFileSync((path))),
|
16
16
|
packageJson = requireJson(path.join(__dirname, 'package.json')),
|
17
|
-
insideNeo =
|
17
|
+
insideNeo = process.env.npm_package_name === 'neo.mjs',
|
18
18
|
program = new Command(),
|
19
19
|
programName = `${packageJson.name} create-class`,
|
20
20
|
questions = [],
|
@@ -27,7 +27,7 @@ const
|
|
27
27
|
* folder (parent of cwd, child of sourceRootDirs[n]) will then be used as the
|
28
28
|
* namespace for this created class.
|
29
29
|
* Can be overwritten with the -s option.
|
30
|
-
* @type {
|
30
|
+
* @type {String[]}
|
31
31
|
*/
|
32
32
|
sourceRootDirs = ['apps'];
|
33
33
|
|
@@ -94,7 +94,7 @@ if (programOpts.info) {
|
|
94
94
|
type : 'input',
|
95
95
|
name : 'className',
|
96
96
|
message: 'Please choose the namespace for your class:',
|
97
|
-
default: 'Covid.view.
|
97
|
+
default: 'Covid.view.MyContainer'
|
98
98
|
});
|
99
99
|
}
|
100
100
|
|
@@ -103,8 +103,17 @@ if (programOpts.info) {
|
|
103
103
|
type : 'list',
|
104
104
|
name : 'baseClass',
|
105
105
|
message: 'Please pick the base class, which you want to extend:',
|
106
|
-
|
107
|
-
|
106
|
+
default: 'container.Base',
|
107
|
+
|
108
|
+
choices: [
|
109
|
+
'component.Base',
|
110
|
+
'container.Base',
|
111
|
+
'controller.Component',
|
112
|
+
'core.Base',
|
113
|
+
'data.Model',
|
114
|
+
'data.Store',
|
115
|
+
'model.Component'
|
116
|
+
]
|
108
117
|
});
|
109
118
|
}
|
110
119
|
|
@@ -113,7 +122,7 @@ if (programOpts.info) {
|
|
113
122
|
className = programOpts.className || answers.className,
|
114
123
|
isDrop = programOpts.drop,
|
115
124
|
startDate = new Date(),
|
116
|
-
classFolder, file, folderDelta, index, ns, root, rootLowerCase, viewFile;
|
125
|
+
baseFileName, baseType, classFolder, configName, file, folderDelta, importName, importPath, index, ns, root, rootLowerCase, viewFile;
|
117
126
|
|
118
127
|
if (className.endsWith('.mjs')) {
|
119
128
|
className = className.slice(0, -4);
|
@@ -184,8 +193,8 @@ if (programOpts.info) {
|
|
184
193
|
}
|
185
194
|
|
186
195
|
if (isDrop !== true) {
|
187
|
-
if (fs.existsSync(path.resolve(
|
188
|
-
classFolder = path.resolve(
|
196
|
+
if (fs.existsSync(path.resolve(cwd, 'apps', rootLowerCase))) {
|
197
|
+
classFolder = path.resolve(cwd, 'apps', rootLowerCase, ns.join('/'));
|
189
198
|
} else {
|
190
199
|
console.log('\nNon existing neo app name:', chalk.red(root));
|
191
200
|
process.exit(1);
|
@@ -198,17 +207,87 @@ if (programOpts.info) {
|
|
198
207
|
|
199
208
|
fs.mkdirpSync(classFolder);
|
200
209
|
|
201
|
-
|
210
|
+
baseFileName = baseClass.split('.').pop();
|
202
211
|
|
203
|
-
if (
|
204
|
-
|
212
|
+
if (baseFileName === file) {
|
213
|
+
baseFileName = baseClass.split('.');
|
214
|
+
baseFileName = baseFileName.map(e => capitalize(e)).join('');
|
215
|
+
}
|
216
|
+
|
217
|
+
console.log(baseFileName, baseClass);
|
218
|
+
|
219
|
+
fs.writeFileSync(path.join(classFolder, file + '.mjs'), createContent({
|
220
|
+
baseClass,
|
221
|
+
baseFileName,
|
222
|
+
className,
|
223
|
+
file,
|
224
|
+
folderDelta,
|
225
|
+
ns,
|
226
|
+
root
|
227
|
+
}));
|
228
|
+
|
229
|
+
switch(baseClass) {
|
230
|
+
case 'controller.Component': {
|
231
|
+
baseType = 'Neo.controller.Component';
|
232
|
+
configName = 'controller';
|
233
|
+
importName = file;
|
234
|
+
importPath = `./${importName}.mjs`;
|
235
|
+
index = file.indexOf('Controller');
|
236
|
+
|
237
|
+
if (index > 0) {
|
238
|
+
viewFile = path.join(classFolder, file.substr(0, index) + '.mjs');
|
239
|
+
|
240
|
+
if (fs.existsSync(viewFile)) {
|
241
|
+
adjustView({baseType, configName, importName, importPath, viewFile});
|
242
|
+
}
|
243
|
+
}
|
244
|
+
break;
|
245
|
+
}
|
246
|
+
|
247
|
+
case 'data.Store': {
|
248
|
+
baseType = 'Neo.data.Model';
|
249
|
+
configName = 'model';
|
250
|
+
importName = className.replace('.store.', '.model.');
|
251
|
+
|
252
|
+
if (importName.endsWith('ies')) {
|
253
|
+
importName.replace(new RegExp('ies$'), 'y')
|
254
|
+
} else {
|
255
|
+
importName = importName.slice(0, -1);
|
256
|
+
}
|
257
|
+
|
258
|
+
viewFile = importName.split('.');
|
259
|
+
viewFile.shift();
|
205
260
|
|
206
|
-
|
207
|
-
viewFile
|
261
|
+
importPath = `../${viewFile.join('/')}.mjs`;
|
262
|
+
viewFile = path.join(classFolder, importPath);
|
208
263
|
|
264
|
+
// checking for the data.Model file
|
209
265
|
if (fs.existsSync(viewFile)) {
|
210
|
-
|
266
|
+
// adjusting the data.Store file
|
267
|
+
viewFile = path.join(classFolder, file + '.mjs');
|
268
|
+
importName = importName.split('.');
|
269
|
+
importName = importName.pop();
|
270
|
+
|
271
|
+
adjustView({baseType, configName, importName, importPath, viewFile});
|
272
|
+
}
|
273
|
+
break;
|
274
|
+
}
|
275
|
+
|
276
|
+
case 'model.Component': {
|
277
|
+
baseType = 'Neo.model.Component';
|
278
|
+
configName = 'model';
|
279
|
+
importName = file;
|
280
|
+
importPath = `./${importName}.mjs`;
|
281
|
+
index = file.indexOf('Model');
|
282
|
+
|
283
|
+
if (index > 0) {
|
284
|
+
viewFile = path.join(classFolder, file.substr(0, index) + '.mjs');
|
285
|
+
|
286
|
+
if (fs.existsSync(viewFile)) {
|
287
|
+
adjustView({baseType, configName, importName, importPath, viewFile});
|
288
|
+
}
|
211
289
|
}
|
290
|
+
break;
|
212
291
|
}
|
213
292
|
}
|
214
293
|
}
|
@@ -222,27 +301,58 @@ if (programOpts.info) {
|
|
222
301
|
/**
|
223
302
|
* Adds a comma to the last element of the contentArray
|
224
303
|
* @param {String[]} contentArray
|
304
|
+
* @param {Number} index=contentArray.length - 1
|
225
305
|
* @returns {String[]}
|
226
306
|
*/
|
227
|
-
function addComma(contentArray) {
|
228
|
-
contentArray[
|
307
|
+
function addComma(contentArray, index=contentArray.length - 1) {
|
308
|
+
contentArray[index] += ',';
|
229
309
|
return contentArray;
|
230
310
|
}
|
231
311
|
|
312
|
+
/**
|
313
|
+
* Adds a config to the given index of the contentArray
|
314
|
+
* @param {Object} opts
|
315
|
+
* @param {String} opts.baseType
|
316
|
+
* @param {String} opts.className
|
317
|
+
* @param {String} opts.configName
|
318
|
+
* @param {String[]} opts.contentArray
|
319
|
+
* @param {Boolean} opts.isLastConfig
|
320
|
+
* @param {Number} opts.index
|
321
|
+
* @returns {String[]}
|
322
|
+
*/
|
323
|
+
function addConfig(opts) {
|
324
|
+
const config = [
|
325
|
+
' /**',
|
326
|
+
` * @member {${opts.baseType}} ${opts.configName}=${opts.className}`,
|
327
|
+
' */',
|
328
|
+
` ${opts.configName}: ${opts.className}`
|
329
|
+
];
|
330
|
+
|
331
|
+
!opts.isLastConfig && addComma(config);
|
332
|
+
|
333
|
+
opts.contentArray.splice(opts.index, 0, config.join(os.EOL));
|
334
|
+
return opts.contentArray;
|
335
|
+
}
|
336
|
+
|
232
337
|
/**
|
233
338
|
* Adjusts the views related to controller.Component or model.Component
|
234
339
|
* @param {Object} opts
|
235
|
-
* @param {String} opts.
|
340
|
+
* @param {String} opts.baseType
|
341
|
+
* @param {String} opts.configName
|
342
|
+
* @param {String} opts.importName
|
343
|
+
* @param {String} opts.importPath
|
236
344
|
* @param {String} opts.viewFile
|
237
345
|
*/
|
238
346
|
function adjustView(opts) {
|
239
|
-
let
|
347
|
+
let baseType = opts.baseType,
|
348
|
+
configName = opts.configName,
|
349
|
+
importName = opts.importName,
|
240
350
|
viewFile = opts.viewFile,
|
241
351
|
content = fs.readFileSync(viewFile).toString().split(os.EOL),
|
242
352
|
fromMaxPosition = 0,
|
243
353
|
i = 0,
|
244
354
|
len = content.length,
|
245
|
-
adjustSpaces, codeLine, fromPosition, importLength,
|
355
|
+
adjustSpaces, className, codeLine, existingImportName, fromPosition, importLength, j, nextLine, spaces;
|
246
356
|
|
247
357
|
// find the index where we want to insert our import statement
|
248
358
|
for (; i < len; i++) {
|
@@ -252,16 +362,16 @@ if (programOpts.info) {
|
|
252
362
|
break;
|
253
363
|
}
|
254
364
|
|
255
|
-
|
256
|
-
|
257
|
-
importLength
|
365
|
+
existingImportName = codeLine.substr(7);
|
366
|
+
existingImportName = existingImportName.substr(0, existingImportName.indexOf(' '));
|
367
|
+
importLength = existingImportName.length;
|
258
368
|
|
259
|
-
if (
|
369
|
+
if (existingImportName > importName) {
|
260
370
|
break;
|
261
371
|
}
|
262
372
|
}
|
263
373
|
|
264
|
-
content.splice(i, 0, `import ${
|
374
|
+
content.splice(i, 0, `import ${importName} from '${opts.importPath}';`);
|
265
375
|
|
266
376
|
// find the longest import module name
|
267
377
|
for (i=0; i < len; i++) {
|
@@ -296,16 +406,76 @@ if (programOpts.info) {
|
|
296
406
|
}
|
297
407
|
}
|
298
408
|
|
409
|
+
i = 0;
|
410
|
+
len = content.length;
|
411
|
+
|
412
|
+
// find the starting point
|
413
|
+
for (; i < len; i++) {
|
414
|
+
if (content[i].includes('static getConfig')) {
|
415
|
+
break;
|
416
|
+
}
|
417
|
+
}
|
418
|
+
|
419
|
+
for (; i < len; i++) {
|
420
|
+
codeLine = content[i];
|
421
|
+
|
422
|
+
if (codeLine.includes('}}')) {
|
423
|
+
addComma(content, i - 1);
|
424
|
+
addConfig({
|
425
|
+
baseType,
|
426
|
+
className : importName,
|
427
|
+
configName,
|
428
|
+
contentArray: content,
|
429
|
+
index : i,
|
430
|
+
isLastConfig: true
|
431
|
+
});
|
432
|
+
break;
|
433
|
+
}
|
434
|
+
|
435
|
+
if (codeLine.includes('*/')) {
|
436
|
+
nextLine = content[i + 1]
|
437
|
+
className = nextLine.substring(0, nextLine.indexOf(':')).trim();
|
438
|
+
|
439
|
+
if (className === 'className' || className === 'ntype') {
|
440
|
+
continue;
|
441
|
+
}
|
442
|
+
|
443
|
+
if (className > configName) {
|
444
|
+
for (j=i; j > 0; j--) {
|
445
|
+
if (content[j].includes('/**')) {
|
446
|
+
addConfig({
|
447
|
+
baseType,
|
448
|
+
className : importName,
|
449
|
+
configName,
|
450
|
+
contentArray: content,
|
451
|
+
index : j,
|
452
|
+
isLastConfig: false
|
453
|
+
});
|
454
|
+
break;
|
455
|
+
}
|
456
|
+
}
|
457
|
+
break;
|
458
|
+
}
|
459
|
+
}
|
460
|
+
}
|
461
|
+
|
299
462
|
fs.writeFileSync(viewFile, content.join(os.EOL));
|
463
|
+
}
|
300
464
|
|
301
|
-
|
302
|
-
|
465
|
+
/**
|
466
|
+
* Makes the first character of a string uppercase
|
467
|
+
* @param {String} value
|
468
|
+
* @returns {Boolean|String} Returns false for non string inputs
|
469
|
+
*/
|
470
|
+
function capitalize(value) {
|
471
|
+
return typeof value === 'string' && value[0].toUpperCase() + value.slice(1);
|
303
472
|
}
|
304
473
|
|
305
474
|
/**
|
306
475
|
* Creates the content of the neo-class .mjs file
|
307
476
|
* @param {Object} opts
|
308
477
|
* @param {String} opts.baseClass
|
478
|
+
* @param {String} opts.baseFileName
|
309
479
|
* @param {String} opts.className
|
310
480
|
* @param {String} opts.file
|
311
481
|
* @param {String} opts.folderDelta
|
@@ -314,20 +484,20 @@ if (programOpts.info) {
|
|
314
484
|
* @returns {String}
|
315
485
|
*/
|
316
486
|
function createContent(opts) {
|
317
|
-
let baseClass
|
318
|
-
|
319
|
-
|
320
|
-
className
|
321
|
-
file
|
322
|
-
i
|
323
|
-
importDelta
|
487
|
+
let baseClass = opts.baseClass,
|
488
|
+
baseFileName = opts.baseFileName,
|
489
|
+
baseClassPath = baseClass.split('.').join('/'),
|
490
|
+
className = opts.className,
|
491
|
+
file = opts.file,
|
492
|
+
i = 0,
|
493
|
+
importDelta = '';
|
324
494
|
|
325
495
|
for (; i < opts.folderDelta; i++) {
|
326
496
|
importDelta += '../';
|
327
497
|
}
|
328
498
|
|
329
499
|
let classContent = [
|
330
|
-
`import ${baseFileName} from '${importDelta}${(insideNeo ? '' : 'node_modules/neo.mjs/')}src/${
|
500
|
+
`import ${baseFileName} from '${importDelta}${(insideNeo ? '' : 'node_modules/neo.mjs/')}src/${baseClassPath}.mjs';`,
|
331
501
|
"",
|
332
502
|
"/**",
|
333
503
|
` * @class ${className}`,
|
@@ -342,6 +512,16 @@ if (programOpts.info) {
|
|
342
512
|
` className: '${className}'`
|
343
513
|
];
|
344
514
|
|
515
|
+
baseClass === 'data.Model' && addComma(classContent).push(
|
516
|
+
" /*",
|
517
|
+
" * @member {Object[]} fields",
|
518
|
+
" */",
|
519
|
+
" fields: [{",
|
520
|
+
" name: 'id',",
|
521
|
+
" type: 'String'",
|
522
|
+
" }]"
|
523
|
+
);
|
524
|
+
|
345
525
|
baseClass === 'container.Base' && addComma(classContent).push(
|
346
526
|
" /*",
|
347
527
|
" * @member {Object[]} items",
|
package/package.json
CHANGED
package/src/core/Util.mjs
CHANGED
@@ -40,11 +40,11 @@ class Util extends Base {
|
|
40
40
|
|
41
41
|
/**
|
42
42
|
* Makes the first character of a string uppercase
|
43
|
-
* @param {String}
|
43
|
+
* @param {String} value
|
44
44
|
* @returns {Boolean|String} Returns false for non string inputs
|
45
45
|
*/
|
46
|
-
static capitalize(
|
47
|
-
return Util.isString(
|
46
|
+
static capitalize(value) {
|
47
|
+
return Util.isString(value) && value[0].toUpperCase() + value.slice(1);
|
48
48
|
}
|
49
49
|
|
50
50
|
/**
|
@@ -100,7 +100,7 @@ class Util extends Base {
|
|
100
100
|
}
|
101
101
|
|
102
102
|
/**
|
103
|
-
* Transforms all uppercase characters of a string into lowercase.
|
103
|
+
* Transforms all uppercase characters of a string into -lowercase.
|
104
104
|
* Does not touch special characters.
|
105
105
|
* @param {String} value The input containing uppercase characters
|
106
106
|
* @returns {String} The lowercase output
|