@rindo/core 2.17.4 → 2.22.2
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/cli/config-flags.d.ts +33 -21
- package/cli/index.cjs +693 -401
- package/cli/index.d.ts +3 -0
- package/cli/index.js +693 -401
- package/cli/package.json +1 -1
- package/compiler/lib.dom.d.ts +898 -184
- package/compiler/lib.dom.iterable.d.ts +22 -4
- package/compiler/lib.es2015.collection.d.ts +62 -1
- package/compiler/lib.es2015.core.d.ts +3 -3
- package/compiler/lib.es2015.iterable.d.ts +2 -1
- package/compiler/lib.es2015.promise.d.ts +9 -4
- package/compiler/lib.es2015.proxy.d.ts +91 -2
- package/compiler/lib.es2015.reflect.d.ts +26 -3
- package/compiler/lib.es2015.symbol.wellknown.d.ts +3 -3
- package/compiler/lib.es2017.intl.d.ts +16 -1
- package/compiler/lib.es2019.d.ts +1 -0
- package/compiler/lib.es2019.intl.d.ts +25 -0
- package/compiler/lib.es2020.bigint.d.ts +7 -5
- package/compiler/lib.es2020.d.ts +2 -0
- package/compiler/lib.es2020.date.d.ts +44 -0
- package/compiler/lib.es2020.intl.d.ts +81 -16
- package/compiler/lib.es2020.number.d.ts +30 -0
- package/compiler/lib.es2021.intl.d.ts +116 -6
- package/compiler/lib.es2022.array.d.ts +123 -0
- package/compiler/lib.es2022.d.ts +27 -0
- package/compiler/lib.es2022.error.d.ts +75 -0
- package/compiler/lib.es2022.full.d.ts +25 -0
- package/compiler/lib.es2022.intl.d.ts +111 -0
- package/compiler/lib.es2022.object.d.ts +28 -0
- package/compiler/lib.es2022.sharedmemory.d.ts +27 -0
- package/compiler/lib.es2022.string.d.ts +27 -0
- package/compiler/lib.es5.d.ts +62 -31
- package/compiler/lib.esnext.d.ts +1 -1
- package/compiler/lib.esnext.intl.d.ts +8 -1
- package/compiler/lib.webworker.d.ts +540 -81
- package/compiler/lib.webworker.iterable.d.ts +19 -4
- package/compiler/package.json +1 -1
- package/compiler/rindo.d.ts +3 -25
- package/compiler/rindo.js +54678 -52205
- package/compiler/rindo.min.js +2 -2
- package/compiler/sys/in-memory-fs.d.ts +218 -0
- package/compiler/transpile.d.ts +32 -0
- package/dependencies.json +12 -1
- package/dev-server/client/app-error.d.ts +1 -1
- package/dev-server/client/index.d.ts +2 -2
- package/dev-server/client/index.js +241 -241
- package/dev-server/client/package.json +1 -1
- package/dev-server/connector.html +3 -3
- package/dev-server/index.d.ts +1 -1
- package/dev-server/index.js +2 -2
- package/dev-server/open-in-editor-api.js +1 -1
- package/dev-server/package.json +1 -1
- package/dev-server/server-process.js +1192 -1158
- package/dev-server/ws.js +1 -1
- package/internal/app-data/package.json +1 -1
- package/internal/client/css-shim.js +2 -2
- package/internal/client/dom.js +1 -1
- package/internal/client/index.js +1130 -823
- package/internal/client/package.json +1 -1
- package/internal/client/patch-browser.js +19 -1
- package/internal/client/patch-esm.js +1 -1
- package/internal/client/polyfills/css-shim.js +1 -1
- package/internal/client/shadow-css.js +1 -1
- package/internal/hydrate/index.js +154 -143
- package/internal/hydrate/package.json +1 -1
- package/internal/hydrate/runner.d.ts +1 -1
- package/internal/hydrate/runner.js +106 -106
- package/internal/package.json +1 -1
- package/internal/rindo-core/index.d.ts +9 -10
- package/internal/rindo-private.d.ts +149 -184
- package/internal/rindo-public-compiler.d.ts +83 -38
- package/internal/rindo-public-docs.d.ts +24 -0
- package/internal/rindo-public-runtime.d.ts +79 -7
- package/internal/testing/index.js +187 -175
- package/internal/testing/package.json +1 -1
- package/mock-doc/index.cjs +526 -501
- package/mock-doc/index.d.ts +15 -14
- package/mock-doc/index.js +526 -501
- package/mock-doc/package.json +1 -1
- package/package.json +48 -59
- package/readme.md +44 -31
- package/screenshot/compare/build/p-f4745c2f.entry.js +1 -1
- package/screenshot/index.d.ts +1 -1
- package/screenshot/index.js +13 -13
- package/screenshot/package.json +1 -1
- package/screenshot/pixel-match.js +983 -849
- package/sys/node/autoprefixer.js +2 -2
- package/sys/node/glob.js +1 -1
- package/sys/node/index.d.ts +4 -0
- package/sys/node/index.js +399 -413
- package/sys/node/package.json +1 -1
- package/sys/node/prompts.js +1 -1
- package/sys/node/worker.js +1 -1
- package/testing/index.d.ts +6 -6
- package/testing/index.js +684 -839
- package/testing/jest/jest-config.d.ts +1 -1
- package/testing/jest/jest-preprocessor.d.ts +3 -3
- package/testing/jest/jest-serializer.d.ts +1 -2
- package/testing/matchers/index.d.ts +3 -3
- package/testing/mock-fetch.d.ts +1 -1
- package/testing/mocks.d.ts +2 -2
- package/testing/package.json +1 -1
- package/testing/puppeteer/puppeteer-declarations.d.ts +5 -5
- package/testing/puppeteer/puppeteer-element.d.ts +2 -2
- package/testing/puppeteer/puppeteer-events.d.ts +1 -1
- package/testing/testing-logger.d.ts +1 -1
- package/testing/testing-utils.d.ts +6 -5
- package/testing/testing.d.ts +1 -1
package/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Rindo CLI (CommonJS) v2.
|
|
2
|
+
Rindo CLI (CommonJS) v2.22.2 | MIT Licensed | https://rindojs.web.app
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
@@ -25,41 +25,6 @@ function _interopNamespace(e) {
|
|
|
25
25
|
return Object.freeze(n);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* This sets the log level hierarchy for our terminal logger, ranging from
|
|
30
|
-
* most to least verbose.
|
|
31
|
-
*
|
|
32
|
-
* Ordering the levels like this lets us easily check whether we should log a
|
|
33
|
-
* message at a given time. For instance, if the log level is set to `'warn'`,
|
|
34
|
-
* then anything passed to the logger with level `'warn'` or `'error'` should
|
|
35
|
-
* be logged, but we should _not_ log anything with level `'info'` or `'debug'`.
|
|
36
|
-
*
|
|
37
|
-
* If we have a current log level `currentLevel` and a message with level
|
|
38
|
-
* `msgLevel` is passed to the logger, we can determine whether or not we should
|
|
39
|
-
* log it by checking if the log level on the message is further up or at the
|
|
40
|
-
* same level in the hierarchy than `currentLevel`, like so:
|
|
41
|
-
*
|
|
42
|
-
* ```ts
|
|
43
|
-
* LOG_LEVELS.indexOf(msgLevel) >= LOG_LEVELS.indexOf(currentLevel)
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* NOTE: for the reasons described above, do not change the order of the entries
|
|
47
|
-
* in this array without good reason!
|
|
48
|
-
*/
|
|
49
|
-
const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Convert a string from PascalCase to dash-case
|
|
53
|
-
*
|
|
54
|
-
* @param str the string to convert
|
|
55
|
-
* @returns a converted string
|
|
56
|
-
*/
|
|
57
|
-
const toDashCase = (str) => str
|
|
58
|
-
.replace(/([A-Z0-9])/g, (match) => ` ${match[0]}`)
|
|
59
|
-
.trim()
|
|
60
|
-
.split(' ')
|
|
61
|
-
.join('-')
|
|
62
|
-
.toLowerCase();
|
|
63
28
|
/**
|
|
64
29
|
* Convert a string from dash-case / kebab-case to PascalCase (or CamelCase,
|
|
65
30
|
* or whatever you call it!)
|
|
@@ -72,6 +37,16 @@ const dashToPascalCase = (str) => str
|
|
|
72
37
|
.split('-')
|
|
73
38
|
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
74
39
|
.join('');
|
|
40
|
+
/**
|
|
41
|
+
* Convert a string to 'camelCase'
|
|
42
|
+
*
|
|
43
|
+
* @param str the string to convert
|
|
44
|
+
* @returns the converted string
|
|
45
|
+
*/
|
|
46
|
+
const toCamelCase = (str) => {
|
|
47
|
+
const pascalCase = dashToPascalCase(str);
|
|
48
|
+
return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
|
|
49
|
+
};
|
|
75
50
|
const isFunction = (v) => typeof v === 'function';
|
|
76
51
|
const isString = (v) => typeof v === 'string';
|
|
77
52
|
|
|
@@ -223,18 +198,18 @@ const getEncodedRootLength = (path) => {
|
|
|
223
198
|
return 0;
|
|
224
199
|
const ch0 = path.charCodeAt(0);
|
|
225
200
|
// POSIX or UNC
|
|
226
|
-
if (ch0 === 47 /* slash */ || ch0 === 92 /* backslash */) {
|
|
201
|
+
if (ch0 === 47 /* CharacterCodes.slash */ || ch0 === 92 /* CharacterCodes.backslash */) {
|
|
227
202
|
if (path.charCodeAt(1) !== ch0)
|
|
228
203
|
return 1; // POSIX: "/" (or non-normalized "\")
|
|
229
|
-
const p1 = path.indexOf(ch0 === 47 /* slash */ ? '/' : altDirectorySeparator, 2);
|
|
204
|
+
const p1 = path.indexOf(ch0 === 47 /* CharacterCodes.slash */ ? '/' : altDirectorySeparator, 2);
|
|
230
205
|
if (p1 < 0)
|
|
231
206
|
return path.length; // UNC: "//server" or "\\server"
|
|
232
207
|
return p1 + 1; // UNC: "//server/" or "\\server\"
|
|
233
208
|
}
|
|
234
209
|
// DOS
|
|
235
|
-
if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* colon */) {
|
|
210
|
+
if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* CharacterCodes.colon */) {
|
|
236
211
|
const ch2 = path.charCodeAt(2);
|
|
237
|
-
if (ch2 === 47 /* slash */ || ch2 === 92 /* backslash */)
|
|
212
|
+
if (ch2 === 47 /* CharacterCodes.slash */ || ch2 === 92 /* CharacterCodes.backslash */)
|
|
238
213
|
return 3; // DOS: "c:/" or "c:\"
|
|
239
214
|
if (path.length === 2)
|
|
240
215
|
return 2; // DOS: "c:" (but not "c:d")
|
|
@@ -256,7 +231,7 @@ const getEncodedRootLength = (path) => {
|
|
|
256
231
|
isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
|
|
257
232
|
const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
|
|
258
233
|
if (volumeSeparatorEnd !== -1) {
|
|
259
|
-
if (path.charCodeAt(volumeSeparatorEnd) === 47 /* slash */) {
|
|
234
|
+
if (path.charCodeAt(volumeSeparatorEnd) === 47 /* CharacterCodes.slash */) {
|
|
260
235
|
// URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
|
|
261
236
|
return ~(volumeSeparatorEnd + 1);
|
|
262
237
|
}
|
|
@@ -274,15 +249,15 @@ const getEncodedRootLength = (path) => {
|
|
|
274
249
|
// relative
|
|
275
250
|
return 0;
|
|
276
251
|
};
|
|
277
|
-
const isVolumeCharacter = (charCode) => (charCode >= 97 /* a */ && charCode <= 122 /* z */) ||
|
|
278
|
-
(charCode >= 65 /* A */ && charCode <= 90 /* Z */);
|
|
252
|
+
const isVolumeCharacter = (charCode) => (charCode >= 97 /* CharacterCodes.a */ && charCode <= 122 /* CharacterCodes.z */) ||
|
|
253
|
+
(charCode >= 65 /* CharacterCodes.A */ && charCode <= 90 /* CharacterCodes.Z */);
|
|
279
254
|
const getFileUrlVolumeSeparatorEnd = (url, start) => {
|
|
280
255
|
const ch0 = url.charCodeAt(start);
|
|
281
|
-
if (ch0 === 58 /* colon */)
|
|
256
|
+
if (ch0 === 58 /* CharacterCodes.colon */)
|
|
282
257
|
return start + 1;
|
|
283
|
-
if (ch0 === 37 /* percent */ && url.charCodeAt(start + 1) === 51 /* _3 */) {
|
|
258
|
+
if (ch0 === 37 /* CharacterCodes.percent */ && url.charCodeAt(start + 1) === 51 /* CharacterCodes._3 */) {
|
|
284
259
|
const ch2 = url.charCodeAt(start + 2);
|
|
285
|
-
if (ch2 === 97 /* a */ || ch2 === 65 /* A */)
|
|
260
|
+
if (ch2 === 97 /* CharacterCodes.a */ || ch2 === 65 /* CharacterCodes.A */)
|
|
286
261
|
return start + 3;
|
|
287
262
|
}
|
|
288
263
|
return -1;
|
|
@@ -297,6 +272,22 @@ const pathComponents = (path, rootLength) => {
|
|
|
297
272
|
return [root, ...rest];
|
|
298
273
|
};
|
|
299
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Check whether a string is a member of a ReadonlyArray<string>
|
|
277
|
+
*
|
|
278
|
+
* We need a little helper for this because unfortunately `includes` is typed
|
|
279
|
+
* on `ReadonlyArray<T>` as `(el: T): boolean` so a `string` cannot be passed
|
|
280
|
+
* to `includes` on a `ReadonlyArray` 😢 thus we have a little helper function
|
|
281
|
+
* where we do the type coercion just once.
|
|
282
|
+
*
|
|
283
|
+
* see microsoft/TypeScript#31018 for some discussion of this
|
|
284
|
+
*
|
|
285
|
+
* @param readOnlyArray the array we're checking
|
|
286
|
+
* @param maybeMember a value which is possibly a member of the array
|
|
287
|
+
* @returns whether the array contains the member or not
|
|
288
|
+
*/
|
|
289
|
+
const readOnlyArrayHasStringMember = (readOnlyArray, maybeMember) => readOnlyArray.includes(maybeMember);
|
|
290
|
+
|
|
300
291
|
/**
|
|
301
292
|
* Validates that a component tag meets required naming conventions to be used for a web component
|
|
302
293
|
* @param tag the tag to validate
|
|
@@ -341,10 +332,33 @@ const validateComponentTag = (tag) => {
|
|
|
341
332
|
return undefined;
|
|
342
333
|
};
|
|
343
334
|
|
|
335
|
+
/**
|
|
336
|
+
* This sets the log level hierarchy for our terminal logger, ranging from
|
|
337
|
+
* most to least verbose.
|
|
338
|
+
*
|
|
339
|
+
* Ordering the levels like this lets us easily check whether we should log a
|
|
340
|
+
* message at a given time. For instance, if the log level is set to `'warn'`,
|
|
341
|
+
* then anything passed to the logger with level `'warn'` or `'error'` should
|
|
342
|
+
* be logged, but we should _not_ log anything with level `'info'` or `'debug'`.
|
|
343
|
+
*
|
|
344
|
+
* If we have a current log level `currentLevel` and a message with level
|
|
345
|
+
* `msgLevel` is passed to the logger, we can determine whether or not we should
|
|
346
|
+
* log it by checking if the log level on the message is further up or at the
|
|
347
|
+
* same level in the hierarchy than `currentLevel`, like so:
|
|
348
|
+
*
|
|
349
|
+
* ```ts
|
|
350
|
+
* LOG_LEVELS.indexOf(msgLevel) >= LOG_LEVELS.indexOf(currentLevel)
|
|
351
|
+
* ```
|
|
352
|
+
*
|
|
353
|
+
* NOTE: for the reasons described above, do not change the order of the entries
|
|
354
|
+
* in this array without good reason!
|
|
355
|
+
*/
|
|
356
|
+
const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
357
|
+
|
|
344
358
|
/**
|
|
345
359
|
* All the Boolean options supported by the Rindo CLI
|
|
346
360
|
*/
|
|
347
|
-
const
|
|
361
|
+
const BOOLEAN_CLI_FLAGS = [
|
|
348
362
|
'build',
|
|
349
363
|
'cache',
|
|
350
364
|
'checkVersion',
|
|
@@ -427,7 +441,7 @@ const BOOLEAN_CLI_ARGS = [
|
|
|
427
441
|
/**
|
|
428
442
|
* All the Number options supported by the Rindo CLI
|
|
429
443
|
*/
|
|
430
|
-
const
|
|
444
|
+
const NUMBER_CLI_FLAGS = [
|
|
431
445
|
'port',
|
|
432
446
|
// JEST CLI ARGS
|
|
433
447
|
'maxConcurrency',
|
|
@@ -436,7 +450,7 @@ const NUMBER_CLI_ARGS = [
|
|
|
436
450
|
/**
|
|
437
451
|
* All the String options supported by the Rindo CLI
|
|
438
452
|
*/
|
|
439
|
-
const
|
|
453
|
+
const STRING_CLI_FLAGS = [
|
|
440
454
|
'address',
|
|
441
455
|
'config',
|
|
442
456
|
'docsApi',
|
|
@@ -475,7 +489,8 @@ const STRING_CLI_ARGS = [
|
|
|
475
489
|
'testURL',
|
|
476
490
|
'timers',
|
|
477
491
|
'transform',
|
|
478
|
-
|
|
492
|
+
];
|
|
493
|
+
const STRING_ARRAY_CLI_FLAGS = [
|
|
479
494
|
'collectCoverageOnlyFrom',
|
|
480
495
|
'coveragePathIgnorePatterns',
|
|
481
496
|
'coverageReporters',
|
|
@@ -504,7 +519,7 @@ const STRING_CLI_ARGS = [
|
|
|
504
519
|
* `maxWorkers` is an argument which is used both by Rindo _and_ by Jest,
|
|
505
520
|
* which means that we need to support parsing both string and number values.
|
|
506
521
|
*/
|
|
507
|
-
const
|
|
522
|
+
const STRING_NUMBER_CLI_FLAGS = ['maxWorkers'];
|
|
508
523
|
/**
|
|
509
524
|
* All the LogLevel-type options supported by the Rindo CLI
|
|
510
525
|
*
|
|
@@ -512,16 +527,21 @@ const STRING_NUMBER_CLI_ARGS = ['maxWorkers'];
|
|
|
512
527
|
* but this approach lets us make sure that we're handling all
|
|
513
528
|
* our arguments in a type-safe way.
|
|
514
529
|
*/
|
|
515
|
-
const
|
|
530
|
+
const LOG_LEVEL_CLI_FLAGS = ['logLevel'];
|
|
516
531
|
/**
|
|
517
532
|
* For a small subset of CLI options we support a short alias e.g. `'h'` for `'help'`
|
|
518
533
|
*/
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
534
|
+
const CLI_FLAG_ALIASES = {
|
|
535
|
+
c: 'config',
|
|
536
|
+
h: 'help',
|
|
537
|
+
p: 'port',
|
|
538
|
+
v: 'version',
|
|
524
539
|
};
|
|
540
|
+
/**
|
|
541
|
+
* A regular expression which can be used to match a CLI flag for one of our
|
|
542
|
+
* short aliases.
|
|
543
|
+
*/
|
|
544
|
+
const CLI_FLAG_REGEX = new RegExp(`^-[chpv]{1}$`);
|
|
525
545
|
/**
|
|
526
546
|
* Helper function for initializing a `ConfigFlags` object. Provide any overrides
|
|
527
547
|
* for default values and off you go!
|
|
@@ -554,8 +574,14 @@ const parseFlags = (args, _sys) => {
|
|
|
554
574
|
flags.args = Array.isArray(args) ? args.slice() : [];
|
|
555
575
|
if (flags.args.length > 0 && flags.args[0] && !flags.args[0].startsWith('-')) {
|
|
556
576
|
flags.task = flags.args[0];
|
|
577
|
+
// if the first argument was a "task" (like `build`, `test`, etc) then
|
|
578
|
+
// we go on to parse the _rest_ of the CLI args
|
|
579
|
+
parseArgs(flags, args.slice(1));
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
// we didn't find a leading flag, so we should just parse them all
|
|
583
|
+
parseArgs(flags, flags.args);
|
|
557
584
|
}
|
|
558
|
-
parseArgs(flags, flags.args);
|
|
559
585
|
if (flags.task != null) {
|
|
560
586
|
const i = flags.args.indexOf(flags.task);
|
|
561
587
|
if (i > -1) {
|
|
@@ -572,120 +598,259 @@ const parseFlags = (args, _sys) => {
|
|
|
572
598
|
return flags;
|
|
573
599
|
};
|
|
574
600
|
/**
|
|
575
|
-
* Parse command line
|
|
576
|
-
* module. Handles leading dashes on arguments, aliases that are
|
|
577
|
-
* small number of arguments, and parsing values for non-boolean
|
|
578
|
-
* (e.g. port number for the dev server).
|
|
601
|
+
* Parse the supported command line flags which are enumerated in the
|
|
602
|
+
* `config-flags` module. Handles leading dashes on arguments, aliases that are
|
|
603
|
+
* defined for a small number of arguments, and parsing values for non-boolean
|
|
604
|
+
* arguments (e.g. port number for the dev server).
|
|
605
|
+
*
|
|
606
|
+
* This parses the following grammar:
|
|
607
|
+
*
|
|
608
|
+
* CLIArguments → ""
|
|
609
|
+
* | CLITerm ( " " CLITerm )* ;
|
|
610
|
+
* CLITerm → EqualsArg
|
|
611
|
+
* | AliasEqualsArg
|
|
612
|
+
* | AliasArg
|
|
613
|
+
* | NegativeDashArg
|
|
614
|
+
* | NegativeArg
|
|
615
|
+
* | SimpleArg ;
|
|
616
|
+
* EqualsArg → "--" ArgName "=" CLIValue ;
|
|
617
|
+
* AliasEqualsArg → "-" AliasName "=" CLIValue ;
|
|
618
|
+
* AliasArg → "-" AliasName ( " " CLIValue )? ;
|
|
619
|
+
* NegativeDashArg → "--no-" ArgName ;
|
|
620
|
+
* NegativeArg → "--no" ArgName ;
|
|
621
|
+
* SimpleArg → "--" ArgName ( " " CLIValue )? ;
|
|
622
|
+
* ArgName → /^[a-zA-Z-]+$/ ;
|
|
623
|
+
* AliasName → /^[a-z]{1}$/ ;
|
|
624
|
+
* CLIValue → '"' /^[a-zA-Z0-9]+$/ '"'
|
|
625
|
+
* | /^[a-zA-Z0-9]+$/ ;
|
|
626
|
+
*
|
|
627
|
+
* There are additional constraints (not shown in the grammar for brevity's sake)
|
|
628
|
+
* on the type of `CLIValue` which will be associated with a particular argument.
|
|
629
|
+
* We enforce this by declaring lists of boolean, string, etc arguments and
|
|
630
|
+
* checking the types of values before setting them.
|
|
631
|
+
*
|
|
632
|
+
* We don't need to turn the list of CLI arg tokens into any kind of
|
|
633
|
+
* intermediate representation since we aren't concerned with doing anything
|
|
634
|
+
* other than setting the correct values on our ConfigFlags object. So we just
|
|
635
|
+
* parse the array of string arguments using a recursive-descent approach
|
|
636
|
+
* (which is not very deep since our grammar is pretty simple) and make the
|
|
637
|
+
* modifications we need to make to the {@link ConfigFlags} object as we go.
|
|
579
638
|
*
|
|
580
639
|
* @param flags a ConfigFlags object to which parsed arguments will be added
|
|
581
640
|
* @param args an array of command-line arguments to parse
|
|
582
641
|
*/
|
|
583
642
|
const parseArgs = (flags, args) => {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
643
|
+
const argsCopy = args.concat();
|
|
644
|
+
while (argsCopy.length > 0) {
|
|
645
|
+
// there are still unprocessed args to deal with
|
|
646
|
+
parseCLITerm(flags, argsCopy);
|
|
647
|
+
}
|
|
589
648
|
};
|
|
590
649
|
/**
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
* - `--booleanArg`
|
|
594
|
-
* - `--boolean-arg`
|
|
595
|
-
* - `--noBooleanArg`
|
|
596
|
-
* - `--no-boolean-arg`
|
|
597
|
-
*
|
|
598
|
-
* The final two variants should be parsed to a value of `false` on the config
|
|
599
|
-
* object.
|
|
650
|
+
* Given an array of CLI arguments, parse it and perform a series of side
|
|
651
|
+
* effects (setting values on the provided `ConfigFlags` object).
|
|
600
652
|
*
|
|
601
|
-
* @param flags
|
|
602
|
-
*
|
|
603
|
-
* @param
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
653
|
+
* @param flags a {@link ConfigFlags} object which is updated as we parse the CLI
|
|
654
|
+
* arguments
|
|
655
|
+
* @param args a list of args to work through. This function (and some functions
|
|
656
|
+
* it calls) calls `Array.prototype.shift` to get the next argument to look at,
|
|
657
|
+
* so this parameter will be modified.
|
|
658
|
+
*/
|
|
659
|
+
const parseCLITerm = (flags, args) => {
|
|
660
|
+
// pull off the first arg from the argument array
|
|
661
|
+
const arg = args.shift();
|
|
662
|
+
// array is empty, we're done!
|
|
663
|
+
if (arg === undefined)
|
|
664
|
+
return;
|
|
665
|
+
// EqualsArg → "--" ArgName "=" CLIValue ;
|
|
666
|
+
if (arg.startsWith('--') && arg.includes('=')) {
|
|
667
|
+
// we're dealing with an EqualsArg, we have a special helper for that
|
|
668
|
+
const [originalArg, value] = parseEqualsArg(arg);
|
|
669
|
+
setCLIArg(flags, arg.split('=')[0], normalizeFlagName(originalArg), value);
|
|
670
|
+
}
|
|
671
|
+
// AliasEqualsArg → "-" AliasName "=" CLIValue ;
|
|
672
|
+
else if (arg.startsWith('-') && arg.includes('=')) {
|
|
673
|
+
// we're dealing with an AliasEqualsArg, we have a special helper for that
|
|
674
|
+
const [originalArg, value] = parseEqualsArg(arg);
|
|
675
|
+
setCLIArg(flags, arg.split('=')[0], normalizeFlagName(originalArg), value);
|
|
676
|
+
}
|
|
677
|
+
// AliasArg → "-" AliasName ( " " CLIValue )? ;
|
|
678
|
+
else if (CLI_FLAG_REGEX.test(arg)) {
|
|
679
|
+
// this is a short alias, like `-c` for Config
|
|
680
|
+
setCLIArg(flags, arg, normalizeFlagName(arg), parseCLIValue(args));
|
|
681
|
+
}
|
|
682
|
+
// NegativeDashArg → "--no-" ArgName ;
|
|
683
|
+
else if (arg.startsWith('--no-') && arg.length > '--no-'.length) {
|
|
684
|
+
// this is a `NegativeDashArg` term, so we need to normalize the negative
|
|
685
|
+
// flag name and then set an appropriate value
|
|
686
|
+
const normalized = normalizeNegativeFlagName(arg);
|
|
687
|
+
setCLIArg(flags, arg, normalized, '');
|
|
688
|
+
}
|
|
689
|
+
// NegativeArg → "--no" ArgName ;
|
|
690
|
+
else if (arg.startsWith('--no') &&
|
|
691
|
+
!readOnlyArrayHasStringMember(BOOLEAN_CLI_FLAGS, normalizeFlagName(arg)) &&
|
|
692
|
+
readOnlyArrayHasStringMember(BOOLEAN_CLI_FLAGS, normalizeNegativeFlagName(arg))) {
|
|
693
|
+
// possibly dealing with a `NegativeArg` here. There is a little ambiguity
|
|
694
|
+
// here because we have arguments that already begin with `no` like
|
|
695
|
+
// `notify`, so we need to test if a normalized form of the raw argument is
|
|
696
|
+
// a valid and supported boolean flag.
|
|
697
|
+
setCLIArg(flags, arg, normalizeNegativeFlagName(arg), '');
|
|
698
|
+
}
|
|
699
|
+
// SimpleArg → "--" ArgName ( " " CLIValue )? ;
|
|
700
|
+
else if (arg.startsWith('--') && arg.length > '--'.length) {
|
|
701
|
+
setCLIArg(flags, arg, normalizeFlagName(arg), parseCLIValue(args));
|
|
702
|
+
}
|
|
703
|
+
// if we get here it is not an argument in our list of supported arguments.
|
|
704
|
+
// This doesn't necessarily mean we want to report an error or anything
|
|
705
|
+
// though! Instead, with unknown / unrecognized arguments we stick them into
|
|
706
|
+
// the `unknownArgs` array, which is used when we pass CLI args to Jest, for
|
|
707
|
+
// instance. So we just return void here.
|
|
629
708
|
};
|
|
630
709
|
/**
|
|
631
|
-
*
|
|
710
|
+
* Normalize a 'negative' flag name, just to do a little pre-processing before
|
|
711
|
+
* we pass it to `setCLIArg`.
|
|
632
712
|
*
|
|
633
|
-
* @param
|
|
634
|
-
* @
|
|
635
|
-
* @param configCaseName the argument we want to look at right now
|
|
713
|
+
* @param flagName the flag name to normalize
|
|
714
|
+
* @returns a normalized flag name
|
|
636
715
|
*/
|
|
637
|
-
const
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
const { value, matchingArg } = getValue(args, configCaseName);
|
|
642
|
-
if (value !== undefined && matchingArg !== undefined) {
|
|
643
|
-
flags[configCaseName] = value;
|
|
644
|
-
flags.knownArgs.push(matchingArg);
|
|
645
|
-
flags.knownArgs.push(value);
|
|
646
|
-
}
|
|
716
|
+
const normalizeNegativeFlagName = (flagName) => {
|
|
717
|
+
const trimmed = flagName.replace(/^--no[-]?/, '');
|
|
718
|
+
return normalizeFlagName(trimmed.charAt(0).toLowerCase() + trimmed.slice(1));
|
|
647
719
|
};
|
|
648
720
|
/**
|
|
649
|
-
*
|
|
721
|
+
* Normalize a flag name by:
|
|
722
|
+
*
|
|
723
|
+
* - replacing any leading dashes (`--foo` -> `foo`)
|
|
724
|
+
* - converting `dash-case` to camelCase (if necessary)
|
|
725
|
+
*
|
|
726
|
+
* Normalizing in this context basically means converting the various
|
|
727
|
+
* supported flag spelling variants to the variant defined in our lists of
|
|
728
|
+
* supported arguments (e.g. BOOLEAN_CLI_FLAGS, etc). So, for instance,
|
|
729
|
+
* `--log-level` should be converted to `logLevel`.
|
|
730
|
+
*
|
|
731
|
+
* @param flagName the flag name to normalize
|
|
732
|
+
* @returns a normalized flag name
|
|
650
733
|
*
|
|
651
|
-
* @param flags the config flags object, while we'll modify
|
|
652
|
-
* @param args our CLI arguments
|
|
653
|
-
* @param configCaseName the argument we want to look at right now
|
|
654
734
|
*/
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
659
|
-
const { value, matchingArg } = getValue(args, configCaseName);
|
|
660
|
-
if (value !== undefined && matchingArg !== undefined) {
|
|
661
|
-
flags[configCaseName] = parseInt(value, 10);
|
|
662
|
-
flags.knownArgs.push(matchingArg);
|
|
663
|
-
flags.knownArgs.push(value);
|
|
664
|
-
}
|
|
735
|
+
const normalizeFlagName = (flagName) => {
|
|
736
|
+
const trimmed = flagName.replace(/^-+/, '');
|
|
737
|
+
return trimmed.includes('-') ? toCamelCase(trimmed) : trimmed;
|
|
665
738
|
};
|
|
666
739
|
/**
|
|
667
|
-
*
|
|
740
|
+
* Set a value on a provided {@link ConfigFlags} object, given an argument
|
|
741
|
+
* name and a raw string value. This function dispatches to other functions
|
|
742
|
+
* which make sure that the string value can be properly parsed into a JS
|
|
743
|
+
* runtime value of the right type (e.g. number, string, etc).
|
|
668
744
|
*
|
|
669
|
-
* @
|
|
670
|
-
* @param
|
|
671
|
-
* @param
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
745
|
+
* @throws if a value cannot be parsed to the right type for a given flag
|
|
746
|
+
* @param flags a {@link ConfigFlags} object
|
|
747
|
+
* @param rawArg the raw argument name matched by the parser
|
|
748
|
+
* @param normalizedArg an argument with leading control characters (`--`,
|
|
749
|
+
* `--no-`, etc) removed
|
|
750
|
+
* @param value the raw value to be set onto the config flags object
|
|
751
|
+
*/
|
|
752
|
+
const setCLIArg = (flags, rawArg, normalizedArg, value) => {
|
|
753
|
+
normalizedArg = dereferenceAlias(normalizedArg);
|
|
754
|
+
// We're setting a boolean!
|
|
755
|
+
if (readOnlyArrayHasStringMember(BOOLEAN_CLI_FLAGS, normalizedArg)) {
|
|
756
|
+
flags[normalizedArg] =
|
|
757
|
+
typeof value === 'string'
|
|
758
|
+
? Boolean(value)
|
|
759
|
+
: // no value was supplied, default to true
|
|
760
|
+
true;
|
|
761
|
+
flags.knownArgs.push(rawArg);
|
|
762
|
+
}
|
|
763
|
+
// We're setting a string!
|
|
764
|
+
else if (readOnlyArrayHasStringMember(STRING_CLI_FLAGS, normalizedArg)) {
|
|
765
|
+
if (typeof value === 'string') {
|
|
766
|
+
flags[normalizedArg] = value;
|
|
767
|
+
flags.knownArgs.push(rawArg);
|
|
768
|
+
flags.knownArgs.push(value);
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
throwCLIParsingError(rawArg, 'expected a string argument but received nothing');
|
|
772
|
+
}
|
|
676
773
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
flags[
|
|
774
|
+
// We're setting a string, but it's one where the user can pass multiple values,
|
|
775
|
+
// like `--reporters="default" --reporters="jest-junit"`
|
|
776
|
+
else if (readOnlyArrayHasStringMember(STRING_ARRAY_CLI_FLAGS, normalizedArg)) {
|
|
777
|
+
if (typeof value === 'string') {
|
|
778
|
+
if (!Array.isArray(flags[normalizedArg])) {
|
|
779
|
+
flags[normalizedArg] = [];
|
|
780
|
+
}
|
|
781
|
+
const targetArray = flags[normalizedArg];
|
|
782
|
+
// this is irritating, but TS doesn't know that the `!Array.isArray`
|
|
783
|
+
// check above guarantees we have an array to work with here, and it
|
|
784
|
+
// doesn't want to narrow the type of `flags[normalizedArg]`, so we need
|
|
785
|
+
// to grab a reference to that array and then `Array.isArray` that. Bah!
|
|
786
|
+
if (Array.isArray(targetArray)) {
|
|
787
|
+
targetArray.push(value);
|
|
788
|
+
flags.knownArgs.push(rawArg);
|
|
789
|
+
flags.knownArgs.push(value);
|
|
790
|
+
}
|
|
682
791
|
}
|
|
683
792
|
else {
|
|
684
|
-
|
|
685
|
-
|
|
793
|
+
throwCLIParsingError(rawArg, 'expected a string argument but received nothing');
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
// We're setting a number!
|
|
797
|
+
else if (readOnlyArrayHasStringMember(NUMBER_CLI_FLAGS, normalizedArg)) {
|
|
798
|
+
if (typeof value === 'string') {
|
|
799
|
+
const parsed = parseInt(value, 10);
|
|
800
|
+
if (isNaN(parsed)) {
|
|
801
|
+
throwNumberParsingError(rawArg, value);
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
flags[normalizedArg] = parsed;
|
|
805
|
+
flags.knownArgs.push(rawArg);
|
|
806
|
+
flags.knownArgs.push(value);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
810
|
+
throwCLIParsingError(rawArg, 'expected a number argument but received nothing');
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
// We're setting a value which could be either a string _or_ a number
|
|
814
|
+
else if (readOnlyArrayHasStringMember(STRING_NUMBER_CLI_FLAGS, normalizedArg)) {
|
|
815
|
+
if (typeof value === 'string') {
|
|
816
|
+
if (CLI_ARG_STRING_REGEX.test(value)) {
|
|
817
|
+
// if it matches the regex we treat it like a string
|
|
818
|
+
flags[normalizedArg] = value;
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
const parsed = Number(value);
|
|
822
|
+
if (isNaN(parsed)) {
|
|
823
|
+
// parsing didn't go so well, we gotta get out of here
|
|
824
|
+
// this is unlikely given our regex guard above
|
|
825
|
+
// but hey, this is ultimately JS so let's be safe
|
|
826
|
+
throwNumberParsingError(rawArg, value);
|
|
827
|
+
}
|
|
828
|
+
else {
|
|
829
|
+
flags[normalizedArg] = parsed;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
flags.knownArgs.push(rawArg);
|
|
833
|
+
flags.knownArgs.push(value);
|
|
834
|
+
}
|
|
835
|
+
else {
|
|
836
|
+
throwCLIParsingError(rawArg, 'expected a string or a number but received nothing');
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
// We're setting the log level, which can only be a set of specific string values
|
|
840
|
+
else if (readOnlyArrayHasStringMember(LOG_LEVEL_CLI_FLAGS, normalizedArg)) {
|
|
841
|
+
if (typeof value === 'string') {
|
|
842
|
+
if (isLogLevel(value)) {
|
|
843
|
+
flags[normalizedArg] = value;
|
|
844
|
+
flags.knownArgs.push(rawArg);
|
|
845
|
+
flags.knownArgs.push(value);
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
throwCLIParsingError(rawArg, `expected to receive a valid log level but received "${String(value)}"`);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
else {
|
|
852
|
+
throwCLIParsingError(rawArg, 'expected to receive a valid log level but received nothing');
|
|
686
853
|
}
|
|
687
|
-
flags.knownArgs.push(matchingArg);
|
|
688
|
-
flags.knownArgs.push(value);
|
|
689
854
|
}
|
|
690
855
|
};
|
|
691
856
|
/**
|
|
@@ -706,73 +871,34 @@ const parseStringNumberArg = (flags, args, configCaseName) => {
|
|
|
706
871
|
* to a number.
|
|
707
872
|
*/
|
|
708
873
|
const CLI_ARG_STRING_REGEX = /[^\d\.Ee\+\-]+/g;
|
|
874
|
+
const Empty = Symbol('Empty');
|
|
709
875
|
/**
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
* the value is correct.
|
|
876
|
+
* A little helper which tries to parse a CLI value (as opposed to a flag) off
|
|
877
|
+
* of the argument array.
|
|
713
878
|
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
if (
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
*
|
|
735
|
-
* - `--my-cli-argument value`
|
|
736
|
-
* - `--my-cli-argument=value`
|
|
737
|
-
* - `--myCliArgument value`
|
|
738
|
-
* - `--myCliArgument=value`
|
|
739
|
-
*
|
|
740
|
-
* We also check for shortened aliases, which we define for a few arguments.
|
|
741
|
-
*
|
|
742
|
-
* @param args the CLI args we're dealing with
|
|
743
|
-
* @param configCaseName the ConfigFlag key which we're looking to pull out a value for
|
|
744
|
-
* @returns the value for the flag as well as the exact string which it matched from
|
|
745
|
-
* the user input.
|
|
746
|
-
*/
|
|
747
|
-
const getValue = (args, configCaseName) => {
|
|
748
|
-
// for some CLI args we have a short alias, like 'c' for 'config'
|
|
749
|
-
const alias = CLI_ARG_ALIASES[configCaseName];
|
|
750
|
-
// we support supplying arguments in both dash-case and configCase
|
|
751
|
-
// for ease of use
|
|
752
|
-
const dashCaseName = toDashCase(configCaseName);
|
|
753
|
-
let value;
|
|
754
|
-
let matchingArg;
|
|
755
|
-
args.forEach((arg, i) => {
|
|
756
|
-
if (arg.startsWith(`--${dashCaseName}=`) || arg.startsWith(`--${configCaseName}=`)) {
|
|
757
|
-
// our argument was passed at the command-line in the format --argName=arg-value
|
|
758
|
-
[matchingArg, value] = parseEqualsArg(arg);
|
|
759
|
-
}
|
|
760
|
-
else if (arg === `--${dashCaseName}` || arg === `--${configCaseName}`) {
|
|
761
|
-
// the next value in the array is assumed to be a value for this argument
|
|
762
|
-
value = args[i + 1];
|
|
763
|
-
matchingArg = arg;
|
|
764
|
-
}
|
|
765
|
-
else if (alias) {
|
|
766
|
-
if (arg.startsWith(`-${alias}=`)) {
|
|
767
|
-
[matchingArg, value] = parseEqualsArg(arg);
|
|
768
|
-
}
|
|
769
|
-
else if (arg === `-${alias}`) {
|
|
770
|
-
value = args[i + 1];
|
|
771
|
-
matchingArg = arg;
|
|
772
|
-
}
|
|
879
|
+
* We support a variety of different argument formats, but all of them start
|
|
880
|
+
* with `-`, so we can check the first character to test whether the next token
|
|
881
|
+
* in our array of CLI arguments is a flag name or a value.
|
|
882
|
+
*
|
|
883
|
+
* @param args an array of CLI args
|
|
884
|
+
* @returns either a string result or an Empty sentinel
|
|
885
|
+
*/
|
|
886
|
+
const parseCLIValue = (args) => {
|
|
887
|
+
// it's possible the arguments array is empty, if so, return empty
|
|
888
|
+
if (args[0] === undefined) {
|
|
889
|
+
return Empty;
|
|
890
|
+
}
|
|
891
|
+
// all we're concerned with here is that it does not start with `"-"`,
|
|
892
|
+
// which would indicate it should be parsed as a CLI flag and not a value.
|
|
893
|
+
if (!args[0].startsWith('-')) {
|
|
894
|
+
// It's not a flag, so we return the value and defer any specific parsing
|
|
895
|
+
// until later on.
|
|
896
|
+
const value = args.shift();
|
|
897
|
+
if (typeof value === 'string') {
|
|
898
|
+
return value;
|
|
773
899
|
}
|
|
774
|
-
}
|
|
775
|
-
return
|
|
900
|
+
}
|
|
901
|
+
return Empty;
|
|
776
902
|
};
|
|
777
903
|
/**
|
|
778
904
|
* Parse an 'equals' argument, which is a CLI argument-value pair in the
|
|
@@ -808,8 +934,9 @@ const getValue = (args, configCaseName) => {
|
|
|
808
934
|
* @returns a tuple containing the arg name and the value (if present)
|
|
809
935
|
*/
|
|
810
936
|
const parseEqualsArg = (arg) => {
|
|
811
|
-
const [originalArg, ...
|
|
812
|
-
|
|
937
|
+
const [originalArg, ...splitSections] = arg.split('=');
|
|
938
|
+
const value = splitSections.join('=');
|
|
939
|
+
return [originalArg, value === '' ? Empty : value];
|
|
813
940
|
};
|
|
814
941
|
/**
|
|
815
942
|
* Small helper for getting type-system-level assurance that a `string` can be
|
|
@@ -818,18 +945,51 @@ const parseEqualsArg = (arg) => {
|
|
|
818
945
|
* @param maybeLogLevel the string to check
|
|
819
946
|
* @returns whether this is a `LogLevel`
|
|
820
947
|
*/
|
|
821
|
-
const isLogLevel = (maybeLogLevel) =>
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
948
|
+
const isLogLevel = (maybeLogLevel) => readOnlyArrayHasStringMember(LOG_LEVELS, maybeLogLevel);
|
|
949
|
+
/**
|
|
950
|
+
* A little helper for constructing and throwing an error message with info
|
|
951
|
+
* about what went wrong
|
|
952
|
+
*
|
|
953
|
+
* @param flag the flag which encountered the error
|
|
954
|
+
* @param message a message specific to the error which was encountered
|
|
955
|
+
*/
|
|
956
|
+
const throwCLIParsingError = (flag, message) => {
|
|
957
|
+
throw new Error(`when parsing CLI flag "${flag}": ${message}`);
|
|
958
|
+
};
|
|
959
|
+
/**
|
|
960
|
+
* Throw a specific error for the situation where we ran into an issue parsing
|
|
961
|
+
* a number.
|
|
962
|
+
*
|
|
963
|
+
* @param flag the flag for which we encountered the issue
|
|
964
|
+
* @param value what we were trying to parse
|
|
965
|
+
*/
|
|
966
|
+
const throwNumberParsingError = (flag, value) => {
|
|
967
|
+
throwCLIParsingError(flag, `expected a number but received "${value}"`);
|
|
968
|
+
};
|
|
969
|
+
/**
|
|
970
|
+
* A little helper to 'dereference' a flag alias, which if you squint a little
|
|
971
|
+
* you can think of like a pointer to a full flag name. Thus 'c' is like a
|
|
972
|
+
* pointer to 'config', so here we're doing something like `*c`. Of course, this
|
|
973
|
+
* being JS, this is just a metaphor!
|
|
974
|
+
*
|
|
975
|
+
* If no 'dereference' is found for the possible alias we just return the
|
|
976
|
+
* passed string unmodified.
|
|
977
|
+
*
|
|
978
|
+
* @param maybeAlias a string which _could_ be an alias to a full flag name
|
|
979
|
+
* @returns the full aliased flag name, if found, or the passed string if not
|
|
980
|
+
*/
|
|
981
|
+
const dereferenceAlias = (maybeAlias) => {
|
|
982
|
+
const possibleDereference = CLI_FLAG_ALIASES[maybeAlias];
|
|
983
|
+
if (typeof possibleDereference === 'string') {
|
|
984
|
+
return possibleDereference;
|
|
985
|
+
}
|
|
986
|
+
return maybeAlias;
|
|
987
|
+
};
|
|
828
988
|
|
|
829
989
|
const dependencies = [
|
|
830
990
|
{
|
|
831
991
|
name: "@rindo/core",
|
|
832
|
-
version: "2.
|
|
992
|
+
version: "2.22.2",
|
|
833
993
|
main: "compiler/rindo.js",
|
|
834
994
|
resources: [
|
|
835
995
|
"package.json",
|
|
@@ -866,13 +1026,16 @@ const dependencies = [
|
|
|
866
1026
|
"compiler/lib.es2019.array.d.ts",
|
|
867
1027
|
"compiler/lib.es2019.d.ts",
|
|
868
1028
|
"compiler/lib.es2019.full.d.ts",
|
|
1029
|
+
"compiler/lib.es2019.intl.d.ts",
|
|
869
1030
|
"compiler/lib.es2019.object.d.ts",
|
|
870
1031
|
"compiler/lib.es2019.string.d.ts",
|
|
871
1032
|
"compiler/lib.es2019.symbol.d.ts",
|
|
872
1033
|
"compiler/lib.es2020.bigint.d.ts",
|
|
873
1034
|
"compiler/lib.es2020.d.ts",
|
|
1035
|
+
"compiler/lib.es2020.date.d.ts",
|
|
874
1036
|
"compiler/lib.es2020.full.d.ts",
|
|
875
1037
|
"compiler/lib.es2020.intl.d.ts",
|
|
1038
|
+
"compiler/lib.es2020.number.d.ts",
|
|
876
1039
|
"compiler/lib.es2020.promise.d.ts",
|
|
877
1040
|
"compiler/lib.es2020.sharedmemory.d.ts",
|
|
878
1041
|
"compiler/lib.es2020.string.d.ts",
|
|
@@ -883,6 +1046,14 @@ const dependencies = [
|
|
|
883
1046
|
"compiler/lib.es2021.promise.d.ts",
|
|
884
1047
|
"compiler/lib.es2021.string.d.ts",
|
|
885
1048
|
"compiler/lib.es2021.weakref.d.ts",
|
|
1049
|
+
"compiler/lib.es2022.array.d.ts",
|
|
1050
|
+
"compiler/lib.es2022.d.ts",
|
|
1051
|
+
"compiler/lib.es2022.error.d.ts",
|
|
1052
|
+
"compiler/lib.es2022.full.d.ts",
|
|
1053
|
+
"compiler/lib.es2022.intl.d.ts",
|
|
1054
|
+
"compiler/lib.es2022.object.d.ts",
|
|
1055
|
+
"compiler/lib.es2022.sharedmemory.d.ts",
|
|
1056
|
+
"compiler/lib.es2022.string.d.ts",
|
|
886
1057
|
"compiler/lib.es5.d.ts",
|
|
887
1058
|
"compiler/lib.es6.d.ts",
|
|
888
1059
|
"compiler/lib.esnext.d.ts",
|
|
@@ -927,16 +1098,112 @@ const dependencies = [
|
|
|
927
1098
|
},
|
|
928
1099
|
{
|
|
929
1100
|
name: "terser",
|
|
930
|
-
version: "5.
|
|
1101
|
+
version: "5.16.1",
|
|
931
1102
|
main: "dist/bundle.min.js"
|
|
932
1103
|
},
|
|
933
1104
|
{
|
|
934
1105
|
name: "typescript",
|
|
935
|
-
version: "4.
|
|
1106
|
+
version: "4.9.4",
|
|
936
1107
|
main: "lib/typescript.js"
|
|
937
1108
|
}
|
|
938
1109
|
];
|
|
939
1110
|
|
|
1111
|
+
const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
1112
|
+
typeof require === 'function' &&
|
|
1113
|
+
!!global.process &&
|
|
1114
|
+
typeof __filename === 'string' &&
|
|
1115
|
+
(!global.origin || typeof global.origin !== 'string');
|
|
1116
|
+
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1117
|
+
|
|
1118
|
+
/**
|
|
1119
|
+
* Creates an instance of a logger
|
|
1120
|
+
* @returns the new logger instance
|
|
1121
|
+
*/
|
|
1122
|
+
const createLogger = () => {
|
|
1123
|
+
let useColors = IS_BROWSER_ENV;
|
|
1124
|
+
let level = 'info';
|
|
1125
|
+
return {
|
|
1126
|
+
enableColors: (uc) => (useColors = uc),
|
|
1127
|
+
getLevel: () => level,
|
|
1128
|
+
setLevel: (l) => (level = l),
|
|
1129
|
+
emoji: (e) => e,
|
|
1130
|
+
info: console.log.bind(console),
|
|
1131
|
+
warn: console.warn.bind(console),
|
|
1132
|
+
error: console.error.bind(console),
|
|
1133
|
+
debug: console.debug.bind(console),
|
|
1134
|
+
red: (msg) => msg,
|
|
1135
|
+
green: (msg) => msg,
|
|
1136
|
+
yellow: (msg) => msg,
|
|
1137
|
+
blue: (msg) => msg,
|
|
1138
|
+
magenta: (msg) => msg,
|
|
1139
|
+
cyan: (msg) => msg,
|
|
1140
|
+
gray: (msg) => msg,
|
|
1141
|
+
bold: (msg) => msg,
|
|
1142
|
+
dim: (msg) => msg,
|
|
1143
|
+
bgRed: (msg) => msg,
|
|
1144
|
+
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
1145
|
+
duration: () => 0,
|
|
1146
|
+
finish: () => 0,
|
|
1147
|
+
}),
|
|
1148
|
+
printDiagnostics(diagnostics) {
|
|
1149
|
+
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
1150
|
+
},
|
|
1151
|
+
};
|
|
1152
|
+
};
|
|
1153
|
+
const logDiagnostic = (diagnostic, useColors) => {
|
|
1154
|
+
let color = BLUE;
|
|
1155
|
+
let prefix = 'Build';
|
|
1156
|
+
let msg = '';
|
|
1157
|
+
if (diagnostic.level === 'error') {
|
|
1158
|
+
color = RED;
|
|
1159
|
+
prefix = 'Error';
|
|
1160
|
+
}
|
|
1161
|
+
else if (diagnostic.level === 'warn') {
|
|
1162
|
+
color = YELLOW;
|
|
1163
|
+
prefix = 'Warning';
|
|
1164
|
+
}
|
|
1165
|
+
if (diagnostic.header) {
|
|
1166
|
+
prefix = diagnostic.header;
|
|
1167
|
+
}
|
|
1168
|
+
const filePath = diagnostic.relFilePath || diagnostic.absFilePath;
|
|
1169
|
+
if (filePath) {
|
|
1170
|
+
msg += filePath;
|
|
1171
|
+
if (typeof diagnostic.lineNumber === 'number' && diagnostic.lineNumber > 0) {
|
|
1172
|
+
msg += ', line ' + diagnostic.lineNumber;
|
|
1173
|
+
if (typeof diagnostic.columnNumber === 'number' && diagnostic.columnNumber > 0) {
|
|
1174
|
+
msg += ', column ' + diagnostic.columnNumber;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
msg += '\n';
|
|
1178
|
+
}
|
|
1179
|
+
msg += diagnostic.messageText;
|
|
1180
|
+
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
1181
|
+
diagnostic.lines.forEach((l) => {
|
|
1182
|
+
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
1183
|
+
});
|
|
1184
|
+
msg += '\n';
|
|
1185
|
+
}
|
|
1186
|
+
if (useColors) {
|
|
1187
|
+
const styledPrefix = [
|
|
1188
|
+
'%c' + prefix,
|
|
1189
|
+
`background: ${color}; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;`,
|
|
1190
|
+
];
|
|
1191
|
+
console.log(...styledPrefix, msg);
|
|
1192
|
+
}
|
|
1193
|
+
else if (diagnostic.level === 'error') {
|
|
1194
|
+
console.error(msg);
|
|
1195
|
+
}
|
|
1196
|
+
else if (diagnostic.level === 'warn') {
|
|
1197
|
+
console.warn(msg);
|
|
1198
|
+
}
|
|
1199
|
+
else {
|
|
1200
|
+
console.log(msg);
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
const YELLOW = `#f39c12`;
|
|
1204
|
+
const RED = `#c0392b`;
|
|
1205
|
+
const BLUE = `#3498db`;
|
|
1206
|
+
|
|
940
1207
|
/**
|
|
941
1208
|
* Attempt to find a Rindo configuration file on the file system
|
|
942
1209
|
* @param opts the options needed to find the configuration file
|
|
@@ -945,11 +1212,7 @@ const dependencies = [
|
|
|
945
1212
|
const findConfig = async (opts) => {
|
|
946
1213
|
const sys = opts.sys;
|
|
947
1214
|
const cwd = sys.getCurrentDirectory();
|
|
948
|
-
const
|
|
949
|
-
configPath: null,
|
|
950
|
-
rootDir: normalizePath(cwd),
|
|
951
|
-
diagnostics: [],
|
|
952
|
-
};
|
|
1215
|
+
const rootDir = normalizePath(cwd);
|
|
953
1216
|
let configPath = opts.configPath;
|
|
954
1217
|
if (isString(configPath)) {
|
|
955
1218
|
if (!sys.platformPath.isAbsolute(configPath)) {
|
|
@@ -964,8 +1227,13 @@ const findConfig = async (opts) => {
|
|
|
964
1227
|
}
|
|
965
1228
|
else {
|
|
966
1229
|
// nothing was passed in, use the current working directory
|
|
967
|
-
configPath =
|
|
1230
|
+
configPath = rootDir;
|
|
968
1231
|
}
|
|
1232
|
+
const results = {
|
|
1233
|
+
configPath,
|
|
1234
|
+
rootDir: normalizePath(cwd),
|
|
1235
|
+
diagnostics: [],
|
|
1236
|
+
};
|
|
969
1237
|
const stat = await sys.stat(configPath);
|
|
970
1238
|
if (stat.error) {
|
|
971
1239
|
const diagnostic = buildError(results.diagnostics);
|
|
@@ -998,12 +1266,33 @@ const loadCoreCompiler = async (sys) => {
|
|
|
998
1266
|
return globalThis.rindo;
|
|
999
1267
|
};
|
|
1000
1268
|
|
|
1269
|
+
/**
|
|
1270
|
+
* Log the name of this package (`@rindo/core`) to an output stream
|
|
1271
|
+
*
|
|
1272
|
+
* The output stream is determined by the {@link Logger} instance that is provided as an argument to this function
|
|
1273
|
+
*
|
|
1274
|
+
* The name of the package may not be logged, by design, for certain `task` types and logging levels
|
|
1275
|
+
*
|
|
1276
|
+
* @param logger the logging entity to use to output the name of the package
|
|
1277
|
+
* @param task the current task
|
|
1278
|
+
*/
|
|
1001
1279
|
const startupLog = (logger, task) => {
|
|
1002
1280
|
if (task === 'info' || task === 'serve' || task === 'version') {
|
|
1003
1281
|
return;
|
|
1004
1282
|
}
|
|
1005
1283
|
logger.info(logger.cyan(`@rindo/core`));
|
|
1006
1284
|
};
|
|
1285
|
+
/**
|
|
1286
|
+
* Log this package's version to an output stream
|
|
1287
|
+
*
|
|
1288
|
+
* The output stream is determined by the {@link Logger} instance that is provided as an argument to this function
|
|
1289
|
+
*
|
|
1290
|
+
* The package version may not be logged, by design, for certain `task` types and logging levels
|
|
1291
|
+
*
|
|
1292
|
+
* @param logger the logging entity to use for output
|
|
1293
|
+
* @param task the current task
|
|
1294
|
+
* @param coreCompiler the compiler instance to derive version information from
|
|
1295
|
+
*/
|
|
1007
1296
|
const startupLogVersion = (logger, task, coreCompiler) => {
|
|
1008
1297
|
if (task === 'info' || task === 'serve' || task === 'version') {
|
|
1009
1298
|
return;
|
|
@@ -1019,11 +1308,25 @@ const startupLogVersion = (logger, task, coreCompiler) => {
|
|
|
1019
1308
|
startupMsg += logger.emoji(' ' + coreCompiler.vermoji);
|
|
1020
1309
|
logger.info(startupMsg);
|
|
1021
1310
|
};
|
|
1311
|
+
/**
|
|
1312
|
+
* Log details from a {@link CompilerSystem} used by Rindo to an output stream
|
|
1313
|
+
*
|
|
1314
|
+
* The output stream is determined by the {@link Logger} instance that is provided as an argument to this function
|
|
1315
|
+
*
|
|
1316
|
+
* @param sys the `CompilerSystem` to report details on
|
|
1317
|
+
* @param logger the logging entity to use for output
|
|
1318
|
+
* @param flags user set flags for the current invocation of Rindo
|
|
1319
|
+
* @param coreCompiler the compiler instance being used for this invocation of Rindo
|
|
1320
|
+
*/
|
|
1022
1321
|
const loadedCompilerLog = (sys, logger, flags, coreCompiler) => {
|
|
1023
1322
|
const sysDetails = sys.details;
|
|
1024
1323
|
const runtimeInfo = `${sys.name} ${sys.version}`;
|
|
1025
|
-
const platformInfo =
|
|
1026
|
-
|
|
1324
|
+
const platformInfo = sysDetails
|
|
1325
|
+
? `${sysDetails.platform}, ${sysDetails.cpuModel}`
|
|
1326
|
+
: `Unknown Platform, Unknown CPU Model`;
|
|
1327
|
+
const statsInfo = sysDetails
|
|
1328
|
+
? `cpus: ${sys.hardwareConcurrency}, freemem: ${Math.round(sysDetails.freemem() / 1000000)}MB, totalmem: ${Math.round(sysDetails.totalmem / 1000000)}MB`
|
|
1329
|
+
: 'Unknown CPU Core Count, Unknown Memory';
|
|
1027
1330
|
if (logger.getLevel() === 'debug') {
|
|
1028
1331
|
logger.debug(runtimeInfo);
|
|
1029
1332
|
logger.debug(platformInfo);
|
|
@@ -1037,6 +1340,14 @@ const loadedCompilerLog = (sys, logger, flags, coreCompiler) => {
|
|
|
1037
1340
|
logger.info(statsInfo);
|
|
1038
1341
|
}
|
|
1039
1342
|
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Log various warnings to an output stream
|
|
1345
|
+
*
|
|
1346
|
+
* The output stream is determined by the {@link Logger} instance attached to the `config` argument to this function
|
|
1347
|
+
*
|
|
1348
|
+
* @param coreCompiler the compiler instance being used for this invocation of Rindo
|
|
1349
|
+
* @param config a validated configuration object to be used for this run of Rindo
|
|
1350
|
+
*/
|
|
1040
1351
|
const startupCompilerLog = (coreCompiler, config) => {
|
|
1041
1352
|
if (config.suppressLogs === true) {
|
|
1042
1353
|
return;
|
|
@@ -1058,6 +1369,21 @@ const startupCompilerLog = (coreCompiler, config) => {
|
|
|
1058
1369
|
}
|
|
1059
1370
|
};
|
|
1060
1371
|
|
|
1372
|
+
const startCheckVersion = async (config, currentVersion) => {
|
|
1373
|
+
if (config.devMode && !config.flags.ci && !currentVersion.includes('-dev.') && isFunction(config.sys.checkVersion)) {
|
|
1374
|
+
return config.sys.checkVersion(config.logger, currentVersion);
|
|
1375
|
+
}
|
|
1376
|
+
return null;
|
|
1377
|
+
};
|
|
1378
|
+
const printCheckVersionResults = async (versionChecker) => {
|
|
1379
|
+
if (versionChecker) {
|
|
1380
|
+
const checkVersionResults = await versionChecker;
|
|
1381
|
+
if (isFunction(checkVersionResults)) {
|
|
1382
|
+
checkVersionResults();
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
1386
|
+
|
|
1061
1387
|
const taskPrerender = async (coreCompiler, config) => {
|
|
1062
1388
|
startupCompilerLog(coreCompiler, config);
|
|
1063
1389
|
const hydrateAppFilePath = config.flags.unknownArgs[0];
|
|
@@ -1089,21 +1415,6 @@ const runPrerenderTask = async (coreCompiler, config, hydrateAppFilePath, compon
|
|
|
1089
1415
|
return diagnostics;
|
|
1090
1416
|
};
|
|
1091
1417
|
|
|
1092
|
-
const startCheckVersion = async (config, currentVersion) => {
|
|
1093
|
-
if (config.devMode && !config.flags.ci && !currentVersion.includes('-dev.') && isFunction(config.sys.checkVersion)) {
|
|
1094
|
-
return config.sys.checkVersion(config.logger, currentVersion);
|
|
1095
|
-
}
|
|
1096
|
-
return null;
|
|
1097
|
-
};
|
|
1098
|
-
const printCheckVersionResults = async (versionChecker) => {
|
|
1099
|
-
if (versionChecker) {
|
|
1100
|
-
const checkVersionResults = await versionChecker;
|
|
1101
|
-
if (isFunction(checkVersionResults)) {
|
|
1102
|
-
checkVersionResults();
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
};
|
|
1106
|
-
|
|
1107
1418
|
const taskWatch = async (coreCompiler, config) => {
|
|
1108
1419
|
let devServer = null;
|
|
1109
1420
|
let exitCode = 0;
|
|
@@ -1150,6 +1461,15 @@ const taskWatch = async (coreCompiler, config) => {
|
|
|
1150
1461
|
}
|
|
1151
1462
|
};
|
|
1152
1463
|
|
|
1464
|
+
const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
|
|
1465
|
+
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
1466
|
+
const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
|
|
1467
|
+
const DOCS_CUSTOM = 'docs-custom';
|
|
1468
|
+
const DOCS_JSON = 'docs-json';
|
|
1469
|
+
const DOCS_README = 'docs-readme';
|
|
1470
|
+
const DOCS_VSCODE = 'docs-vscode';
|
|
1471
|
+
const WWW = 'www';
|
|
1472
|
+
|
|
1153
1473
|
const tryFn = async (fn, ...args) => {
|
|
1154
1474
|
try {
|
|
1155
1475
|
return await fn(...args);
|
|
@@ -1163,12 +1483,12 @@ const isInteractive = (sys, flags, object) => {
|
|
|
1163
1483
|
const terminalInfo = object ||
|
|
1164
1484
|
Object.freeze({
|
|
1165
1485
|
tty: sys.isTTY() ? true : false,
|
|
1166
|
-
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!flags.ci,
|
|
1486
|
+
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => { var _a; return !!((_a = sys.getEnvironmentVar) === null || _a === void 0 ? void 0 : _a.call(sys, v)); }).length > 0 || !!flags.ci,
|
|
1167
1487
|
});
|
|
1168
1488
|
return terminalInfo.tty && !terminalInfo.ci;
|
|
1169
1489
|
};
|
|
1170
1490
|
const UUID_REGEX = new RegExp(/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i);
|
|
1171
|
-
// Plucked from https://github.com/
|
|
1491
|
+
// Plucked from https://github.com/familyjs/jigra/blob/HEAD/cli/src/util/uuid.ts
|
|
1172
1492
|
function uuidv4() {
|
|
1173
1493
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
1174
1494
|
const r = (Math.random() * 16) | 0;
|
|
@@ -1192,7 +1512,7 @@ async function readJson(sys, path) {
|
|
|
1192
1512
|
* @returns true if --debug has been passed, otherwise false
|
|
1193
1513
|
*/
|
|
1194
1514
|
function hasDebug(flags) {
|
|
1195
|
-
return flags.debug;
|
|
1515
|
+
return !!flags.debug;
|
|
1196
1516
|
}
|
|
1197
1517
|
/**
|
|
1198
1518
|
* Does the command have the verbose and debug flags?
|
|
@@ -1200,25 +1520,14 @@ function hasDebug(flags) {
|
|
|
1200
1520
|
* @returns true if both --debug and --verbose have been passed, otherwise false
|
|
1201
1521
|
*/
|
|
1202
1522
|
function hasVerbose(flags) {
|
|
1203
|
-
return flags.verbose && hasDebug(flags);
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
/**
|
|
1207
|
-
* Used to determine if tracking should occur.
|
|
1208
|
-
* @param config The config passed into the Rindo command
|
|
1209
|
-
* @param sys The system where the command is invoked
|
|
1210
|
-
* @param ci whether or not the process is running in a Continuous Integration (CI) environment
|
|
1211
|
-
* @returns true if telemetry should be sent, false otherwise
|
|
1212
|
-
*/
|
|
1213
|
-
async function shouldTrack(config, sys, ci) {
|
|
1214
|
-
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
1523
|
+
return !!flags.verbose && hasDebug(flags);
|
|
1215
1524
|
}
|
|
1216
1525
|
|
|
1217
1526
|
const isTest$1 = () => process.env.JEST_WORKER_ID !== undefined;
|
|
1218
|
-
const defaultConfig = (sys) => sys.resolvePath(`${sys.homeDir()}/.
|
|
1219
|
-
const defaultConfigDirectory = (sys) => sys.resolvePath(`${sys.homeDir()}/.
|
|
1527
|
+
const defaultConfig = (sys) => sys.resolvePath(`${sys.homeDir()}/.family/${isTest$1() ? 'tmp-config.json' : 'config.json'}`);
|
|
1528
|
+
const defaultConfigDirectory = (sys) => sys.resolvePath(`${sys.homeDir()}/.family`);
|
|
1220
1529
|
/**
|
|
1221
|
-
* Reads an
|
|
1530
|
+
* Reads an Family configuration file from disk, parses it, and performs any necessary corrections to it if certain
|
|
1222
1531
|
* values are deemed to be malformed
|
|
1223
1532
|
* @param sys The system where the command is invoked
|
|
1224
1533
|
* @returns the config read from disk that has been potentially been updated
|
|
@@ -1232,7 +1541,7 @@ async function readConfig(sys) {
|
|
|
1232
1541
|
};
|
|
1233
1542
|
await writeConfig(sys, config);
|
|
1234
1543
|
}
|
|
1235
|
-
else if (!UUID_REGEX.test(config['tokens.telemetry'])) {
|
|
1544
|
+
else if (!config['tokens.telemetry'] || !UUID_REGEX.test(config['tokens.telemetry'])) {
|
|
1236
1545
|
const newUuid = uuidv4();
|
|
1237
1546
|
await writeConfig(sys, { ...config, 'tokens.telemetry': newUuid });
|
|
1238
1547
|
config['tokens.telemetry'] = newUuid;
|
|
@@ -1240,7 +1549,7 @@ async function readConfig(sys) {
|
|
|
1240
1549
|
return config;
|
|
1241
1550
|
}
|
|
1242
1551
|
/**
|
|
1243
|
-
* Writes an
|
|
1552
|
+
* Writes an Family configuration file to disk.
|
|
1244
1553
|
* @param sys The system where the command is invoked
|
|
1245
1554
|
* @param config The config passed into the Rindo command
|
|
1246
1555
|
* @returns boolean If the command was successful
|
|
@@ -1258,7 +1567,7 @@ async function writeConfig(sys, config) {
|
|
|
1258
1567
|
return result;
|
|
1259
1568
|
}
|
|
1260
1569
|
/**
|
|
1261
|
-
* Update a subset of the
|
|
1570
|
+
* Update a subset of the Family config.
|
|
1262
1571
|
* @param sys The system where the command is invoked
|
|
1263
1572
|
* @param newOptions The new options to save
|
|
1264
1573
|
* @returns boolean If the command was successful
|
|
@@ -1268,14 +1577,16 @@ async function updateConfig(sys, newOptions) {
|
|
|
1268
1577
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
1269
1578
|
}
|
|
1270
1579
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1580
|
+
/**
|
|
1581
|
+
* Used to determine if tracking should occur.
|
|
1582
|
+
* @param config The config passed into the Rindo command
|
|
1583
|
+
* @param sys The system where the command is invoked
|
|
1584
|
+
* @param ci whether or not the process is running in a Continuous Integration (CI) environment
|
|
1585
|
+
* @returns true if telemetry should be sent, false otherwise
|
|
1586
|
+
*/
|
|
1587
|
+
async function shouldTrack(config, sys, ci) {
|
|
1588
|
+
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
1589
|
+
}
|
|
1279
1590
|
|
|
1280
1591
|
/**
|
|
1281
1592
|
* Used to within taskBuild to provide the component_count property.
|
|
@@ -1286,11 +1597,11 @@ const WWW = 'www';
|
|
|
1286
1597
|
* @param result The results of a compiler build.
|
|
1287
1598
|
*/
|
|
1288
1599
|
async function telemetryBuildFinishedAction(sys, config, coreCompiler, result) {
|
|
1289
|
-
const tracking = await shouldTrack(config, sys, config.flags.ci);
|
|
1600
|
+
const tracking = await shouldTrack(config, sys, !!config.flags.ci);
|
|
1290
1601
|
if (!tracking) {
|
|
1291
1602
|
return;
|
|
1292
1603
|
}
|
|
1293
|
-
const component_count = Object.keys(result.componentGraph).length;
|
|
1604
|
+
const component_count = result.componentGraph ? Object.keys(result.componentGraph).length : undefined;
|
|
1294
1605
|
const data = await prepareData(coreCompiler, config, sys, result.duration, component_count);
|
|
1295
1606
|
await sendMetric(sys, config, 'rindo_cli_command', data);
|
|
1296
1607
|
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
@@ -1369,38 +1680,41 @@ function getActiveTargets(config) {
|
|
|
1369
1680
|
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1370
1681
|
*/
|
|
1371
1682
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1683
|
+
var _a, _b, _c;
|
|
1372
1684
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1373
1685
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
1374
1686
|
const targets = getActiveTargets(config);
|
|
1375
1687
|
const yarn = isUsingYarn(sys);
|
|
1376
1688
|
const rindo = coreCompiler.version || 'unknown';
|
|
1377
1689
|
const system = `${sys.name} ${sys.version}`;
|
|
1378
|
-
const os_name = sys.details.platform;
|
|
1379
|
-
const os_version = sys.details.release;
|
|
1380
|
-
const cpu_model = sys.details.cpuModel;
|
|
1690
|
+
const os_name = (_a = sys.details) === null || _a === void 0 ? void 0 : _a.platform;
|
|
1691
|
+
const os_version = (_b = sys.details) === null || _b === void 0 ? void 0 : _b.release;
|
|
1692
|
+
const cpu_model = (_c = sys.details) === null || _c === void 0 ? void 0 : _c.cpuModel;
|
|
1381
1693
|
const build = coreCompiler.buildId || 'unknown';
|
|
1382
1694
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1383
1695
|
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1696
|
+
const is_browser_env = IS_BROWSER_ENV;
|
|
1384
1697
|
return {
|
|
1385
|
-
|
|
1386
|
-
|
|
1698
|
+
arguments: config.flags.args,
|
|
1699
|
+
build,
|
|
1387
1700
|
component_count,
|
|
1388
|
-
|
|
1701
|
+
config: anonymizedConfig,
|
|
1702
|
+
cpu_model,
|
|
1703
|
+
duration_ms,
|
|
1704
|
+
has_app_pwa_config,
|
|
1705
|
+
is_browser_env,
|
|
1706
|
+
os_name,
|
|
1707
|
+
os_version,
|
|
1389
1708
|
packages,
|
|
1390
1709
|
packages_no_versions: packagesNoVersions,
|
|
1391
|
-
|
|
1392
|
-
task: config.flags.task,
|
|
1710
|
+
rollup,
|
|
1393
1711
|
rindo,
|
|
1394
1712
|
system,
|
|
1395
1713
|
system_major: getMajorVersion(system),
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
cpu_model,
|
|
1399
|
-
build,
|
|
1714
|
+
targets,
|
|
1715
|
+
task: config.flags.task,
|
|
1400
1716
|
typescript,
|
|
1401
|
-
|
|
1402
|
-
has_app_pwa_config,
|
|
1403
|
-
config: anonymizedConfig,
|
|
1717
|
+
yarn,
|
|
1404
1718
|
};
|
|
1405
1719
|
};
|
|
1406
1720
|
// props in output targets for which we retain their original values when
|
|
@@ -1424,7 +1738,16 @@ const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
|
1424
1738
|
// Props we delete entirely from the config for telemetry
|
|
1425
1739
|
//
|
|
1426
1740
|
// TODO: Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1427
|
-
const CONFIG_PROPS_TO_DELETE = [
|
|
1741
|
+
const CONFIG_PROPS_TO_DELETE = [
|
|
1742
|
+
'commonjs',
|
|
1743
|
+
'devServer',
|
|
1744
|
+
'env',
|
|
1745
|
+
'logger',
|
|
1746
|
+
'rollupConfig',
|
|
1747
|
+
'sys',
|
|
1748
|
+
'testing',
|
|
1749
|
+
'tsCompilerOptions',
|
|
1750
|
+
];
|
|
1428
1751
|
/**
|
|
1429
1752
|
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1430
1753
|
* with a placeholder string if they are present (this lets us still track how frequently
|
|
@@ -1474,7 +1797,7 @@ const anonymizeConfigForTelemetry = (config) => {
|
|
|
1474
1797
|
/**
|
|
1475
1798
|
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1476
1799
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1477
|
-
* of each package under the @rindo, @
|
|
1800
|
+
* of each package under the @rindo, @familyjs, and @jigra scopes.
|
|
1478
1801
|
*
|
|
1479
1802
|
* @param sys the system instance where telemetry is invoked
|
|
1480
1803
|
* @param config the Rindo configuration associated with the current task that triggered telemetry
|
|
@@ -1496,16 +1819,16 @@ async function getInstalledPackages(sys, config) {
|
|
|
1496
1819
|
...packageJson.devDependencies,
|
|
1497
1820
|
...packageJson.dependencies,
|
|
1498
1821
|
});
|
|
1499
|
-
// Collect packages only in the rindo,
|
|
1822
|
+
// Collect packages only in the rindo, familyjs, or jigra org's:
|
|
1500
1823
|
// https://www.npmjs.com/org/rindo
|
|
1501
|
-
const
|
|
1824
|
+
const familyPackages = rawPackages.filter(([k]) => k.startsWith('@rindo/') || k.startsWith('@familyjs/') || k.startsWith('@jigra/'));
|
|
1502
1825
|
try {
|
|
1503
|
-
packages = yarn ? await yarnPackages(sys,
|
|
1826
|
+
packages = yarn ? await yarnPackages(sys, familyPackages) : await npmPackages(sys, familyPackages);
|
|
1504
1827
|
}
|
|
1505
1828
|
catch (e) {
|
|
1506
|
-
packages =
|
|
1829
|
+
packages = familyPackages.map(([k, v]) => `${k}@${v.replace('^', '')}`);
|
|
1507
1830
|
}
|
|
1508
|
-
packagesNoVersions =
|
|
1831
|
+
packagesNoVersions = familyPackages.map(([k]) => `${k}`);
|
|
1509
1832
|
return { packages, packagesNoVersions };
|
|
1510
1833
|
}
|
|
1511
1834
|
catch (err) {
|
|
@@ -1516,13 +1839,13 @@ async function getInstalledPackages(sys, config) {
|
|
|
1516
1839
|
/**
|
|
1517
1840
|
* Visits the npm lock file to find the exact versions that are installed
|
|
1518
1841
|
* @param sys The system where the command is invoked
|
|
1519
|
-
* @param
|
|
1842
|
+
* @param familyPackages a list of the found packages matching `@rindo`, `@jigra`, or `@familyjs` from the package.json file.
|
|
1520
1843
|
* @returns an array of strings of all the packages and their versions.
|
|
1521
1844
|
*/
|
|
1522
|
-
async function npmPackages(sys,
|
|
1845
|
+
async function npmPackages(sys, familyPackages) {
|
|
1523
1846
|
const appRootDir = sys.getCurrentDirectory();
|
|
1524
1847
|
const packageLockJson = await tryFn(readJson, sys, sys.resolvePath(appRootDir + '/package-lock.json'));
|
|
1525
|
-
return
|
|
1848
|
+
return familyPackages.map(([k, v]) => {
|
|
1526
1849
|
var _a, _b, _c, _d;
|
|
1527
1850
|
let version = (_d = (_b = (_a = packageLockJson === null || packageLockJson === void 0 ? void 0 : packageLockJson.dependencies[k]) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : (_c = packageLockJson === null || packageLockJson === void 0 ? void 0 : packageLockJson.devDependencies[k]) === null || _c === void 0 ? void 0 : _c.version) !== null && _d !== void 0 ? _d : v;
|
|
1528
1851
|
version = version.includes('file:') ? sanitizeDeclaredVersion(v) : version;
|
|
@@ -1532,14 +1855,14 @@ async function npmPackages(sys, navifyPackages) {
|
|
|
1532
1855
|
/**
|
|
1533
1856
|
* Visits the yarn lock file to find the exact versions that are installed
|
|
1534
1857
|
* @param sys The system where the command is invoked
|
|
1535
|
-
* @param
|
|
1858
|
+
* @param familyPackages a list of the found packages matching `@rindo`, `@jigra`, or `@familyjs` from the package.json file.
|
|
1536
1859
|
* @returns an array of strings of all the packages and their versions.
|
|
1537
1860
|
*/
|
|
1538
|
-
async function yarnPackages(sys,
|
|
1861
|
+
async function yarnPackages(sys, familyPackages) {
|
|
1539
1862
|
const appRootDir = sys.getCurrentDirectory();
|
|
1540
1863
|
const yarnLock = sys.readFileSync(sys.resolvePath(appRootDir + '/yarn.lock'));
|
|
1541
1864
|
const yarnLockYml = sys.parseYarnLockFile(yarnLock);
|
|
1542
|
-
return
|
|
1865
|
+
return familyPackages.map(([k, v]) => {
|
|
1543
1866
|
var _a;
|
|
1544
1867
|
const identifiedVersion = `${k}@${v}`;
|
|
1545
1868
|
let version = (_a = yarnLockYml.object[identifiedVersion]) === null || _a === void 0 ? void 0 : _a.version;
|
|
@@ -1604,7 +1927,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1604
1927
|
sent_at: now,
|
|
1605
1928
|
};
|
|
1606
1929
|
// This request is only made if telemetry is on.
|
|
1607
|
-
const response = await sys.fetch('https://api
|
|
1930
|
+
const response = await sys.fetch('https://familyjs-api.web.app/events/metrics', {
|
|
1608
1931
|
method: 'POST',
|
|
1609
1932
|
headers: {
|
|
1610
1933
|
'Content-Type': 'application/json',
|
|
@@ -1707,13 +2030,6 @@ const taskDocs = async (coreCompiler, config) => {
|
|
|
1707
2030
|
await compiler.destroy();
|
|
1708
2031
|
};
|
|
1709
2032
|
|
|
1710
|
-
const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
1711
|
-
typeof require === 'function' &&
|
|
1712
|
-
!!global.process &&
|
|
1713
|
-
typeof __filename === 'string' &&
|
|
1714
|
-
(!global.origin || typeof global.origin !== 'string');
|
|
1715
|
-
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1716
|
-
|
|
1717
2033
|
/**
|
|
1718
2034
|
* Task to generate component boilerplate and write it to disk. This task can
|
|
1719
2035
|
* cause the program to exit with an error under various circumstances, such as
|
|
@@ -1742,13 +2058,24 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1742
2058
|
const { prompt } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('../sys/node/prompts.js')); });
|
|
1743
2059
|
const input = config.flags.unknownArgs.find((arg) => !arg.startsWith('-')) ||
|
|
1744
2060
|
(await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName;
|
|
2061
|
+
if (undefined === input) {
|
|
2062
|
+
// in some shells (e.g. Windows PowerShell), hitting Ctrl+C results in a TypeError printed to the console.
|
|
2063
|
+
// explicitly return here to avoid printing the error message.
|
|
2064
|
+
return;
|
|
2065
|
+
}
|
|
1745
2066
|
const { dir, base: componentName } = path.parse(input);
|
|
1746
2067
|
const tagError = validateComponentTag(componentName);
|
|
1747
2068
|
if (tagError) {
|
|
1748
2069
|
config.logger.error(tagError);
|
|
1749
2070
|
return config.sys.exit(1);
|
|
1750
2071
|
}
|
|
1751
|
-
const
|
|
2072
|
+
const filesToGenerateExt = await chooseFilesToGenerate();
|
|
2073
|
+
if (undefined === filesToGenerateExt) {
|
|
2074
|
+
// in some shells (e.g. Windows PowerShell), hitting Ctrl+C results in a TypeError printed to the console.
|
|
2075
|
+
// explicitly return here to avoid printing the error message.
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
const extensionsToGenerate = ['tsx', ...filesToGenerateExt];
|
|
1752
2079
|
const testFolder = extensionsToGenerate.some(isTest) ? 'test' : '';
|
|
1753
2080
|
const outDir = path.join(absoluteSrcDir, 'components', dir, componentName);
|
|
1754
2081
|
await config.sys.createDir(path.join(outDir, testFolder), { recursive: true });
|
|
@@ -1972,7 +2299,7 @@ const taskTelemetry = async (flags, sys, logger) => {
|
|
|
1972
2299
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1973
2300
|
const isEnabling = flags.args.includes('on');
|
|
1974
2301
|
const isDisabling = flags.args.includes('off');
|
|
1975
|
-
const INFORMATION = `Opt in or
|
|
2302
|
+
const INFORMATION = `Opt in or out of telemetry. Information about the data we collect is available on our website: ${logger.bold('https://rindojs.web.app/telemetry')}`;
|
|
1976
2303
|
const THANK_YOU = `Thank you for helping to make Rindo better! 💖`;
|
|
1977
2304
|
const ENABLED_MESSAGE = `${logger.green('Enabled')}. ${THANK_YOU}\n\n`;
|
|
1978
2305
|
const DISABLED_MESSAGE = `${logger.red('Disabled')}\n\n`;
|
|
@@ -2095,93 +2422,54 @@ const taskServe = async (config) => {
|
|
|
2095
2422
|
};
|
|
2096
2423
|
|
|
2097
2424
|
/**
|
|
2098
|
-
*
|
|
2099
|
-
* @
|
|
2425
|
+
* Entrypoint for any Rindo tests
|
|
2426
|
+
* @param config a validated Rindo configuration entity
|
|
2100
2427
|
*/
|
|
2101
|
-
const
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
enableColors: (uc) => (useColors = uc),
|
|
2106
|
-
getLevel: () => level,
|
|
2107
|
-
setLevel: (l) => (level = l),
|
|
2108
|
-
emoji: (e) => e,
|
|
2109
|
-
info: console.log.bind(console),
|
|
2110
|
-
warn: console.warn.bind(console),
|
|
2111
|
-
error: console.error.bind(console),
|
|
2112
|
-
debug: console.debug.bind(console),
|
|
2113
|
-
red: (msg) => msg,
|
|
2114
|
-
green: (msg) => msg,
|
|
2115
|
-
yellow: (msg) => msg,
|
|
2116
|
-
blue: (msg) => msg,
|
|
2117
|
-
magenta: (msg) => msg,
|
|
2118
|
-
cyan: (msg) => msg,
|
|
2119
|
-
gray: (msg) => msg,
|
|
2120
|
-
bold: (msg) => msg,
|
|
2121
|
-
dim: (msg) => msg,
|
|
2122
|
-
bgRed: (msg) => msg,
|
|
2123
|
-
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
2124
|
-
duration: () => 0,
|
|
2125
|
-
finish: () => 0,
|
|
2126
|
-
}),
|
|
2127
|
-
printDiagnostics(diagnostics) {
|
|
2128
|
-
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
2129
|
-
},
|
|
2130
|
-
};
|
|
2131
|
-
};
|
|
2132
|
-
const logDiagnostic = (diagnostic, useColors) => {
|
|
2133
|
-
let color = BLUE;
|
|
2134
|
-
let prefix = 'Build';
|
|
2135
|
-
let msg = '';
|
|
2136
|
-
if (diagnostic.level === 'error') {
|
|
2137
|
-
color = RED;
|
|
2138
|
-
prefix = 'Error';
|
|
2139
|
-
}
|
|
2140
|
-
else if (diagnostic.level === 'warn') {
|
|
2141
|
-
color = YELLOW;
|
|
2142
|
-
prefix = 'Warning';
|
|
2143
|
-
}
|
|
2144
|
-
if (diagnostic.header) {
|
|
2145
|
-
prefix = diagnostic.header;
|
|
2428
|
+
const taskTest = async (config) => {
|
|
2429
|
+
if (!IS_NODE_ENV) {
|
|
2430
|
+
config.logger.error(`"test" command is currently only implemented for a NodeJS environment`);
|
|
2431
|
+
return config.sys.exit(1);
|
|
2146
2432
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2433
|
+
config.buildDocs = false;
|
|
2434
|
+
const testingRunOpts = {
|
|
2435
|
+
e2e: !!config.flags.e2e,
|
|
2436
|
+
screenshot: !!config.flags.screenshot,
|
|
2437
|
+
spec: !!config.flags.spec,
|
|
2438
|
+
updateScreenshot: !!config.flags.updateScreenshot,
|
|
2439
|
+
};
|
|
2440
|
+
// always ensure we have jest modules installed
|
|
2441
|
+
const ensureModuleIds = ['@types/jest', 'jest', 'jest-cli'];
|
|
2442
|
+
if (testingRunOpts.e2e) {
|
|
2443
|
+
// if it's an e2e test, also make sure we're got
|
|
2444
|
+
// puppeteer modules installed and if browserExecutablePath is provided don't download Chromium use only puppeteer-core instead
|
|
2445
|
+
const puppeteer = config.testing.browserExecutablePath ? 'puppeteer-core' : 'puppeteer';
|
|
2446
|
+
ensureModuleIds.push(puppeteer);
|
|
2447
|
+
if (testingRunOpts.screenshot) {
|
|
2448
|
+
// ensure we've got pixelmatch for screenshots
|
|
2449
|
+
config.logger.warn(config.logger.yellow(`EXPERIMENTAL: screenshot visual diff testing is currently under heavy development and has not reached a stable status. However, any assistance testing would be appreciated.`));
|
|
2155
2450
|
}
|
|
2156
|
-
msg += '\n';
|
|
2157
|
-
}
|
|
2158
|
-
msg += diagnostic.messageText;
|
|
2159
|
-
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
2160
|
-
diagnostic.lines.forEach((l) => {
|
|
2161
|
-
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
2162
|
-
});
|
|
2163
|
-
msg += '\n';
|
|
2164
2451
|
}
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
console.log(...styledPrefix, msg);
|
|
2171
|
-
}
|
|
2172
|
-
else if (diagnostic.level === 'error') {
|
|
2173
|
-
console.error(msg);
|
|
2452
|
+
// ensure we've got the required modules installed
|
|
2453
|
+
const diagnostics = await config.sys.lazyRequire.ensure(config.rootDir, ensureModuleIds);
|
|
2454
|
+
if (diagnostics.length > 0) {
|
|
2455
|
+
config.logger.printDiagnostics(diagnostics);
|
|
2456
|
+
return config.sys.exit(1);
|
|
2174
2457
|
}
|
|
2175
|
-
|
|
2176
|
-
|
|
2458
|
+
try {
|
|
2459
|
+
// let's test!
|
|
2460
|
+
const { createTesting } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('../testing/index.js')); });
|
|
2461
|
+
const testing = await createTesting(config);
|
|
2462
|
+
const passed = await testing.run(testingRunOpts);
|
|
2463
|
+
await testing.destroy();
|
|
2464
|
+
if (!passed) {
|
|
2465
|
+
return config.sys.exit(1);
|
|
2466
|
+
}
|
|
2177
2467
|
}
|
|
2178
|
-
|
|
2179
|
-
|
|
2468
|
+
catch (e) {
|
|
2469
|
+
config.logger.error(e);
|
|
2470
|
+
return config.sys.exit(1);
|
|
2180
2471
|
}
|
|
2181
|
-
};
|
|
2182
|
-
const YELLOW = `#f39c12`;
|
|
2183
|
-
const RED = `#c0392b`;
|
|
2184
|
-
const BLUE = `#3498db`;
|
|
2472
|
+
};
|
|
2185
2473
|
|
|
2186
2474
|
const run = async (init) => {
|
|
2187
2475
|
const { args, logger, sys } = init;
|
|
@@ -2197,7 +2485,7 @@ const run = async (init) => {
|
|
|
2197
2485
|
if (isFunction(sys.applyGlobalPatch)) {
|
|
2198
2486
|
sys.applyGlobalPatch(sys.getCurrentDirectory());
|
|
2199
2487
|
}
|
|
2200
|
-
if (task === 'help' || flags.help) {
|
|
2488
|
+
if (!task || task === 'help' || flags.help) {
|
|
2201
2489
|
await taskHelp(createConfigFlags({ task: 'help', args }), logger, sys);
|
|
2202
2490
|
return;
|
|
2203
2491
|
}
|
|
@@ -2266,15 +2554,16 @@ const run = async (init) => {
|
|
|
2266
2554
|
* @public
|
|
2267
2555
|
*/
|
|
2268
2556
|
const runTask = async (coreCompiler, config, task, sys) => {
|
|
2269
|
-
var _a, _b, _c, _d, _e;
|
|
2557
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2270
2558
|
const logger = (_a = config.logger) !== null && _a !== void 0 ? _a : createLogger();
|
|
2271
2559
|
const strictConfig = {
|
|
2272
2560
|
...config,
|
|
2273
2561
|
flags: createConfigFlags((_b = config.flags) !== null && _b !== void 0 ? _b : { task }),
|
|
2274
2562
|
logger,
|
|
2275
2563
|
outputTargets: (_c = config.outputTargets) !== null && _c !== void 0 ? _c : [],
|
|
2276
|
-
|
|
2277
|
-
|
|
2564
|
+
rootDir: (_d = config.rootDir) !== null && _d !== void 0 ? _d : '/',
|
|
2565
|
+
sys: (_e = sys !== null && sys !== void 0 ? sys : config.sys) !== null && _e !== void 0 ? _e : coreCompiler.createSystem({ logger }),
|
|
2566
|
+
testing: (_f = config.testing) !== null && _f !== void 0 ? _f : {},
|
|
2278
2567
|
};
|
|
2279
2568
|
switch (task) {
|
|
2280
2569
|
case 'build':
|
|
@@ -2299,6 +2588,9 @@ const runTask = async (coreCompiler, config, task, sys) => {
|
|
|
2299
2588
|
case 'telemetry':
|
|
2300
2589
|
await taskTelemetry(strictConfig.flags, sys, strictConfig.logger);
|
|
2301
2590
|
break;
|
|
2591
|
+
case 'test':
|
|
2592
|
+
await taskTest(strictConfig);
|
|
2593
|
+
break;
|
|
2302
2594
|
case 'version':
|
|
2303
2595
|
console.log(coreCompiler.version);
|
|
2304
2596
|
break;
|