@rindo/core 2.18.0 → 2.22.3
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 +670 -388
- package/cli/index.d.ts +3 -0
- package/cli/index.js +670 -388
- package/cli/package.json +1 -1
- package/compiler/lib.dom.d.ts +434 -251
- package/compiler/lib.dom.iterable.d.ts +7 -13
- package/compiler/lib.es2015.collection.d.ts +62 -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 +25 -2
- 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.intl.d.ts +31 -6
- package/compiler/lib.es2021.intl.d.ts +11 -3
- package/compiler/lib.es2022.d.ts +1 -0
- package/compiler/lib.es2022.error.d.ts +2 -2
- package/compiler/lib.es2022.sharedmemory.d.ts +27 -0
- package/compiler/lib.es5.d.ts +39 -14
- package/compiler/lib.esnext.intl.d.ts +5 -1
- package/compiler/lib.webworker.d.ts +318 -55
- package/compiler/lib.webworker.iterable.d.ts +11 -3
- package/compiler/package.json +1 -1
- package/compiler/rindo.d.ts +3 -25
- package/compiler/rindo.js +53912 -51834
- package/compiler/rindo.min.js +2 -2
- package/compiler/sys/in-memory-fs.d.ts +3 -3
- package/compiler/transpile.d.ts +32 -0
- package/dependencies.json +3 -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 +1182 -1148
- 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 +800 -673
- 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 -80
- package/internal/rindo-public-compiler.d.ts +68 -32
- 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 +905 -896
- package/mock-doc/index.d.ts +2 -2
- package/mock-doc/index.js +905 -896
- package/mock-doc/package.json +1 -1
- package/package.json +48 -57
- 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 +3 -3
- 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 +407 -418
- 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 +1136 -1277
- 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 +1 -1
- package/testing/testing.d.ts +1 -1
package/cli/index.js
CHANGED
|
@@ -1,41 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Rindo CLI v2.
|
|
2
|
+
Rindo CLI v2.22.3 | MIT Licensed | https://rindojs.web.app
|
|
3
3
|
*/
|
|
4
|
-
/**
|
|
5
|
-
* This sets the log level hierarchy for our terminal logger, ranging from
|
|
6
|
-
* most to least verbose.
|
|
7
|
-
*
|
|
8
|
-
* Ordering the levels like this lets us easily check whether we should log a
|
|
9
|
-
* message at a given time. For instance, if the log level is set to `'warn'`,
|
|
10
|
-
* then anything passed to the logger with level `'warn'` or `'error'` should
|
|
11
|
-
* be logged, but we should _not_ log anything with level `'info'` or `'debug'`.
|
|
12
|
-
*
|
|
13
|
-
* If we have a current log level `currentLevel` and a message with level
|
|
14
|
-
* `msgLevel` is passed to the logger, we can determine whether or not we should
|
|
15
|
-
* log it by checking if the log level on the message is further up or at the
|
|
16
|
-
* same level in the hierarchy than `currentLevel`, like so:
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* LOG_LEVELS.indexOf(msgLevel) >= LOG_LEVELS.indexOf(currentLevel)
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* NOTE: for the reasons described above, do not change the order of the entries
|
|
23
|
-
* in this array without good reason!
|
|
24
|
-
*/
|
|
25
|
-
const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Convert a string from PascalCase to dash-case
|
|
29
|
-
*
|
|
30
|
-
* @param str the string to convert
|
|
31
|
-
* @returns a converted string
|
|
32
|
-
*/
|
|
33
|
-
const toDashCase = (str) => str
|
|
34
|
-
.replace(/([A-Z0-9])/g, (match) => ` ${match[0]}`)
|
|
35
|
-
.trim()
|
|
36
|
-
.split(' ')
|
|
37
|
-
.join('-')
|
|
38
|
-
.toLowerCase();
|
|
39
4
|
/**
|
|
40
5
|
* Convert a string from dash-case / kebab-case to PascalCase (or CamelCase,
|
|
41
6
|
* or whatever you call it!)
|
|
@@ -48,6 +13,16 @@ const dashToPascalCase = (str) => str
|
|
|
48
13
|
.split('-')
|
|
49
14
|
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
50
15
|
.join('');
|
|
16
|
+
/**
|
|
17
|
+
* Convert a string to 'camelCase'
|
|
18
|
+
*
|
|
19
|
+
* @param str the string to convert
|
|
20
|
+
* @returns the converted string
|
|
21
|
+
*/
|
|
22
|
+
const toCamelCase = (str) => {
|
|
23
|
+
const pascalCase = dashToPascalCase(str);
|
|
24
|
+
return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
|
|
25
|
+
};
|
|
51
26
|
const isFunction = (v) => typeof v === 'function';
|
|
52
27
|
const isString = (v) => typeof v === 'string';
|
|
53
28
|
|
|
@@ -273,6 +248,22 @@ const pathComponents = (path, rootLength) => {
|
|
|
273
248
|
return [root, ...rest];
|
|
274
249
|
};
|
|
275
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Check whether a string is a member of a ReadonlyArray<string>
|
|
253
|
+
*
|
|
254
|
+
* We need a little helper for this because unfortunately `includes` is typed
|
|
255
|
+
* on `ReadonlyArray<T>` as `(el: T): boolean` so a `string` cannot be passed
|
|
256
|
+
* to `includes` on a `ReadonlyArray` 😢 thus we have a little helper function
|
|
257
|
+
* where we do the type coercion just once.
|
|
258
|
+
*
|
|
259
|
+
* see microsoft/TypeScript#31018 for some discussion of this
|
|
260
|
+
*
|
|
261
|
+
* @param readOnlyArray the array we're checking
|
|
262
|
+
* @param maybeMember a value which is possibly a member of the array
|
|
263
|
+
* @returns whether the array contains the member or not
|
|
264
|
+
*/
|
|
265
|
+
const readOnlyArrayHasStringMember = (readOnlyArray, maybeMember) => readOnlyArray.includes(maybeMember);
|
|
266
|
+
|
|
276
267
|
/**
|
|
277
268
|
* Validates that a component tag meets required naming conventions to be used for a web component
|
|
278
269
|
* @param tag the tag to validate
|
|
@@ -317,10 +308,33 @@ const validateComponentTag = (tag) => {
|
|
|
317
308
|
return undefined;
|
|
318
309
|
};
|
|
319
310
|
|
|
311
|
+
/**
|
|
312
|
+
* This sets the log level hierarchy for our terminal logger, ranging from
|
|
313
|
+
* most to least verbose.
|
|
314
|
+
*
|
|
315
|
+
* Ordering the levels like this lets us easily check whether we should log a
|
|
316
|
+
* message at a given time. For instance, if the log level is set to `'warn'`,
|
|
317
|
+
* then anything passed to the logger with level `'warn'` or `'error'` should
|
|
318
|
+
* be logged, but we should _not_ log anything with level `'info'` or `'debug'`.
|
|
319
|
+
*
|
|
320
|
+
* If we have a current log level `currentLevel` and a message with level
|
|
321
|
+
* `msgLevel` is passed to the logger, we can determine whether or not we should
|
|
322
|
+
* log it by checking if the log level on the message is further up or at the
|
|
323
|
+
* same level in the hierarchy than `currentLevel`, like so:
|
|
324
|
+
*
|
|
325
|
+
* ```ts
|
|
326
|
+
* LOG_LEVELS.indexOf(msgLevel) >= LOG_LEVELS.indexOf(currentLevel)
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* NOTE: for the reasons described above, do not change the order of the entries
|
|
330
|
+
* in this array without good reason!
|
|
331
|
+
*/
|
|
332
|
+
const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
333
|
+
|
|
320
334
|
/**
|
|
321
335
|
* All the Boolean options supported by the Rindo CLI
|
|
322
336
|
*/
|
|
323
|
-
const
|
|
337
|
+
const BOOLEAN_CLI_FLAGS = [
|
|
324
338
|
'build',
|
|
325
339
|
'cache',
|
|
326
340
|
'checkVersion',
|
|
@@ -403,7 +417,7 @@ const BOOLEAN_CLI_ARGS = [
|
|
|
403
417
|
/**
|
|
404
418
|
* All the Number options supported by the Rindo CLI
|
|
405
419
|
*/
|
|
406
|
-
const
|
|
420
|
+
const NUMBER_CLI_FLAGS = [
|
|
407
421
|
'port',
|
|
408
422
|
// JEST CLI ARGS
|
|
409
423
|
'maxConcurrency',
|
|
@@ -412,7 +426,7 @@ const NUMBER_CLI_ARGS = [
|
|
|
412
426
|
/**
|
|
413
427
|
* All the String options supported by the Rindo CLI
|
|
414
428
|
*/
|
|
415
|
-
const
|
|
429
|
+
const STRING_CLI_FLAGS = [
|
|
416
430
|
'address',
|
|
417
431
|
'config',
|
|
418
432
|
'docsApi',
|
|
@@ -451,7 +465,8 @@ const STRING_CLI_ARGS = [
|
|
|
451
465
|
'testURL',
|
|
452
466
|
'timers',
|
|
453
467
|
'transform',
|
|
454
|
-
|
|
468
|
+
];
|
|
469
|
+
const STRING_ARRAY_CLI_FLAGS = [
|
|
455
470
|
'collectCoverageOnlyFrom',
|
|
456
471
|
'coveragePathIgnorePatterns',
|
|
457
472
|
'coverageReporters',
|
|
@@ -480,7 +495,7 @@ const STRING_CLI_ARGS = [
|
|
|
480
495
|
* `maxWorkers` is an argument which is used both by Rindo _and_ by Jest,
|
|
481
496
|
* which means that we need to support parsing both string and number values.
|
|
482
497
|
*/
|
|
483
|
-
const
|
|
498
|
+
const STRING_NUMBER_CLI_FLAGS = ['maxWorkers'];
|
|
484
499
|
/**
|
|
485
500
|
* All the LogLevel-type options supported by the Rindo CLI
|
|
486
501
|
*
|
|
@@ -488,16 +503,21 @@ const STRING_NUMBER_CLI_ARGS = ['maxWorkers'];
|
|
|
488
503
|
* but this approach lets us make sure that we're handling all
|
|
489
504
|
* our arguments in a type-safe way.
|
|
490
505
|
*/
|
|
491
|
-
const
|
|
506
|
+
const LOG_LEVEL_CLI_FLAGS = ['logLevel'];
|
|
492
507
|
/**
|
|
493
508
|
* For a small subset of CLI options we support a short alias e.g. `'h'` for `'help'`
|
|
494
509
|
*/
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
510
|
+
const CLI_FLAG_ALIASES = {
|
|
511
|
+
c: 'config',
|
|
512
|
+
h: 'help',
|
|
513
|
+
p: 'port',
|
|
514
|
+
v: 'version',
|
|
500
515
|
};
|
|
516
|
+
/**
|
|
517
|
+
* A regular expression which can be used to match a CLI flag for one of our
|
|
518
|
+
* short aliases.
|
|
519
|
+
*/
|
|
520
|
+
const CLI_FLAG_REGEX = new RegExp(`^-[chpv]{1}$`);
|
|
501
521
|
/**
|
|
502
522
|
* Helper function for initializing a `ConfigFlags` object. Provide any overrides
|
|
503
523
|
* for default values and off you go!
|
|
@@ -530,8 +550,14 @@ const parseFlags = (args, _sys) => {
|
|
|
530
550
|
flags.args = Array.isArray(args) ? args.slice() : [];
|
|
531
551
|
if (flags.args.length > 0 && flags.args[0] && !flags.args[0].startsWith('-')) {
|
|
532
552
|
flags.task = flags.args[0];
|
|
553
|
+
// if the first argument was a "task" (like `build`, `test`, etc) then
|
|
554
|
+
// we go on to parse the _rest_ of the CLI args
|
|
555
|
+
parseArgs(flags, args.slice(1));
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
// we didn't find a leading flag, so we should just parse them all
|
|
559
|
+
parseArgs(flags, flags.args);
|
|
533
560
|
}
|
|
534
|
-
parseArgs(flags, flags.args);
|
|
535
561
|
if (flags.task != null) {
|
|
536
562
|
const i = flags.args.indexOf(flags.task);
|
|
537
563
|
if (i > -1) {
|
|
@@ -548,120 +574,259 @@ const parseFlags = (args, _sys) => {
|
|
|
548
574
|
return flags;
|
|
549
575
|
};
|
|
550
576
|
/**
|
|
551
|
-
* Parse command line
|
|
552
|
-
* module. Handles leading dashes on arguments, aliases that are
|
|
553
|
-
* small number of arguments, and parsing values for non-boolean
|
|
554
|
-
* (e.g. port number for the dev server).
|
|
577
|
+
* Parse the supported command line flags which are enumerated in the
|
|
578
|
+
* `config-flags` module. Handles leading dashes on arguments, aliases that are
|
|
579
|
+
* defined for a small number of arguments, and parsing values for non-boolean
|
|
580
|
+
* arguments (e.g. port number for the dev server).
|
|
581
|
+
*
|
|
582
|
+
* This parses the following grammar:
|
|
583
|
+
*
|
|
584
|
+
* CLIArguments → ""
|
|
585
|
+
* | CLITerm ( " " CLITerm )* ;
|
|
586
|
+
* CLITerm → EqualsArg
|
|
587
|
+
* | AliasEqualsArg
|
|
588
|
+
* | AliasArg
|
|
589
|
+
* | NegativeDashArg
|
|
590
|
+
* | NegativeArg
|
|
591
|
+
* | SimpleArg ;
|
|
592
|
+
* EqualsArg → "--" ArgName "=" CLIValue ;
|
|
593
|
+
* AliasEqualsArg → "-" AliasName "=" CLIValue ;
|
|
594
|
+
* AliasArg → "-" AliasName ( " " CLIValue )? ;
|
|
595
|
+
* NegativeDashArg → "--no-" ArgName ;
|
|
596
|
+
* NegativeArg → "--no" ArgName ;
|
|
597
|
+
* SimpleArg → "--" ArgName ( " " CLIValue )? ;
|
|
598
|
+
* ArgName → /^[a-zA-Z-]+$/ ;
|
|
599
|
+
* AliasName → /^[a-z]{1}$/ ;
|
|
600
|
+
* CLIValue → '"' /^[a-zA-Z0-9]+$/ '"'
|
|
601
|
+
* | /^[a-zA-Z0-9]+$/ ;
|
|
602
|
+
*
|
|
603
|
+
* There are additional constraints (not shown in the grammar for brevity's sake)
|
|
604
|
+
* on the type of `CLIValue` which will be associated with a particular argument.
|
|
605
|
+
* We enforce this by declaring lists of boolean, string, etc arguments and
|
|
606
|
+
* checking the types of values before setting them.
|
|
607
|
+
*
|
|
608
|
+
* We don't need to turn the list of CLI arg tokens into any kind of
|
|
609
|
+
* intermediate representation since we aren't concerned with doing anything
|
|
610
|
+
* other than setting the correct values on our ConfigFlags object. So we just
|
|
611
|
+
* parse the array of string arguments using a recursive-descent approach
|
|
612
|
+
* (which is not very deep since our grammar is pretty simple) and make the
|
|
613
|
+
* modifications we need to make to the {@link ConfigFlags} object as we go.
|
|
555
614
|
*
|
|
556
615
|
* @param flags a ConfigFlags object to which parsed arguments will be added
|
|
557
616
|
* @param args an array of command-line arguments to parse
|
|
558
617
|
*/
|
|
559
618
|
const parseArgs = (flags, args) => {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
619
|
+
const argsCopy = args.concat();
|
|
620
|
+
while (argsCopy.length > 0) {
|
|
621
|
+
// there are still unprocessed args to deal with
|
|
622
|
+
parseCLITerm(flags, argsCopy);
|
|
623
|
+
}
|
|
565
624
|
};
|
|
566
625
|
/**
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
* - `--booleanArg`
|
|
570
|
-
* - `--boolean-arg`
|
|
571
|
-
* - `--noBooleanArg`
|
|
572
|
-
* - `--no-boolean-arg`
|
|
573
|
-
*
|
|
574
|
-
* The final two variants should be parsed to a value of `false` on the config
|
|
575
|
-
* object.
|
|
626
|
+
* Given an array of CLI arguments, parse it and perform a series of side
|
|
627
|
+
* effects (setting values on the provided `ConfigFlags` object).
|
|
576
628
|
*
|
|
577
|
-
* @param flags
|
|
578
|
-
*
|
|
579
|
-
* @param
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
629
|
+
* @param flags a {@link ConfigFlags} object which is updated as we parse the CLI
|
|
630
|
+
* arguments
|
|
631
|
+
* @param args a list of args to work through. This function (and some functions
|
|
632
|
+
* it calls) calls `Array.prototype.shift` to get the next argument to look at,
|
|
633
|
+
* so this parameter will be modified.
|
|
634
|
+
*/
|
|
635
|
+
const parseCLITerm = (flags, args) => {
|
|
636
|
+
// pull off the first arg from the argument array
|
|
637
|
+
const arg = args.shift();
|
|
638
|
+
// array is empty, we're done!
|
|
639
|
+
if (arg === undefined)
|
|
640
|
+
return;
|
|
641
|
+
// EqualsArg → "--" ArgName "=" CLIValue ;
|
|
642
|
+
if (arg.startsWith('--') && arg.includes('=')) {
|
|
643
|
+
// we're dealing with an EqualsArg, we have a special helper for that
|
|
644
|
+
const [originalArg, value] = parseEqualsArg(arg);
|
|
645
|
+
setCLIArg(flags, arg.split('=')[0], normalizeFlagName(originalArg), value);
|
|
646
|
+
}
|
|
647
|
+
// AliasEqualsArg → "-" AliasName "=" CLIValue ;
|
|
648
|
+
else if (arg.startsWith('-') && arg.includes('=')) {
|
|
649
|
+
// we're dealing with an AliasEqualsArg, we have a special helper for that
|
|
650
|
+
const [originalArg, value] = parseEqualsArg(arg);
|
|
651
|
+
setCLIArg(flags, arg.split('=')[0], normalizeFlagName(originalArg), value);
|
|
652
|
+
}
|
|
653
|
+
// AliasArg → "-" AliasName ( " " CLIValue )? ;
|
|
654
|
+
else if (CLI_FLAG_REGEX.test(arg)) {
|
|
655
|
+
// this is a short alias, like `-c` for Config
|
|
656
|
+
setCLIArg(flags, arg, normalizeFlagName(arg), parseCLIValue(args));
|
|
657
|
+
}
|
|
658
|
+
// NegativeDashArg → "--no-" ArgName ;
|
|
659
|
+
else if (arg.startsWith('--no-') && arg.length > '--no-'.length) {
|
|
660
|
+
// this is a `NegativeDashArg` term, so we need to normalize the negative
|
|
661
|
+
// flag name and then set an appropriate value
|
|
662
|
+
const normalized = normalizeNegativeFlagName(arg);
|
|
663
|
+
setCLIArg(flags, arg, normalized, '');
|
|
664
|
+
}
|
|
665
|
+
// NegativeArg → "--no" ArgName ;
|
|
666
|
+
else if (arg.startsWith('--no') &&
|
|
667
|
+
!readOnlyArrayHasStringMember(BOOLEAN_CLI_FLAGS, normalizeFlagName(arg)) &&
|
|
668
|
+
readOnlyArrayHasStringMember(BOOLEAN_CLI_FLAGS, normalizeNegativeFlagName(arg))) {
|
|
669
|
+
// possibly dealing with a `NegativeArg` here. There is a little ambiguity
|
|
670
|
+
// here because we have arguments that already begin with `no` like
|
|
671
|
+
// `notify`, so we need to test if a normalized form of the raw argument is
|
|
672
|
+
// a valid and supported boolean flag.
|
|
673
|
+
setCLIArg(flags, arg, normalizeNegativeFlagName(arg), '');
|
|
674
|
+
}
|
|
675
|
+
// SimpleArg → "--" ArgName ( " " CLIValue )? ;
|
|
676
|
+
else if (arg.startsWith('--') && arg.length > '--'.length) {
|
|
677
|
+
setCLIArg(flags, arg, normalizeFlagName(arg), parseCLIValue(args));
|
|
678
|
+
}
|
|
679
|
+
// if we get here it is not an argument in our list of supported arguments.
|
|
680
|
+
// This doesn't necessarily mean we want to report an error or anything
|
|
681
|
+
// though! Instead, with unknown / unrecognized arguments we stick them into
|
|
682
|
+
// the `unknownArgs` array, which is used when we pass CLI args to Jest, for
|
|
683
|
+
// instance. So we just return void here.
|
|
605
684
|
};
|
|
606
685
|
/**
|
|
607
|
-
*
|
|
686
|
+
* Normalize a 'negative' flag name, just to do a little pre-processing before
|
|
687
|
+
* we pass it to `setCLIArg`.
|
|
608
688
|
*
|
|
609
|
-
* @param
|
|
610
|
-
* @
|
|
611
|
-
* @param configCaseName the argument we want to look at right now
|
|
689
|
+
* @param flagName the flag name to normalize
|
|
690
|
+
* @returns a normalized flag name
|
|
612
691
|
*/
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
}
|
|
617
|
-
const { value, matchingArg } = getValue(args, configCaseName);
|
|
618
|
-
if (value !== undefined && matchingArg !== undefined) {
|
|
619
|
-
flags[configCaseName] = value;
|
|
620
|
-
flags.knownArgs.push(matchingArg);
|
|
621
|
-
flags.knownArgs.push(value);
|
|
622
|
-
}
|
|
692
|
+
const normalizeNegativeFlagName = (flagName) => {
|
|
693
|
+
const trimmed = flagName.replace(/^--no[-]?/, '');
|
|
694
|
+
return normalizeFlagName(trimmed.charAt(0).toLowerCase() + trimmed.slice(1));
|
|
623
695
|
};
|
|
624
696
|
/**
|
|
625
|
-
*
|
|
697
|
+
* Normalize a flag name by:
|
|
698
|
+
*
|
|
699
|
+
* - replacing any leading dashes (`--foo` -> `foo`)
|
|
700
|
+
* - converting `dash-case` to camelCase (if necessary)
|
|
701
|
+
*
|
|
702
|
+
* Normalizing in this context basically means converting the various
|
|
703
|
+
* supported flag spelling variants to the variant defined in our lists of
|
|
704
|
+
* supported arguments (e.g. BOOLEAN_CLI_FLAGS, etc). So, for instance,
|
|
705
|
+
* `--log-level` should be converted to `logLevel`.
|
|
706
|
+
*
|
|
707
|
+
* @param flagName the flag name to normalize
|
|
708
|
+
* @returns a normalized flag name
|
|
626
709
|
*
|
|
627
|
-
* @param flags the config flags object, while we'll modify
|
|
628
|
-
* @param args our CLI arguments
|
|
629
|
-
* @param configCaseName the argument we want to look at right now
|
|
630
710
|
*/
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
}
|
|
635
|
-
const { value, matchingArg } = getValue(args, configCaseName);
|
|
636
|
-
if (value !== undefined && matchingArg !== undefined) {
|
|
637
|
-
flags[configCaseName] = parseInt(value, 10);
|
|
638
|
-
flags.knownArgs.push(matchingArg);
|
|
639
|
-
flags.knownArgs.push(value);
|
|
640
|
-
}
|
|
711
|
+
const normalizeFlagName = (flagName) => {
|
|
712
|
+
const trimmed = flagName.replace(/^-+/, '');
|
|
713
|
+
return trimmed.includes('-') ? toCamelCase(trimmed) : trimmed;
|
|
641
714
|
};
|
|
642
715
|
/**
|
|
643
|
-
*
|
|
716
|
+
* Set a value on a provided {@link ConfigFlags} object, given an argument
|
|
717
|
+
* name and a raw string value. This function dispatches to other functions
|
|
718
|
+
* which make sure that the string value can be properly parsed into a JS
|
|
719
|
+
* runtime value of the right type (e.g. number, string, etc).
|
|
644
720
|
*
|
|
645
|
-
* @
|
|
646
|
-
* @param
|
|
647
|
-
* @param
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
721
|
+
* @throws if a value cannot be parsed to the right type for a given flag
|
|
722
|
+
* @param flags a {@link ConfigFlags} object
|
|
723
|
+
* @param rawArg the raw argument name matched by the parser
|
|
724
|
+
* @param normalizedArg an argument with leading control characters (`--`,
|
|
725
|
+
* `--no-`, etc) removed
|
|
726
|
+
* @param value the raw value to be set onto the config flags object
|
|
727
|
+
*/
|
|
728
|
+
const setCLIArg = (flags, rawArg, normalizedArg, value) => {
|
|
729
|
+
normalizedArg = dereferenceAlias(normalizedArg);
|
|
730
|
+
// We're setting a boolean!
|
|
731
|
+
if (readOnlyArrayHasStringMember(BOOLEAN_CLI_FLAGS, normalizedArg)) {
|
|
732
|
+
flags[normalizedArg] =
|
|
733
|
+
typeof value === 'string'
|
|
734
|
+
? Boolean(value)
|
|
735
|
+
: // no value was supplied, default to true
|
|
736
|
+
true;
|
|
737
|
+
flags.knownArgs.push(rawArg);
|
|
738
|
+
}
|
|
739
|
+
// We're setting a string!
|
|
740
|
+
else if (readOnlyArrayHasStringMember(STRING_CLI_FLAGS, normalizedArg)) {
|
|
741
|
+
if (typeof value === 'string') {
|
|
742
|
+
flags[normalizedArg] = value;
|
|
743
|
+
flags.knownArgs.push(rawArg);
|
|
744
|
+
flags.knownArgs.push(value);
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
throwCLIParsingError(rawArg, 'expected a string argument but received nothing');
|
|
748
|
+
}
|
|
652
749
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
flags[
|
|
750
|
+
// We're setting a string, but it's one where the user can pass multiple values,
|
|
751
|
+
// like `--reporters="default" --reporters="jest-junit"`
|
|
752
|
+
else if (readOnlyArrayHasStringMember(STRING_ARRAY_CLI_FLAGS, normalizedArg)) {
|
|
753
|
+
if (typeof value === 'string') {
|
|
754
|
+
if (!Array.isArray(flags[normalizedArg])) {
|
|
755
|
+
flags[normalizedArg] = [];
|
|
756
|
+
}
|
|
757
|
+
const targetArray = flags[normalizedArg];
|
|
758
|
+
// this is irritating, but TS doesn't know that the `!Array.isArray`
|
|
759
|
+
// check above guarantees we have an array to work with here, and it
|
|
760
|
+
// doesn't want to narrow the type of `flags[normalizedArg]`, so we need
|
|
761
|
+
// to grab a reference to that array and then `Array.isArray` that. Bah!
|
|
762
|
+
if (Array.isArray(targetArray)) {
|
|
763
|
+
targetArray.push(value);
|
|
764
|
+
flags.knownArgs.push(rawArg);
|
|
765
|
+
flags.knownArgs.push(value);
|
|
766
|
+
}
|
|
658
767
|
}
|
|
659
768
|
else {
|
|
660
|
-
|
|
661
|
-
|
|
769
|
+
throwCLIParsingError(rawArg, 'expected a string argument but received nothing');
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
// We're setting a number!
|
|
773
|
+
else if (readOnlyArrayHasStringMember(NUMBER_CLI_FLAGS, normalizedArg)) {
|
|
774
|
+
if (typeof value === 'string') {
|
|
775
|
+
const parsed = parseInt(value, 10);
|
|
776
|
+
if (isNaN(parsed)) {
|
|
777
|
+
throwNumberParsingError(rawArg, value);
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
flags[normalizedArg] = parsed;
|
|
781
|
+
flags.knownArgs.push(rawArg);
|
|
782
|
+
flags.knownArgs.push(value);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
throwCLIParsingError(rawArg, 'expected a number argument but received nothing');
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// We're setting a value which could be either a string _or_ a number
|
|
790
|
+
else if (readOnlyArrayHasStringMember(STRING_NUMBER_CLI_FLAGS, normalizedArg)) {
|
|
791
|
+
if (typeof value === 'string') {
|
|
792
|
+
if (CLI_ARG_STRING_REGEX.test(value)) {
|
|
793
|
+
// if it matches the regex we treat it like a string
|
|
794
|
+
flags[normalizedArg] = value;
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
const parsed = Number(value);
|
|
798
|
+
if (isNaN(parsed)) {
|
|
799
|
+
// parsing didn't go so well, we gotta get out of here
|
|
800
|
+
// this is unlikely given our regex guard above
|
|
801
|
+
// but hey, this is ultimately JS so let's be safe
|
|
802
|
+
throwNumberParsingError(rawArg, value);
|
|
803
|
+
}
|
|
804
|
+
else {
|
|
805
|
+
flags[normalizedArg] = parsed;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
flags.knownArgs.push(rawArg);
|
|
809
|
+
flags.knownArgs.push(value);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
throwCLIParsingError(rawArg, 'expected a string or a number but received nothing');
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
// We're setting the log level, which can only be a set of specific string values
|
|
816
|
+
else if (readOnlyArrayHasStringMember(LOG_LEVEL_CLI_FLAGS, normalizedArg)) {
|
|
817
|
+
if (typeof value === 'string') {
|
|
818
|
+
if (isLogLevel(value)) {
|
|
819
|
+
flags[normalizedArg] = value;
|
|
820
|
+
flags.knownArgs.push(rawArg);
|
|
821
|
+
flags.knownArgs.push(value);
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
throwCLIParsingError(rawArg, `expected to receive a valid log level but received "${String(value)}"`);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
else {
|
|
828
|
+
throwCLIParsingError(rawArg, 'expected to receive a valid log level but received nothing');
|
|
662
829
|
}
|
|
663
|
-
flags.knownArgs.push(matchingArg);
|
|
664
|
-
flags.knownArgs.push(value);
|
|
665
830
|
}
|
|
666
831
|
};
|
|
667
832
|
/**
|
|
@@ -682,73 +847,34 @@ const parseStringNumberArg = (flags, args, configCaseName) => {
|
|
|
682
847
|
* to a number.
|
|
683
848
|
*/
|
|
684
849
|
const CLI_ARG_STRING_REGEX = /[^\d\.Ee\+\-]+/g;
|
|
850
|
+
const Empty = Symbol('Empty');
|
|
685
851
|
/**
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
* the value is correct.
|
|
852
|
+
* A little helper which tries to parse a CLI value (as opposed to a flag) off
|
|
853
|
+
* of the argument array.
|
|
689
854
|
*
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
*
|
|
711
|
-
* - `--my-cli-argument value`
|
|
712
|
-
* - `--my-cli-argument=value`
|
|
713
|
-
* - `--myCliArgument value`
|
|
714
|
-
* - `--myCliArgument=value`
|
|
715
|
-
*
|
|
716
|
-
* We also check for shortened aliases, which we define for a few arguments.
|
|
717
|
-
*
|
|
718
|
-
* @param args the CLI args we're dealing with
|
|
719
|
-
* @param configCaseName the ConfigFlag key which we're looking to pull out a value for
|
|
720
|
-
* @returns the value for the flag as well as the exact string which it matched from
|
|
721
|
-
* the user input.
|
|
722
|
-
*/
|
|
723
|
-
const getValue = (args, configCaseName) => {
|
|
724
|
-
// for some CLI args we have a short alias, like 'c' for 'config'
|
|
725
|
-
const alias = CLI_ARG_ALIASES[configCaseName];
|
|
726
|
-
// we support supplying arguments in both dash-case and configCase
|
|
727
|
-
// for ease of use
|
|
728
|
-
const dashCaseName = toDashCase(configCaseName);
|
|
729
|
-
let value;
|
|
730
|
-
let matchingArg;
|
|
731
|
-
args.forEach((arg, i) => {
|
|
732
|
-
if (arg.startsWith(`--${dashCaseName}=`) || arg.startsWith(`--${configCaseName}=`)) {
|
|
733
|
-
// our argument was passed at the command-line in the format --argName=arg-value
|
|
734
|
-
[matchingArg, value] = parseEqualsArg(arg);
|
|
735
|
-
}
|
|
736
|
-
else if (arg === `--${dashCaseName}` || arg === `--${configCaseName}`) {
|
|
737
|
-
// the next value in the array is assumed to be a value for this argument
|
|
738
|
-
value = args[i + 1];
|
|
739
|
-
matchingArg = arg;
|
|
740
|
-
}
|
|
741
|
-
else if (alias) {
|
|
742
|
-
if (arg.startsWith(`-${alias}=`)) {
|
|
743
|
-
[matchingArg, value] = parseEqualsArg(arg);
|
|
744
|
-
}
|
|
745
|
-
else if (arg === `-${alias}`) {
|
|
746
|
-
value = args[i + 1];
|
|
747
|
-
matchingArg = arg;
|
|
748
|
-
}
|
|
855
|
+
* We support a variety of different argument formats, but all of them start
|
|
856
|
+
* with `-`, so we can check the first character to test whether the next token
|
|
857
|
+
* in our array of CLI arguments is a flag name or a value.
|
|
858
|
+
*
|
|
859
|
+
* @param args an array of CLI args
|
|
860
|
+
* @returns either a string result or an Empty sentinel
|
|
861
|
+
*/
|
|
862
|
+
const parseCLIValue = (args) => {
|
|
863
|
+
// it's possible the arguments array is empty, if so, return empty
|
|
864
|
+
if (args[0] === undefined) {
|
|
865
|
+
return Empty;
|
|
866
|
+
}
|
|
867
|
+
// all we're concerned with here is that it does not start with `"-"`,
|
|
868
|
+
// which would indicate it should be parsed as a CLI flag and not a value.
|
|
869
|
+
if (!args[0].startsWith('-')) {
|
|
870
|
+
// It's not a flag, so we return the value and defer any specific parsing
|
|
871
|
+
// until later on.
|
|
872
|
+
const value = args.shift();
|
|
873
|
+
if (typeof value === 'string') {
|
|
874
|
+
return value;
|
|
749
875
|
}
|
|
750
|
-
}
|
|
751
|
-
return
|
|
876
|
+
}
|
|
877
|
+
return Empty;
|
|
752
878
|
};
|
|
753
879
|
/**
|
|
754
880
|
* Parse an 'equals' argument, which is a CLI argument-value pair in the
|
|
@@ -784,8 +910,9 @@ const getValue = (args, configCaseName) => {
|
|
|
784
910
|
* @returns a tuple containing the arg name and the value (if present)
|
|
785
911
|
*/
|
|
786
912
|
const parseEqualsArg = (arg) => {
|
|
787
|
-
const [originalArg, ...
|
|
788
|
-
|
|
913
|
+
const [originalArg, ...splitSections] = arg.split('=');
|
|
914
|
+
const value = splitSections.join('=');
|
|
915
|
+
return [originalArg, value === '' ? Empty : value];
|
|
789
916
|
};
|
|
790
917
|
/**
|
|
791
918
|
* Small helper for getting type-system-level assurance that a `string` can be
|
|
@@ -794,18 +921,51 @@ const parseEqualsArg = (arg) => {
|
|
|
794
921
|
* @param maybeLogLevel the string to check
|
|
795
922
|
* @returns whether this is a `LogLevel`
|
|
796
923
|
*/
|
|
797
|
-
const isLogLevel = (maybeLogLevel) =>
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
924
|
+
const isLogLevel = (maybeLogLevel) => readOnlyArrayHasStringMember(LOG_LEVELS, maybeLogLevel);
|
|
925
|
+
/**
|
|
926
|
+
* A little helper for constructing and throwing an error message with info
|
|
927
|
+
* about what went wrong
|
|
928
|
+
*
|
|
929
|
+
* @param flag the flag which encountered the error
|
|
930
|
+
* @param message a message specific to the error which was encountered
|
|
931
|
+
*/
|
|
932
|
+
const throwCLIParsingError = (flag, message) => {
|
|
933
|
+
throw new Error(`when parsing CLI flag "${flag}": ${message}`);
|
|
934
|
+
};
|
|
935
|
+
/**
|
|
936
|
+
* Throw a specific error for the situation where we ran into an issue parsing
|
|
937
|
+
* a number.
|
|
938
|
+
*
|
|
939
|
+
* @param flag the flag for which we encountered the issue
|
|
940
|
+
* @param value what we were trying to parse
|
|
941
|
+
*/
|
|
942
|
+
const throwNumberParsingError = (flag, value) => {
|
|
943
|
+
throwCLIParsingError(flag, `expected a number but received "${value}"`);
|
|
944
|
+
};
|
|
945
|
+
/**
|
|
946
|
+
* A little helper to 'dereference' a flag alias, which if you squint a little
|
|
947
|
+
* you can think of like a pointer to a full flag name. Thus 'c' is like a
|
|
948
|
+
* pointer to 'config', so here we're doing something like `*c`. Of course, this
|
|
949
|
+
* being JS, this is just a metaphor!
|
|
950
|
+
*
|
|
951
|
+
* If no 'dereference' is found for the possible alias we just return the
|
|
952
|
+
* passed string unmodified.
|
|
953
|
+
*
|
|
954
|
+
* @param maybeAlias a string which _could_ be an alias to a full flag name
|
|
955
|
+
* @returns the full aliased flag name, if found, or the passed string if not
|
|
956
|
+
*/
|
|
957
|
+
const dereferenceAlias = (maybeAlias) => {
|
|
958
|
+
const possibleDereference = CLI_FLAG_ALIASES[maybeAlias];
|
|
959
|
+
if (typeof possibleDereference === 'string') {
|
|
960
|
+
return possibleDereference;
|
|
961
|
+
}
|
|
962
|
+
return maybeAlias;
|
|
963
|
+
};
|
|
804
964
|
|
|
805
965
|
const dependencies = [
|
|
806
966
|
{
|
|
807
967
|
name: "@rindo/core",
|
|
808
|
-
version: "2.
|
|
968
|
+
version: "2.22.3",
|
|
809
969
|
main: "compiler/rindo.js",
|
|
810
970
|
resources: [
|
|
811
971
|
"package.json",
|
|
@@ -842,6 +1002,7 @@ const dependencies = [
|
|
|
842
1002
|
"compiler/lib.es2019.array.d.ts",
|
|
843
1003
|
"compiler/lib.es2019.d.ts",
|
|
844
1004
|
"compiler/lib.es2019.full.d.ts",
|
|
1005
|
+
"compiler/lib.es2019.intl.d.ts",
|
|
845
1006
|
"compiler/lib.es2019.object.d.ts",
|
|
846
1007
|
"compiler/lib.es2019.string.d.ts",
|
|
847
1008
|
"compiler/lib.es2019.symbol.d.ts",
|
|
@@ -867,6 +1028,7 @@ const dependencies = [
|
|
|
867
1028
|
"compiler/lib.es2022.full.d.ts",
|
|
868
1029
|
"compiler/lib.es2022.intl.d.ts",
|
|
869
1030
|
"compiler/lib.es2022.object.d.ts",
|
|
1031
|
+
"compiler/lib.es2022.sharedmemory.d.ts",
|
|
870
1032
|
"compiler/lib.es2022.string.d.ts",
|
|
871
1033
|
"compiler/lib.es5.d.ts",
|
|
872
1034
|
"compiler/lib.es6.d.ts",
|
|
@@ -912,16 +1074,112 @@ const dependencies = [
|
|
|
912
1074
|
},
|
|
913
1075
|
{
|
|
914
1076
|
name: "terser",
|
|
915
|
-
version: "5.
|
|
1077
|
+
version: "5.16.1",
|
|
916
1078
|
main: "dist/bundle.min.js"
|
|
917
1079
|
},
|
|
918
1080
|
{
|
|
919
1081
|
name: "typescript",
|
|
920
|
-
version: "4.
|
|
1082
|
+
version: "4.9.4",
|
|
921
1083
|
main: "lib/typescript.js"
|
|
922
1084
|
}
|
|
923
1085
|
];
|
|
924
1086
|
|
|
1087
|
+
const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
1088
|
+
typeof require === 'function' &&
|
|
1089
|
+
!!global.process &&
|
|
1090
|
+
typeof __filename === 'string' &&
|
|
1091
|
+
(!global.origin || typeof global.origin !== 'string');
|
|
1092
|
+
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1093
|
+
|
|
1094
|
+
/**
|
|
1095
|
+
* Creates an instance of a logger
|
|
1096
|
+
* @returns the new logger instance
|
|
1097
|
+
*/
|
|
1098
|
+
const createLogger = () => {
|
|
1099
|
+
let useColors = IS_BROWSER_ENV;
|
|
1100
|
+
let level = 'info';
|
|
1101
|
+
return {
|
|
1102
|
+
enableColors: (uc) => (useColors = uc),
|
|
1103
|
+
getLevel: () => level,
|
|
1104
|
+
setLevel: (l) => (level = l),
|
|
1105
|
+
emoji: (e) => e,
|
|
1106
|
+
info: console.log.bind(console),
|
|
1107
|
+
warn: console.warn.bind(console),
|
|
1108
|
+
error: console.error.bind(console),
|
|
1109
|
+
debug: console.debug.bind(console),
|
|
1110
|
+
red: (msg) => msg,
|
|
1111
|
+
green: (msg) => msg,
|
|
1112
|
+
yellow: (msg) => msg,
|
|
1113
|
+
blue: (msg) => msg,
|
|
1114
|
+
magenta: (msg) => msg,
|
|
1115
|
+
cyan: (msg) => msg,
|
|
1116
|
+
gray: (msg) => msg,
|
|
1117
|
+
bold: (msg) => msg,
|
|
1118
|
+
dim: (msg) => msg,
|
|
1119
|
+
bgRed: (msg) => msg,
|
|
1120
|
+
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
1121
|
+
duration: () => 0,
|
|
1122
|
+
finish: () => 0,
|
|
1123
|
+
}),
|
|
1124
|
+
printDiagnostics(diagnostics) {
|
|
1125
|
+
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
1126
|
+
},
|
|
1127
|
+
};
|
|
1128
|
+
};
|
|
1129
|
+
const logDiagnostic = (diagnostic, useColors) => {
|
|
1130
|
+
let color = BLUE;
|
|
1131
|
+
let prefix = 'Build';
|
|
1132
|
+
let msg = '';
|
|
1133
|
+
if (diagnostic.level === 'error') {
|
|
1134
|
+
color = RED;
|
|
1135
|
+
prefix = 'Error';
|
|
1136
|
+
}
|
|
1137
|
+
else if (diagnostic.level === 'warn') {
|
|
1138
|
+
color = YELLOW;
|
|
1139
|
+
prefix = 'Warning';
|
|
1140
|
+
}
|
|
1141
|
+
if (diagnostic.header) {
|
|
1142
|
+
prefix = diagnostic.header;
|
|
1143
|
+
}
|
|
1144
|
+
const filePath = diagnostic.relFilePath || diagnostic.absFilePath;
|
|
1145
|
+
if (filePath) {
|
|
1146
|
+
msg += filePath;
|
|
1147
|
+
if (typeof diagnostic.lineNumber === 'number' && diagnostic.lineNumber > 0) {
|
|
1148
|
+
msg += ', line ' + diagnostic.lineNumber;
|
|
1149
|
+
if (typeof diagnostic.columnNumber === 'number' && diagnostic.columnNumber > 0) {
|
|
1150
|
+
msg += ', column ' + diagnostic.columnNumber;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
msg += '\n';
|
|
1154
|
+
}
|
|
1155
|
+
msg += diagnostic.messageText;
|
|
1156
|
+
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
1157
|
+
diagnostic.lines.forEach((l) => {
|
|
1158
|
+
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
1159
|
+
});
|
|
1160
|
+
msg += '\n';
|
|
1161
|
+
}
|
|
1162
|
+
if (useColors) {
|
|
1163
|
+
const styledPrefix = [
|
|
1164
|
+
'%c' + prefix,
|
|
1165
|
+
`background: ${color}; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;`,
|
|
1166
|
+
];
|
|
1167
|
+
console.log(...styledPrefix, msg);
|
|
1168
|
+
}
|
|
1169
|
+
else if (diagnostic.level === 'error') {
|
|
1170
|
+
console.error(msg);
|
|
1171
|
+
}
|
|
1172
|
+
else if (diagnostic.level === 'warn') {
|
|
1173
|
+
console.warn(msg);
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
console.log(msg);
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
const YELLOW = `#f39c12`;
|
|
1180
|
+
const RED = `#c0392b`;
|
|
1181
|
+
const BLUE = `#3498db`;
|
|
1182
|
+
|
|
925
1183
|
/**
|
|
926
1184
|
* Attempt to find a Rindo configuration file on the file system
|
|
927
1185
|
* @param opts the options needed to find the configuration file
|
|
@@ -930,11 +1188,7 @@ const dependencies = [
|
|
|
930
1188
|
const findConfig = async (opts) => {
|
|
931
1189
|
const sys = opts.sys;
|
|
932
1190
|
const cwd = sys.getCurrentDirectory();
|
|
933
|
-
const
|
|
934
|
-
configPath: null,
|
|
935
|
-
rootDir: normalizePath(cwd),
|
|
936
|
-
diagnostics: [],
|
|
937
|
-
};
|
|
1191
|
+
const rootDir = normalizePath(cwd);
|
|
938
1192
|
let configPath = opts.configPath;
|
|
939
1193
|
if (isString(configPath)) {
|
|
940
1194
|
if (!sys.platformPath.isAbsolute(configPath)) {
|
|
@@ -949,8 +1203,13 @@ const findConfig = async (opts) => {
|
|
|
949
1203
|
}
|
|
950
1204
|
else {
|
|
951
1205
|
// nothing was passed in, use the current working directory
|
|
952
|
-
configPath =
|
|
1206
|
+
configPath = rootDir;
|
|
953
1207
|
}
|
|
1208
|
+
const results = {
|
|
1209
|
+
configPath,
|
|
1210
|
+
rootDir: normalizePath(cwd),
|
|
1211
|
+
diagnostics: [],
|
|
1212
|
+
};
|
|
954
1213
|
const stat = await sys.stat(configPath);
|
|
955
1214
|
if (stat.error) {
|
|
956
1215
|
const diagnostic = buildError(results.diagnostics);
|
|
@@ -983,12 +1242,33 @@ const loadCoreCompiler = async (sys) => {
|
|
|
983
1242
|
return globalThis.rindo;
|
|
984
1243
|
};
|
|
985
1244
|
|
|
1245
|
+
/**
|
|
1246
|
+
* Log the name of this package (`@rindo/core`) to an output stream
|
|
1247
|
+
*
|
|
1248
|
+
* The output stream is determined by the {@link Logger} instance that is provided as an argument to this function
|
|
1249
|
+
*
|
|
1250
|
+
* The name of the package may not be logged, by design, for certain `task` types and logging levels
|
|
1251
|
+
*
|
|
1252
|
+
* @param logger the logging entity to use to output the name of the package
|
|
1253
|
+
* @param task the current task
|
|
1254
|
+
*/
|
|
986
1255
|
const startupLog = (logger, task) => {
|
|
987
1256
|
if (task === 'info' || task === 'serve' || task === 'version') {
|
|
988
1257
|
return;
|
|
989
1258
|
}
|
|
990
1259
|
logger.info(logger.cyan(`@rindo/core`));
|
|
991
1260
|
};
|
|
1261
|
+
/**
|
|
1262
|
+
* Log this package's version to an output stream
|
|
1263
|
+
*
|
|
1264
|
+
* The output stream is determined by the {@link Logger} instance that is provided as an argument to this function
|
|
1265
|
+
*
|
|
1266
|
+
* The package version may not be logged, by design, for certain `task` types and logging levels
|
|
1267
|
+
*
|
|
1268
|
+
* @param logger the logging entity to use for output
|
|
1269
|
+
* @param task the current task
|
|
1270
|
+
* @param coreCompiler the compiler instance to derive version information from
|
|
1271
|
+
*/
|
|
992
1272
|
const startupLogVersion = (logger, task, coreCompiler) => {
|
|
993
1273
|
if (task === 'info' || task === 'serve' || task === 'version') {
|
|
994
1274
|
return;
|
|
@@ -1004,11 +1284,25 @@ const startupLogVersion = (logger, task, coreCompiler) => {
|
|
|
1004
1284
|
startupMsg += logger.emoji(' ' + coreCompiler.vermoji);
|
|
1005
1285
|
logger.info(startupMsg);
|
|
1006
1286
|
};
|
|
1287
|
+
/**
|
|
1288
|
+
* Log details from a {@link CompilerSystem} used by Rindo to an output stream
|
|
1289
|
+
*
|
|
1290
|
+
* The output stream is determined by the {@link Logger} instance that is provided as an argument to this function
|
|
1291
|
+
*
|
|
1292
|
+
* @param sys the `CompilerSystem` to report details on
|
|
1293
|
+
* @param logger the logging entity to use for output
|
|
1294
|
+
* @param flags user set flags for the current invocation of Rindo
|
|
1295
|
+
* @param coreCompiler the compiler instance being used for this invocation of Rindo
|
|
1296
|
+
*/
|
|
1007
1297
|
const loadedCompilerLog = (sys, logger, flags, coreCompiler) => {
|
|
1008
1298
|
const sysDetails = sys.details;
|
|
1009
1299
|
const runtimeInfo = `${sys.name} ${sys.version}`;
|
|
1010
|
-
const platformInfo =
|
|
1011
|
-
|
|
1300
|
+
const platformInfo = sysDetails
|
|
1301
|
+
? `${sysDetails.platform}, ${sysDetails.cpuModel}`
|
|
1302
|
+
: `Unknown Platform, Unknown CPU Model`;
|
|
1303
|
+
const statsInfo = sysDetails
|
|
1304
|
+
? `cpus: ${sys.hardwareConcurrency}, freemem: ${Math.round(sysDetails.freemem() / 1000000)}MB, totalmem: ${Math.round(sysDetails.totalmem / 1000000)}MB`
|
|
1305
|
+
: 'Unknown CPU Core Count, Unknown Memory';
|
|
1012
1306
|
if (logger.getLevel() === 'debug') {
|
|
1013
1307
|
logger.debug(runtimeInfo);
|
|
1014
1308
|
logger.debug(platformInfo);
|
|
@@ -1022,6 +1316,14 @@ const loadedCompilerLog = (sys, logger, flags, coreCompiler) => {
|
|
|
1022
1316
|
logger.info(statsInfo);
|
|
1023
1317
|
}
|
|
1024
1318
|
};
|
|
1319
|
+
/**
|
|
1320
|
+
* Log various warnings to an output stream
|
|
1321
|
+
*
|
|
1322
|
+
* The output stream is determined by the {@link Logger} instance attached to the `config` argument to this function
|
|
1323
|
+
*
|
|
1324
|
+
* @param coreCompiler the compiler instance being used for this invocation of Rindo
|
|
1325
|
+
* @param config a validated configuration object to be used for this run of Rindo
|
|
1326
|
+
*/
|
|
1025
1327
|
const startupCompilerLog = (coreCompiler, config) => {
|
|
1026
1328
|
if (config.suppressLogs === true) {
|
|
1027
1329
|
return;
|
|
@@ -1043,6 +1345,21 @@ const startupCompilerLog = (coreCompiler, config) => {
|
|
|
1043
1345
|
}
|
|
1044
1346
|
};
|
|
1045
1347
|
|
|
1348
|
+
const startCheckVersion = async (config, currentVersion) => {
|
|
1349
|
+
if (config.devMode && !config.flags.ci && !currentVersion.includes('-dev.') && isFunction(config.sys.checkVersion)) {
|
|
1350
|
+
return config.sys.checkVersion(config.logger, currentVersion);
|
|
1351
|
+
}
|
|
1352
|
+
return null;
|
|
1353
|
+
};
|
|
1354
|
+
const printCheckVersionResults = async (versionChecker) => {
|
|
1355
|
+
if (versionChecker) {
|
|
1356
|
+
const checkVersionResults = await versionChecker;
|
|
1357
|
+
if (isFunction(checkVersionResults)) {
|
|
1358
|
+
checkVersionResults();
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1362
|
+
|
|
1046
1363
|
const taskPrerender = async (coreCompiler, config) => {
|
|
1047
1364
|
startupCompilerLog(coreCompiler, config);
|
|
1048
1365
|
const hydrateAppFilePath = config.flags.unknownArgs[0];
|
|
@@ -1074,21 +1391,6 @@ const runPrerenderTask = async (coreCompiler, config, hydrateAppFilePath, compon
|
|
|
1074
1391
|
return diagnostics;
|
|
1075
1392
|
};
|
|
1076
1393
|
|
|
1077
|
-
const startCheckVersion = async (config, currentVersion) => {
|
|
1078
|
-
if (config.devMode && !config.flags.ci && !currentVersion.includes('-dev.') && isFunction(config.sys.checkVersion)) {
|
|
1079
|
-
return config.sys.checkVersion(config.logger, currentVersion);
|
|
1080
|
-
}
|
|
1081
|
-
return null;
|
|
1082
|
-
};
|
|
1083
|
-
const printCheckVersionResults = async (versionChecker) => {
|
|
1084
|
-
if (versionChecker) {
|
|
1085
|
-
const checkVersionResults = await versionChecker;
|
|
1086
|
-
if (isFunction(checkVersionResults)) {
|
|
1087
|
-
checkVersionResults();
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
};
|
|
1091
|
-
|
|
1092
1394
|
const taskWatch = async (coreCompiler, config) => {
|
|
1093
1395
|
let devServer = null;
|
|
1094
1396
|
let exitCode = 0;
|
|
@@ -1135,6 +1437,15 @@ const taskWatch = async (coreCompiler, config) => {
|
|
|
1135
1437
|
}
|
|
1136
1438
|
};
|
|
1137
1439
|
|
|
1440
|
+
const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
|
|
1441
|
+
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
1442
|
+
const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
|
|
1443
|
+
const DOCS_CUSTOM = 'docs-custom';
|
|
1444
|
+
const DOCS_JSON = 'docs-json';
|
|
1445
|
+
const DOCS_README = 'docs-readme';
|
|
1446
|
+
const DOCS_VSCODE = 'docs-vscode';
|
|
1447
|
+
const WWW = 'www';
|
|
1448
|
+
|
|
1138
1449
|
const tryFn = async (fn, ...args) => {
|
|
1139
1450
|
try {
|
|
1140
1451
|
return await fn(...args);
|
|
@@ -1148,12 +1459,12 @@ const isInteractive = (sys, flags, object) => {
|
|
|
1148
1459
|
const terminalInfo = object ||
|
|
1149
1460
|
Object.freeze({
|
|
1150
1461
|
tty: sys.isTTY() ? true : false,
|
|
1151
|
-
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!flags.ci,
|
|
1462
|
+
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,
|
|
1152
1463
|
});
|
|
1153
1464
|
return terminalInfo.tty && !terminalInfo.ci;
|
|
1154
1465
|
};
|
|
1155
1466
|
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);
|
|
1156
|
-
// Plucked from https://github.com/
|
|
1467
|
+
// Plucked from https://github.com/familyjs/jigra/blob/HEAD/cli/src/util/uuid.ts
|
|
1157
1468
|
function uuidv4() {
|
|
1158
1469
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
1159
1470
|
const r = (Math.random() * 16) | 0;
|
|
@@ -1177,7 +1488,7 @@ async function readJson(sys, path) {
|
|
|
1177
1488
|
* @returns true if --debug has been passed, otherwise false
|
|
1178
1489
|
*/
|
|
1179
1490
|
function hasDebug(flags) {
|
|
1180
|
-
return flags.debug;
|
|
1491
|
+
return !!flags.debug;
|
|
1181
1492
|
}
|
|
1182
1493
|
/**
|
|
1183
1494
|
* Does the command have the verbose and debug flags?
|
|
@@ -1185,25 +1496,14 @@ function hasDebug(flags) {
|
|
|
1185
1496
|
* @returns true if both --debug and --verbose have been passed, otherwise false
|
|
1186
1497
|
*/
|
|
1187
1498
|
function hasVerbose(flags) {
|
|
1188
|
-
return flags.verbose && hasDebug(flags);
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
/**
|
|
1192
|
-
* Used to determine if tracking should occur.
|
|
1193
|
-
* @param config The config passed into the Rindo command
|
|
1194
|
-
* @param sys The system where the command is invoked
|
|
1195
|
-
* @param ci whether or not the process is running in a Continuous Integration (CI) environment
|
|
1196
|
-
* @returns true if telemetry should be sent, false otherwise
|
|
1197
|
-
*/
|
|
1198
|
-
async function shouldTrack(config, sys, ci) {
|
|
1199
|
-
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
1499
|
+
return !!flags.verbose && hasDebug(flags);
|
|
1200
1500
|
}
|
|
1201
1501
|
|
|
1202
1502
|
const isTest$1 = () => process.env.JEST_WORKER_ID !== undefined;
|
|
1203
|
-
const defaultConfig = (sys) => sys.resolvePath(`${sys.homeDir()}/.
|
|
1204
|
-
const defaultConfigDirectory = (sys) => sys.resolvePath(`${sys.homeDir()}/.
|
|
1503
|
+
const defaultConfig = (sys) => sys.resolvePath(`${sys.homeDir()}/.family/${isTest$1() ? 'tmp-config.json' : 'config.json'}`);
|
|
1504
|
+
const defaultConfigDirectory = (sys) => sys.resolvePath(`${sys.homeDir()}/.family`);
|
|
1205
1505
|
/**
|
|
1206
|
-
* Reads an
|
|
1506
|
+
* Reads an Family configuration file from disk, parses it, and performs any necessary corrections to it if certain
|
|
1207
1507
|
* values are deemed to be malformed
|
|
1208
1508
|
* @param sys The system where the command is invoked
|
|
1209
1509
|
* @returns the config read from disk that has been potentially been updated
|
|
@@ -1217,7 +1517,7 @@ async function readConfig(sys) {
|
|
|
1217
1517
|
};
|
|
1218
1518
|
await writeConfig(sys, config);
|
|
1219
1519
|
}
|
|
1220
|
-
else if (!UUID_REGEX.test(config['tokens.telemetry'])) {
|
|
1520
|
+
else if (!config['tokens.telemetry'] || !UUID_REGEX.test(config['tokens.telemetry'])) {
|
|
1221
1521
|
const newUuid = uuidv4();
|
|
1222
1522
|
await writeConfig(sys, { ...config, 'tokens.telemetry': newUuid });
|
|
1223
1523
|
config['tokens.telemetry'] = newUuid;
|
|
@@ -1225,7 +1525,7 @@ async function readConfig(sys) {
|
|
|
1225
1525
|
return config;
|
|
1226
1526
|
}
|
|
1227
1527
|
/**
|
|
1228
|
-
* Writes an
|
|
1528
|
+
* Writes an Family configuration file to disk.
|
|
1229
1529
|
* @param sys The system where the command is invoked
|
|
1230
1530
|
* @param config The config passed into the Rindo command
|
|
1231
1531
|
* @returns boolean If the command was successful
|
|
@@ -1243,7 +1543,7 @@ async function writeConfig(sys, config) {
|
|
|
1243
1543
|
return result;
|
|
1244
1544
|
}
|
|
1245
1545
|
/**
|
|
1246
|
-
* Update a subset of the
|
|
1546
|
+
* Update a subset of the Family config.
|
|
1247
1547
|
* @param sys The system where the command is invoked
|
|
1248
1548
|
* @param newOptions The new options to save
|
|
1249
1549
|
* @returns boolean If the command was successful
|
|
@@ -1253,14 +1553,16 @@ async function updateConfig(sys, newOptions) {
|
|
|
1253
1553
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
1254
1554
|
}
|
|
1255
1555
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1556
|
+
/**
|
|
1557
|
+
* Used to determine if tracking should occur.
|
|
1558
|
+
* @param config The config passed into the Rindo command
|
|
1559
|
+
* @param sys The system where the command is invoked
|
|
1560
|
+
* @param ci whether or not the process is running in a Continuous Integration (CI) environment
|
|
1561
|
+
* @returns true if telemetry should be sent, false otherwise
|
|
1562
|
+
*/
|
|
1563
|
+
async function shouldTrack(config, sys, ci) {
|
|
1564
|
+
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
1565
|
+
}
|
|
1264
1566
|
|
|
1265
1567
|
/**
|
|
1266
1568
|
* Used to within taskBuild to provide the component_count property.
|
|
@@ -1271,11 +1573,11 @@ const WWW = 'www';
|
|
|
1271
1573
|
* @param result The results of a compiler build.
|
|
1272
1574
|
*/
|
|
1273
1575
|
async function telemetryBuildFinishedAction(sys, config, coreCompiler, result) {
|
|
1274
|
-
const tracking = await shouldTrack(config, sys, config.flags.ci);
|
|
1576
|
+
const tracking = await shouldTrack(config, sys, !!config.flags.ci);
|
|
1275
1577
|
if (!tracking) {
|
|
1276
1578
|
return;
|
|
1277
1579
|
}
|
|
1278
|
-
const component_count = Object.keys(result.componentGraph).length;
|
|
1580
|
+
const component_count = result.componentGraph ? Object.keys(result.componentGraph).length : undefined;
|
|
1279
1581
|
const data = await prepareData(coreCompiler, config, sys, result.duration, component_count);
|
|
1280
1582
|
await sendMetric(sys, config, 'rindo_cli_command', data);
|
|
1281
1583
|
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
@@ -1354,38 +1656,41 @@ function getActiveTargets(config) {
|
|
|
1354
1656
|
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1355
1657
|
*/
|
|
1356
1658
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1659
|
+
var _a, _b, _c;
|
|
1357
1660
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1358
1661
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
1359
1662
|
const targets = getActiveTargets(config);
|
|
1360
1663
|
const yarn = isUsingYarn(sys);
|
|
1361
1664
|
const rindo = coreCompiler.version || 'unknown';
|
|
1362
1665
|
const system = `${sys.name} ${sys.version}`;
|
|
1363
|
-
const os_name = sys.details.platform;
|
|
1364
|
-
const os_version = sys.details.release;
|
|
1365
|
-
const cpu_model = sys.details.cpuModel;
|
|
1666
|
+
const os_name = (_a = sys.details) === null || _a === void 0 ? void 0 : _a.platform;
|
|
1667
|
+
const os_version = (_b = sys.details) === null || _b === void 0 ? void 0 : _b.release;
|
|
1668
|
+
const cpu_model = (_c = sys.details) === null || _c === void 0 ? void 0 : _c.cpuModel;
|
|
1366
1669
|
const build = coreCompiler.buildId || 'unknown';
|
|
1367
1670
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1368
1671
|
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1672
|
+
const is_browser_env = IS_BROWSER_ENV;
|
|
1369
1673
|
return {
|
|
1370
|
-
|
|
1371
|
-
|
|
1674
|
+
arguments: config.flags.args,
|
|
1675
|
+
build,
|
|
1372
1676
|
component_count,
|
|
1373
|
-
|
|
1677
|
+
config: anonymizedConfig,
|
|
1678
|
+
cpu_model,
|
|
1679
|
+
duration_ms,
|
|
1680
|
+
has_app_pwa_config,
|
|
1681
|
+
is_browser_env,
|
|
1682
|
+
os_name,
|
|
1683
|
+
os_version,
|
|
1374
1684
|
packages,
|
|
1375
1685
|
packages_no_versions: packagesNoVersions,
|
|
1376
|
-
|
|
1377
|
-
task: config.flags.task,
|
|
1686
|
+
rollup,
|
|
1378
1687
|
rindo,
|
|
1379
1688
|
system,
|
|
1380
1689
|
system_major: getMajorVersion(system),
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
cpu_model,
|
|
1384
|
-
build,
|
|
1690
|
+
targets,
|
|
1691
|
+
task: config.flags.task,
|
|
1385
1692
|
typescript,
|
|
1386
|
-
|
|
1387
|
-
has_app_pwa_config,
|
|
1388
|
-
config: anonymizedConfig,
|
|
1693
|
+
yarn,
|
|
1389
1694
|
};
|
|
1390
1695
|
};
|
|
1391
1696
|
// props in output targets for which we retain their original values when
|
|
@@ -1409,7 +1714,16 @@ const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
|
1409
1714
|
// Props we delete entirely from the config for telemetry
|
|
1410
1715
|
//
|
|
1411
1716
|
// TODO: Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1412
|
-
const CONFIG_PROPS_TO_DELETE = [
|
|
1717
|
+
const CONFIG_PROPS_TO_DELETE = [
|
|
1718
|
+
'commonjs',
|
|
1719
|
+
'devServer',
|
|
1720
|
+
'env',
|
|
1721
|
+
'logger',
|
|
1722
|
+
'rollupConfig',
|
|
1723
|
+
'sys',
|
|
1724
|
+
'testing',
|
|
1725
|
+
'tsCompilerOptions',
|
|
1726
|
+
];
|
|
1413
1727
|
/**
|
|
1414
1728
|
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1415
1729
|
* with a placeholder string if they are present (this lets us still track how frequently
|
|
@@ -1459,7 +1773,7 @@ const anonymizeConfigForTelemetry = (config) => {
|
|
|
1459
1773
|
/**
|
|
1460
1774
|
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1461
1775
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1462
|
-
* of each package under the @rindo, @
|
|
1776
|
+
* of each package under the @rindo, @familyjs, and @jigra scopes.
|
|
1463
1777
|
*
|
|
1464
1778
|
* @param sys the system instance where telemetry is invoked
|
|
1465
1779
|
* @param config the Rindo configuration associated with the current task that triggered telemetry
|
|
@@ -1481,16 +1795,16 @@ async function getInstalledPackages(sys, config) {
|
|
|
1481
1795
|
...packageJson.devDependencies,
|
|
1482
1796
|
...packageJson.dependencies,
|
|
1483
1797
|
});
|
|
1484
|
-
// Collect packages only in the rindo,
|
|
1798
|
+
// Collect packages only in the rindo, familyjs, or jigra org's:
|
|
1485
1799
|
// https://www.npmjs.com/org/rindo
|
|
1486
|
-
const
|
|
1800
|
+
const familyPackages = rawPackages.filter(([k]) => k.startsWith('@rindo/') || k.startsWith('@familyjs/') || k.startsWith('@jigra/'));
|
|
1487
1801
|
try {
|
|
1488
|
-
packages = yarn ? await yarnPackages(sys,
|
|
1802
|
+
packages = yarn ? await yarnPackages(sys, familyPackages) : await npmPackages(sys, familyPackages);
|
|
1489
1803
|
}
|
|
1490
1804
|
catch (e) {
|
|
1491
|
-
packages =
|
|
1805
|
+
packages = familyPackages.map(([k, v]) => `${k}@${v.replace('^', '')}`);
|
|
1492
1806
|
}
|
|
1493
|
-
packagesNoVersions =
|
|
1807
|
+
packagesNoVersions = familyPackages.map(([k]) => `${k}`);
|
|
1494
1808
|
return { packages, packagesNoVersions };
|
|
1495
1809
|
}
|
|
1496
1810
|
catch (err) {
|
|
@@ -1501,13 +1815,13 @@ async function getInstalledPackages(sys, config) {
|
|
|
1501
1815
|
/**
|
|
1502
1816
|
* Visits the npm lock file to find the exact versions that are installed
|
|
1503
1817
|
* @param sys The system where the command is invoked
|
|
1504
|
-
* @param
|
|
1818
|
+
* @param familyPackages a list of the found packages matching `@rindo`, `@jigra`, or `@familyjs` from the package.json file.
|
|
1505
1819
|
* @returns an array of strings of all the packages and their versions.
|
|
1506
1820
|
*/
|
|
1507
|
-
async function npmPackages(sys,
|
|
1821
|
+
async function npmPackages(sys, familyPackages) {
|
|
1508
1822
|
const appRootDir = sys.getCurrentDirectory();
|
|
1509
1823
|
const packageLockJson = await tryFn(readJson, sys, sys.resolvePath(appRootDir + '/package-lock.json'));
|
|
1510
|
-
return
|
|
1824
|
+
return familyPackages.map(([k, v]) => {
|
|
1511
1825
|
var _a, _b, _c, _d;
|
|
1512
1826
|
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;
|
|
1513
1827
|
version = version.includes('file:') ? sanitizeDeclaredVersion(v) : version;
|
|
@@ -1517,14 +1831,14 @@ async function npmPackages(sys, navifyPackages) {
|
|
|
1517
1831
|
/**
|
|
1518
1832
|
* Visits the yarn lock file to find the exact versions that are installed
|
|
1519
1833
|
* @param sys The system where the command is invoked
|
|
1520
|
-
* @param
|
|
1834
|
+
* @param familyPackages a list of the found packages matching `@rindo`, `@jigra`, or `@familyjs` from the package.json file.
|
|
1521
1835
|
* @returns an array of strings of all the packages and their versions.
|
|
1522
1836
|
*/
|
|
1523
|
-
async function yarnPackages(sys,
|
|
1837
|
+
async function yarnPackages(sys, familyPackages) {
|
|
1524
1838
|
const appRootDir = sys.getCurrentDirectory();
|
|
1525
1839
|
const yarnLock = sys.readFileSync(sys.resolvePath(appRootDir + '/yarn.lock'));
|
|
1526
1840
|
const yarnLockYml = sys.parseYarnLockFile(yarnLock);
|
|
1527
|
-
return
|
|
1841
|
+
return familyPackages.map(([k, v]) => {
|
|
1528
1842
|
var _a;
|
|
1529
1843
|
const identifiedVersion = `${k}@${v}`;
|
|
1530
1844
|
let version = (_a = yarnLockYml.object[identifiedVersion]) === null || _a === void 0 ? void 0 : _a.version;
|
|
@@ -1589,7 +1903,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1589
1903
|
sent_at: now,
|
|
1590
1904
|
};
|
|
1591
1905
|
// This request is only made if telemetry is on.
|
|
1592
|
-
const response = await sys.fetch('https://api
|
|
1906
|
+
const response = await sys.fetch('https://familyjs-api.web.app/events/metrics', {
|
|
1593
1907
|
method: 'POST',
|
|
1594
1908
|
headers: {
|
|
1595
1909
|
'Content-Type': 'application/json',
|
|
@@ -1692,13 +2006,6 @@ const taskDocs = async (coreCompiler, config) => {
|
|
|
1692
2006
|
await compiler.destroy();
|
|
1693
2007
|
};
|
|
1694
2008
|
|
|
1695
|
-
const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
1696
|
-
typeof require === 'function' &&
|
|
1697
|
-
!!global.process &&
|
|
1698
|
-
typeof __filename === 'string' &&
|
|
1699
|
-
(!global.origin || typeof global.origin !== 'string');
|
|
1700
|
-
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1701
|
-
|
|
1702
2009
|
/**
|
|
1703
2010
|
* Task to generate component boilerplate and write it to disk. This task can
|
|
1704
2011
|
* cause the program to exit with an error under various circumstances, such as
|
|
@@ -1727,13 +2034,24 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1727
2034
|
const { prompt } = await import('../sys/node/prompts.js');
|
|
1728
2035
|
const input = config.flags.unknownArgs.find((arg) => !arg.startsWith('-')) ||
|
|
1729
2036
|
(await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName;
|
|
2037
|
+
if (undefined === input) {
|
|
2038
|
+
// in some shells (e.g. Windows PowerShell), hitting Ctrl+C results in a TypeError printed to the console.
|
|
2039
|
+
// explicitly return here to avoid printing the error message.
|
|
2040
|
+
return;
|
|
2041
|
+
}
|
|
1730
2042
|
const { dir, base: componentName } = path.parse(input);
|
|
1731
2043
|
const tagError = validateComponentTag(componentName);
|
|
1732
2044
|
if (tagError) {
|
|
1733
2045
|
config.logger.error(tagError);
|
|
1734
2046
|
return config.sys.exit(1);
|
|
1735
2047
|
}
|
|
1736
|
-
const
|
|
2048
|
+
const filesToGenerateExt = await chooseFilesToGenerate();
|
|
2049
|
+
if (undefined === filesToGenerateExt) {
|
|
2050
|
+
// in some shells (e.g. Windows PowerShell), hitting Ctrl+C results in a TypeError printed to the console.
|
|
2051
|
+
// explicitly return here to avoid printing the error message.
|
|
2052
|
+
return;
|
|
2053
|
+
}
|
|
2054
|
+
const extensionsToGenerate = ['tsx', ...filesToGenerateExt];
|
|
1737
2055
|
const testFolder = extensionsToGenerate.some(isTest) ? 'test' : '';
|
|
1738
2056
|
const outDir = path.join(absoluteSrcDir, 'components', dir, componentName);
|
|
1739
2057
|
await config.sys.createDir(path.join(outDir, testFolder), { recursive: true });
|
|
@@ -1957,7 +2275,7 @@ const taskTelemetry = async (flags, sys, logger) => {
|
|
|
1957
2275
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1958
2276
|
const isEnabling = flags.args.includes('on');
|
|
1959
2277
|
const isDisabling = flags.args.includes('off');
|
|
1960
|
-
const INFORMATION = `Opt in or
|
|
2278
|
+
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')}`;
|
|
1961
2279
|
const THANK_YOU = `Thank you for helping to make Rindo better! 💖`;
|
|
1962
2280
|
const ENABLED_MESSAGE = `${logger.green('Enabled')}. ${THANK_YOU}\n\n`;
|
|
1963
2281
|
const DISABLED_MESSAGE = `${logger.red('Disabled')}\n\n`;
|
|
@@ -2080,93 +2398,54 @@ const taskServe = async (config) => {
|
|
|
2080
2398
|
};
|
|
2081
2399
|
|
|
2082
2400
|
/**
|
|
2083
|
-
*
|
|
2084
|
-
* @
|
|
2401
|
+
* Entrypoint for any Rindo tests
|
|
2402
|
+
* @param config a validated Rindo configuration entity
|
|
2085
2403
|
*/
|
|
2086
|
-
const
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
enableColors: (uc) => (useColors = uc),
|
|
2091
|
-
getLevel: () => level,
|
|
2092
|
-
setLevel: (l) => (level = l),
|
|
2093
|
-
emoji: (e) => e,
|
|
2094
|
-
info: console.log.bind(console),
|
|
2095
|
-
warn: console.warn.bind(console),
|
|
2096
|
-
error: console.error.bind(console),
|
|
2097
|
-
debug: console.debug.bind(console),
|
|
2098
|
-
red: (msg) => msg,
|
|
2099
|
-
green: (msg) => msg,
|
|
2100
|
-
yellow: (msg) => msg,
|
|
2101
|
-
blue: (msg) => msg,
|
|
2102
|
-
magenta: (msg) => msg,
|
|
2103
|
-
cyan: (msg) => msg,
|
|
2104
|
-
gray: (msg) => msg,
|
|
2105
|
-
bold: (msg) => msg,
|
|
2106
|
-
dim: (msg) => msg,
|
|
2107
|
-
bgRed: (msg) => msg,
|
|
2108
|
-
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
2109
|
-
duration: () => 0,
|
|
2110
|
-
finish: () => 0,
|
|
2111
|
-
}),
|
|
2112
|
-
printDiagnostics(diagnostics) {
|
|
2113
|
-
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
2114
|
-
},
|
|
2115
|
-
};
|
|
2116
|
-
};
|
|
2117
|
-
const logDiagnostic = (diagnostic, useColors) => {
|
|
2118
|
-
let color = BLUE;
|
|
2119
|
-
let prefix = 'Build';
|
|
2120
|
-
let msg = '';
|
|
2121
|
-
if (diagnostic.level === 'error') {
|
|
2122
|
-
color = RED;
|
|
2123
|
-
prefix = 'Error';
|
|
2124
|
-
}
|
|
2125
|
-
else if (diagnostic.level === 'warn') {
|
|
2126
|
-
color = YELLOW;
|
|
2127
|
-
prefix = 'Warning';
|
|
2128
|
-
}
|
|
2129
|
-
if (diagnostic.header) {
|
|
2130
|
-
prefix = diagnostic.header;
|
|
2404
|
+
const taskTest = async (config) => {
|
|
2405
|
+
if (!IS_NODE_ENV) {
|
|
2406
|
+
config.logger.error(`"test" command is currently only implemented for a NodeJS environment`);
|
|
2407
|
+
return config.sys.exit(1);
|
|
2131
2408
|
}
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2409
|
+
config.buildDocs = false;
|
|
2410
|
+
const testingRunOpts = {
|
|
2411
|
+
e2e: !!config.flags.e2e,
|
|
2412
|
+
screenshot: !!config.flags.screenshot,
|
|
2413
|
+
spec: !!config.flags.spec,
|
|
2414
|
+
updateScreenshot: !!config.flags.updateScreenshot,
|
|
2415
|
+
};
|
|
2416
|
+
// always ensure we have jest modules installed
|
|
2417
|
+
const ensureModuleIds = ['@types/jest', 'jest', 'jest-cli'];
|
|
2418
|
+
if (testingRunOpts.e2e) {
|
|
2419
|
+
// if it's an e2e test, also make sure we're got
|
|
2420
|
+
// puppeteer modules installed and if browserExecutablePath is provided don't download Chromium use only puppeteer-core instead
|
|
2421
|
+
const puppeteer = config.testing.browserExecutablePath ? 'puppeteer-core' : 'puppeteer';
|
|
2422
|
+
ensureModuleIds.push(puppeteer);
|
|
2423
|
+
if (testingRunOpts.screenshot) {
|
|
2424
|
+
// ensure we've got pixelmatch for screenshots
|
|
2425
|
+
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.`));
|
|
2140
2426
|
}
|
|
2141
|
-
msg += '\n';
|
|
2142
|
-
}
|
|
2143
|
-
msg += diagnostic.messageText;
|
|
2144
|
-
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
2145
|
-
diagnostic.lines.forEach((l) => {
|
|
2146
|
-
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
2147
|
-
});
|
|
2148
|
-
msg += '\n';
|
|
2149
2427
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
console.log(...styledPrefix, msg);
|
|
2156
|
-
}
|
|
2157
|
-
else if (diagnostic.level === 'error') {
|
|
2158
|
-
console.error(msg);
|
|
2428
|
+
// ensure we've got the required modules installed
|
|
2429
|
+
const diagnostics = await config.sys.lazyRequire.ensure(config.rootDir, ensureModuleIds);
|
|
2430
|
+
if (diagnostics.length > 0) {
|
|
2431
|
+
config.logger.printDiagnostics(diagnostics);
|
|
2432
|
+
return config.sys.exit(1);
|
|
2159
2433
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2434
|
+
try {
|
|
2435
|
+
// let's test!
|
|
2436
|
+
const { createTesting } = await import('../testing/index.js');
|
|
2437
|
+
const testing = await createTesting(config);
|
|
2438
|
+
const passed = await testing.run(testingRunOpts);
|
|
2439
|
+
await testing.destroy();
|
|
2440
|
+
if (!passed) {
|
|
2441
|
+
return config.sys.exit(1);
|
|
2442
|
+
}
|
|
2162
2443
|
}
|
|
2163
|
-
|
|
2164
|
-
|
|
2444
|
+
catch (e) {
|
|
2445
|
+
config.logger.error(e);
|
|
2446
|
+
return config.sys.exit(1);
|
|
2165
2447
|
}
|
|
2166
|
-
};
|
|
2167
|
-
const YELLOW = `#f39c12`;
|
|
2168
|
-
const RED = `#c0392b`;
|
|
2169
|
-
const BLUE = `#3498db`;
|
|
2448
|
+
};
|
|
2170
2449
|
|
|
2171
2450
|
const run = async (init) => {
|
|
2172
2451
|
const { args, logger, sys } = init;
|
|
@@ -2182,7 +2461,7 @@ const run = async (init) => {
|
|
|
2182
2461
|
if (isFunction(sys.applyGlobalPatch)) {
|
|
2183
2462
|
sys.applyGlobalPatch(sys.getCurrentDirectory());
|
|
2184
2463
|
}
|
|
2185
|
-
if (task === 'help' || flags.help) {
|
|
2464
|
+
if (!task || task === 'help' || flags.help) {
|
|
2186
2465
|
await taskHelp(createConfigFlags({ task: 'help', args }), logger, sys);
|
|
2187
2466
|
return;
|
|
2188
2467
|
}
|
|
@@ -2285,6 +2564,9 @@ const runTask = async (coreCompiler, config, task, sys) => {
|
|
|
2285
2564
|
case 'telemetry':
|
|
2286
2565
|
await taskTelemetry(strictConfig.flags, sys, strictConfig.logger);
|
|
2287
2566
|
break;
|
|
2567
|
+
case 'test':
|
|
2568
|
+
await taskTest(strictConfig);
|
|
2569
|
+
break;
|
|
2288
2570
|
case 'version':
|
|
2289
2571
|
console.log(coreCompiler.version);
|
|
2290
2572
|
break;
|