@stencil/core 2.17.0 → 2.17.1

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.
Files changed (49) hide show
  1. package/cli/config-flags.d.ts +102 -0
  2. package/cli/index.cjs +603 -220
  3. package/cli/index.d.ts +2 -1
  4. package/cli/index.js +603 -220
  5. package/cli/package.json +1 -1
  6. package/compiler/package.json +1 -1
  7. package/compiler/stencil.js +337 -174
  8. package/compiler/stencil.min.js +2 -2
  9. package/dependencies.json +1 -1
  10. package/dev-server/client/index.js +1 -1
  11. package/dev-server/client/package.json +1 -1
  12. package/dev-server/connector.html +2 -2
  13. package/dev-server/index.js +1 -1
  14. package/dev-server/package.json +1 -1
  15. package/dev-server/server-process.js +2 -2
  16. package/internal/app-data/package.json +1 -1
  17. package/internal/client/css-shim.js +1 -1
  18. package/internal/client/dom.js +1 -1
  19. package/internal/client/index.js +11 -6
  20. package/internal/client/package.json +1 -1
  21. package/internal/client/patch-browser.js +1 -1
  22. package/internal/client/patch-esm.js +1 -1
  23. package/internal/client/shadow-css.js +1 -1
  24. package/internal/hydrate/index.js +2 -2
  25. package/internal/hydrate/package.json +1 -1
  26. package/internal/package.json +1 -1
  27. package/internal/stencil-private.d.ts +2 -2
  28. package/internal/stencil-public-compiler.d.ts +67 -48
  29. package/internal/testing/index.js +1 -1
  30. package/internal/testing/package.json +1 -1
  31. package/mock-doc/index.cjs +1 -1
  32. package/mock-doc/index.js +1 -1
  33. package/mock-doc/package.json +1 -1
  34. package/package.json +2 -1
  35. package/screenshot/package.json +1 -1
  36. package/sys/node/index.js +4 -4
  37. package/sys/node/package.json +1 -1
  38. package/sys/node/worker.js +1 -1
  39. package/testing/index.d.ts +1 -1
  40. package/testing/index.js +40 -24
  41. package/testing/jest/jest-config.d.ts +1 -1
  42. package/testing/jest/jest-runner.d.ts +3 -2
  43. package/testing/jest/jest-screenshot.d.ts +1 -1
  44. package/testing/mocks.d.ts +27 -2
  45. package/testing/package.json +1 -1
  46. package/testing/puppeteer/puppeteer-browser.d.ts +2 -2
  47. package/testing/test/testing-utils.spec.d.ts +1 -0
  48. package/testing/testing-utils.d.ts +74 -2
  49. package/testing/testing.d.ts +2 -2
package/cli/index.js CHANGED
@@ -1,8 +1,50 @@
1
1
  /*!
2
- Stencil CLI v2.17.0 | MIT Licensed | https://stenciljs.com
2
+ Stencil CLI v2.17.1 | MIT Licensed | https://stenciljs.com
3
3
  */
4
- const toLowerCase = (str) => str.toLowerCase();
5
- const dashToPascalCase = (str) => toLowerCase(str)
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
+ /**
40
+ * Convert a string from dash-case / kebab-case to PascalCase (or CamelCase,
41
+ * or whatever you call it!)
42
+ *
43
+ * @param str a string to convert
44
+ * @returns a converted string
45
+ */
46
+ const dashToPascalCase = (str) => str
47
+ .toLowerCase()
6
48
  .split('-')
7
49
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
8
50
  .join('');
@@ -275,22 +317,211 @@ const validateComponentTag = (tag) => {
275
317
  return undefined;
276
318
  };
277
319
 
320
+ /**
321
+ * All the Boolean options supported by the Stencil CLI
322
+ */
323
+ const BOOLEAN_CLI_ARGS = [
324
+ 'build',
325
+ 'cache',
326
+ 'checkVersion',
327
+ 'ci',
328
+ 'compare',
329
+ 'debug',
330
+ 'dev',
331
+ 'devtools',
332
+ 'docs',
333
+ 'e2e',
334
+ 'es5',
335
+ 'esm',
336
+ 'headless',
337
+ 'help',
338
+ 'log',
339
+ 'open',
340
+ 'prerender',
341
+ 'prerenderExternal',
342
+ 'prod',
343
+ 'profile',
344
+ 'serviceWorker',
345
+ 'screenshot',
346
+ 'serve',
347
+ 'skipNodeCheck',
348
+ 'spec',
349
+ 'ssr',
350
+ 'stats',
351
+ 'updateScreenshot',
352
+ 'verbose',
353
+ 'version',
354
+ 'watch',
355
+ // JEST CLI OPTIONS
356
+ 'all',
357
+ 'automock',
358
+ 'bail',
359
+ // 'cache', Stencil already supports this argument
360
+ 'changedFilesWithAncestor',
361
+ // 'ci', Stencil already supports this argument
362
+ 'clearCache',
363
+ 'clearMocks',
364
+ 'collectCoverage',
365
+ 'color',
366
+ 'colors',
367
+ 'coverage',
368
+ // 'debug', Stencil already supports this argument
369
+ 'detectLeaks',
370
+ 'detectOpenHandles',
371
+ 'errorOnDeprecated',
372
+ 'expand',
373
+ 'findRelatedTests',
374
+ 'forceExit',
375
+ 'init',
376
+ 'injectGlobals',
377
+ 'json',
378
+ 'lastCommit',
379
+ 'listTests',
380
+ 'logHeapUsage',
381
+ 'noStackTrace',
382
+ 'notify',
383
+ 'onlyChanged',
384
+ 'onlyFailures',
385
+ 'passWithNoTests',
386
+ 'resetMocks',
387
+ 'resetModules',
388
+ 'restoreMocks',
389
+ 'runInBand',
390
+ 'runTestsByPath',
391
+ 'showConfig',
392
+ 'silent',
393
+ 'skipFilter',
394
+ 'testLocationInResults',
395
+ 'updateSnapshot',
396
+ 'useStderr',
397
+ // 'verbose', Stencil already supports this argument
398
+ // 'version', Stencil already supports this argument
399
+ // 'watch', Stencil already supports this argument
400
+ 'watchAll',
401
+ 'watchman',
402
+ ];
403
+ /**
404
+ * All the Number options supported by the Stencil CLI
405
+ */
406
+ const NUMBER_CLI_ARGS = [
407
+ 'port',
408
+ // JEST CLI ARGS
409
+ 'maxConcurrency',
410
+ 'testTimeout',
411
+ ];
412
+ /**
413
+ * All the String options supported by the Stencil CLI
414
+ */
415
+ const STRING_CLI_ARGS = [
416
+ 'address',
417
+ 'config',
418
+ 'docsApi',
419
+ 'docsJson',
420
+ 'emulate',
421
+ 'root',
422
+ 'screenshotConnector',
423
+ // JEST CLI ARGS
424
+ 'cacheDirectory',
425
+ 'changedSince',
426
+ 'collectCoverageFrom',
427
+ // 'config', Stencil already supports this argument
428
+ 'coverageDirectory',
429
+ 'coverageThreshold',
430
+ 'env',
431
+ 'filter',
432
+ 'globalSetup',
433
+ 'globalTeardown',
434
+ 'globals',
435
+ 'haste',
436
+ 'moduleNameMapper',
437
+ 'notifyMode',
438
+ 'outputFile',
439
+ 'preset',
440
+ 'prettierPath',
441
+ 'resolver',
442
+ 'rootDir',
443
+ 'runner',
444
+ 'testEnvironment',
445
+ 'testEnvironmentOptions',
446
+ 'testFailureExitCode',
447
+ 'testNamePattern',
448
+ 'testResultsProcessor',
449
+ 'testRunner',
450
+ 'testSequencer',
451
+ 'testURL',
452
+ 'timers',
453
+ 'transform',
454
+ // ARRAY ARGS
455
+ 'collectCoverageOnlyFrom',
456
+ 'coveragePathIgnorePatterns',
457
+ 'coverageReporters',
458
+ 'moduleDirectories',
459
+ 'moduleFileExtensions',
460
+ 'modulePathIgnorePatterns',
461
+ 'modulePaths',
462
+ 'projects',
463
+ 'reporters',
464
+ 'roots',
465
+ 'selectProjects',
466
+ 'setupFiles',
467
+ 'setupFilesAfterEnv',
468
+ 'snapshotSerializers',
469
+ 'testMatch',
470
+ 'testPathIgnorePatterns',
471
+ 'testPathPattern',
472
+ 'testRegex',
473
+ 'transformIgnorePatterns',
474
+ 'unmockedModulePathPatterns',
475
+ 'watchPathIgnorePatterns',
476
+ ];
477
+ /**
478
+ * All the CLI arguments which may have string or number values
479
+ *
480
+ * `maxWorkers` is an argument which is used both by Stencil _and_ by Jest,
481
+ * which means that we need to support parsing both string and number values.
482
+ */
483
+ const STRING_NUMBER_CLI_ARGS = ['maxWorkers'];
484
+ /**
485
+ * All the LogLevel-type options supported by the Stencil CLI
486
+ *
487
+ * This is a bit silly since there's only one such argument atm,
488
+ * but this approach lets us make sure that we're handling all
489
+ * our arguments in a type-safe way.
490
+ */
491
+ const LOG_LEVEL_CLI_ARGS = ['logLevel'];
492
+ /**
493
+ * For a small subset of CLI options we support a short alias e.g. `'h'` for `'help'`
494
+ */
495
+ const CLI_ARG_ALIASES = {
496
+ config: 'c',
497
+ help: 'h',
498
+ port: 'p',
499
+ version: 'v',
500
+ };
501
+
502
+ /**
503
+ * Parse command line arguments into a structured `ConfigFlags` object
504
+ *
505
+ * @param args an array of config flags
506
+ * @param sys an optional compiler system
507
+ * @returns a structured ConfigFlags object
508
+ */
278
509
  const parseFlags = (args, sys) => {
279
510
  const flags = {
280
511
  task: null,
281
512
  args: [],
282
513
  knownArgs: [],
283
- unknownArgs: null,
514
+ unknownArgs: [],
284
515
  };
285
516
  // cmd line has more priority over npm scripts cmd
286
- flags.args = args.slice();
517
+ flags.args = Array.isArray(args) ? args.slice() : [];
287
518
  if (flags.args.length > 0 && flags.args[0] && !flags.args[0].startsWith('-')) {
288
519
  flags.task = flags.args[0];
289
520
  }
290
- parseArgs(flags, flags.args, flags.knownArgs);
521
+ parseArgs(flags, flags.args);
291
522
  if (sys && sys.name === 'node') {
292
523
  const envArgs = getNpmConfigEnvArgs(sys);
293
- parseArgs(flags, envArgs, flags.knownArgs);
524
+ parseArgs(flags, envArgs);
294
525
  envArgs.forEach((envArg) => {
295
526
  if (!flags.args.includes(envArg)) {
296
527
  flags.args.push(envArg);
@@ -309,185 +540,230 @@ const parseFlags = (args, sys) => {
309
540
  return flags;
310
541
  };
311
542
  /**
312
- * Parse command line arguments that are whitelisted via the BOOLEAN_ARG_OPTS,
313
- * STRING_ARG_OPTS, and NUMBER_ARG_OPTS arrays in this file. Handles leading
314
- * dashes on arguments, aliases that are defined for a small number of argument
315
- * types, and parsing values for non-boolean arguments (e.g. port number).
543
+ * Parse command line arguments that are enumerated in the `config-flags`
544
+ * module. Handles leading dashes on arguments, aliases that are defined for a
545
+ * small number of arguments, and parsing values for non-boolean arguments
546
+ * (e.g. port number for the dev server).
316
547
  *
317
- * @param flags a ConfigFlags object
318
- * @param args an array of command-line arguments to parse
319
- * @param knownArgs an array to which all recognized, legal arguments are added
320
- */
321
- const parseArgs = (flags, args, knownArgs) => {
322
- BOOLEAN_ARG_OPTS.forEach((booleanName) => {
323
- const alias = ARG_OPTS_ALIASES[booleanName];
324
- const flagKey = configCase(booleanName);
325
- if (typeof flags[flagKey] !== 'boolean') {
326
- flags[flagKey] = null;
548
+ * @param flags a ConfigFlags object to which parsed arguments will be added
549
+ * @param args an array of command-line arguments to parse
550
+ */
551
+ const parseArgs = (flags, args) => {
552
+ BOOLEAN_CLI_ARGS.forEach((argName) => parseBooleanArg(flags, args, argName));
553
+ STRING_CLI_ARGS.forEach((argName) => parseStringArg(flags, args, argName));
554
+ NUMBER_CLI_ARGS.forEach((argName) => parseNumberArg(flags, args, argName));
555
+ STRING_NUMBER_CLI_ARGS.forEach((argName) => parseStringNumberArg(flags, args, argName));
556
+ LOG_LEVEL_CLI_ARGS.forEach((argName) => parseLogLevelArg(flags, args, argName));
557
+ };
558
+ /**
559
+ * Parse a boolean CLI argument. For these, we support the following formats:
560
+ *
561
+ * - `--booleanArg`
562
+ * - `--boolean-arg`
563
+ * - `--noBooleanArg`
564
+ * - `--no-boolean-arg`
565
+ *
566
+ * The final two variants should be parsed to a value of `false` on the config
567
+ * object.
568
+ *
569
+ * @param flags the config flags object, while we'll modify
570
+ * @param args our CLI arguments
571
+ * @param configCaseName the argument we want to look at right now
572
+ */
573
+ const parseBooleanArg = (flags, args, configCaseName) => {
574
+ // we support both dash-case and PascalCase versions of the parameter
575
+ // argName is 'configCase' version which can be found in BOOLEAN_ARG_OPTS
576
+ const alias = CLI_ARG_ALIASES[configCaseName];
577
+ const dashCaseName = toDashCase(configCaseName);
578
+ if (typeof flags[configCaseName] !== 'boolean') {
579
+ flags[configCaseName] = null;
580
+ }
581
+ args.forEach((cmdArg) => {
582
+ let value;
583
+ if (cmdArg === `--${configCaseName}` || cmdArg === `--${dashCaseName}`) {
584
+ value = true;
327
585
  }
328
- args.forEach((cmdArg) => {
329
- if (cmdArg === `--${booleanName}`) {
330
- flags[flagKey] = true;
331
- knownArgs.push(cmdArg);
332
- }
333
- else if (cmdArg === `--${flagKey}`) {
334
- flags[flagKey] = true;
335
- knownArgs.push(cmdArg);
336
- }
337
- else if (cmdArg === `--no-${booleanName}`) {
338
- flags[flagKey] = false;
339
- knownArgs.push(cmdArg);
340
- }
341
- else if (cmdArg === `--no${dashToPascalCase(booleanName)}`) {
342
- flags[flagKey] = false;
343
- knownArgs.push(cmdArg);
344
- }
345
- else if (alias && cmdArg === `-${alias}`) {
346
- flags[flagKey] = true;
347
- knownArgs.push(cmdArg);
348
- }
349
- });
350
- });
351
- STRING_ARG_OPTS.forEach((stringName) => {
352
- const alias = ARG_OPTS_ALIASES[stringName];
353
- const flagKey = configCase(stringName);
354
- if (typeof flags[flagKey] !== 'string') {
355
- flags[flagKey] = null;
586
+ else if (cmdArg === `--no-${dashCaseName}` || cmdArg === `--no${dashToPascalCase(dashCaseName)}`) {
587
+ value = false;
356
588
  }
357
- for (let i = 0; i < args.length; i++) {
358
- const cmdArg = args[i];
359
- if (cmdArg.startsWith(`--${stringName}=`)) {
360
- const values = cmdArg.split('=');
361
- values.shift();
362
- flags[flagKey] = values.join('=');
363
- knownArgs.push(cmdArg);
364
- }
365
- else if (cmdArg === `--${stringName}`) {
366
- flags[flagKey] = args[i + 1];
367
- knownArgs.push(cmdArg);
368
- knownArgs.push(args[i + 1]);
369
- }
370
- else if (cmdArg === `--${flagKey}`) {
371
- flags[flagKey] = args[i + 1];
372
- knownArgs.push(cmdArg);
373
- knownArgs.push(args[i + 1]);
374
- }
375
- else if (cmdArg.startsWith(`--${flagKey}=`)) {
376
- const values = cmdArg.split('=');
377
- values.shift();
378
- flags[flagKey] = values.join('=');
379
- knownArgs.push(cmdArg);
380
- }
381
- else if (alias) {
382
- if (cmdArg.startsWith(`-${alias}=`)) {
383
- const values = cmdArg.split('=');
384
- values.shift();
385
- flags[flagKey] = values.join('=');
386
- knownArgs.push(cmdArg);
387
- }
388
- else if (cmdArg === `-${alias}`) {
389
- flags[flagKey] = args[i + 1];
390
- knownArgs.push(args[i + 1]);
391
- }
392
- }
589
+ else if (alias && cmdArg === `-${alias}`) {
590
+ value = true;
591
+ }
592
+ if (value !== undefined && cmdArg !== undefined) {
593
+ flags[configCaseName] = value;
594
+ flags.knownArgs.push(cmdArg);
393
595
  }
394
596
  });
395
- NUMBER_ARG_OPTS.forEach((numberName) => {
396
- const alias = ARG_OPTS_ALIASES[numberName];
397
- const flagKey = configCase(numberName);
398
- if (typeof flags[flagKey] !== 'number') {
399
- flags[flagKey] = null;
597
+ };
598
+ /**
599
+ * Parse a string CLI argument
600
+ *
601
+ * @param flags the config flags object, while we'll modify
602
+ * @param args our CLI arguments
603
+ * @param configCaseName the argument we want to look at right now
604
+ */
605
+ const parseStringArg = (flags, args, configCaseName) => {
606
+ if (typeof flags[configCaseName] !== 'string') {
607
+ flags[configCaseName] = null;
608
+ }
609
+ const { value, matchingArg } = getValue(args, configCaseName);
610
+ if (value !== undefined && matchingArg !== undefined) {
611
+ flags[configCaseName] = value;
612
+ flags.knownArgs.push(matchingArg);
613
+ flags.knownArgs.push(value);
614
+ }
615
+ };
616
+ /**
617
+ * Parse a number CLI argument
618
+ *
619
+ * @param flags the config flags object, while we'll modify
620
+ * @param args our CLI arguments
621
+ * @param configCaseName the argument we want to look at right now
622
+ */
623
+ const parseNumberArg = (flags, args, configCaseName) => {
624
+ if (typeof flags[configCaseName] !== 'number') {
625
+ flags[configCaseName] = null;
626
+ }
627
+ const { value, matchingArg } = getValue(args, configCaseName);
628
+ if (value !== undefined && matchingArg !== undefined) {
629
+ flags[configCaseName] = parseInt(value, 10);
630
+ flags.knownArgs.push(matchingArg);
631
+ flags.knownArgs.push(value);
632
+ }
633
+ };
634
+ /**
635
+ * Parse a CLI argument which may be either a string or a number
636
+ *
637
+ * @param flags the config flags object, while we'll modify
638
+ * @param args our CLI arguments
639
+ * @param configCaseName the argument we want to look at right now
640
+ */
641
+ const parseStringNumberArg = (flags, args, configCaseName) => {
642
+ if (!['number', 'string'].includes(typeof flags[configCaseName])) {
643
+ flags[configCaseName] = null;
644
+ }
645
+ const { value, matchingArg } = getValue(args, configCaseName);
646
+ if (value !== undefined && matchingArg !== undefined) {
647
+ if (CLI_ARG_STRING_REGEX.test(value)) {
648
+ // if it matches the regex we treat it like a string
649
+ flags[configCaseName] = value;
400
650
  }
401
- for (let i = 0; i < args.length; i++) {
402
- const cmdArg = args[i];
403
- if (cmdArg.startsWith(`--${numberName}=`)) {
404
- const values = cmdArg.split('=');
405
- values.shift();
406
- flags[flagKey] = parseInt(values.join(''), 10);
407
- knownArgs.push(cmdArg);
408
- }
409
- else if (cmdArg === `--${numberName}`) {
410
- flags[flagKey] = parseInt(args[i + 1], 10);
411
- knownArgs.push(args[i + 1]);
412
- }
413
- else if (cmdArg.startsWith(`--${flagKey}=`)) {
414
- const values = cmdArg.split('=');
415
- values.shift();
416
- flags[flagKey] = parseInt(values.join(''), 10);
417
- knownArgs.push(cmdArg);
418
- }
419
- else if (cmdArg === `--${flagKey}`) {
420
- flags[flagKey] = parseInt(args[i + 1], 10);
421
- knownArgs.push(args[i + 1]);
651
+ else {
652
+ // it was a number, great!
653
+ flags[configCaseName] = Number(value);
654
+ }
655
+ flags.knownArgs.push(matchingArg);
656
+ flags.knownArgs.push(value);
657
+ }
658
+ };
659
+ /**
660
+ * We use this regular expression to detect CLI parameters which
661
+ * should be parsed as string values (as opposed to numbers) for
662
+ * the argument types for which we support both a string and a
663
+ * number value.
664
+ *
665
+ * The regex tests for the presence of at least one character which is
666
+ * _not_ a digit (`\d`), a period (`\.`), or one of the characters `"e"`,
667
+ * `"E"`, `"+"`, or `"-"` (the latter four characters are necessary to
668
+ * support the admittedly unlikely use of scientific notation, like `"4e+0"`
669
+ * for `4`).
670
+ *
671
+ * Thus we'll match a string like `"50%"`, but not a string like `"50"` or
672
+ * `"5.0"`. If it matches a given string we conclude that the string should
673
+ * be parsed as a string literal, rather than using `Number` to convert it
674
+ * to a number.
675
+ */
676
+ const CLI_ARG_STRING_REGEX = /[^\d\.Ee\+\-]+/g;
677
+ /**
678
+ * Parse a LogLevel CLI argument. These can be only a specific
679
+ * set of strings, so this function takes care of validating that
680
+ * the value is correct.
681
+ *
682
+ * @param flags the config flags object, while we'll modify
683
+ * @param args our CLI arguments
684
+ * @param configCaseName the argument we want to look at right now
685
+ */
686
+ const parseLogLevelArg = (flags, args, configCaseName) => {
687
+ if (typeof flags[configCaseName] !== 'string') {
688
+ flags[configCaseName] = null;
689
+ }
690
+ const { value, matchingArg } = getValue(args, configCaseName);
691
+ if (value !== undefined && matchingArg !== undefined && isLogLevel(value)) {
692
+ flags[configCaseName] = value;
693
+ flags.knownArgs.push(matchingArg);
694
+ flags.knownArgs.push(value);
695
+ }
696
+ };
697
+ /**
698
+ * Helper for pulling values out from the raw array of CLI arguments. This logic
699
+ * is shared between a few different types of CLI args.
700
+ *
701
+ * We look for arguments in the following formats:
702
+ *
703
+ * - `--my-cli-argument value`
704
+ * - `--my-cli-argument=value`
705
+ * - `--myCliArgument value`
706
+ * - `--myCliArgument=value`
707
+ *
708
+ * We also check for shortened aliases, which we define for a few arguments.
709
+ *
710
+ * @param args the CLI args we're dealing with
711
+ * @param configCaseName the ConfigFlag key which we're looking to pull out a value for
712
+ * @returns the value for the flag as well as the exact string which it matched from
713
+ * the user input.
714
+ */
715
+ const getValue = (args, configCaseName) => {
716
+ // for some CLI args we have a short alias, like 'c' for 'config'
717
+ const alias = CLI_ARG_ALIASES[configCaseName];
718
+ // we support supplying arguments in both dash-case and configCase
719
+ // for ease of use
720
+ const dashCaseName = toDashCase(configCaseName);
721
+ let value;
722
+ let matchingArg;
723
+ args.forEach((arg, i) => {
724
+ if (arg.startsWith(`--${dashCaseName}=`) || arg.startsWith(`--${configCaseName}=`)) {
725
+ value = getEqualsValue(arg);
726
+ matchingArg = arg;
727
+ }
728
+ else if (arg === `--${dashCaseName}` || arg === `--${configCaseName}`) {
729
+ value = args[i + 1];
730
+ matchingArg = arg;
731
+ }
732
+ else if (alias) {
733
+ if (arg.startsWith(`-${alias}=`)) {
734
+ value = getEqualsValue(arg);
735
+ matchingArg = arg;
422
736
  }
423
- else if (alias) {
424
- if (cmdArg.startsWith(`-${alias}=`)) {
425
- const values = cmdArg.split('=');
426
- values.shift();
427
- flags[flagKey] = parseInt(values.join(''), 10);
428
- knownArgs.push(cmdArg);
429
- }
430
- else if (cmdArg === `-${alias}`) {
431
- flags[flagKey] = parseInt(args[i + 1], 10);
432
- knownArgs.push(args[i + 1]);
433
- }
737
+ else if (arg === `-${alias}`) {
738
+ value = args[i + 1];
739
+ matchingArg = arg;
434
740
  }
435
741
  }
436
742
  });
743
+ return { value, matchingArg };
437
744
  };
438
- const configCase = (prop) => {
439
- prop = dashToPascalCase(prop);
440
- return prop.charAt(0).toLowerCase() + prop.slice(1);
441
- };
442
- const BOOLEAN_ARG_OPTS = [
443
- 'build',
444
- 'cache',
445
- 'check-version',
446
- 'ci',
447
- 'compare',
448
- 'debug',
449
- 'dev',
450
- 'devtools',
451
- 'docs',
452
- 'e2e',
453
- 'es5',
454
- 'esm',
455
- 'headless',
456
- 'help',
457
- 'log',
458
- 'open',
459
- 'prerender',
460
- 'prerender-external',
461
- 'prod',
462
- 'profile',
463
- 'service-worker',
464
- 'screenshot',
465
- 'serve',
466
- 'skip-node-check',
467
- 'spec',
468
- 'ssr',
469
- 'stats',
470
- 'update-screenshot',
471
- 'verbose',
472
- 'version',
473
- 'watch',
474
- ];
475
- const NUMBER_ARG_OPTS = ['max-workers', 'port'];
476
- const STRING_ARG_OPTS = [
477
- 'address',
478
- 'config',
479
- 'docs-json',
480
- 'emulate',
481
- 'log-level',
482
- 'root',
483
- 'screenshot-connector',
484
- ];
485
- const ARG_OPTS_ALIASES = {
486
- config: 'c',
487
- help: 'h',
488
- port: 'p',
489
- version: 'v',
490
- };
745
+ /**
746
+ * When a parameter is set in the format `--foobar=12` at the CLI (as opposed to
747
+ * `--foobar 12`) we want to get the value after the `=` sign
748
+ *
749
+ * @param commandArgument the arg in question
750
+ * @returns the value after the `=`
751
+ */
752
+ const getEqualsValue = (commandArgument) => commandArgument.split('=').slice(1).join('=');
753
+ /**
754
+ * Small helper for getting type-system-level assurance that a `string` can be
755
+ * narrowed to a `LogLevel`
756
+ *
757
+ * @param maybeLogLevel the string to check
758
+ * @returns whether this is a `LogLevel`
759
+ */
760
+ const isLogLevel = (maybeLogLevel) =>
761
+ // unfortunately `includes` is typed on `ReadonlyArray<T>` as `(el: T):
762
+ // boolean` so a `string` cannot be passed to `includes` on a
763
+ // `ReadonlyArray` 😢 thus we `as any`
764
+ //
765
+ // see microsoft/TypeScript#31018 for some discussion of this
766
+ LOG_LEVELS.includes(maybeLogLevel);
491
767
  const getNpmConfigEnvArgs = (sys) => {
492
768
  // process.env.npm_config_argv
493
769
  // {"remain":["4444"],"cooked":["run","serve","--port","4444"],"original":["run","serve","--port","4444"]}
@@ -508,7 +784,7 @@ const getNpmConfigEnvArgs = (sys) => {
508
784
  const dependencies = [
509
785
  {
510
786
  name: "@stencil/core",
511
- version: "2.17.0",
787
+ version: "2.17.1",
512
788
  main: "compiler/stencil.js",
513
789
  resources: [
514
790
  "package.json",
@@ -833,12 +1109,11 @@ const tryFn = async (fn, ...args) => {
833
1109
  }
834
1110
  return null;
835
1111
  };
836
- const isInteractive = (sys, config, object) => {
837
- var _a;
1112
+ const isInteractive = (sys, flags, object) => {
838
1113
  const terminalInfo = object ||
839
1114
  Object.freeze({
840
1115
  tty: sys.isTTY() ? true : false,
841
- ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!((_a = config.flags) === null || _a === void 0 ? void 0 : _a.ci),
1116
+ ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!flags.ci,
842
1117
  });
843
1118
  return terminalInfo.tty && !terminalInfo.ci;
844
1119
  };
@@ -863,19 +1138,19 @@ async function readJson(sys, path) {
863
1138
  }
864
1139
  /**
865
1140
  * Does the command have the debug flag?
866
- * @param config The config passed into the Stencil command
1141
+ * @param flags The configuration flags passed into the Stencil command
867
1142
  * @returns true if --debug has been passed, otherwise false
868
1143
  */
869
- function hasDebug(config) {
870
- return config.flags.debug;
1144
+ function hasDebug(flags) {
1145
+ return flags.debug;
871
1146
  }
872
1147
  /**
873
1148
  * Does the command have the verbose and debug flags?
874
- * @param config The config passed into the Stencil command
1149
+ * @param flags The configuration flags passed into the Stencil command
875
1150
  * @returns true if both --debug and --verbose have been passed, otherwise false
876
1151
  */
877
- function hasVerbose(config) {
878
- return config.flags.verbose && hasDebug(config);
1152
+ function hasVerbose(flags) {
1153
+ return flags.verbose && hasDebug(flags);
879
1154
  }
880
1155
 
881
1156
  /**
@@ -886,7 +1161,7 @@ function hasVerbose(config) {
886
1161
  * @returns true if telemetry should be sent, false otherwise
887
1162
  */
888
1163
  async function shouldTrack(config, sys, ci) {
889
- return !ci && isInteractive(sys, config) && (await checkTelemetry(sys));
1164
+ return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
890
1165
  }
891
1166
 
892
1167
  const isTest$1 = () => process.env.JEST_WORKER_ID !== undefined;
@@ -957,11 +1232,10 @@ const WWW = 'www';
957
1232
  *
958
1233
  * @param sys The system where the command is invoked
959
1234
  * @param config The config passed into the Stencil command
960
- * @param logger The tool used to do logging
961
1235
  * @param coreCompiler The compiler used to do builds
962
1236
  * @param result The results of a compiler build.
963
1237
  */
964
- async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, result) {
1238
+ async function telemetryBuildFinishedAction(sys, config, coreCompiler, result) {
965
1239
  const tracking = await shouldTrack(config, sys, config.flags.ci);
966
1240
  if (!tracking) {
967
1241
  return;
@@ -969,21 +1243,19 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
969
1243
  const component_count = Object.keys(result.componentGraph).length;
970
1244
  const data = await prepareData(coreCompiler, config, sys, result.duration, component_count);
971
1245
  await sendMetric(sys, config, 'stencil_cli_command', data);
972
- logger.debug(`${logger.blue('Telemetry')}: ${logger.gray(JSON.stringify(data))}`);
1246
+ config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
973
1247
  }
974
1248
  /**
975
1249
  * A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
976
1250
  *
977
1251
  * @param sys The system where the command is invoked
978
1252
  * @param config The config passed into the Stencil command
979
- * @param logger The tool used to do logging
980
1253
  * @param coreCompiler The compiler used to do builds
981
1254
  * @param action A Promise-based function to call in order to get the duration of any given command.
982
1255
  * @returns void
983
1256
  */
984
- async function telemetryAction(sys, config, logger, coreCompiler, action) {
985
- var _a;
986
- const tracking = await shouldTrack(config, sys, !!((_a = config === null || config === void 0 ? void 0 : config.flags) === null || _a === void 0 ? void 0 : _a.ci));
1257
+ async function telemetryAction(sys, config, coreCompiler, action) {
1258
+ const tracking = await shouldTrack(config, sys, !!config.flags.ci);
987
1259
  let duration = undefined;
988
1260
  let error;
989
1261
  if (action) {
@@ -1003,7 +1275,7 @@ async function telemetryAction(sys, config, logger, coreCompiler, action) {
1003
1275
  }
1004
1276
  const data = await prepareData(coreCompiler, config, sys, duration);
1005
1277
  await sendMetric(sys, config, 'stencil_cli_command', data);
1006
- logger.debug(`${logger.blue('Telemetry')}: ${logger.gray(JSON.stringify(data))}`);
1278
+ config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
1007
1279
  if (error) {
1008
1280
  throw error;
1009
1281
  }
@@ -1171,7 +1443,7 @@ async function getInstalledPackages(sys, config) {
1171
1443
  return { packages, packagesNoVersions };
1172
1444
  }
1173
1445
  catch (err) {
1174
- hasDebug(config) && console.error(err);
1446
+ hasDebug(config.flags) && console.error(err);
1175
1447
  return { packages, packagesNoVersions };
1176
1448
  }
1177
1449
  }
@@ -1273,15 +1545,15 @@ async function sendTelemetry(sys, config, data) {
1273
1545
  },
1274
1546
  body: JSON.stringify(body),
1275
1547
  });
1276
- hasVerbose(config) &&
1548
+ hasVerbose(config.flags) &&
1277
1549
  console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
1278
1550
  if (response.status !== 204) {
1279
- hasVerbose(config) &&
1551
+ hasVerbose(config.flags) &&
1280
1552
  console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
1281
1553
  }
1282
1554
  }
1283
1555
  catch (e) {
1284
- hasVerbose(config) && console.debug('Telemetry request failed:', e);
1556
+ hasVerbose(config.flags) && console.debug('Telemetry request failed:', e);
1285
1557
  }
1286
1558
  }
1287
1559
  /**
@@ -1338,7 +1610,7 @@ const taskBuild = async (coreCompiler, config, sys) => {
1338
1610
  const results = await compiler.build();
1339
1611
  // TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
1340
1612
  if (sys) {
1341
- await telemetryBuildFinishedAction(sys, config, config.logger, coreCompiler, results);
1613
+ await telemetryBuildFinishedAction(sys, config, coreCompiler, results);
1342
1614
  }
1343
1615
  await compiler.destroy();
1344
1616
  if (results.hasError) {
@@ -1377,6 +1649,7 @@ const IS_NODE_ENV = typeof global !== 'undefined' &&
1377
1649
  !!global.process &&
1378
1650
  typeof __filename === 'string' &&
1379
1651
  (!global.origin || typeof global.origin !== 'string');
1652
+ const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
1380
1653
 
1381
1654
  /**
1382
1655
  * Task to generate component boilerplate and write it to disk. This task can
@@ -1572,7 +1845,8 @@ export class ${toPascalCase(tagName)} {
1572
1845
  `;
1573
1846
  };
1574
1847
  /**
1575
- * Get the boilerplate for style.
1848
+ * Get the boilerplate for style for a generated component
1849
+ * @returns a boilerplate CSS block
1576
1850
  */
1577
1851
  const getStyleUrlBoilerplate = () => `:host {
1578
1852
  display: block;
@@ -1626,10 +1900,17 @@ describe('${tagName}', () => {
1626
1900
  */
1627
1901
  const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
1628
1902
 
1629
- const taskTelemetry = async (config, sys, logger) => {
1903
+ /**
1904
+ * Entrypoint for the Telemetry task
1905
+ * @param flags configuration flags provided to Stencil when a task was called (either this task or a task that invokes
1906
+ * telemetry)
1907
+ * @param sys the abstraction for interfacing with the operating system
1908
+ * @param logger a logging implementation to log the results out to the user
1909
+ */
1910
+ const taskTelemetry = async (flags, sys, logger) => {
1630
1911
  const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
1631
- const isEnabling = config.flags.args.includes('on');
1632
- const isDisabling = config.flags.args.includes('off');
1912
+ const isEnabling = flags.args.includes('on');
1913
+ const isDisabling = flags.args.includes('off');
1633
1914
  const INFORMATION = `Opt in or our of telemetry. Information about the data we collect is available on our website: ${logger.bold('https://stenciljs.com/telemetry')}`;
1634
1915
  const THANK_YOU = `Thank you for helping to make Stencil better! 💖`;
1635
1916
  const ENABLED_MESSAGE = `${logger.green('Enabled')}. ${THANK_YOU}\n\n`;
@@ -1658,7 +1939,14 @@ const taskTelemetry = async (config, sys, logger) => {
1658
1939
  `);
1659
1940
  };
1660
1941
 
1661
- const taskHelp = async (config, logger, sys) => {
1942
+ /**
1943
+ * Entrypoint for the Help task, providing Stencil usage context to the user
1944
+ * @param flags configuration flags provided to Stencil when a task was call (either this task or a task that invokes
1945
+ * telemetry)
1946
+ * @param logger a logging implementation to log the results out to the user
1947
+ * @param sys the abstraction for interfacing with the operating system
1948
+ */
1949
+ const taskHelp = async (flags, logger, sys) => {
1662
1950
  const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
1663
1951
  console.log(`
1664
1952
  ${logger.bold('Build:')} ${logger.dim('Build components for development or production.')}
@@ -1691,7 +1979,7 @@ const taskHelp = async (config, logger, sys) => {
1691
1979
  `);
1692
1980
  // TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
1693
1981
  if (sys) {
1694
- await taskTelemetry(config, sys, logger);
1982
+ await taskTelemetry(flags, sys, logger);
1695
1983
  }
1696
1984
  console.log(`
1697
1985
  ${logger.bold('Examples:')}
@@ -1748,6 +2036,10 @@ const taskServe = async (config) => {
1748
2036
  });
1749
2037
  };
1750
2038
 
2039
+ /**
2040
+ * Entrypoint for any Stencil tests
2041
+ * @param config a validated Stencil configuration entity
2042
+ */
1751
2043
  const taskTest = async (config) => {
1752
2044
  if (!IS_NODE_ENV) {
1753
2045
  config.logger.error(`"test" command is currently only implemented for a NodeJS environment`);
@@ -1794,6 +2086,95 @@ const taskTest = async (config) => {
1794
2086
  }
1795
2087
  };
1796
2088
 
2089
+ /**
2090
+ * Creates an instance of a logger
2091
+ * @returns the new logger instance
2092
+ */
2093
+ const createLogger = () => {
2094
+ let useColors = IS_BROWSER_ENV;
2095
+ let level = 'info';
2096
+ return {
2097
+ enableColors: (uc) => (useColors = uc),
2098
+ getLevel: () => level,
2099
+ setLevel: (l) => (level = l),
2100
+ emoji: (e) => e,
2101
+ info: console.log.bind(console),
2102
+ warn: console.warn.bind(console),
2103
+ error: console.error.bind(console),
2104
+ debug: console.debug.bind(console),
2105
+ red: (msg) => msg,
2106
+ green: (msg) => msg,
2107
+ yellow: (msg) => msg,
2108
+ blue: (msg) => msg,
2109
+ magenta: (msg) => msg,
2110
+ cyan: (msg) => msg,
2111
+ gray: (msg) => msg,
2112
+ bold: (msg) => msg,
2113
+ dim: (msg) => msg,
2114
+ bgRed: (msg) => msg,
2115
+ createTimeSpan: (_startMsg, _debug = false) => ({
2116
+ duration: () => 0,
2117
+ finish: () => 0,
2118
+ }),
2119
+ printDiagnostics(diagnostics) {
2120
+ diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
2121
+ },
2122
+ };
2123
+ };
2124
+ const logDiagnostic = (diagnostic, useColors) => {
2125
+ let color = BLUE;
2126
+ let prefix = 'Build';
2127
+ let msg = '';
2128
+ if (diagnostic.level === 'error') {
2129
+ color = RED;
2130
+ prefix = 'Error';
2131
+ }
2132
+ else if (diagnostic.level === 'warn') {
2133
+ color = YELLOW;
2134
+ prefix = 'Warning';
2135
+ }
2136
+ if (diagnostic.header) {
2137
+ prefix = diagnostic.header;
2138
+ }
2139
+ const filePath = diagnostic.relFilePath || diagnostic.absFilePath;
2140
+ if (filePath) {
2141
+ msg += filePath;
2142
+ if (typeof diagnostic.lineNumber === 'number' && diagnostic.lineNumber > 0) {
2143
+ msg += ', line ' + diagnostic.lineNumber;
2144
+ if (typeof diagnostic.columnNumber === 'number' && diagnostic.columnNumber > 0) {
2145
+ msg += ', column ' + diagnostic.columnNumber;
2146
+ }
2147
+ }
2148
+ msg += '\n';
2149
+ }
2150
+ msg += diagnostic.messageText;
2151
+ if (diagnostic.lines && diagnostic.lines.length > 0) {
2152
+ diagnostic.lines.forEach((l) => {
2153
+ msg += '\n' + l.lineNumber + ': ' + l.text;
2154
+ });
2155
+ msg += '\n';
2156
+ }
2157
+ if (useColors) {
2158
+ const styledPrefix = [
2159
+ '%c' + prefix,
2160
+ `background: ${color}; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;`,
2161
+ ];
2162
+ console.log(...styledPrefix, msg);
2163
+ }
2164
+ else if (diagnostic.level === 'error') {
2165
+ console.error(msg);
2166
+ }
2167
+ else if (diagnostic.level === 'warn') {
2168
+ console.warn(msg);
2169
+ }
2170
+ else {
2171
+ console.log(msg);
2172
+ }
2173
+ };
2174
+ const YELLOW = `#f39c12`;
2175
+ const RED = `#c0392b`;
2176
+ const BLUE = `#3498db`;
2177
+
1797
2178
  const run = async (init) => {
1798
2179
  const { args, logger, sys } = init;
1799
2180
  try {
@@ -1809,7 +2190,7 @@ const run = async (init) => {
1809
2190
  sys.applyGlobalPatch(sys.getCurrentDirectory());
1810
2191
  }
1811
2192
  if (task === 'help' || flags.help) {
1812
- await taskHelp({ flags: { task: 'help', args }, outputTargets: [] }, logger, sys);
2193
+ await taskHelp({ task: 'help', args }, logger, sys);
1813
2194
  return;
1814
2195
  }
1815
2196
  startupLog(logger, task);
@@ -1835,7 +2216,7 @@ const run = async (init) => {
1835
2216
  startupLogVersion(logger, task, coreCompiler);
1836
2217
  loadedCompilerLog(sys, logger, flags, coreCompiler);
1837
2218
  if (task === 'info') {
1838
- await telemetryAction(sys, { flags: { task: 'info' }, outputTargets: [] }, logger, coreCompiler, async () => {
2219
+ await telemetryAction(sys, { flags: { task: 'info' }, logger }, coreCompiler, async () => {
1839
2220
  await taskInfo(coreCompiler, sys, logger);
1840
2221
  });
1841
2222
  return;
@@ -1858,7 +2239,7 @@ const run = async (init) => {
1858
2239
  sys.applyGlobalPatch(validated.config.rootDir);
1859
2240
  }
1860
2241
  await sys.ensureResources({ rootDir: validated.config.rootDir, logger, dependencies: dependencies });
1861
- await telemetryAction(sys, validated.config, logger, coreCompiler, async () => {
2242
+ await telemetryAction(sys, validated.config, coreCompiler, async () => {
1862
2243
  await runTask(coreCompiler, validated.config, task, sys);
1863
2244
  });
1864
2245
  }
@@ -1871,43 +2252,45 @@ const run = async (init) => {
1871
2252
  }
1872
2253
  };
1873
2254
  const runTask = async (coreCompiler, config, task, sys) => {
1874
- config.flags = config.flags || { task };
1875
- config.outputTargets = config.outputTargets || [];
2255
+ var _a, _b;
2256
+ const logger = (_a = config.logger) !== null && _a !== void 0 ? _a : createLogger();
2257
+ const strictConfig = { ...config, flags: (_b = { ...config.flags }) !== null && _b !== void 0 ? _b : { task }, logger };
2258
+ strictConfig.outputTargets = strictConfig.outputTargets || [];
1876
2259
  switch (task) {
1877
2260
  case 'build':
1878
- await taskBuild(coreCompiler, config, sys);
2261
+ await taskBuild(coreCompiler, strictConfig, sys);
1879
2262
  break;
1880
2263
  case 'docs':
1881
- await taskDocs(coreCompiler, config);
2264
+ await taskDocs(coreCompiler, strictConfig);
1882
2265
  break;
1883
2266
  case 'generate':
1884
2267
  case 'g':
1885
- await taskGenerate(coreCompiler, config);
2268
+ await taskGenerate(coreCompiler, strictConfig);
1886
2269
  break;
1887
2270
  case 'help':
1888
- await taskHelp(config, config.logger, sys);
2271
+ await taskHelp(strictConfig.flags, strictConfig.logger, sys);
1889
2272
  break;
1890
2273
  case 'prerender':
1891
- await taskPrerender(coreCompiler, config);
2274
+ await taskPrerender(coreCompiler, strictConfig);
1892
2275
  break;
1893
2276
  case 'serve':
1894
- await taskServe(config);
2277
+ await taskServe(strictConfig);
1895
2278
  break;
1896
2279
  case 'telemetry':
1897
2280
  // TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
1898
2281
  if (sys) {
1899
- await taskTelemetry(config, sys, config.logger);
2282
+ await taskTelemetry(strictConfig.flags, sys, strictConfig.logger);
1900
2283
  }
1901
2284
  break;
1902
2285
  case 'test':
1903
- await taskTest(config);
2286
+ await taskTest(strictConfig);
1904
2287
  break;
1905
2288
  case 'version':
1906
2289
  console.log(coreCompiler.version);
1907
2290
  break;
1908
2291
  default:
1909
- config.logger.error(`${config.logger.emoji('❌ ')}Invalid stencil command, please see the options below:`);
1910
- await taskHelp(config, config.logger, sys);
2292
+ strictConfig.logger.error(`${strictConfig.logger.emoji('❌ ')}Invalid stencil command, please see the options below:`);
2293
+ await taskHelp(strictConfig.flags, strictConfig.logger, sys);
1911
2294
  return config.sys.exit(1);
1912
2295
  }
1913
2296
  };