@stencil/core 2.16.1 → 2.17.2-0
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 +110 -0
- package/cli/index.cjs +710 -225
- package/cli/index.d.ts +2 -1
- package/cli/index.js +710 -225
- package/cli/package.json +1 -1
- package/compiler/package.json +1 -1
- package/compiler/stencil.js +905 -290
- package/compiler/stencil.min.js +2 -2
- package/dependencies.json +1 -1
- package/dev-server/client/index.js +1 -1
- package/dev-server/client/package.json +1 -1
- package/dev-server/connector.html +2 -2
- package/dev-server/index.js +1 -1
- package/dev-server/package.json +1 -1
- package/dev-server/server-process.js +2 -2
- package/internal/app-data/package.json +1 -1
- package/internal/client/css-shim.js +1 -1
- package/internal/client/dom.js +1 -1
- package/internal/client/index.js +11 -6
- package/internal/client/package.json +1 -1
- package/internal/client/patch-browser.js +1 -1
- package/internal/client/patch-esm.js +1 -1
- package/internal/client/shadow-css.js +1 -1
- package/internal/hydrate/index.js +2 -2
- package/internal/hydrate/package.json +1 -1
- package/internal/package.json +1 -1
- package/internal/stencil-private.d.ts +6 -2
- package/internal/stencil-public-compiler.d.ts +67 -48
- package/internal/testing/index.js +1 -1
- package/internal/testing/package.json +1 -1
- package/mock-doc/index.cjs +163 -5
- package/mock-doc/index.d.ts +86 -1
- package/mock-doc/index.js +163 -5
- package/mock-doc/package.json +1 -1
- package/package.json +2 -1
- package/screenshot/package.json +1 -1
- package/sys/node/index.js +325 -314
- package/sys/node/package.json +1 -1
- package/sys/node/worker.js +1 -1
- package/testing/index.d.ts +1 -1
- package/testing/index.js +445 -382
- package/testing/jest/jest-config.d.ts +1 -1
- package/testing/jest/jest-runner.d.ts +3 -2
- package/testing/jest/jest-screenshot.d.ts +1 -1
- package/testing/mocks.d.ts +48 -3
- package/testing/package.json +1 -1
- package/testing/puppeteer/puppeteer-browser.d.ts +2 -2
- package/testing/test/testing-utils.spec.d.ts +1 -0
- package/testing/testing-utils.d.ts +74 -2
- package/testing/testing.d.ts +2 -2
package/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil CLI (CommonJS) v2.
|
|
2
|
+
Stencil CLI (CommonJS) v2.17.2-0 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
@@ -25,8 +25,50 @@ function _interopNamespace(e) {
|
|
|
25
25
|
return Object.freeze(n);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
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
|
+
/**
|
|
64
|
+
* Convert a string from dash-case / kebab-case to PascalCase (or CamelCase,
|
|
65
|
+
* or whatever you call it!)
|
|
66
|
+
*
|
|
67
|
+
* @param str a string to convert
|
|
68
|
+
* @returns a converted string
|
|
69
|
+
*/
|
|
70
|
+
const dashToPascalCase = (str) => str
|
|
71
|
+
.toLowerCase()
|
|
30
72
|
.split('-')
|
|
31
73
|
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
32
74
|
.join('');
|
|
@@ -299,22 +341,223 @@ const validateComponentTag = (tag) => {
|
|
|
299
341
|
return undefined;
|
|
300
342
|
};
|
|
301
343
|
|
|
302
|
-
|
|
344
|
+
/**
|
|
345
|
+
* All the Boolean options supported by the Stencil CLI
|
|
346
|
+
*/
|
|
347
|
+
const BOOLEAN_CLI_ARGS = [
|
|
348
|
+
'build',
|
|
349
|
+
'cache',
|
|
350
|
+
'checkVersion',
|
|
351
|
+
'ci',
|
|
352
|
+
'compare',
|
|
353
|
+
'debug',
|
|
354
|
+
'dev',
|
|
355
|
+
'devtools',
|
|
356
|
+
'docs',
|
|
357
|
+
'e2e',
|
|
358
|
+
'es5',
|
|
359
|
+
'esm',
|
|
360
|
+
'headless',
|
|
361
|
+
'help',
|
|
362
|
+
'log',
|
|
363
|
+
'open',
|
|
364
|
+
'prerender',
|
|
365
|
+
'prerenderExternal',
|
|
366
|
+
'prod',
|
|
367
|
+
'profile',
|
|
368
|
+
'serviceWorker',
|
|
369
|
+
'screenshot',
|
|
370
|
+
'serve',
|
|
371
|
+
'skipNodeCheck',
|
|
372
|
+
'spec',
|
|
373
|
+
'ssr',
|
|
374
|
+
'stats',
|
|
375
|
+
'updateScreenshot',
|
|
376
|
+
'verbose',
|
|
377
|
+
'version',
|
|
378
|
+
'watch',
|
|
379
|
+
// JEST CLI OPTIONS
|
|
380
|
+
'all',
|
|
381
|
+
'automock',
|
|
382
|
+
'bail',
|
|
383
|
+
// 'cache', Stencil already supports this argument
|
|
384
|
+
'changedFilesWithAncestor',
|
|
385
|
+
// 'ci', Stencil already supports this argument
|
|
386
|
+
'clearCache',
|
|
387
|
+
'clearMocks',
|
|
388
|
+
'collectCoverage',
|
|
389
|
+
'color',
|
|
390
|
+
'colors',
|
|
391
|
+
'coverage',
|
|
392
|
+
// 'debug', Stencil already supports this argument
|
|
393
|
+
'detectLeaks',
|
|
394
|
+
'detectOpenHandles',
|
|
395
|
+
'errorOnDeprecated',
|
|
396
|
+
'expand',
|
|
397
|
+
'findRelatedTests',
|
|
398
|
+
'forceExit',
|
|
399
|
+
'init',
|
|
400
|
+
'injectGlobals',
|
|
401
|
+
'json',
|
|
402
|
+
'lastCommit',
|
|
403
|
+
'listTests',
|
|
404
|
+
'logHeapUsage',
|
|
405
|
+
'noStackTrace',
|
|
406
|
+
'notify',
|
|
407
|
+
'onlyChanged',
|
|
408
|
+
'onlyFailures',
|
|
409
|
+
'passWithNoTests',
|
|
410
|
+
'resetMocks',
|
|
411
|
+
'resetModules',
|
|
412
|
+
'restoreMocks',
|
|
413
|
+
'runInBand',
|
|
414
|
+
'runTestsByPath',
|
|
415
|
+
'showConfig',
|
|
416
|
+
'silent',
|
|
417
|
+
'skipFilter',
|
|
418
|
+
'testLocationInResults',
|
|
419
|
+
'updateSnapshot',
|
|
420
|
+
'useStderr',
|
|
421
|
+
// 'verbose', Stencil already supports this argument
|
|
422
|
+
// 'version', Stencil already supports this argument
|
|
423
|
+
// 'watch', Stencil already supports this argument
|
|
424
|
+
'watchAll',
|
|
425
|
+
'watchman',
|
|
426
|
+
];
|
|
427
|
+
/**
|
|
428
|
+
* All the Number options supported by the Stencil CLI
|
|
429
|
+
*/
|
|
430
|
+
const NUMBER_CLI_ARGS = [
|
|
431
|
+
'port',
|
|
432
|
+
// JEST CLI ARGS
|
|
433
|
+
'maxConcurrency',
|
|
434
|
+
'testTimeout',
|
|
435
|
+
];
|
|
436
|
+
/**
|
|
437
|
+
* All the String options supported by the Stencil CLI
|
|
438
|
+
*/
|
|
439
|
+
const STRING_CLI_ARGS = [
|
|
440
|
+
'address',
|
|
441
|
+
'config',
|
|
442
|
+
'docsApi',
|
|
443
|
+
'docsJson',
|
|
444
|
+
'emulate',
|
|
445
|
+
'root',
|
|
446
|
+
'screenshotConnector',
|
|
447
|
+
// JEST CLI ARGS
|
|
448
|
+
'cacheDirectory',
|
|
449
|
+
'changedSince',
|
|
450
|
+
'collectCoverageFrom',
|
|
451
|
+
// 'config', Stencil already supports this argument
|
|
452
|
+
'coverageDirectory',
|
|
453
|
+
'coverageThreshold',
|
|
454
|
+
'env',
|
|
455
|
+
'filter',
|
|
456
|
+
'globalSetup',
|
|
457
|
+
'globalTeardown',
|
|
458
|
+
'globals',
|
|
459
|
+
'haste',
|
|
460
|
+
'moduleNameMapper',
|
|
461
|
+
'notifyMode',
|
|
462
|
+
'outputFile',
|
|
463
|
+
'preset',
|
|
464
|
+
'prettierPath',
|
|
465
|
+
'resolver',
|
|
466
|
+
'rootDir',
|
|
467
|
+
'runner',
|
|
468
|
+
'testEnvironment',
|
|
469
|
+
'testEnvironmentOptions',
|
|
470
|
+
'testFailureExitCode',
|
|
471
|
+
'testNamePattern',
|
|
472
|
+
'testResultsProcessor',
|
|
473
|
+
'testRunner',
|
|
474
|
+
'testSequencer',
|
|
475
|
+
'testURL',
|
|
476
|
+
'timers',
|
|
477
|
+
'transform',
|
|
478
|
+
// ARRAY ARGS
|
|
479
|
+
'collectCoverageOnlyFrom',
|
|
480
|
+
'coveragePathIgnorePatterns',
|
|
481
|
+
'coverageReporters',
|
|
482
|
+
'moduleDirectories',
|
|
483
|
+
'moduleFileExtensions',
|
|
484
|
+
'modulePathIgnorePatterns',
|
|
485
|
+
'modulePaths',
|
|
486
|
+
'projects',
|
|
487
|
+
'reporters',
|
|
488
|
+
'roots',
|
|
489
|
+
'selectProjects',
|
|
490
|
+
'setupFiles',
|
|
491
|
+
'setupFilesAfterEnv',
|
|
492
|
+
'snapshotSerializers',
|
|
493
|
+
'testMatch',
|
|
494
|
+
'testPathIgnorePatterns',
|
|
495
|
+
'testPathPattern',
|
|
496
|
+
'testRegex',
|
|
497
|
+
'transformIgnorePatterns',
|
|
498
|
+
'unmockedModulePathPatterns',
|
|
499
|
+
'watchPathIgnorePatterns',
|
|
500
|
+
];
|
|
501
|
+
/**
|
|
502
|
+
* All the CLI arguments which may have string or number values
|
|
503
|
+
*
|
|
504
|
+
* `maxWorkers` is an argument which is used both by Stencil _and_ by Jest,
|
|
505
|
+
* which means that we need to support parsing both string and number values.
|
|
506
|
+
*/
|
|
507
|
+
const STRING_NUMBER_CLI_ARGS = ['maxWorkers'];
|
|
508
|
+
/**
|
|
509
|
+
* All the LogLevel-type options supported by the Stencil CLI
|
|
510
|
+
*
|
|
511
|
+
* This is a bit silly since there's only one such argument atm,
|
|
512
|
+
* but this approach lets us make sure that we're handling all
|
|
513
|
+
* our arguments in a type-safe way.
|
|
514
|
+
*/
|
|
515
|
+
const LOG_LEVEL_CLI_ARGS = ['logLevel'];
|
|
516
|
+
/**
|
|
517
|
+
* For a small subset of CLI options we support a short alias e.g. `'h'` for `'help'`
|
|
518
|
+
*/
|
|
519
|
+
const CLI_ARG_ALIASES = {
|
|
520
|
+
config: 'c',
|
|
521
|
+
help: 'h',
|
|
522
|
+
port: 'p',
|
|
523
|
+
version: 'v',
|
|
524
|
+
};
|
|
525
|
+
/**
|
|
526
|
+
* Helper function for initializing a `ConfigFlags` object. Provide any overrides
|
|
527
|
+
* for default values and off you go!
|
|
528
|
+
*
|
|
529
|
+
* @param init an object with any overrides for default values
|
|
530
|
+
* @returns a complete CLI flag object
|
|
531
|
+
*/
|
|
532
|
+
const createConfigFlags = (init = {}) => {
|
|
303
533
|
const flags = {
|
|
304
534
|
task: null,
|
|
305
535
|
args: [],
|
|
306
536
|
knownArgs: [],
|
|
307
|
-
unknownArgs:
|
|
537
|
+
unknownArgs: [],
|
|
538
|
+
...init,
|
|
308
539
|
};
|
|
540
|
+
return flags;
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Parse command line arguments into a structured `ConfigFlags` object
|
|
545
|
+
*
|
|
546
|
+
* @param args an array of config flags
|
|
547
|
+
* @param sys an optional compiler system
|
|
548
|
+
* @returns a structured ConfigFlags object
|
|
549
|
+
*/
|
|
550
|
+
const parseFlags = (args, sys) => {
|
|
551
|
+
const flags = createConfigFlags();
|
|
309
552
|
// cmd line has more priority over npm scripts cmd
|
|
310
|
-
flags.args = args.slice();
|
|
553
|
+
flags.args = Array.isArray(args) ? args.slice() : [];
|
|
311
554
|
if (flags.args.length > 0 && flags.args[0] && !flags.args[0].startsWith('-')) {
|
|
312
555
|
flags.task = flags.args[0];
|
|
313
556
|
}
|
|
314
|
-
parseArgs(flags, flags.args
|
|
557
|
+
parseArgs(flags, flags.args);
|
|
315
558
|
if (sys && sys.name === 'node') {
|
|
316
559
|
const envArgs = getNpmConfigEnvArgs(sys);
|
|
317
|
-
parseArgs(flags, envArgs
|
|
560
|
+
parseArgs(flags, envArgs);
|
|
318
561
|
envArgs.forEach((envArg) => {
|
|
319
562
|
if (!flags.args.includes(envArg)) {
|
|
320
563
|
flags.args.push(envArg);
|
|
@@ -333,185 +576,230 @@ const parseFlags = (args, sys) => {
|
|
|
333
576
|
return flags;
|
|
334
577
|
};
|
|
335
578
|
/**
|
|
336
|
-
* Parse command line arguments that are
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
579
|
+
* Parse command line arguments that are enumerated in the `config-flags`
|
|
580
|
+
* module. Handles leading dashes on arguments, aliases that are defined for a
|
|
581
|
+
* small number of arguments, and parsing values for non-boolean arguments
|
|
582
|
+
* (e.g. port number for the dev server).
|
|
583
|
+
*
|
|
584
|
+
* @param flags a ConfigFlags object to which parsed arguments will be added
|
|
585
|
+
* @param args an array of command-line arguments to parse
|
|
586
|
+
*/
|
|
587
|
+
const parseArgs = (flags, args) => {
|
|
588
|
+
BOOLEAN_CLI_ARGS.forEach((argName) => parseBooleanArg(flags, args, argName));
|
|
589
|
+
STRING_CLI_ARGS.forEach((argName) => parseStringArg(flags, args, argName));
|
|
590
|
+
NUMBER_CLI_ARGS.forEach((argName) => parseNumberArg(flags, args, argName));
|
|
591
|
+
STRING_NUMBER_CLI_ARGS.forEach((argName) => parseStringNumberArg(flags, args, argName));
|
|
592
|
+
LOG_LEVEL_CLI_ARGS.forEach((argName) => parseLogLevelArg(flags, args, argName));
|
|
593
|
+
};
|
|
594
|
+
/**
|
|
595
|
+
* Parse a boolean CLI argument. For these, we support the following formats:
|
|
340
596
|
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
597
|
+
* - `--booleanArg`
|
|
598
|
+
* - `--boolean-arg`
|
|
599
|
+
* - `--noBooleanArg`
|
|
600
|
+
* - `--no-boolean-arg`
|
|
601
|
+
*
|
|
602
|
+
* The final two variants should be parsed to a value of `false` on the config
|
|
603
|
+
* object.
|
|
604
|
+
*
|
|
605
|
+
* @param flags the config flags object, while we'll modify
|
|
606
|
+
* @param args our CLI arguments
|
|
607
|
+
* @param configCaseName the argument we want to look at right now
|
|
608
|
+
*/
|
|
609
|
+
const parseBooleanArg = (flags, args, configCaseName) => {
|
|
610
|
+
// we support both dash-case and PascalCase versions of the parameter
|
|
611
|
+
// argName is 'configCase' version which can be found in BOOLEAN_ARG_OPTS
|
|
612
|
+
const alias = CLI_ARG_ALIASES[configCaseName];
|
|
613
|
+
const dashCaseName = toDashCase(configCaseName);
|
|
614
|
+
if (typeof flags[configCaseName] !== 'boolean') {
|
|
615
|
+
flags[configCaseName] = null;
|
|
616
|
+
}
|
|
617
|
+
args.forEach((cmdArg) => {
|
|
618
|
+
let value;
|
|
619
|
+
if (cmdArg === `--${configCaseName}` || cmdArg === `--${dashCaseName}`) {
|
|
620
|
+
value = true;
|
|
351
621
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
flags[flagKey] = true;
|
|
355
|
-
knownArgs.push(cmdArg);
|
|
356
|
-
}
|
|
357
|
-
else if (cmdArg === `--${flagKey}`) {
|
|
358
|
-
flags[flagKey] = true;
|
|
359
|
-
knownArgs.push(cmdArg);
|
|
360
|
-
}
|
|
361
|
-
else if (cmdArg === `--no-${booleanName}`) {
|
|
362
|
-
flags[flagKey] = false;
|
|
363
|
-
knownArgs.push(cmdArg);
|
|
364
|
-
}
|
|
365
|
-
else if (cmdArg === `--no${dashToPascalCase(booleanName)}`) {
|
|
366
|
-
flags[flagKey] = false;
|
|
367
|
-
knownArgs.push(cmdArg);
|
|
368
|
-
}
|
|
369
|
-
else if (alias && cmdArg === `-${alias}`) {
|
|
370
|
-
flags[flagKey] = true;
|
|
371
|
-
knownArgs.push(cmdArg);
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
STRING_ARG_OPTS.forEach((stringName) => {
|
|
376
|
-
const alias = ARG_OPTS_ALIASES[stringName];
|
|
377
|
-
const flagKey = configCase(stringName);
|
|
378
|
-
if (typeof flags[flagKey] !== 'string') {
|
|
379
|
-
flags[flagKey] = null;
|
|
622
|
+
else if (cmdArg === `--no-${dashCaseName}` || cmdArg === `--no${dashToPascalCase(dashCaseName)}`) {
|
|
623
|
+
value = false;
|
|
380
624
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
knownArgs.push(cmdArg);
|
|
388
|
-
}
|
|
389
|
-
else if (cmdArg === `--${stringName}`) {
|
|
390
|
-
flags[flagKey] = args[i + 1];
|
|
391
|
-
knownArgs.push(cmdArg);
|
|
392
|
-
knownArgs.push(args[i + 1]);
|
|
393
|
-
}
|
|
394
|
-
else if (cmdArg === `--${flagKey}`) {
|
|
395
|
-
flags[flagKey] = args[i + 1];
|
|
396
|
-
knownArgs.push(cmdArg);
|
|
397
|
-
knownArgs.push(args[i + 1]);
|
|
398
|
-
}
|
|
399
|
-
else if (cmdArg.startsWith(`--${flagKey}=`)) {
|
|
400
|
-
const values = cmdArg.split('=');
|
|
401
|
-
values.shift();
|
|
402
|
-
flags[flagKey] = values.join('=');
|
|
403
|
-
knownArgs.push(cmdArg);
|
|
404
|
-
}
|
|
405
|
-
else if (alias) {
|
|
406
|
-
if (cmdArg.startsWith(`-${alias}=`)) {
|
|
407
|
-
const values = cmdArg.split('=');
|
|
408
|
-
values.shift();
|
|
409
|
-
flags[flagKey] = values.join('=');
|
|
410
|
-
knownArgs.push(cmdArg);
|
|
411
|
-
}
|
|
412
|
-
else if (cmdArg === `-${alias}`) {
|
|
413
|
-
flags[flagKey] = args[i + 1];
|
|
414
|
-
knownArgs.push(args[i + 1]);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
625
|
+
else if (alias && cmdArg === `-${alias}`) {
|
|
626
|
+
value = true;
|
|
627
|
+
}
|
|
628
|
+
if (value !== undefined && cmdArg !== undefined) {
|
|
629
|
+
flags[configCaseName] = value;
|
|
630
|
+
flags.knownArgs.push(cmdArg);
|
|
417
631
|
}
|
|
418
632
|
});
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
633
|
+
};
|
|
634
|
+
/**
|
|
635
|
+
* Parse a string CLI argument
|
|
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 parseStringArg = (flags, args, configCaseName) => {
|
|
642
|
+
if (typeof flags[configCaseName] !== 'string') {
|
|
643
|
+
flags[configCaseName] = null;
|
|
644
|
+
}
|
|
645
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
646
|
+
if (value !== undefined && matchingArg !== undefined) {
|
|
647
|
+
flags[configCaseName] = value;
|
|
648
|
+
flags.knownArgs.push(matchingArg);
|
|
649
|
+
flags.knownArgs.push(value);
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
/**
|
|
653
|
+
* Parse a number CLI argument
|
|
654
|
+
*
|
|
655
|
+
* @param flags the config flags object, while we'll modify
|
|
656
|
+
* @param args our CLI arguments
|
|
657
|
+
* @param configCaseName the argument we want to look at right now
|
|
658
|
+
*/
|
|
659
|
+
const parseNumberArg = (flags, args, configCaseName) => {
|
|
660
|
+
if (typeof flags[configCaseName] !== 'number') {
|
|
661
|
+
flags[configCaseName] = null;
|
|
662
|
+
}
|
|
663
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
664
|
+
if (value !== undefined && matchingArg !== undefined) {
|
|
665
|
+
flags[configCaseName] = parseInt(value, 10);
|
|
666
|
+
flags.knownArgs.push(matchingArg);
|
|
667
|
+
flags.knownArgs.push(value);
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
/**
|
|
671
|
+
* Parse a CLI argument which may be either a string or a number
|
|
672
|
+
*
|
|
673
|
+
* @param flags the config flags object, while we'll modify
|
|
674
|
+
* @param args our CLI arguments
|
|
675
|
+
* @param configCaseName the argument we want to look at right now
|
|
676
|
+
*/
|
|
677
|
+
const parseStringNumberArg = (flags, args, configCaseName) => {
|
|
678
|
+
if (!['number', 'string'].includes(typeof flags[configCaseName])) {
|
|
679
|
+
flags[configCaseName] = null;
|
|
680
|
+
}
|
|
681
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
682
|
+
if (value !== undefined && matchingArg !== undefined) {
|
|
683
|
+
if (CLI_ARG_STRING_REGEX.test(value)) {
|
|
684
|
+
// if it matches the regex we treat it like a string
|
|
685
|
+
flags[configCaseName] = value;
|
|
424
686
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
687
|
+
else {
|
|
688
|
+
// it was a number, great!
|
|
689
|
+
flags[configCaseName] = Number(value);
|
|
690
|
+
}
|
|
691
|
+
flags.knownArgs.push(matchingArg);
|
|
692
|
+
flags.knownArgs.push(value);
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
/**
|
|
696
|
+
* We use this regular expression to detect CLI parameters which
|
|
697
|
+
* should be parsed as string values (as opposed to numbers) for
|
|
698
|
+
* the argument types for which we support both a string and a
|
|
699
|
+
* number value.
|
|
700
|
+
*
|
|
701
|
+
* The regex tests for the presence of at least one character which is
|
|
702
|
+
* _not_ a digit (`\d`), a period (`\.`), or one of the characters `"e"`,
|
|
703
|
+
* `"E"`, `"+"`, or `"-"` (the latter four characters are necessary to
|
|
704
|
+
* support the admittedly unlikely use of scientific notation, like `"4e+0"`
|
|
705
|
+
* for `4`).
|
|
706
|
+
*
|
|
707
|
+
* Thus we'll match a string like `"50%"`, but not a string like `"50"` or
|
|
708
|
+
* `"5.0"`. If it matches a given string we conclude that the string should
|
|
709
|
+
* be parsed as a string literal, rather than using `Number` to convert it
|
|
710
|
+
* to a number.
|
|
711
|
+
*/
|
|
712
|
+
const CLI_ARG_STRING_REGEX = /[^\d\.Ee\+\-]+/g;
|
|
713
|
+
/**
|
|
714
|
+
* Parse a LogLevel CLI argument. These can be only a specific
|
|
715
|
+
* set of strings, so this function takes care of validating that
|
|
716
|
+
* the value is correct.
|
|
717
|
+
*
|
|
718
|
+
* @param flags the config flags object, while we'll modify
|
|
719
|
+
* @param args our CLI arguments
|
|
720
|
+
* @param configCaseName the argument we want to look at right now
|
|
721
|
+
*/
|
|
722
|
+
const parseLogLevelArg = (flags, args, configCaseName) => {
|
|
723
|
+
if (typeof flags[configCaseName] !== 'string') {
|
|
724
|
+
flags[configCaseName] = null;
|
|
725
|
+
}
|
|
726
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
727
|
+
if (value !== undefined && matchingArg !== undefined && isLogLevel(value)) {
|
|
728
|
+
flags[configCaseName] = value;
|
|
729
|
+
flags.knownArgs.push(matchingArg);
|
|
730
|
+
flags.knownArgs.push(value);
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
/**
|
|
734
|
+
* Helper for pulling values out from the raw array of CLI arguments. This logic
|
|
735
|
+
* is shared between a few different types of CLI args.
|
|
736
|
+
*
|
|
737
|
+
* We look for arguments in the following formats:
|
|
738
|
+
*
|
|
739
|
+
* - `--my-cli-argument value`
|
|
740
|
+
* - `--my-cli-argument=value`
|
|
741
|
+
* - `--myCliArgument value`
|
|
742
|
+
* - `--myCliArgument=value`
|
|
743
|
+
*
|
|
744
|
+
* We also check for shortened aliases, which we define for a few arguments.
|
|
745
|
+
*
|
|
746
|
+
* @param args the CLI args we're dealing with
|
|
747
|
+
* @param configCaseName the ConfigFlag key which we're looking to pull out a value for
|
|
748
|
+
* @returns the value for the flag as well as the exact string which it matched from
|
|
749
|
+
* the user input.
|
|
750
|
+
*/
|
|
751
|
+
const getValue = (args, configCaseName) => {
|
|
752
|
+
// for some CLI args we have a short alias, like 'c' for 'config'
|
|
753
|
+
const alias = CLI_ARG_ALIASES[configCaseName];
|
|
754
|
+
// we support supplying arguments in both dash-case and configCase
|
|
755
|
+
// for ease of use
|
|
756
|
+
const dashCaseName = toDashCase(configCaseName);
|
|
757
|
+
let value;
|
|
758
|
+
let matchingArg;
|
|
759
|
+
args.forEach((arg, i) => {
|
|
760
|
+
if (arg.startsWith(`--${dashCaseName}=`) || arg.startsWith(`--${configCaseName}=`)) {
|
|
761
|
+
value = getEqualsValue(arg);
|
|
762
|
+
matchingArg = arg;
|
|
763
|
+
}
|
|
764
|
+
else if (arg === `--${dashCaseName}` || arg === `--${configCaseName}`) {
|
|
765
|
+
value = args[i + 1];
|
|
766
|
+
matchingArg = arg;
|
|
767
|
+
}
|
|
768
|
+
else if (alias) {
|
|
769
|
+
if (arg.startsWith(`-${alias}=`)) {
|
|
770
|
+
value = getEqualsValue(arg);
|
|
771
|
+
matchingArg = arg;
|
|
446
772
|
}
|
|
447
|
-
else if (alias) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
values.shift();
|
|
451
|
-
flags[flagKey] = parseInt(values.join(''), 10);
|
|
452
|
-
knownArgs.push(cmdArg);
|
|
453
|
-
}
|
|
454
|
-
else if (cmdArg === `-${alias}`) {
|
|
455
|
-
flags[flagKey] = parseInt(args[i + 1], 10);
|
|
456
|
-
knownArgs.push(args[i + 1]);
|
|
457
|
-
}
|
|
773
|
+
else if (arg === `-${alias}`) {
|
|
774
|
+
value = args[i + 1];
|
|
775
|
+
matchingArg = arg;
|
|
458
776
|
}
|
|
459
777
|
}
|
|
460
778
|
});
|
|
779
|
+
return { value, matchingArg };
|
|
461
780
|
};
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
'prerender-external',
|
|
485
|
-
'prod',
|
|
486
|
-
'profile',
|
|
487
|
-
'service-worker',
|
|
488
|
-
'screenshot',
|
|
489
|
-
'serve',
|
|
490
|
-
'skip-node-check',
|
|
491
|
-
'spec',
|
|
492
|
-
'ssr',
|
|
493
|
-
'stats',
|
|
494
|
-
'update-screenshot',
|
|
495
|
-
'verbose',
|
|
496
|
-
'version',
|
|
497
|
-
'watch',
|
|
498
|
-
];
|
|
499
|
-
const NUMBER_ARG_OPTS = ['max-workers', 'port'];
|
|
500
|
-
const STRING_ARG_OPTS = [
|
|
501
|
-
'address',
|
|
502
|
-
'config',
|
|
503
|
-
'docs-json',
|
|
504
|
-
'emulate',
|
|
505
|
-
'log-level',
|
|
506
|
-
'root',
|
|
507
|
-
'screenshot-connector',
|
|
508
|
-
];
|
|
509
|
-
const ARG_OPTS_ALIASES = {
|
|
510
|
-
config: 'c',
|
|
511
|
-
help: 'h',
|
|
512
|
-
port: 'p',
|
|
513
|
-
version: 'v',
|
|
514
|
-
};
|
|
781
|
+
/**
|
|
782
|
+
* When a parameter is set in the format `--foobar=12` at the CLI (as opposed to
|
|
783
|
+
* `--foobar 12`) we want to get the value after the `=` sign
|
|
784
|
+
*
|
|
785
|
+
* @param commandArgument the arg in question
|
|
786
|
+
* @returns the value after the `=`
|
|
787
|
+
*/
|
|
788
|
+
const getEqualsValue = (commandArgument) => commandArgument.split('=').slice(1).join('=');
|
|
789
|
+
/**
|
|
790
|
+
* Small helper for getting type-system-level assurance that a `string` can be
|
|
791
|
+
* narrowed to a `LogLevel`
|
|
792
|
+
*
|
|
793
|
+
* @param maybeLogLevel the string to check
|
|
794
|
+
* @returns whether this is a `LogLevel`
|
|
795
|
+
*/
|
|
796
|
+
const isLogLevel = (maybeLogLevel) =>
|
|
797
|
+
// unfortunately `includes` is typed on `ReadonlyArray<T>` as `(el: T):
|
|
798
|
+
// boolean` so a `string` cannot be passed to `includes` on a
|
|
799
|
+
// `ReadonlyArray` 😢 thus we `as any`
|
|
800
|
+
//
|
|
801
|
+
// see microsoft/TypeScript#31018 for some discussion of this
|
|
802
|
+
LOG_LEVELS.includes(maybeLogLevel);
|
|
515
803
|
const getNpmConfigEnvArgs = (sys) => {
|
|
516
804
|
// process.env.npm_config_argv
|
|
517
805
|
// {"remain":["4444"],"cooked":["run","serve","--port","4444"],"original":["run","serve","--port","4444"]}
|
|
@@ -532,7 +820,7 @@ const getNpmConfigEnvArgs = (sys) => {
|
|
|
532
820
|
const dependencies = [
|
|
533
821
|
{
|
|
534
822
|
name: "@stencil/core",
|
|
535
|
-
version: "2.
|
|
823
|
+
version: "2.17.2-0",
|
|
536
824
|
main: "compiler/stencil.js",
|
|
537
825
|
resources: [
|
|
538
826
|
"package.json",
|
|
@@ -857,12 +1145,11 @@ const tryFn = async (fn, ...args) => {
|
|
|
857
1145
|
}
|
|
858
1146
|
return null;
|
|
859
1147
|
};
|
|
860
|
-
const isInteractive = (sys,
|
|
861
|
-
var _a;
|
|
1148
|
+
const isInteractive = (sys, flags, object) => {
|
|
862
1149
|
const terminalInfo = object ||
|
|
863
1150
|
Object.freeze({
|
|
864
1151
|
tty: sys.isTTY() ? true : false,
|
|
865
|
-
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!
|
|
1152
|
+
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!flags.ci,
|
|
866
1153
|
});
|
|
867
1154
|
return terminalInfo.tty && !terminalInfo.ci;
|
|
868
1155
|
};
|
|
@@ -887,19 +1174,19 @@ async function readJson(sys, path) {
|
|
|
887
1174
|
}
|
|
888
1175
|
/**
|
|
889
1176
|
* Does the command have the debug flag?
|
|
890
|
-
* @param
|
|
1177
|
+
* @param flags The configuration flags passed into the Stencil command
|
|
891
1178
|
* @returns true if --debug has been passed, otherwise false
|
|
892
1179
|
*/
|
|
893
|
-
function hasDebug(
|
|
894
|
-
return
|
|
1180
|
+
function hasDebug(flags) {
|
|
1181
|
+
return flags.debug;
|
|
895
1182
|
}
|
|
896
1183
|
/**
|
|
897
1184
|
* Does the command have the verbose and debug flags?
|
|
898
|
-
* @param
|
|
1185
|
+
* @param flags The configuration flags passed into the Stencil command
|
|
899
1186
|
* @returns true if both --debug and --verbose have been passed, otherwise false
|
|
900
1187
|
*/
|
|
901
|
-
function hasVerbose(
|
|
902
|
-
return
|
|
1188
|
+
function hasVerbose(flags) {
|
|
1189
|
+
return flags.verbose && hasDebug(flags);
|
|
903
1190
|
}
|
|
904
1191
|
|
|
905
1192
|
/**
|
|
@@ -910,7 +1197,7 @@ function hasVerbose(config) {
|
|
|
910
1197
|
* @returns true if telemetry should be sent, false otherwise
|
|
911
1198
|
*/
|
|
912
1199
|
async function shouldTrack(config, sys, ci) {
|
|
913
|
-
return !ci && isInteractive(sys, config) && (await checkTelemetry(sys));
|
|
1200
|
+
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
914
1201
|
}
|
|
915
1202
|
|
|
916
1203
|
const isTest$1 = () => process.env.JEST_WORKER_ID !== undefined;
|
|
@@ -967,7 +1254,9 @@ async function updateConfig(sys, newOptions) {
|
|
|
967
1254
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
968
1255
|
}
|
|
969
1256
|
|
|
1257
|
+
const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
|
|
970
1258
|
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
1259
|
+
const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
|
|
971
1260
|
const DOCS_CUSTOM = 'docs-custom';
|
|
972
1261
|
const DOCS_JSON = 'docs-json';
|
|
973
1262
|
const DOCS_README = 'docs-readme';
|
|
@@ -979,11 +1268,10 @@ const WWW = 'www';
|
|
|
979
1268
|
*
|
|
980
1269
|
* @param sys The system where the command is invoked
|
|
981
1270
|
* @param config The config passed into the Stencil command
|
|
982
|
-
* @param logger The tool used to do logging
|
|
983
1271
|
* @param coreCompiler The compiler used to do builds
|
|
984
1272
|
* @param result The results of a compiler build.
|
|
985
1273
|
*/
|
|
986
|
-
async function telemetryBuildFinishedAction(sys, config,
|
|
1274
|
+
async function telemetryBuildFinishedAction(sys, config, coreCompiler, result) {
|
|
987
1275
|
const tracking = await shouldTrack(config, sys, config.flags.ci);
|
|
988
1276
|
if (!tracking) {
|
|
989
1277
|
return;
|
|
@@ -991,20 +1279,19 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
|
|
|
991
1279
|
const component_count = Object.keys(result.componentGraph).length;
|
|
992
1280
|
const data = await prepareData(coreCompiler, config, sys, result.duration, component_count);
|
|
993
1281
|
await sendMetric(sys, config, 'stencil_cli_command', data);
|
|
994
|
-
logger.debug(`${logger.blue('Telemetry')}: ${logger.gray(JSON.stringify(data))}`);
|
|
1282
|
+
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
995
1283
|
}
|
|
996
1284
|
/**
|
|
997
1285
|
* A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
|
|
1286
|
+
*
|
|
998
1287
|
* @param sys The system where the command is invoked
|
|
999
1288
|
* @param config The config passed into the Stencil command
|
|
1000
|
-
* @param logger The tool used to do logging
|
|
1001
1289
|
* @param coreCompiler The compiler used to do builds
|
|
1002
1290
|
* @param action A Promise-based function to call in order to get the duration of any given command.
|
|
1003
1291
|
* @returns void
|
|
1004
1292
|
*/
|
|
1005
|
-
async function telemetryAction(sys, config,
|
|
1006
|
-
|
|
1007
|
-
const tracking = await shouldTrack(config, sys, !!((_a = config === null || config === void 0 ? void 0 : config.flags) === null || _a === void 0 ? void 0 : _a.ci));
|
|
1293
|
+
async function telemetryAction(sys, config, coreCompiler, action) {
|
|
1294
|
+
const tracking = await shouldTrack(config, sys, !!config.flags.ci);
|
|
1008
1295
|
let duration = undefined;
|
|
1009
1296
|
let error;
|
|
1010
1297
|
if (action) {
|
|
@@ -1024,7 +1311,7 @@ async function telemetryAction(sys, config, logger, coreCompiler, action) {
|
|
|
1024
1311
|
}
|
|
1025
1312
|
const data = await prepareData(coreCompiler, config, sys, duration);
|
|
1026
1313
|
await sendMetric(sys, config, 'stencil_cli_command', data);
|
|
1027
|
-
logger.debug(`${logger.blue('Telemetry')}: ${logger.gray(JSON.stringify(data))}`);
|
|
1314
|
+
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
1028
1315
|
if (error) {
|
|
1029
1316
|
throw error;
|
|
1030
1317
|
}
|
|
@@ -1040,6 +1327,16 @@ async function getActiveTargets(config) {
|
|
|
1040
1327
|
const result = config.outputTargets.map((t) => t.type);
|
|
1041
1328
|
return Array.from(new Set(result));
|
|
1042
1329
|
}
|
|
1330
|
+
/**
|
|
1331
|
+
* Prepare data for telemetry
|
|
1332
|
+
*
|
|
1333
|
+
* @param coreCompiler the core compiler
|
|
1334
|
+
* @param config the current Stencil config
|
|
1335
|
+
* @param sys the compiler system instance in use
|
|
1336
|
+
* @param duration_ms the duration of the action being tracked
|
|
1337
|
+
* @param component_count the number of components being built (optional)
|
|
1338
|
+
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1339
|
+
*/
|
|
1043
1340
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1044
1341
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1045
1342
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
@@ -1052,6 +1349,7 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1052
1349
|
const cpu_model = sys.details.cpuModel;
|
|
1053
1350
|
const build = coreCompiler.buildId || 'unknown';
|
|
1054
1351
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1352
|
+
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1055
1353
|
return {
|
|
1056
1354
|
yarn,
|
|
1057
1355
|
duration_ms,
|
|
@@ -1071,12 +1369,83 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1071
1369
|
typescript,
|
|
1072
1370
|
rollup,
|
|
1073
1371
|
has_app_pwa_config,
|
|
1372
|
+
config: anonymizedConfig,
|
|
1074
1373
|
};
|
|
1075
1374
|
};
|
|
1375
|
+
// props in output targets for which we retain their original values when
|
|
1376
|
+
// preparing a config for telemetry
|
|
1377
|
+
//
|
|
1378
|
+
// we omit the values of all other fields on output targets.
|
|
1379
|
+
const OUTPUT_TARGET_KEYS_TO_KEEP = ['type'];
|
|
1380
|
+
// top-level config props that we anonymize for telemetry
|
|
1381
|
+
const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
1382
|
+
'rootDir',
|
|
1383
|
+
'fsNamespace',
|
|
1384
|
+
'packageJsonFilePath',
|
|
1385
|
+
'namespace',
|
|
1386
|
+
'srcDir',
|
|
1387
|
+
'srcIndexHtml',
|
|
1388
|
+
'buildLogFilePath',
|
|
1389
|
+
'cacheDir',
|
|
1390
|
+
'configPath',
|
|
1391
|
+
'tsconfig',
|
|
1392
|
+
];
|
|
1393
|
+
// Props we delete entirely from the config for telemetry
|
|
1394
|
+
//
|
|
1395
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1396
|
+
const CONFIG_PROPS_TO_DELETE = ['sys', 'logger', 'tsCompilerOptions', 'devServer'];
|
|
1397
|
+
/**
|
|
1398
|
+
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1399
|
+
* with a placeholder string if they are present (this lets us still track how frequently
|
|
1400
|
+
* these config options are being used)
|
|
1401
|
+
*
|
|
1402
|
+
* @param config the config to anonymize
|
|
1403
|
+
* @returns an anonymized copy of the same config
|
|
1404
|
+
*/
|
|
1405
|
+
const anonymizeConfigForTelemetry = (config) => {
|
|
1406
|
+
var _a;
|
|
1407
|
+
const anonymizedConfig = { ...config };
|
|
1408
|
+
for (const prop of CONFIG_PROPS_TO_ANONYMIZE) {
|
|
1409
|
+
if (anonymizedConfig[prop] !== undefined) {
|
|
1410
|
+
anonymizedConfig[prop] = 'omitted';
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
anonymizedConfig.outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).map((target) => {
|
|
1414
|
+
// Anonymize the outputTargets on our configuration, taking advantage of the
|
|
1415
|
+
// optional 2nd argument to `JSON.stringify`. If anything is not a string
|
|
1416
|
+
// we retain it so that any nested properties are handled, else we check
|
|
1417
|
+
// whether it's in our 'keep' list to decide whether to keep it or replace it
|
|
1418
|
+
// with `"omitted"`.
|
|
1419
|
+
const anonymizedOT = JSON.parse(JSON.stringify(target, (key, value) => {
|
|
1420
|
+
if (!(typeof value === 'string')) {
|
|
1421
|
+
return value;
|
|
1422
|
+
}
|
|
1423
|
+
if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) {
|
|
1424
|
+
return value;
|
|
1425
|
+
}
|
|
1426
|
+
return 'omitted';
|
|
1427
|
+
}));
|
|
1428
|
+
// this prop has to be handled separately because it is an array
|
|
1429
|
+
// so the replace function above will be called with all of its
|
|
1430
|
+
// members, giving us `["omitted", "omitted", ...]`.
|
|
1431
|
+
//
|
|
1432
|
+
// Instead, we check for its presence and manually copy over.
|
|
1433
|
+
if (isOutputTargetHydrate(target) && target.external) {
|
|
1434
|
+
anonymizedOT['external'] = target.external.concat();
|
|
1435
|
+
}
|
|
1436
|
+
return anonymizedOT;
|
|
1437
|
+
});
|
|
1438
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1439
|
+
for (const prop of CONFIG_PROPS_TO_DELETE) {
|
|
1440
|
+
delete anonymizedConfig[prop];
|
|
1441
|
+
}
|
|
1442
|
+
return anonymizedConfig;
|
|
1443
|
+
};
|
|
1076
1444
|
/**
|
|
1077
1445
|
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1078
1446
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1079
1447
|
* of each package under the @stencil, @ionic, and @capacitor scopes.
|
|
1448
|
+
*
|
|
1080
1449
|
* @param sys the system instance where telemetry is invoked
|
|
1081
1450
|
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1082
1451
|
* @returns an object listing all dev and production dependencies under the aforementioned scopes
|
|
@@ -1110,7 +1479,7 @@ async function getInstalledPackages(sys, config) {
|
|
|
1110
1479
|
return { packages, packagesNoVersions };
|
|
1111
1480
|
}
|
|
1112
1481
|
catch (err) {
|
|
1113
|
-
hasDebug(config) && console.error(err);
|
|
1482
|
+
hasDebug(config.flags) && console.error(err);
|
|
1114
1483
|
return { packages, packagesNoVersions };
|
|
1115
1484
|
}
|
|
1116
1485
|
}
|
|
@@ -1159,6 +1528,7 @@ function sanitizeDeclaredVersion(version) {
|
|
|
1159
1528
|
}
|
|
1160
1529
|
/**
|
|
1161
1530
|
* If telemetry is enabled, send a metric to an external data store
|
|
1531
|
+
*
|
|
1162
1532
|
* @param sys the system instance where telemetry is invoked
|
|
1163
1533
|
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1164
1534
|
* @param name the name of a trackable metric. Note this name is not necessarily a scalar value to track, like
|
|
@@ -1174,10 +1544,11 @@ async function sendMetric(sys, config, name, value) {
|
|
|
1174
1544
|
value,
|
|
1175
1545
|
session_id,
|
|
1176
1546
|
};
|
|
1177
|
-
await sendTelemetry(sys, config,
|
|
1547
|
+
await sendTelemetry(sys, config, message);
|
|
1178
1548
|
}
|
|
1179
1549
|
/**
|
|
1180
1550
|
* Used to read the config file's tokens.telemetry property.
|
|
1551
|
+
*
|
|
1181
1552
|
* @param sys The system where the command is invoked
|
|
1182
1553
|
* @returns string
|
|
1183
1554
|
*/
|
|
@@ -1199,7 +1570,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1199
1570
|
try {
|
|
1200
1571
|
const now = new Date().toISOString();
|
|
1201
1572
|
const body = {
|
|
1202
|
-
metrics: [data
|
|
1573
|
+
metrics: [data],
|
|
1203
1574
|
sent_at: now,
|
|
1204
1575
|
};
|
|
1205
1576
|
// This request is only made if telemetry is on.
|
|
@@ -1210,15 +1581,15 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1210
1581
|
},
|
|
1211
1582
|
body: JSON.stringify(body),
|
|
1212
1583
|
});
|
|
1213
|
-
hasVerbose(config) &&
|
|
1214
|
-
console.debug('\nSent %O metric to events service (status: %O)', data.
|
|
1584
|
+
hasVerbose(config.flags) &&
|
|
1585
|
+
console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
|
|
1215
1586
|
if (response.status !== 204) {
|
|
1216
|
-
hasVerbose(config) &&
|
|
1587
|
+
hasVerbose(config.flags) &&
|
|
1217
1588
|
console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
|
|
1218
1589
|
}
|
|
1219
1590
|
}
|
|
1220
1591
|
catch (e) {
|
|
1221
|
-
hasVerbose(config) && console.debug('Telemetry request failed:', e);
|
|
1592
|
+
hasVerbose(config.flags) && console.debug('Telemetry request failed:', e);
|
|
1222
1593
|
}
|
|
1223
1594
|
}
|
|
1224
1595
|
/**
|
|
@@ -1275,7 +1646,7 @@ const taskBuild = async (coreCompiler, config, sys) => {
|
|
|
1275
1646
|
const results = await compiler.build();
|
|
1276
1647
|
// TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
|
|
1277
1648
|
if (sys) {
|
|
1278
|
-
await telemetryBuildFinishedAction(sys, config,
|
|
1649
|
+
await telemetryBuildFinishedAction(sys, config, coreCompiler, results);
|
|
1279
1650
|
}
|
|
1280
1651
|
await compiler.destroy();
|
|
1281
1652
|
if (results.hasError) {
|
|
@@ -1314,6 +1685,7 @@ const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
|
1314
1685
|
!!global.process &&
|
|
1315
1686
|
typeof __filename === 'string' &&
|
|
1316
1687
|
(!global.origin || typeof global.origin !== 'string');
|
|
1688
|
+
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1317
1689
|
|
|
1318
1690
|
/**
|
|
1319
1691
|
* Task to generate component boilerplate and write it to disk. This task can
|
|
@@ -1362,7 +1734,10 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1362
1734
|
if (!writtenFiles) {
|
|
1363
1735
|
return config.sys.exit(1);
|
|
1364
1736
|
}
|
|
1365
|
-
//
|
|
1737
|
+
// We use `console.log` here rather than our `config.logger` because we don't want
|
|
1738
|
+
// our TUI messages to be prefixed with timestamps and so on.
|
|
1739
|
+
//
|
|
1740
|
+
// See STENCIL-424 for details.
|
|
1366
1741
|
console.log();
|
|
1367
1742
|
console.log(`${config.logger.gray('$')} stencil generate ${input}`);
|
|
1368
1743
|
console.log();
|
|
@@ -1506,7 +1881,8 @@ export class ${toPascalCase(tagName)} {
|
|
|
1506
1881
|
`;
|
|
1507
1882
|
};
|
|
1508
1883
|
/**
|
|
1509
|
-
* Get the boilerplate for style
|
|
1884
|
+
* Get the boilerplate for style for a generated component
|
|
1885
|
+
* @returns a boilerplate CSS block
|
|
1510
1886
|
*/
|
|
1511
1887
|
const getStyleUrlBoilerplate = () => `:host {
|
|
1512
1888
|
display: block;
|
|
@@ -1560,10 +1936,17 @@ describe('${tagName}', () => {
|
|
|
1560
1936
|
*/
|
|
1561
1937
|
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
|
|
1562
1938
|
|
|
1563
|
-
|
|
1939
|
+
/**
|
|
1940
|
+
* Entrypoint for the Telemetry task
|
|
1941
|
+
* @param flags configuration flags provided to Stencil when a task was called (either this task or a task that invokes
|
|
1942
|
+
* telemetry)
|
|
1943
|
+
* @param sys the abstraction for interfacing with the operating system
|
|
1944
|
+
* @param logger a logging implementation to log the results out to the user
|
|
1945
|
+
*/
|
|
1946
|
+
const taskTelemetry = async (flags, sys, logger) => {
|
|
1564
1947
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1565
|
-
const isEnabling =
|
|
1566
|
-
const isDisabling =
|
|
1948
|
+
const isEnabling = flags.args.includes('on');
|
|
1949
|
+
const isDisabling = flags.args.includes('off');
|
|
1567
1950
|
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')}`;
|
|
1568
1951
|
const THANK_YOU = `Thank you for helping to make Stencil better! 💖`;
|
|
1569
1952
|
const ENABLED_MESSAGE = `${logger.green('Enabled')}. ${THANK_YOU}\n\n`;
|
|
@@ -1592,7 +1975,14 @@ const taskTelemetry = async (config, sys, logger) => {
|
|
|
1592
1975
|
`);
|
|
1593
1976
|
};
|
|
1594
1977
|
|
|
1595
|
-
|
|
1978
|
+
/**
|
|
1979
|
+
* Entrypoint for the Help task, providing Stencil usage context to the user
|
|
1980
|
+
* @param flags configuration flags provided to Stencil when a task was call (either this task or a task that invokes
|
|
1981
|
+
* telemetry)
|
|
1982
|
+
* @param logger a logging implementation to log the results out to the user
|
|
1983
|
+
* @param sys the abstraction for interfacing with the operating system
|
|
1984
|
+
*/
|
|
1985
|
+
const taskHelp = async (flags, logger, sys) => {
|
|
1596
1986
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1597
1987
|
console.log(`
|
|
1598
1988
|
${logger.bold('Build:')} ${logger.dim('Build components for development or production.')}
|
|
@@ -1625,7 +2015,7 @@ const taskHelp = async (config, logger, sys) => {
|
|
|
1625
2015
|
`);
|
|
1626
2016
|
// TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
|
|
1627
2017
|
if (sys) {
|
|
1628
|
-
await taskTelemetry(
|
|
2018
|
+
await taskTelemetry(flags, sys, logger);
|
|
1629
2019
|
}
|
|
1630
2020
|
console.log(`
|
|
1631
2021
|
${logger.bold('Examples:')}
|
|
@@ -1682,6 +2072,10 @@ const taskServe = async (config) => {
|
|
|
1682
2072
|
});
|
|
1683
2073
|
};
|
|
1684
2074
|
|
|
2075
|
+
/**
|
|
2076
|
+
* Entrypoint for any Stencil tests
|
|
2077
|
+
* @param config a validated Stencil configuration entity
|
|
2078
|
+
*/
|
|
1685
2079
|
const taskTest = async (config) => {
|
|
1686
2080
|
if (!IS_NODE_ENV) {
|
|
1687
2081
|
config.logger.error(`"test" command is currently only implemented for a NodeJS environment`);
|
|
@@ -1728,6 +2122,95 @@ const taskTest = async (config) => {
|
|
|
1728
2122
|
}
|
|
1729
2123
|
};
|
|
1730
2124
|
|
|
2125
|
+
/**
|
|
2126
|
+
* Creates an instance of a logger
|
|
2127
|
+
* @returns the new logger instance
|
|
2128
|
+
*/
|
|
2129
|
+
const createLogger = () => {
|
|
2130
|
+
let useColors = IS_BROWSER_ENV;
|
|
2131
|
+
let level = 'info';
|
|
2132
|
+
return {
|
|
2133
|
+
enableColors: (uc) => (useColors = uc),
|
|
2134
|
+
getLevel: () => level,
|
|
2135
|
+
setLevel: (l) => (level = l),
|
|
2136
|
+
emoji: (e) => e,
|
|
2137
|
+
info: console.log.bind(console),
|
|
2138
|
+
warn: console.warn.bind(console),
|
|
2139
|
+
error: console.error.bind(console),
|
|
2140
|
+
debug: console.debug.bind(console),
|
|
2141
|
+
red: (msg) => msg,
|
|
2142
|
+
green: (msg) => msg,
|
|
2143
|
+
yellow: (msg) => msg,
|
|
2144
|
+
blue: (msg) => msg,
|
|
2145
|
+
magenta: (msg) => msg,
|
|
2146
|
+
cyan: (msg) => msg,
|
|
2147
|
+
gray: (msg) => msg,
|
|
2148
|
+
bold: (msg) => msg,
|
|
2149
|
+
dim: (msg) => msg,
|
|
2150
|
+
bgRed: (msg) => msg,
|
|
2151
|
+
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
2152
|
+
duration: () => 0,
|
|
2153
|
+
finish: () => 0,
|
|
2154
|
+
}),
|
|
2155
|
+
printDiagnostics(diagnostics) {
|
|
2156
|
+
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
2157
|
+
},
|
|
2158
|
+
};
|
|
2159
|
+
};
|
|
2160
|
+
const logDiagnostic = (diagnostic, useColors) => {
|
|
2161
|
+
let color = BLUE;
|
|
2162
|
+
let prefix = 'Build';
|
|
2163
|
+
let msg = '';
|
|
2164
|
+
if (diagnostic.level === 'error') {
|
|
2165
|
+
color = RED;
|
|
2166
|
+
prefix = 'Error';
|
|
2167
|
+
}
|
|
2168
|
+
else if (diagnostic.level === 'warn') {
|
|
2169
|
+
color = YELLOW;
|
|
2170
|
+
prefix = 'Warning';
|
|
2171
|
+
}
|
|
2172
|
+
if (diagnostic.header) {
|
|
2173
|
+
prefix = diagnostic.header;
|
|
2174
|
+
}
|
|
2175
|
+
const filePath = diagnostic.relFilePath || diagnostic.absFilePath;
|
|
2176
|
+
if (filePath) {
|
|
2177
|
+
msg += filePath;
|
|
2178
|
+
if (typeof diagnostic.lineNumber === 'number' && diagnostic.lineNumber > 0) {
|
|
2179
|
+
msg += ', line ' + diagnostic.lineNumber;
|
|
2180
|
+
if (typeof diagnostic.columnNumber === 'number' && diagnostic.columnNumber > 0) {
|
|
2181
|
+
msg += ', column ' + diagnostic.columnNumber;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
msg += '\n';
|
|
2185
|
+
}
|
|
2186
|
+
msg += diagnostic.messageText;
|
|
2187
|
+
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
2188
|
+
diagnostic.lines.forEach((l) => {
|
|
2189
|
+
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
2190
|
+
});
|
|
2191
|
+
msg += '\n';
|
|
2192
|
+
}
|
|
2193
|
+
if (useColors) {
|
|
2194
|
+
const styledPrefix = [
|
|
2195
|
+
'%c' + prefix,
|
|
2196
|
+
`background: ${color}; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;`,
|
|
2197
|
+
];
|
|
2198
|
+
console.log(...styledPrefix, msg);
|
|
2199
|
+
}
|
|
2200
|
+
else if (diagnostic.level === 'error') {
|
|
2201
|
+
console.error(msg);
|
|
2202
|
+
}
|
|
2203
|
+
else if (diagnostic.level === 'warn') {
|
|
2204
|
+
console.warn(msg);
|
|
2205
|
+
}
|
|
2206
|
+
else {
|
|
2207
|
+
console.log(msg);
|
|
2208
|
+
}
|
|
2209
|
+
};
|
|
2210
|
+
const YELLOW = `#f39c12`;
|
|
2211
|
+
const RED = `#c0392b`;
|
|
2212
|
+
const BLUE = `#3498db`;
|
|
2213
|
+
|
|
1731
2214
|
const run = async (init) => {
|
|
1732
2215
|
const { args, logger, sys } = init;
|
|
1733
2216
|
try {
|
|
@@ -1743,7 +2226,7 @@ const run = async (init) => {
|
|
|
1743
2226
|
sys.applyGlobalPatch(sys.getCurrentDirectory());
|
|
1744
2227
|
}
|
|
1745
2228
|
if (task === 'help' || flags.help) {
|
|
1746
|
-
await taskHelp({
|
|
2229
|
+
await taskHelp(createConfigFlags({ task: 'help', args }), logger, sys);
|
|
1747
2230
|
return;
|
|
1748
2231
|
}
|
|
1749
2232
|
startupLog(logger, task);
|
|
@@ -1769,7 +2252,7 @@ const run = async (init) => {
|
|
|
1769
2252
|
startupLogVersion(logger, task, coreCompiler);
|
|
1770
2253
|
loadedCompilerLog(sys, logger, flags, coreCompiler);
|
|
1771
2254
|
if (task === 'info') {
|
|
1772
|
-
await telemetryAction(sys, { flags: { task: 'info' },
|
|
2255
|
+
await telemetryAction(sys, { flags: createConfigFlags({ task: 'info' }), logger }, coreCompiler, async () => {
|
|
1773
2256
|
await taskInfo(coreCompiler, sys, logger);
|
|
1774
2257
|
});
|
|
1775
2258
|
return;
|
|
@@ -1792,7 +2275,7 @@ const run = async (init) => {
|
|
|
1792
2275
|
sys.applyGlobalPatch(validated.config.rootDir);
|
|
1793
2276
|
}
|
|
1794
2277
|
await sys.ensureResources({ rootDir: validated.config.rootDir, logger, dependencies: dependencies });
|
|
1795
|
-
await telemetryAction(sys, validated.config,
|
|
2278
|
+
await telemetryAction(sys, validated.config, coreCompiler, async () => {
|
|
1796
2279
|
await runTask(coreCompiler, validated.config, task, sys);
|
|
1797
2280
|
});
|
|
1798
2281
|
}
|
|
@@ -1805,43 +2288,45 @@ const run = async (init) => {
|
|
|
1805
2288
|
}
|
|
1806
2289
|
};
|
|
1807
2290
|
const runTask = async (coreCompiler, config, task, sys) => {
|
|
1808
|
-
|
|
1809
|
-
|
|
2291
|
+
var _a, _b;
|
|
2292
|
+
const logger = (_a = config.logger) !== null && _a !== void 0 ? _a : createLogger();
|
|
2293
|
+
const strictConfig = { ...config, flags: createConfigFlags((_b = config.flags) !== null && _b !== void 0 ? _b : { task }), logger };
|
|
2294
|
+
strictConfig.outputTargets = strictConfig.outputTargets || [];
|
|
1810
2295
|
switch (task) {
|
|
1811
2296
|
case 'build':
|
|
1812
|
-
await taskBuild(coreCompiler,
|
|
2297
|
+
await taskBuild(coreCompiler, strictConfig, sys);
|
|
1813
2298
|
break;
|
|
1814
2299
|
case 'docs':
|
|
1815
|
-
await taskDocs(coreCompiler,
|
|
2300
|
+
await taskDocs(coreCompiler, strictConfig);
|
|
1816
2301
|
break;
|
|
1817
2302
|
case 'generate':
|
|
1818
2303
|
case 'g':
|
|
1819
|
-
await taskGenerate(coreCompiler,
|
|
2304
|
+
await taskGenerate(coreCompiler, strictConfig);
|
|
1820
2305
|
break;
|
|
1821
2306
|
case 'help':
|
|
1822
|
-
await taskHelp(
|
|
2307
|
+
await taskHelp(strictConfig.flags, strictConfig.logger, sys);
|
|
1823
2308
|
break;
|
|
1824
2309
|
case 'prerender':
|
|
1825
|
-
await taskPrerender(coreCompiler,
|
|
2310
|
+
await taskPrerender(coreCompiler, strictConfig);
|
|
1826
2311
|
break;
|
|
1827
2312
|
case 'serve':
|
|
1828
|
-
await taskServe(
|
|
2313
|
+
await taskServe(strictConfig);
|
|
1829
2314
|
break;
|
|
1830
2315
|
case 'telemetry':
|
|
1831
2316
|
// TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
|
|
1832
2317
|
if (sys) {
|
|
1833
|
-
await taskTelemetry(
|
|
2318
|
+
await taskTelemetry(strictConfig.flags, sys, strictConfig.logger);
|
|
1834
2319
|
}
|
|
1835
2320
|
break;
|
|
1836
2321
|
case 'test':
|
|
1837
|
-
await taskTest(
|
|
2322
|
+
await taskTest(strictConfig);
|
|
1838
2323
|
break;
|
|
1839
2324
|
case 'version':
|
|
1840
2325
|
console.log(coreCompiler.version);
|
|
1841
2326
|
break;
|
|
1842
2327
|
default:
|
|
1843
|
-
|
|
1844
|
-
await taskHelp(
|
|
2328
|
+
strictConfig.logger.error(`${strictConfig.logger.emoji('❌ ')}Invalid stencil command, please see the options below:`);
|
|
2329
|
+
await taskHelp(strictConfig.flags, strictConfig.logger, sys);
|
|
1845
2330
|
return config.sys.exit(1);
|
|
1846
2331
|
}
|
|
1847
2332
|
};
|