@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.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Rindo CLI (CommonJS) v2.
|
|
2
|
+
Rindo CLI (CommonJS) v2.22.3 | 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
|
|
|
@@ -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.3",
|
|
833
993
|
main: "compiler/rindo.js",
|
|
834
994
|
resources: [
|
|
835
995
|
"package.json",
|
|
@@ -866,6 +1026,7 @@ 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",
|
|
@@ -891,6 +1052,7 @@ const dependencies = [
|
|
|
891
1052
|
"compiler/lib.es2022.full.d.ts",
|
|
892
1053
|
"compiler/lib.es2022.intl.d.ts",
|
|
893
1054
|
"compiler/lib.es2022.object.d.ts",
|
|
1055
|
+
"compiler/lib.es2022.sharedmemory.d.ts",
|
|
894
1056
|
"compiler/lib.es2022.string.d.ts",
|
|
895
1057
|
"compiler/lib.es5.d.ts",
|
|
896
1058
|
"compiler/lib.es6.d.ts",
|
|
@@ -936,16 +1098,112 @@ const dependencies = [
|
|
|
936
1098
|
},
|
|
937
1099
|
{
|
|
938
1100
|
name: "terser",
|
|
939
|
-
version: "5.
|
|
1101
|
+
version: "5.16.1",
|
|
940
1102
|
main: "dist/bundle.min.js"
|
|
941
1103
|
},
|
|
942
1104
|
{
|
|
943
1105
|
name: "typescript",
|
|
944
|
-
version: "4.
|
|
1106
|
+
version: "4.9.4",
|
|
945
1107
|
main: "lib/typescript.js"
|
|
946
1108
|
}
|
|
947
1109
|
];
|
|
948
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
|
+
|
|
949
1207
|
/**
|
|
950
1208
|
* Attempt to find a Rindo configuration file on the file system
|
|
951
1209
|
* @param opts the options needed to find the configuration file
|
|
@@ -954,11 +1212,7 @@ const dependencies = [
|
|
|
954
1212
|
const findConfig = async (opts) => {
|
|
955
1213
|
const sys = opts.sys;
|
|
956
1214
|
const cwd = sys.getCurrentDirectory();
|
|
957
|
-
const
|
|
958
|
-
configPath: null,
|
|
959
|
-
rootDir: normalizePath(cwd),
|
|
960
|
-
diagnostics: [],
|
|
961
|
-
};
|
|
1215
|
+
const rootDir = normalizePath(cwd);
|
|
962
1216
|
let configPath = opts.configPath;
|
|
963
1217
|
if (isString(configPath)) {
|
|
964
1218
|
if (!sys.platformPath.isAbsolute(configPath)) {
|
|
@@ -973,8 +1227,13 @@ const findConfig = async (opts) => {
|
|
|
973
1227
|
}
|
|
974
1228
|
else {
|
|
975
1229
|
// nothing was passed in, use the current working directory
|
|
976
|
-
configPath =
|
|
1230
|
+
configPath = rootDir;
|
|
977
1231
|
}
|
|
1232
|
+
const results = {
|
|
1233
|
+
configPath,
|
|
1234
|
+
rootDir: normalizePath(cwd),
|
|
1235
|
+
diagnostics: [],
|
|
1236
|
+
};
|
|
978
1237
|
const stat = await sys.stat(configPath);
|
|
979
1238
|
if (stat.error) {
|
|
980
1239
|
const diagnostic = buildError(results.diagnostics);
|
|
@@ -1007,12 +1266,33 @@ const loadCoreCompiler = async (sys) => {
|
|
|
1007
1266
|
return globalThis.rindo;
|
|
1008
1267
|
};
|
|
1009
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
|
+
*/
|
|
1010
1279
|
const startupLog = (logger, task) => {
|
|
1011
1280
|
if (task === 'info' || task === 'serve' || task === 'version') {
|
|
1012
1281
|
return;
|
|
1013
1282
|
}
|
|
1014
1283
|
logger.info(logger.cyan(`@rindo/core`));
|
|
1015
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
|
+
*/
|
|
1016
1296
|
const startupLogVersion = (logger, task, coreCompiler) => {
|
|
1017
1297
|
if (task === 'info' || task === 'serve' || task === 'version') {
|
|
1018
1298
|
return;
|
|
@@ -1028,11 +1308,25 @@ const startupLogVersion = (logger, task, coreCompiler) => {
|
|
|
1028
1308
|
startupMsg += logger.emoji(' ' + coreCompiler.vermoji);
|
|
1029
1309
|
logger.info(startupMsg);
|
|
1030
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
|
+
*/
|
|
1031
1321
|
const loadedCompilerLog = (sys, logger, flags, coreCompiler) => {
|
|
1032
1322
|
const sysDetails = sys.details;
|
|
1033
1323
|
const runtimeInfo = `${sys.name} ${sys.version}`;
|
|
1034
|
-
const platformInfo =
|
|
1035
|
-
|
|
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';
|
|
1036
1330
|
if (logger.getLevel() === 'debug') {
|
|
1037
1331
|
logger.debug(runtimeInfo);
|
|
1038
1332
|
logger.debug(platformInfo);
|
|
@@ -1046,6 +1340,14 @@ const loadedCompilerLog = (sys, logger, flags, coreCompiler) => {
|
|
|
1046
1340
|
logger.info(statsInfo);
|
|
1047
1341
|
}
|
|
1048
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
|
+
*/
|
|
1049
1351
|
const startupCompilerLog = (coreCompiler, config) => {
|
|
1050
1352
|
if (config.suppressLogs === true) {
|
|
1051
1353
|
return;
|
|
@@ -1067,6 +1369,21 @@ const startupCompilerLog = (coreCompiler, config) => {
|
|
|
1067
1369
|
}
|
|
1068
1370
|
};
|
|
1069
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
|
+
|
|
1070
1387
|
const taskPrerender = async (coreCompiler, config) => {
|
|
1071
1388
|
startupCompilerLog(coreCompiler, config);
|
|
1072
1389
|
const hydrateAppFilePath = config.flags.unknownArgs[0];
|
|
@@ -1098,21 +1415,6 @@ const runPrerenderTask = async (coreCompiler, config, hydrateAppFilePath, compon
|
|
|
1098
1415
|
return diagnostics;
|
|
1099
1416
|
};
|
|
1100
1417
|
|
|
1101
|
-
const startCheckVersion = async (config, currentVersion) => {
|
|
1102
|
-
if (config.devMode && !config.flags.ci && !currentVersion.includes('-dev.') && isFunction(config.sys.checkVersion)) {
|
|
1103
|
-
return config.sys.checkVersion(config.logger, currentVersion);
|
|
1104
|
-
}
|
|
1105
|
-
return null;
|
|
1106
|
-
};
|
|
1107
|
-
const printCheckVersionResults = async (versionChecker) => {
|
|
1108
|
-
if (versionChecker) {
|
|
1109
|
-
const checkVersionResults = await versionChecker;
|
|
1110
|
-
if (isFunction(checkVersionResults)) {
|
|
1111
|
-
checkVersionResults();
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
};
|
|
1115
|
-
|
|
1116
1418
|
const taskWatch = async (coreCompiler, config) => {
|
|
1117
1419
|
let devServer = null;
|
|
1118
1420
|
let exitCode = 0;
|
|
@@ -1159,6 +1461,15 @@ const taskWatch = async (coreCompiler, config) => {
|
|
|
1159
1461
|
}
|
|
1160
1462
|
};
|
|
1161
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
|
+
|
|
1162
1473
|
const tryFn = async (fn, ...args) => {
|
|
1163
1474
|
try {
|
|
1164
1475
|
return await fn(...args);
|
|
@@ -1172,12 +1483,12 @@ const isInteractive = (sys, flags, object) => {
|
|
|
1172
1483
|
const terminalInfo = object ||
|
|
1173
1484
|
Object.freeze({
|
|
1174
1485
|
tty: sys.isTTY() ? true : false,
|
|
1175
|
-
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,
|
|
1176
1487
|
});
|
|
1177
1488
|
return terminalInfo.tty && !terminalInfo.ci;
|
|
1178
1489
|
};
|
|
1179
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);
|
|
1180
|
-
// Plucked from https://github.com/
|
|
1491
|
+
// Plucked from https://github.com/familyjs/jigra/blob/HEAD/cli/src/util/uuid.ts
|
|
1181
1492
|
function uuidv4() {
|
|
1182
1493
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
1183
1494
|
const r = (Math.random() * 16) | 0;
|
|
@@ -1201,7 +1512,7 @@ async function readJson(sys, path) {
|
|
|
1201
1512
|
* @returns true if --debug has been passed, otherwise false
|
|
1202
1513
|
*/
|
|
1203
1514
|
function hasDebug(flags) {
|
|
1204
|
-
return flags.debug;
|
|
1515
|
+
return !!flags.debug;
|
|
1205
1516
|
}
|
|
1206
1517
|
/**
|
|
1207
1518
|
* Does the command have the verbose and debug flags?
|
|
@@ -1209,25 +1520,14 @@ function hasDebug(flags) {
|
|
|
1209
1520
|
* @returns true if both --debug and --verbose have been passed, otherwise false
|
|
1210
1521
|
*/
|
|
1211
1522
|
function hasVerbose(flags) {
|
|
1212
|
-
return flags.verbose && hasDebug(flags);
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
/**
|
|
1216
|
-
* Used to determine if tracking should occur.
|
|
1217
|
-
* @param config The config passed into the Rindo command
|
|
1218
|
-
* @param sys The system where the command is invoked
|
|
1219
|
-
* @param ci whether or not the process is running in a Continuous Integration (CI) environment
|
|
1220
|
-
* @returns true if telemetry should be sent, false otherwise
|
|
1221
|
-
*/
|
|
1222
|
-
async function shouldTrack(config, sys, ci) {
|
|
1223
|
-
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
1523
|
+
return !!flags.verbose && hasDebug(flags);
|
|
1224
1524
|
}
|
|
1225
1525
|
|
|
1226
1526
|
const isTest$1 = () => process.env.JEST_WORKER_ID !== undefined;
|
|
1227
|
-
const defaultConfig = (sys) => sys.resolvePath(`${sys.homeDir()}/.
|
|
1228
|
-
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`);
|
|
1229
1529
|
/**
|
|
1230
|
-
* Reads an
|
|
1530
|
+
* Reads an Family configuration file from disk, parses it, and performs any necessary corrections to it if certain
|
|
1231
1531
|
* values are deemed to be malformed
|
|
1232
1532
|
* @param sys The system where the command is invoked
|
|
1233
1533
|
* @returns the config read from disk that has been potentially been updated
|
|
@@ -1241,7 +1541,7 @@ async function readConfig(sys) {
|
|
|
1241
1541
|
};
|
|
1242
1542
|
await writeConfig(sys, config);
|
|
1243
1543
|
}
|
|
1244
|
-
else if (!UUID_REGEX.test(config['tokens.telemetry'])) {
|
|
1544
|
+
else if (!config['tokens.telemetry'] || !UUID_REGEX.test(config['tokens.telemetry'])) {
|
|
1245
1545
|
const newUuid = uuidv4();
|
|
1246
1546
|
await writeConfig(sys, { ...config, 'tokens.telemetry': newUuid });
|
|
1247
1547
|
config['tokens.telemetry'] = newUuid;
|
|
@@ -1249,7 +1549,7 @@ async function readConfig(sys) {
|
|
|
1249
1549
|
return config;
|
|
1250
1550
|
}
|
|
1251
1551
|
/**
|
|
1252
|
-
* Writes an
|
|
1552
|
+
* Writes an Family configuration file to disk.
|
|
1253
1553
|
* @param sys The system where the command is invoked
|
|
1254
1554
|
* @param config The config passed into the Rindo command
|
|
1255
1555
|
* @returns boolean If the command was successful
|
|
@@ -1267,7 +1567,7 @@ async function writeConfig(sys, config) {
|
|
|
1267
1567
|
return result;
|
|
1268
1568
|
}
|
|
1269
1569
|
/**
|
|
1270
|
-
* Update a subset of the
|
|
1570
|
+
* Update a subset of the Family config.
|
|
1271
1571
|
* @param sys The system where the command is invoked
|
|
1272
1572
|
* @param newOptions The new options to save
|
|
1273
1573
|
* @returns boolean If the command was successful
|
|
@@ -1277,14 +1577,16 @@ async function updateConfig(sys, newOptions) {
|
|
|
1277
1577
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
1278
1578
|
}
|
|
1279
1579
|
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
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
|
+
}
|
|
1288
1590
|
|
|
1289
1591
|
/**
|
|
1290
1592
|
* Used to within taskBuild to provide the component_count property.
|
|
@@ -1295,11 +1597,11 @@ const WWW = 'www';
|
|
|
1295
1597
|
* @param result The results of a compiler build.
|
|
1296
1598
|
*/
|
|
1297
1599
|
async function telemetryBuildFinishedAction(sys, config, coreCompiler, result) {
|
|
1298
|
-
const tracking = await shouldTrack(config, sys, config.flags.ci);
|
|
1600
|
+
const tracking = await shouldTrack(config, sys, !!config.flags.ci);
|
|
1299
1601
|
if (!tracking) {
|
|
1300
1602
|
return;
|
|
1301
1603
|
}
|
|
1302
|
-
const component_count = Object.keys(result.componentGraph).length;
|
|
1604
|
+
const component_count = result.componentGraph ? Object.keys(result.componentGraph).length : undefined;
|
|
1303
1605
|
const data = await prepareData(coreCompiler, config, sys, result.duration, component_count);
|
|
1304
1606
|
await sendMetric(sys, config, 'rindo_cli_command', data);
|
|
1305
1607
|
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
@@ -1378,38 +1680,41 @@ function getActiveTargets(config) {
|
|
|
1378
1680
|
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1379
1681
|
*/
|
|
1380
1682
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1683
|
+
var _a, _b, _c;
|
|
1381
1684
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1382
1685
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
1383
1686
|
const targets = getActiveTargets(config);
|
|
1384
1687
|
const yarn = isUsingYarn(sys);
|
|
1385
1688
|
const rindo = coreCompiler.version || 'unknown';
|
|
1386
1689
|
const system = `${sys.name} ${sys.version}`;
|
|
1387
|
-
const os_name = sys.details.platform;
|
|
1388
|
-
const os_version = sys.details.release;
|
|
1389
|
-
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;
|
|
1390
1693
|
const build = coreCompiler.buildId || 'unknown';
|
|
1391
1694
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1392
1695
|
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1696
|
+
const is_browser_env = IS_BROWSER_ENV;
|
|
1393
1697
|
return {
|
|
1394
|
-
|
|
1395
|
-
|
|
1698
|
+
arguments: config.flags.args,
|
|
1699
|
+
build,
|
|
1396
1700
|
component_count,
|
|
1397
|
-
|
|
1701
|
+
config: anonymizedConfig,
|
|
1702
|
+
cpu_model,
|
|
1703
|
+
duration_ms,
|
|
1704
|
+
has_app_pwa_config,
|
|
1705
|
+
is_browser_env,
|
|
1706
|
+
os_name,
|
|
1707
|
+
os_version,
|
|
1398
1708
|
packages,
|
|
1399
1709
|
packages_no_versions: packagesNoVersions,
|
|
1400
|
-
|
|
1401
|
-
task: config.flags.task,
|
|
1710
|
+
rollup,
|
|
1402
1711
|
rindo,
|
|
1403
1712
|
system,
|
|
1404
1713
|
system_major: getMajorVersion(system),
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
cpu_model,
|
|
1408
|
-
build,
|
|
1714
|
+
targets,
|
|
1715
|
+
task: config.flags.task,
|
|
1409
1716
|
typescript,
|
|
1410
|
-
|
|
1411
|
-
has_app_pwa_config,
|
|
1412
|
-
config: anonymizedConfig,
|
|
1717
|
+
yarn,
|
|
1413
1718
|
};
|
|
1414
1719
|
};
|
|
1415
1720
|
// props in output targets for which we retain their original values when
|
|
@@ -1433,7 +1738,16 @@ const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
|
1433
1738
|
// Props we delete entirely from the config for telemetry
|
|
1434
1739
|
//
|
|
1435
1740
|
// TODO: Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1436
|
-
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
|
+
];
|
|
1437
1751
|
/**
|
|
1438
1752
|
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1439
1753
|
* with a placeholder string if they are present (this lets us still track how frequently
|
|
@@ -1483,7 +1797,7 @@ const anonymizeConfigForTelemetry = (config) => {
|
|
|
1483
1797
|
/**
|
|
1484
1798
|
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1485
1799
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1486
|
-
* of each package under the @rindo, @
|
|
1800
|
+
* of each package under the @rindo, @familyjs, and @jigra scopes.
|
|
1487
1801
|
*
|
|
1488
1802
|
* @param sys the system instance where telemetry is invoked
|
|
1489
1803
|
* @param config the Rindo configuration associated with the current task that triggered telemetry
|
|
@@ -1505,16 +1819,16 @@ async function getInstalledPackages(sys, config) {
|
|
|
1505
1819
|
...packageJson.devDependencies,
|
|
1506
1820
|
...packageJson.dependencies,
|
|
1507
1821
|
});
|
|
1508
|
-
// Collect packages only in the rindo,
|
|
1822
|
+
// Collect packages only in the rindo, familyjs, or jigra org's:
|
|
1509
1823
|
// https://www.npmjs.com/org/rindo
|
|
1510
|
-
const
|
|
1824
|
+
const familyPackages = rawPackages.filter(([k]) => k.startsWith('@rindo/') || k.startsWith('@familyjs/') || k.startsWith('@jigra/'));
|
|
1511
1825
|
try {
|
|
1512
|
-
packages = yarn ? await yarnPackages(sys,
|
|
1826
|
+
packages = yarn ? await yarnPackages(sys, familyPackages) : await npmPackages(sys, familyPackages);
|
|
1513
1827
|
}
|
|
1514
1828
|
catch (e) {
|
|
1515
|
-
packages =
|
|
1829
|
+
packages = familyPackages.map(([k, v]) => `${k}@${v.replace('^', '')}`);
|
|
1516
1830
|
}
|
|
1517
|
-
packagesNoVersions =
|
|
1831
|
+
packagesNoVersions = familyPackages.map(([k]) => `${k}`);
|
|
1518
1832
|
return { packages, packagesNoVersions };
|
|
1519
1833
|
}
|
|
1520
1834
|
catch (err) {
|
|
@@ -1525,13 +1839,13 @@ async function getInstalledPackages(sys, config) {
|
|
|
1525
1839
|
/**
|
|
1526
1840
|
* Visits the npm lock file to find the exact versions that are installed
|
|
1527
1841
|
* @param sys The system where the command is invoked
|
|
1528
|
-
* @param
|
|
1842
|
+
* @param familyPackages a list of the found packages matching `@rindo`, `@jigra`, or `@familyjs` from the package.json file.
|
|
1529
1843
|
* @returns an array of strings of all the packages and their versions.
|
|
1530
1844
|
*/
|
|
1531
|
-
async function npmPackages(sys,
|
|
1845
|
+
async function npmPackages(sys, familyPackages) {
|
|
1532
1846
|
const appRootDir = sys.getCurrentDirectory();
|
|
1533
1847
|
const packageLockJson = await tryFn(readJson, sys, sys.resolvePath(appRootDir + '/package-lock.json'));
|
|
1534
|
-
return
|
|
1848
|
+
return familyPackages.map(([k, v]) => {
|
|
1535
1849
|
var _a, _b, _c, _d;
|
|
1536
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;
|
|
1537
1851
|
version = version.includes('file:') ? sanitizeDeclaredVersion(v) : version;
|
|
@@ -1541,14 +1855,14 @@ async function npmPackages(sys, navifyPackages) {
|
|
|
1541
1855
|
/**
|
|
1542
1856
|
* Visits the yarn lock file to find the exact versions that are installed
|
|
1543
1857
|
* @param sys The system where the command is invoked
|
|
1544
|
-
* @param
|
|
1858
|
+
* @param familyPackages a list of the found packages matching `@rindo`, `@jigra`, or `@familyjs` from the package.json file.
|
|
1545
1859
|
* @returns an array of strings of all the packages and their versions.
|
|
1546
1860
|
*/
|
|
1547
|
-
async function yarnPackages(sys,
|
|
1861
|
+
async function yarnPackages(sys, familyPackages) {
|
|
1548
1862
|
const appRootDir = sys.getCurrentDirectory();
|
|
1549
1863
|
const yarnLock = sys.readFileSync(sys.resolvePath(appRootDir + '/yarn.lock'));
|
|
1550
1864
|
const yarnLockYml = sys.parseYarnLockFile(yarnLock);
|
|
1551
|
-
return
|
|
1865
|
+
return familyPackages.map(([k, v]) => {
|
|
1552
1866
|
var _a;
|
|
1553
1867
|
const identifiedVersion = `${k}@${v}`;
|
|
1554
1868
|
let version = (_a = yarnLockYml.object[identifiedVersion]) === null || _a === void 0 ? void 0 : _a.version;
|
|
@@ -1613,7 +1927,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1613
1927
|
sent_at: now,
|
|
1614
1928
|
};
|
|
1615
1929
|
// This request is only made if telemetry is on.
|
|
1616
|
-
const response = await sys.fetch('https://api
|
|
1930
|
+
const response = await sys.fetch('https://familyjs-api.web.app/events/metrics', {
|
|
1617
1931
|
method: 'POST',
|
|
1618
1932
|
headers: {
|
|
1619
1933
|
'Content-Type': 'application/json',
|
|
@@ -1716,13 +2030,6 @@ const taskDocs = async (coreCompiler, config) => {
|
|
|
1716
2030
|
await compiler.destroy();
|
|
1717
2031
|
};
|
|
1718
2032
|
|
|
1719
|
-
const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
1720
|
-
typeof require === 'function' &&
|
|
1721
|
-
!!global.process &&
|
|
1722
|
-
typeof __filename === 'string' &&
|
|
1723
|
-
(!global.origin || typeof global.origin !== 'string');
|
|
1724
|
-
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1725
|
-
|
|
1726
2033
|
/**
|
|
1727
2034
|
* Task to generate component boilerplate and write it to disk. This task can
|
|
1728
2035
|
* cause the program to exit with an error under various circumstances, such as
|
|
@@ -1751,13 +2058,24 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1751
2058
|
const { prompt } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('../sys/node/prompts.js')); });
|
|
1752
2059
|
const input = config.flags.unknownArgs.find((arg) => !arg.startsWith('-')) ||
|
|
1753
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
|
+
}
|
|
1754
2066
|
const { dir, base: componentName } = path.parse(input);
|
|
1755
2067
|
const tagError = validateComponentTag(componentName);
|
|
1756
2068
|
if (tagError) {
|
|
1757
2069
|
config.logger.error(tagError);
|
|
1758
2070
|
return config.sys.exit(1);
|
|
1759
2071
|
}
|
|
1760
|
-
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];
|
|
1761
2079
|
const testFolder = extensionsToGenerate.some(isTest) ? 'test' : '';
|
|
1762
2080
|
const outDir = path.join(absoluteSrcDir, 'components', dir, componentName);
|
|
1763
2081
|
await config.sys.createDir(path.join(outDir, testFolder), { recursive: true });
|
|
@@ -1981,7 +2299,7 @@ const taskTelemetry = async (flags, sys, logger) => {
|
|
|
1981
2299
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1982
2300
|
const isEnabling = flags.args.includes('on');
|
|
1983
2301
|
const isDisabling = flags.args.includes('off');
|
|
1984
|
-
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')}`;
|
|
1985
2303
|
const THANK_YOU = `Thank you for helping to make Rindo better! 💖`;
|
|
1986
2304
|
const ENABLED_MESSAGE = `${logger.green('Enabled')}. ${THANK_YOU}\n\n`;
|
|
1987
2305
|
const DISABLED_MESSAGE = `${logger.red('Disabled')}\n\n`;
|
|
@@ -2104,93 +2422,54 @@ const taskServe = async (config) => {
|
|
|
2104
2422
|
};
|
|
2105
2423
|
|
|
2106
2424
|
/**
|
|
2107
|
-
*
|
|
2108
|
-
* @
|
|
2425
|
+
* Entrypoint for any Rindo tests
|
|
2426
|
+
* @param config a validated Rindo configuration entity
|
|
2109
2427
|
*/
|
|
2110
|
-
const
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
enableColors: (uc) => (useColors = uc),
|
|
2115
|
-
getLevel: () => level,
|
|
2116
|
-
setLevel: (l) => (level = l),
|
|
2117
|
-
emoji: (e) => e,
|
|
2118
|
-
info: console.log.bind(console),
|
|
2119
|
-
warn: console.warn.bind(console),
|
|
2120
|
-
error: console.error.bind(console),
|
|
2121
|
-
debug: console.debug.bind(console),
|
|
2122
|
-
red: (msg) => msg,
|
|
2123
|
-
green: (msg) => msg,
|
|
2124
|
-
yellow: (msg) => msg,
|
|
2125
|
-
blue: (msg) => msg,
|
|
2126
|
-
magenta: (msg) => msg,
|
|
2127
|
-
cyan: (msg) => msg,
|
|
2128
|
-
gray: (msg) => msg,
|
|
2129
|
-
bold: (msg) => msg,
|
|
2130
|
-
dim: (msg) => msg,
|
|
2131
|
-
bgRed: (msg) => msg,
|
|
2132
|
-
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
2133
|
-
duration: () => 0,
|
|
2134
|
-
finish: () => 0,
|
|
2135
|
-
}),
|
|
2136
|
-
printDiagnostics(diagnostics) {
|
|
2137
|
-
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
2138
|
-
},
|
|
2139
|
-
};
|
|
2140
|
-
};
|
|
2141
|
-
const logDiagnostic = (diagnostic, useColors) => {
|
|
2142
|
-
let color = BLUE;
|
|
2143
|
-
let prefix = 'Build';
|
|
2144
|
-
let msg = '';
|
|
2145
|
-
if (diagnostic.level === 'error') {
|
|
2146
|
-
color = RED;
|
|
2147
|
-
prefix = 'Error';
|
|
2148
|
-
}
|
|
2149
|
-
else if (diagnostic.level === 'warn') {
|
|
2150
|
-
color = YELLOW;
|
|
2151
|
-
prefix = 'Warning';
|
|
2152
|
-
}
|
|
2153
|
-
if (diagnostic.header) {
|
|
2154
|
-
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);
|
|
2155
2432
|
}
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
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.`));
|
|
2164
2450
|
}
|
|
2165
|
-
msg += '\n';
|
|
2166
|
-
}
|
|
2167
|
-
msg += diagnostic.messageText;
|
|
2168
|
-
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
2169
|
-
diagnostic.lines.forEach((l) => {
|
|
2170
|
-
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
2171
|
-
});
|
|
2172
|
-
msg += '\n';
|
|
2173
2451
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
console.log(...styledPrefix, msg);
|
|
2180
|
-
}
|
|
2181
|
-
else if (diagnostic.level === 'error') {
|
|
2182
|
-
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);
|
|
2183
2457
|
}
|
|
2184
|
-
|
|
2185
|
-
|
|
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
|
+
}
|
|
2186
2467
|
}
|
|
2187
|
-
|
|
2188
|
-
|
|
2468
|
+
catch (e) {
|
|
2469
|
+
config.logger.error(e);
|
|
2470
|
+
return config.sys.exit(1);
|
|
2189
2471
|
}
|
|
2190
|
-
};
|
|
2191
|
-
const YELLOW = `#f39c12`;
|
|
2192
|
-
const RED = `#c0392b`;
|
|
2193
|
-
const BLUE = `#3498db`;
|
|
2472
|
+
};
|
|
2194
2473
|
|
|
2195
2474
|
const run = async (init) => {
|
|
2196
2475
|
const { args, logger, sys } = init;
|
|
@@ -2206,7 +2485,7 @@ const run = async (init) => {
|
|
|
2206
2485
|
if (isFunction(sys.applyGlobalPatch)) {
|
|
2207
2486
|
sys.applyGlobalPatch(sys.getCurrentDirectory());
|
|
2208
2487
|
}
|
|
2209
|
-
if (task === 'help' || flags.help) {
|
|
2488
|
+
if (!task || task === 'help' || flags.help) {
|
|
2210
2489
|
await taskHelp(createConfigFlags({ task: 'help', args }), logger, sys);
|
|
2211
2490
|
return;
|
|
2212
2491
|
}
|
|
@@ -2309,6 +2588,9 @@ const runTask = async (coreCompiler, config, task, sys) => {
|
|
|
2309
2588
|
case 'telemetry':
|
|
2310
2589
|
await taskTelemetry(strictConfig.flags, sys, strictConfig.logger);
|
|
2311
2590
|
break;
|
|
2591
|
+
case 'test':
|
|
2592
|
+
await taskTest(strictConfig);
|
|
2593
|
+
break;
|
|
2312
2594
|
case 'version':
|
|
2313
2595
|
console.log(coreCompiler.version);
|
|
2314
2596
|
break;
|