@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.js
CHANGED
|
@@ -1,8 +1,50 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil CLI v2.
|
|
2
|
+
Stencil CLI v2.17.2-0 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
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,223 @@ const validateComponentTag = (tag) => {
|
|
|
275
317
|
return undefined;
|
|
276
318
|
};
|
|
277
319
|
|
|
278
|
-
|
|
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
|
+
* Helper function for initializing a `ConfigFlags` object. Provide any overrides
|
|
503
|
+
* for default values and off you go!
|
|
504
|
+
*
|
|
505
|
+
* @param init an object with any overrides for default values
|
|
506
|
+
* @returns a complete CLI flag object
|
|
507
|
+
*/
|
|
508
|
+
const createConfigFlags = (init = {}) => {
|
|
279
509
|
const flags = {
|
|
280
510
|
task: null,
|
|
281
511
|
args: [],
|
|
282
512
|
knownArgs: [],
|
|
283
|
-
unknownArgs:
|
|
513
|
+
unknownArgs: [],
|
|
514
|
+
...init,
|
|
284
515
|
};
|
|
516
|
+
return flags;
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Parse command line arguments into a structured `ConfigFlags` object
|
|
521
|
+
*
|
|
522
|
+
* @param args an array of config flags
|
|
523
|
+
* @param sys an optional compiler system
|
|
524
|
+
* @returns a structured ConfigFlags object
|
|
525
|
+
*/
|
|
526
|
+
const parseFlags = (args, sys) => {
|
|
527
|
+
const flags = createConfigFlags();
|
|
285
528
|
// cmd line has more priority over npm scripts cmd
|
|
286
|
-
flags.args = args.slice();
|
|
529
|
+
flags.args = Array.isArray(args) ? args.slice() : [];
|
|
287
530
|
if (flags.args.length > 0 && flags.args[0] && !flags.args[0].startsWith('-')) {
|
|
288
531
|
flags.task = flags.args[0];
|
|
289
532
|
}
|
|
290
|
-
parseArgs(flags, flags.args
|
|
533
|
+
parseArgs(flags, flags.args);
|
|
291
534
|
if (sys && sys.name === 'node') {
|
|
292
535
|
const envArgs = getNpmConfigEnvArgs(sys);
|
|
293
|
-
parseArgs(flags, envArgs
|
|
536
|
+
parseArgs(flags, envArgs);
|
|
294
537
|
envArgs.forEach((envArg) => {
|
|
295
538
|
if (!flags.args.includes(envArg)) {
|
|
296
539
|
flags.args.push(envArg);
|
|
@@ -309,185 +552,230 @@ const parseFlags = (args, sys) => {
|
|
|
309
552
|
return flags;
|
|
310
553
|
};
|
|
311
554
|
/**
|
|
312
|
-
* Parse command line arguments that are
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
555
|
+
* Parse command line arguments that are enumerated in the `config-flags`
|
|
556
|
+
* module. Handles leading dashes on arguments, aliases that are defined for a
|
|
557
|
+
* small number of arguments, and parsing values for non-boolean arguments
|
|
558
|
+
* (e.g. port number for the dev server).
|
|
559
|
+
*
|
|
560
|
+
* @param flags a ConfigFlags object to which parsed arguments will be added
|
|
561
|
+
* @param args an array of command-line arguments to parse
|
|
562
|
+
*/
|
|
563
|
+
const parseArgs = (flags, args) => {
|
|
564
|
+
BOOLEAN_CLI_ARGS.forEach((argName) => parseBooleanArg(flags, args, argName));
|
|
565
|
+
STRING_CLI_ARGS.forEach((argName) => parseStringArg(flags, args, argName));
|
|
566
|
+
NUMBER_CLI_ARGS.forEach((argName) => parseNumberArg(flags, args, argName));
|
|
567
|
+
STRING_NUMBER_CLI_ARGS.forEach((argName) => parseStringNumberArg(flags, args, argName));
|
|
568
|
+
LOG_LEVEL_CLI_ARGS.forEach((argName) => parseLogLevelArg(flags, args, argName));
|
|
569
|
+
};
|
|
570
|
+
/**
|
|
571
|
+
* Parse a boolean CLI argument. For these, we support the following formats:
|
|
316
572
|
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
573
|
+
* - `--booleanArg`
|
|
574
|
+
* - `--boolean-arg`
|
|
575
|
+
* - `--noBooleanArg`
|
|
576
|
+
* - `--no-boolean-arg`
|
|
577
|
+
*
|
|
578
|
+
* The final two variants should be parsed to a value of `false` on the config
|
|
579
|
+
* object.
|
|
580
|
+
*
|
|
581
|
+
* @param flags the config flags object, while we'll modify
|
|
582
|
+
* @param args our CLI arguments
|
|
583
|
+
* @param configCaseName the argument we want to look at right now
|
|
584
|
+
*/
|
|
585
|
+
const parseBooleanArg = (flags, args, configCaseName) => {
|
|
586
|
+
// we support both dash-case and PascalCase versions of the parameter
|
|
587
|
+
// argName is 'configCase' version which can be found in BOOLEAN_ARG_OPTS
|
|
588
|
+
const alias = CLI_ARG_ALIASES[configCaseName];
|
|
589
|
+
const dashCaseName = toDashCase(configCaseName);
|
|
590
|
+
if (typeof flags[configCaseName] !== 'boolean') {
|
|
591
|
+
flags[configCaseName] = null;
|
|
592
|
+
}
|
|
593
|
+
args.forEach((cmdArg) => {
|
|
594
|
+
let value;
|
|
595
|
+
if (cmdArg === `--${configCaseName}` || cmdArg === `--${dashCaseName}`) {
|
|
596
|
+
value = true;
|
|
327
597
|
}
|
|
328
|
-
|
|
329
|
-
|
|
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;
|
|
598
|
+
else if (cmdArg === `--no-${dashCaseName}` || cmdArg === `--no${dashToPascalCase(dashCaseName)}`) {
|
|
599
|
+
value = false;
|
|
356
600
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
-
}
|
|
601
|
+
else if (alias && cmdArg === `-${alias}`) {
|
|
602
|
+
value = true;
|
|
603
|
+
}
|
|
604
|
+
if (value !== undefined && cmdArg !== undefined) {
|
|
605
|
+
flags[configCaseName] = value;
|
|
606
|
+
flags.knownArgs.push(cmdArg);
|
|
393
607
|
}
|
|
394
608
|
});
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* Parse a string CLI argument
|
|
612
|
+
*
|
|
613
|
+
* @param flags the config flags object, while we'll modify
|
|
614
|
+
* @param args our CLI arguments
|
|
615
|
+
* @param configCaseName the argument we want to look at right now
|
|
616
|
+
*/
|
|
617
|
+
const parseStringArg = (flags, args, configCaseName) => {
|
|
618
|
+
if (typeof flags[configCaseName] !== 'string') {
|
|
619
|
+
flags[configCaseName] = null;
|
|
620
|
+
}
|
|
621
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
622
|
+
if (value !== undefined && matchingArg !== undefined) {
|
|
623
|
+
flags[configCaseName] = value;
|
|
624
|
+
flags.knownArgs.push(matchingArg);
|
|
625
|
+
flags.knownArgs.push(value);
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
/**
|
|
629
|
+
* Parse a number CLI argument
|
|
630
|
+
*
|
|
631
|
+
* @param flags the config flags object, while we'll modify
|
|
632
|
+
* @param args our CLI arguments
|
|
633
|
+
* @param configCaseName the argument we want to look at right now
|
|
634
|
+
*/
|
|
635
|
+
const parseNumberArg = (flags, args, configCaseName) => {
|
|
636
|
+
if (typeof flags[configCaseName] !== 'number') {
|
|
637
|
+
flags[configCaseName] = null;
|
|
638
|
+
}
|
|
639
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
640
|
+
if (value !== undefined && matchingArg !== undefined) {
|
|
641
|
+
flags[configCaseName] = parseInt(value, 10);
|
|
642
|
+
flags.knownArgs.push(matchingArg);
|
|
643
|
+
flags.knownArgs.push(value);
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
/**
|
|
647
|
+
* Parse a CLI argument which may be either a string or a number
|
|
648
|
+
*
|
|
649
|
+
* @param flags the config flags object, while we'll modify
|
|
650
|
+
* @param args our CLI arguments
|
|
651
|
+
* @param configCaseName the argument we want to look at right now
|
|
652
|
+
*/
|
|
653
|
+
const parseStringNumberArg = (flags, args, configCaseName) => {
|
|
654
|
+
if (!['number', 'string'].includes(typeof flags[configCaseName])) {
|
|
655
|
+
flags[configCaseName] = null;
|
|
656
|
+
}
|
|
657
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
658
|
+
if (value !== undefined && matchingArg !== undefined) {
|
|
659
|
+
if (CLI_ARG_STRING_REGEX.test(value)) {
|
|
660
|
+
// if it matches the regex we treat it like a string
|
|
661
|
+
flags[configCaseName] = value;
|
|
400
662
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
663
|
+
else {
|
|
664
|
+
// it was a number, great!
|
|
665
|
+
flags[configCaseName] = Number(value);
|
|
666
|
+
}
|
|
667
|
+
flags.knownArgs.push(matchingArg);
|
|
668
|
+
flags.knownArgs.push(value);
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
/**
|
|
672
|
+
* We use this regular expression to detect CLI parameters which
|
|
673
|
+
* should be parsed as string values (as opposed to numbers) for
|
|
674
|
+
* the argument types for which we support both a string and a
|
|
675
|
+
* number value.
|
|
676
|
+
*
|
|
677
|
+
* The regex tests for the presence of at least one character which is
|
|
678
|
+
* _not_ a digit (`\d`), a period (`\.`), or one of the characters `"e"`,
|
|
679
|
+
* `"E"`, `"+"`, or `"-"` (the latter four characters are necessary to
|
|
680
|
+
* support the admittedly unlikely use of scientific notation, like `"4e+0"`
|
|
681
|
+
* for `4`).
|
|
682
|
+
*
|
|
683
|
+
* Thus we'll match a string like `"50%"`, but not a string like `"50"` or
|
|
684
|
+
* `"5.0"`. If it matches a given string we conclude that the string should
|
|
685
|
+
* be parsed as a string literal, rather than using `Number` to convert it
|
|
686
|
+
* to a number.
|
|
687
|
+
*/
|
|
688
|
+
const CLI_ARG_STRING_REGEX = /[^\d\.Ee\+\-]+/g;
|
|
689
|
+
/**
|
|
690
|
+
* Parse a LogLevel CLI argument. These can be only a specific
|
|
691
|
+
* set of strings, so this function takes care of validating that
|
|
692
|
+
* the value is correct.
|
|
693
|
+
*
|
|
694
|
+
* @param flags the config flags object, while we'll modify
|
|
695
|
+
* @param args our CLI arguments
|
|
696
|
+
* @param configCaseName the argument we want to look at right now
|
|
697
|
+
*/
|
|
698
|
+
const parseLogLevelArg = (flags, args, configCaseName) => {
|
|
699
|
+
if (typeof flags[configCaseName] !== 'string') {
|
|
700
|
+
flags[configCaseName] = null;
|
|
701
|
+
}
|
|
702
|
+
const { value, matchingArg } = getValue(args, configCaseName);
|
|
703
|
+
if (value !== undefined && matchingArg !== undefined && isLogLevel(value)) {
|
|
704
|
+
flags[configCaseName] = value;
|
|
705
|
+
flags.knownArgs.push(matchingArg);
|
|
706
|
+
flags.knownArgs.push(value);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
/**
|
|
710
|
+
* Helper for pulling values out from the raw array of CLI arguments. This logic
|
|
711
|
+
* is shared between a few different types of CLI args.
|
|
712
|
+
*
|
|
713
|
+
* We look for arguments in the following formats:
|
|
714
|
+
*
|
|
715
|
+
* - `--my-cli-argument value`
|
|
716
|
+
* - `--my-cli-argument=value`
|
|
717
|
+
* - `--myCliArgument value`
|
|
718
|
+
* - `--myCliArgument=value`
|
|
719
|
+
*
|
|
720
|
+
* We also check for shortened aliases, which we define for a few arguments.
|
|
721
|
+
*
|
|
722
|
+
* @param args the CLI args we're dealing with
|
|
723
|
+
* @param configCaseName the ConfigFlag key which we're looking to pull out a value for
|
|
724
|
+
* @returns the value for the flag as well as the exact string which it matched from
|
|
725
|
+
* the user input.
|
|
726
|
+
*/
|
|
727
|
+
const getValue = (args, configCaseName) => {
|
|
728
|
+
// for some CLI args we have a short alias, like 'c' for 'config'
|
|
729
|
+
const alias = CLI_ARG_ALIASES[configCaseName];
|
|
730
|
+
// we support supplying arguments in both dash-case and configCase
|
|
731
|
+
// for ease of use
|
|
732
|
+
const dashCaseName = toDashCase(configCaseName);
|
|
733
|
+
let value;
|
|
734
|
+
let matchingArg;
|
|
735
|
+
args.forEach((arg, i) => {
|
|
736
|
+
if (arg.startsWith(`--${dashCaseName}=`) || arg.startsWith(`--${configCaseName}=`)) {
|
|
737
|
+
value = getEqualsValue(arg);
|
|
738
|
+
matchingArg = arg;
|
|
739
|
+
}
|
|
740
|
+
else if (arg === `--${dashCaseName}` || arg === `--${configCaseName}`) {
|
|
741
|
+
value = args[i + 1];
|
|
742
|
+
matchingArg = arg;
|
|
743
|
+
}
|
|
744
|
+
else if (alias) {
|
|
745
|
+
if (arg.startsWith(`-${alias}=`)) {
|
|
746
|
+
value = getEqualsValue(arg);
|
|
747
|
+
matchingArg = arg;
|
|
422
748
|
}
|
|
423
|
-
else if (alias) {
|
|
424
|
-
|
|
425
|
-
|
|
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
|
-
}
|
|
749
|
+
else if (arg === `-${alias}`) {
|
|
750
|
+
value = args[i + 1];
|
|
751
|
+
matchingArg = arg;
|
|
434
752
|
}
|
|
435
753
|
}
|
|
436
754
|
});
|
|
755
|
+
return { value, matchingArg };
|
|
437
756
|
};
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
};
|
|
757
|
+
/**
|
|
758
|
+
* When a parameter is set in the format `--foobar=12` at the CLI (as opposed to
|
|
759
|
+
* `--foobar 12`) we want to get the value after the `=` sign
|
|
760
|
+
*
|
|
761
|
+
* @param commandArgument the arg in question
|
|
762
|
+
* @returns the value after the `=`
|
|
763
|
+
*/
|
|
764
|
+
const getEqualsValue = (commandArgument) => commandArgument.split('=').slice(1).join('=');
|
|
765
|
+
/**
|
|
766
|
+
* Small helper for getting type-system-level assurance that a `string` can be
|
|
767
|
+
* narrowed to a `LogLevel`
|
|
768
|
+
*
|
|
769
|
+
* @param maybeLogLevel the string to check
|
|
770
|
+
* @returns whether this is a `LogLevel`
|
|
771
|
+
*/
|
|
772
|
+
const isLogLevel = (maybeLogLevel) =>
|
|
773
|
+
// unfortunately `includes` is typed on `ReadonlyArray<T>` as `(el: T):
|
|
774
|
+
// boolean` so a `string` cannot be passed to `includes` on a
|
|
775
|
+
// `ReadonlyArray` 😢 thus we `as any`
|
|
776
|
+
//
|
|
777
|
+
// see microsoft/TypeScript#31018 for some discussion of this
|
|
778
|
+
LOG_LEVELS.includes(maybeLogLevel);
|
|
491
779
|
const getNpmConfigEnvArgs = (sys) => {
|
|
492
780
|
// process.env.npm_config_argv
|
|
493
781
|
// {"remain":["4444"],"cooked":["run","serve","--port","4444"],"original":["run","serve","--port","4444"]}
|
|
@@ -508,7 +796,7 @@ const getNpmConfigEnvArgs = (sys) => {
|
|
|
508
796
|
const dependencies = [
|
|
509
797
|
{
|
|
510
798
|
name: "@stencil/core",
|
|
511
|
-
version: "2.
|
|
799
|
+
version: "2.17.2-0",
|
|
512
800
|
main: "compiler/stencil.js",
|
|
513
801
|
resources: [
|
|
514
802
|
"package.json",
|
|
@@ -833,12 +1121,11 @@ const tryFn = async (fn, ...args) => {
|
|
|
833
1121
|
}
|
|
834
1122
|
return null;
|
|
835
1123
|
};
|
|
836
|
-
const isInteractive = (sys,
|
|
837
|
-
var _a;
|
|
1124
|
+
const isInteractive = (sys, flags, object) => {
|
|
838
1125
|
const terminalInfo = object ||
|
|
839
1126
|
Object.freeze({
|
|
840
1127
|
tty: sys.isTTY() ? true : false,
|
|
841
|
-
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!
|
|
1128
|
+
ci: ['CI', 'BUILD_ID', 'BUILD_NUMBER', 'BITBUCKET_COMMIT', 'CODEBUILD_BUILD_ARN'].filter((v) => !!sys.getEnvironmentVar(v)).length > 0 || !!flags.ci,
|
|
842
1129
|
});
|
|
843
1130
|
return terminalInfo.tty && !terminalInfo.ci;
|
|
844
1131
|
};
|
|
@@ -863,19 +1150,19 @@ async function readJson(sys, path) {
|
|
|
863
1150
|
}
|
|
864
1151
|
/**
|
|
865
1152
|
* Does the command have the debug flag?
|
|
866
|
-
* @param
|
|
1153
|
+
* @param flags The configuration flags passed into the Stencil command
|
|
867
1154
|
* @returns true if --debug has been passed, otherwise false
|
|
868
1155
|
*/
|
|
869
|
-
function hasDebug(
|
|
870
|
-
return
|
|
1156
|
+
function hasDebug(flags) {
|
|
1157
|
+
return flags.debug;
|
|
871
1158
|
}
|
|
872
1159
|
/**
|
|
873
1160
|
* Does the command have the verbose and debug flags?
|
|
874
|
-
* @param
|
|
1161
|
+
* @param flags The configuration flags passed into the Stencil command
|
|
875
1162
|
* @returns true if both --debug and --verbose have been passed, otherwise false
|
|
876
1163
|
*/
|
|
877
|
-
function hasVerbose(
|
|
878
|
-
return
|
|
1164
|
+
function hasVerbose(flags) {
|
|
1165
|
+
return flags.verbose && hasDebug(flags);
|
|
879
1166
|
}
|
|
880
1167
|
|
|
881
1168
|
/**
|
|
@@ -886,7 +1173,7 @@ function hasVerbose(config) {
|
|
|
886
1173
|
* @returns true if telemetry should be sent, false otherwise
|
|
887
1174
|
*/
|
|
888
1175
|
async function shouldTrack(config, sys, ci) {
|
|
889
|
-
return !ci && isInteractive(sys, config) && (await checkTelemetry(sys));
|
|
1176
|
+
return !ci && isInteractive(sys, config.flags) && (await checkTelemetry(sys));
|
|
890
1177
|
}
|
|
891
1178
|
|
|
892
1179
|
const isTest$1 = () => process.env.JEST_WORKER_ID !== undefined;
|
|
@@ -943,7 +1230,9 @@ async function updateConfig(sys, newOptions) {
|
|
|
943
1230
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
944
1231
|
}
|
|
945
1232
|
|
|
1233
|
+
const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
|
|
946
1234
|
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
1235
|
+
const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
|
|
947
1236
|
const DOCS_CUSTOM = 'docs-custom';
|
|
948
1237
|
const DOCS_JSON = 'docs-json';
|
|
949
1238
|
const DOCS_README = 'docs-readme';
|
|
@@ -955,11 +1244,10 @@ const WWW = 'www';
|
|
|
955
1244
|
*
|
|
956
1245
|
* @param sys The system where the command is invoked
|
|
957
1246
|
* @param config The config passed into the Stencil command
|
|
958
|
-
* @param logger The tool used to do logging
|
|
959
1247
|
* @param coreCompiler The compiler used to do builds
|
|
960
1248
|
* @param result The results of a compiler build.
|
|
961
1249
|
*/
|
|
962
|
-
async function telemetryBuildFinishedAction(sys, config,
|
|
1250
|
+
async function telemetryBuildFinishedAction(sys, config, coreCompiler, result) {
|
|
963
1251
|
const tracking = await shouldTrack(config, sys, config.flags.ci);
|
|
964
1252
|
if (!tracking) {
|
|
965
1253
|
return;
|
|
@@ -967,20 +1255,19 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
|
|
|
967
1255
|
const component_count = Object.keys(result.componentGraph).length;
|
|
968
1256
|
const data = await prepareData(coreCompiler, config, sys, result.duration, component_count);
|
|
969
1257
|
await sendMetric(sys, config, 'stencil_cli_command', data);
|
|
970
|
-
logger.debug(`${logger.blue('Telemetry')}: ${logger.gray(JSON.stringify(data))}`);
|
|
1258
|
+
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
971
1259
|
}
|
|
972
1260
|
/**
|
|
973
1261
|
* A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
|
|
1262
|
+
*
|
|
974
1263
|
* @param sys The system where the command is invoked
|
|
975
1264
|
* @param config The config passed into the Stencil command
|
|
976
|
-
* @param logger The tool used to do logging
|
|
977
1265
|
* @param coreCompiler The compiler used to do builds
|
|
978
1266
|
* @param action A Promise-based function to call in order to get the duration of any given command.
|
|
979
1267
|
* @returns void
|
|
980
1268
|
*/
|
|
981
|
-
async function telemetryAction(sys, config,
|
|
982
|
-
|
|
983
|
-
const tracking = await shouldTrack(config, sys, !!((_a = config === null || config === void 0 ? void 0 : config.flags) === null || _a === void 0 ? void 0 : _a.ci));
|
|
1269
|
+
async function telemetryAction(sys, config, coreCompiler, action) {
|
|
1270
|
+
const tracking = await shouldTrack(config, sys, !!config.flags.ci);
|
|
984
1271
|
let duration = undefined;
|
|
985
1272
|
let error;
|
|
986
1273
|
if (action) {
|
|
@@ -1000,7 +1287,7 @@ async function telemetryAction(sys, config, logger, coreCompiler, action) {
|
|
|
1000
1287
|
}
|
|
1001
1288
|
const data = await prepareData(coreCompiler, config, sys, duration);
|
|
1002
1289
|
await sendMetric(sys, config, 'stencil_cli_command', data);
|
|
1003
|
-
logger.debug(`${logger.blue('Telemetry')}: ${logger.gray(JSON.stringify(data))}`);
|
|
1290
|
+
config.logger.debug(`${config.logger.blue('Telemetry')}: ${config.logger.gray(JSON.stringify(data))}`);
|
|
1004
1291
|
if (error) {
|
|
1005
1292
|
throw error;
|
|
1006
1293
|
}
|
|
@@ -1016,6 +1303,16 @@ async function getActiveTargets(config) {
|
|
|
1016
1303
|
const result = config.outputTargets.map((t) => t.type);
|
|
1017
1304
|
return Array.from(new Set(result));
|
|
1018
1305
|
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Prepare data for telemetry
|
|
1308
|
+
*
|
|
1309
|
+
* @param coreCompiler the core compiler
|
|
1310
|
+
* @param config the current Stencil config
|
|
1311
|
+
* @param sys the compiler system instance in use
|
|
1312
|
+
* @param duration_ms the duration of the action being tracked
|
|
1313
|
+
* @param component_count the number of components being built (optional)
|
|
1314
|
+
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1315
|
+
*/
|
|
1019
1316
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1020
1317
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1021
1318
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
@@ -1028,6 +1325,7 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1028
1325
|
const cpu_model = sys.details.cpuModel;
|
|
1029
1326
|
const build = coreCompiler.buildId || 'unknown';
|
|
1030
1327
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1328
|
+
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1031
1329
|
return {
|
|
1032
1330
|
yarn,
|
|
1033
1331
|
duration_ms,
|
|
@@ -1047,12 +1345,83 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1047
1345
|
typescript,
|
|
1048
1346
|
rollup,
|
|
1049
1347
|
has_app_pwa_config,
|
|
1348
|
+
config: anonymizedConfig,
|
|
1050
1349
|
};
|
|
1051
1350
|
};
|
|
1351
|
+
// props in output targets for which we retain their original values when
|
|
1352
|
+
// preparing a config for telemetry
|
|
1353
|
+
//
|
|
1354
|
+
// we omit the values of all other fields on output targets.
|
|
1355
|
+
const OUTPUT_TARGET_KEYS_TO_KEEP = ['type'];
|
|
1356
|
+
// top-level config props that we anonymize for telemetry
|
|
1357
|
+
const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
1358
|
+
'rootDir',
|
|
1359
|
+
'fsNamespace',
|
|
1360
|
+
'packageJsonFilePath',
|
|
1361
|
+
'namespace',
|
|
1362
|
+
'srcDir',
|
|
1363
|
+
'srcIndexHtml',
|
|
1364
|
+
'buildLogFilePath',
|
|
1365
|
+
'cacheDir',
|
|
1366
|
+
'configPath',
|
|
1367
|
+
'tsconfig',
|
|
1368
|
+
];
|
|
1369
|
+
// Props we delete entirely from the config for telemetry
|
|
1370
|
+
//
|
|
1371
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1372
|
+
const CONFIG_PROPS_TO_DELETE = ['sys', 'logger', 'tsCompilerOptions', 'devServer'];
|
|
1373
|
+
/**
|
|
1374
|
+
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1375
|
+
* with a placeholder string if they are present (this lets us still track how frequently
|
|
1376
|
+
* these config options are being used)
|
|
1377
|
+
*
|
|
1378
|
+
* @param config the config to anonymize
|
|
1379
|
+
* @returns an anonymized copy of the same config
|
|
1380
|
+
*/
|
|
1381
|
+
const anonymizeConfigForTelemetry = (config) => {
|
|
1382
|
+
var _a;
|
|
1383
|
+
const anonymizedConfig = { ...config };
|
|
1384
|
+
for (const prop of CONFIG_PROPS_TO_ANONYMIZE) {
|
|
1385
|
+
if (anonymizedConfig[prop] !== undefined) {
|
|
1386
|
+
anonymizedConfig[prop] = 'omitted';
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
anonymizedConfig.outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).map((target) => {
|
|
1390
|
+
// Anonymize the outputTargets on our configuration, taking advantage of the
|
|
1391
|
+
// optional 2nd argument to `JSON.stringify`. If anything is not a string
|
|
1392
|
+
// we retain it so that any nested properties are handled, else we check
|
|
1393
|
+
// whether it's in our 'keep' list to decide whether to keep it or replace it
|
|
1394
|
+
// with `"omitted"`.
|
|
1395
|
+
const anonymizedOT = JSON.parse(JSON.stringify(target, (key, value) => {
|
|
1396
|
+
if (!(typeof value === 'string')) {
|
|
1397
|
+
return value;
|
|
1398
|
+
}
|
|
1399
|
+
if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) {
|
|
1400
|
+
return value;
|
|
1401
|
+
}
|
|
1402
|
+
return 'omitted';
|
|
1403
|
+
}));
|
|
1404
|
+
// this prop has to be handled separately because it is an array
|
|
1405
|
+
// so the replace function above will be called with all of its
|
|
1406
|
+
// members, giving us `["omitted", "omitted", ...]`.
|
|
1407
|
+
//
|
|
1408
|
+
// Instead, we check for its presence and manually copy over.
|
|
1409
|
+
if (isOutputTargetHydrate(target) && target.external) {
|
|
1410
|
+
anonymizedOT['external'] = target.external.concat();
|
|
1411
|
+
}
|
|
1412
|
+
return anonymizedOT;
|
|
1413
|
+
});
|
|
1414
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1415
|
+
for (const prop of CONFIG_PROPS_TO_DELETE) {
|
|
1416
|
+
delete anonymizedConfig[prop];
|
|
1417
|
+
}
|
|
1418
|
+
return anonymizedConfig;
|
|
1419
|
+
};
|
|
1052
1420
|
/**
|
|
1053
1421
|
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1054
1422
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1055
1423
|
* of each package under the @stencil, @ionic, and @capacitor scopes.
|
|
1424
|
+
*
|
|
1056
1425
|
* @param sys the system instance where telemetry is invoked
|
|
1057
1426
|
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1058
1427
|
* @returns an object listing all dev and production dependencies under the aforementioned scopes
|
|
@@ -1086,7 +1455,7 @@ async function getInstalledPackages(sys, config) {
|
|
|
1086
1455
|
return { packages, packagesNoVersions };
|
|
1087
1456
|
}
|
|
1088
1457
|
catch (err) {
|
|
1089
|
-
hasDebug(config) && console.error(err);
|
|
1458
|
+
hasDebug(config.flags) && console.error(err);
|
|
1090
1459
|
return { packages, packagesNoVersions };
|
|
1091
1460
|
}
|
|
1092
1461
|
}
|
|
@@ -1135,6 +1504,7 @@ function sanitizeDeclaredVersion(version) {
|
|
|
1135
1504
|
}
|
|
1136
1505
|
/**
|
|
1137
1506
|
* If telemetry is enabled, send a metric to an external data store
|
|
1507
|
+
*
|
|
1138
1508
|
* @param sys the system instance where telemetry is invoked
|
|
1139
1509
|
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1140
1510
|
* @param name the name of a trackable metric. Note this name is not necessarily a scalar value to track, like
|
|
@@ -1150,10 +1520,11 @@ async function sendMetric(sys, config, name, value) {
|
|
|
1150
1520
|
value,
|
|
1151
1521
|
session_id,
|
|
1152
1522
|
};
|
|
1153
|
-
await sendTelemetry(sys, config,
|
|
1523
|
+
await sendTelemetry(sys, config, message);
|
|
1154
1524
|
}
|
|
1155
1525
|
/**
|
|
1156
1526
|
* Used to read the config file's tokens.telemetry property.
|
|
1527
|
+
*
|
|
1157
1528
|
* @param sys The system where the command is invoked
|
|
1158
1529
|
* @returns string
|
|
1159
1530
|
*/
|
|
@@ -1175,7 +1546,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1175
1546
|
try {
|
|
1176
1547
|
const now = new Date().toISOString();
|
|
1177
1548
|
const body = {
|
|
1178
|
-
metrics: [data
|
|
1549
|
+
metrics: [data],
|
|
1179
1550
|
sent_at: now,
|
|
1180
1551
|
};
|
|
1181
1552
|
// This request is only made if telemetry is on.
|
|
@@ -1186,15 +1557,15 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1186
1557
|
},
|
|
1187
1558
|
body: JSON.stringify(body),
|
|
1188
1559
|
});
|
|
1189
|
-
hasVerbose(config) &&
|
|
1190
|
-
console.debug('\nSent %O metric to events service (status: %O)', data.
|
|
1560
|
+
hasVerbose(config.flags) &&
|
|
1561
|
+
console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
|
|
1191
1562
|
if (response.status !== 204) {
|
|
1192
|
-
hasVerbose(config) &&
|
|
1563
|
+
hasVerbose(config.flags) &&
|
|
1193
1564
|
console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
|
|
1194
1565
|
}
|
|
1195
1566
|
}
|
|
1196
1567
|
catch (e) {
|
|
1197
|
-
hasVerbose(config) && console.debug('Telemetry request failed:', e);
|
|
1568
|
+
hasVerbose(config.flags) && console.debug('Telemetry request failed:', e);
|
|
1198
1569
|
}
|
|
1199
1570
|
}
|
|
1200
1571
|
/**
|
|
@@ -1251,7 +1622,7 @@ const taskBuild = async (coreCompiler, config, sys) => {
|
|
|
1251
1622
|
const results = await compiler.build();
|
|
1252
1623
|
// TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
|
|
1253
1624
|
if (sys) {
|
|
1254
|
-
await telemetryBuildFinishedAction(sys, config,
|
|
1625
|
+
await telemetryBuildFinishedAction(sys, config, coreCompiler, results);
|
|
1255
1626
|
}
|
|
1256
1627
|
await compiler.destroy();
|
|
1257
1628
|
if (results.hasError) {
|
|
@@ -1290,6 +1661,7 @@ const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
|
1290
1661
|
!!global.process &&
|
|
1291
1662
|
typeof __filename === 'string' &&
|
|
1292
1663
|
(!global.origin || typeof global.origin !== 'string');
|
|
1664
|
+
const IS_BROWSER_ENV = typeof location !== 'undefined' && typeof navigator !== 'undefined' && typeof XMLHttpRequest !== 'undefined';
|
|
1293
1665
|
|
|
1294
1666
|
/**
|
|
1295
1667
|
* Task to generate component boilerplate and write it to disk. This task can
|
|
@@ -1338,7 +1710,10 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1338
1710
|
if (!writtenFiles) {
|
|
1339
1711
|
return config.sys.exit(1);
|
|
1340
1712
|
}
|
|
1341
|
-
//
|
|
1713
|
+
// We use `console.log` here rather than our `config.logger` because we don't want
|
|
1714
|
+
// our TUI messages to be prefixed with timestamps and so on.
|
|
1715
|
+
//
|
|
1716
|
+
// See STENCIL-424 for details.
|
|
1342
1717
|
console.log();
|
|
1343
1718
|
console.log(`${config.logger.gray('$')} stencil generate ${input}`);
|
|
1344
1719
|
console.log();
|
|
@@ -1482,7 +1857,8 @@ export class ${toPascalCase(tagName)} {
|
|
|
1482
1857
|
`;
|
|
1483
1858
|
};
|
|
1484
1859
|
/**
|
|
1485
|
-
* Get the boilerplate for style
|
|
1860
|
+
* Get the boilerplate for style for a generated component
|
|
1861
|
+
* @returns a boilerplate CSS block
|
|
1486
1862
|
*/
|
|
1487
1863
|
const getStyleUrlBoilerplate = () => `:host {
|
|
1488
1864
|
display: block;
|
|
@@ -1536,10 +1912,17 @@ describe('${tagName}', () => {
|
|
|
1536
1912
|
*/
|
|
1537
1913
|
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
|
|
1538
1914
|
|
|
1539
|
-
|
|
1915
|
+
/**
|
|
1916
|
+
* Entrypoint for the Telemetry task
|
|
1917
|
+
* @param flags configuration flags provided to Stencil when a task was called (either this task or a task that invokes
|
|
1918
|
+
* telemetry)
|
|
1919
|
+
* @param sys the abstraction for interfacing with the operating system
|
|
1920
|
+
* @param logger a logging implementation to log the results out to the user
|
|
1921
|
+
*/
|
|
1922
|
+
const taskTelemetry = async (flags, sys, logger) => {
|
|
1540
1923
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1541
|
-
const isEnabling =
|
|
1542
|
-
const isDisabling =
|
|
1924
|
+
const isEnabling = flags.args.includes('on');
|
|
1925
|
+
const isDisabling = flags.args.includes('off');
|
|
1543
1926
|
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')}`;
|
|
1544
1927
|
const THANK_YOU = `Thank you for helping to make Stencil better! 💖`;
|
|
1545
1928
|
const ENABLED_MESSAGE = `${logger.green('Enabled')}. ${THANK_YOU}\n\n`;
|
|
@@ -1568,7 +1951,14 @@ const taskTelemetry = async (config, sys, logger) => {
|
|
|
1568
1951
|
`);
|
|
1569
1952
|
};
|
|
1570
1953
|
|
|
1571
|
-
|
|
1954
|
+
/**
|
|
1955
|
+
* Entrypoint for the Help task, providing Stencil usage context to the user
|
|
1956
|
+
* @param flags configuration flags provided to Stencil when a task was call (either this task or a task that invokes
|
|
1957
|
+
* telemetry)
|
|
1958
|
+
* @param logger a logging implementation to log the results out to the user
|
|
1959
|
+
* @param sys the abstraction for interfacing with the operating system
|
|
1960
|
+
*/
|
|
1961
|
+
const taskHelp = async (flags, logger, sys) => {
|
|
1572
1962
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
|
1573
1963
|
console.log(`
|
|
1574
1964
|
${logger.bold('Build:')} ${logger.dim('Build components for development or production.')}
|
|
@@ -1601,7 +1991,7 @@ const taskHelp = async (config, logger, sys) => {
|
|
|
1601
1991
|
`);
|
|
1602
1992
|
// TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
|
|
1603
1993
|
if (sys) {
|
|
1604
|
-
await taskTelemetry(
|
|
1994
|
+
await taskTelemetry(flags, sys, logger);
|
|
1605
1995
|
}
|
|
1606
1996
|
console.log(`
|
|
1607
1997
|
${logger.bold('Examples:')}
|
|
@@ -1658,6 +2048,10 @@ const taskServe = async (config) => {
|
|
|
1658
2048
|
});
|
|
1659
2049
|
};
|
|
1660
2050
|
|
|
2051
|
+
/**
|
|
2052
|
+
* Entrypoint for any Stencil tests
|
|
2053
|
+
* @param config a validated Stencil configuration entity
|
|
2054
|
+
*/
|
|
1661
2055
|
const taskTest = async (config) => {
|
|
1662
2056
|
if (!IS_NODE_ENV) {
|
|
1663
2057
|
config.logger.error(`"test" command is currently only implemented for a NodeJS environment`);
|
|
@@ -1704,6 +2098,95 @@ const taskTest = async (config) => {
|
|
|
1704
2098
|
}
|
|
1705
2099
|
};
|
|
1706
2100
|
|
|
2101
|
+
/**
|
|
2102
|
+
* Creates an instance of a logger
|
|
2103
|
+
* @returns the new logger instance
|
|
2104
|
+
*/
|
|
2105
|
+
const createLogger = () => {
|
|
2106
|
+
let useColors = IS_BROWSER_ENV;
|
|
2107
|
+
let level = 'info';
|
|
2108
|
+
return {
|
|
2109
|
+
enableColors: (uc) => (useColors = uc),
|
|
2110
|
+
getLevel: () => level,
|
|
2111
|
+
setLevel: (l) => (level = l),
|
|
2112
|
+
emoji: (e) => e,
|
|
2113
|
+
info: console.log.bind(console),
|
|
2114
|
+
warn: console.warn.bind(console),
|
|
2115
|
+
error: console.error.bind(console),
|
|
2116
|
+
debug: console.debug.bind(console),
|
|
2117
|
+
red: (msg) => msg,
|
|
2118
|
+
green: (msg) => msg,
|
|
2119
|
+
yellow: (msg) => msg,
|
|
2120
|
+
blue: (msg) => msg,
|
|
2121
|
+
magenta: (msg) => msg,
|
|
2122
|
+
cyan: (msg) => msg,
|
|
2123
|
+
gray: (msg) => msg,
|
|
2124
|
+
bold: (msg) => msg,
|
|
2125
|
+
dim: (msg) => msg,
|
|
2126
|
+
bgRed: (msg) => msg,
|
|
2127
|
+
createTimeSpan: (_startMsg, _debug = false) => ({
|
|
2128
|
+
duration: () => 0,
|
|
2129
|
+
finish: () => 0,
|
|
2130
|
+
}),
|
|
2131
|
+
printDiagnostics(diagnostics) {
|
|
2132
|
+
diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
|
|
2133
|
+
},
|
|
2134
|
+
};
|
|
2135
|
+
};
|
|
2136
|
+
const logDiagnostic = (diagnostic, useColors) => {
|
|
2137
|
+
let color = BLUE;
|
|
2138
|
+
let prefix = 'Build';
|
|
2139
|
+
let msg = '';
|
|
2140
|
+
if (diagnostic.level === 'error') {
|
|
2141
|
+
color = RED;
|
|
2142
|
+
prefix = 'Error';
|
|
2143
|
+
}
|
|
2144
|
+
else if (diagnostic.level === 'warn') {
|
|
2145
|
+
color = YELLOW;
|
|
2146
|
+
prefix = 'Warning';
|
|
2147
|
+
}
|
|
2148
|
+
if (diagnostic.header) {
|
|
2149
|
+
prefix = diagnostic.header;
|
|
2150
|
+
}
|
|
2151
|
+
const filePath = diagnostic.relFilePath || diagnostic.absFilePath;
|
|
2152
|
+
if (filePath) {
|
|
2153
|
+
msg += filePath;
|
|
2154
|
+
if (typeof diagnostic.lineNumber === 'number' && diagnostic.lineNumber > 0) {
|
|
2155
|
+
msg += ', line ' + diagnostic.lineNumber;
|
|
2156
|
+
if (typeof diagnostic.columnNumber === 'number' && diagnostic.columnNumber > 0) {
|
|
2157
|
+
msg += ', column ' + diagnostic.columnNumber;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
msg += '\n';
|
|
2161
|
+
}
|
|
2162
|
+
msg += diagnostic.messageText;
|
|
2163
|
+
if (diagnostic.lines && diagnostic.lines.length > 0) {
|
|
2164
|
+
diagnostic.lines.forEach((l) => {
|
|
2165
|
+
msg += '\n' + l.lineNumber + ': ' + l.text;
|
|
2166
|
+
});
|
|
2167
|
+
msg += '\n';
|
|
2168
|
+
}
|
|
2169
|
+
if (useColors) {
|
|
2170
|
+
const styledPrefix = [
|
|
2171
|
+
'%c' + prefix,
|
|
2172
|
+
`background: ${color}; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;`,
|
|
2173
|
+
];
|
|
2174
|
+
console.log(...styledPrefix, msg);
|
|
2175
|
+
}
|
|
2176
|
+
else if (diagnostic.level === 'error') {
|
|
2177
|
+
console.error(msg);
|
|
2178
|
+
}
|
|
2179
|
+
else if (diagnostic.level === 'warn') {
|
|
2180
|
+
console.warn(msg);
|
|
2181
|
+
}
|
|
2182
|
+
else {
|
|
2183
|
+
console.log(msg);
|
|
2184
|
+
}
|
|
2185
|
+
};
|
|
2186
|
+
const YELLOW = `#f39c12`;
|
|
2187
|
+
const RED = `#c0392b`;
|
|
2188
|
+
const BLUE = `#3498db`;
|
|
2189
|
+
|
|
1707
2190
|
const run = async (init) => {
|
|
1708
2191
|
const { args, logger, sys } = init;
|
|
1709
2192
|
try {
|
|
@@ -1719,7 +2202,7 @@ const run = async (init) => {
|
|
|
1719
2202
|
sys.applyGlobalPatch(sys.getCurrentDirectory());
|
|
1720
2203
|
}
|
|
1721
2204
|
if (task === 'help' || flags.help) {
|
|
1722
|
-
await taskHelp({
|
|
2205
|
+
await taskHelp(createConfigFlags({ task: 'help', args }), logger, sys);
|
|
1723
2206
|
return;
|
|
1724
2207
|
}
|
|
1725
2208
|
startupLog(logger, task);
|
|
@@ -1745,7 +2228,7 @@ const run = async (init) => {
|
|
|
1745
2228
|
startupLogVersion(logger, task, coreCompiler);
|
|
1746
2229
|
loadedCompilerLog(sys, logger, flags, coreCompiler);
|
|
1747
2230
|
if (task === 'info') {
|
|
1748
|
-
await telemetryAction(sys, { flags: { task: 'info' },
|
|
2231
|
+
await telemetryAction(sys, { flags: createConfigFlags({ task: 'info' }), logger }, coreCompiler, async () => {
|
|
1749
2232
|
await taskInfo(coreCompiler, sys, logger);
|
|
1750
2233
|
});
|
|
1751
2234
|
return;
|
|
@@ -1768,7 +2251,7 @@ const run = async (init) => {
|
|
|
1768
2251
|
sys.applyGlobalPatch(validated.config.rootDir);
|
|
1769
2252
|
}
|
|
1770
2253
|
await sys.ensureResources({ rootDir: validated.config.rootDir, logger, dependencies: dependencies });
|
|
1771
|
-
await telemetryAction(sys, validated.config,
|
|
2254
|
+
await telemetryAction(sys, validated.config, coreCompiler, async () => {
|
|
1772
2255
|
await runTask(coreCompiler, validated.config, task, sys);
|
|
1773
2256
|
});
|
|
1774
2257
|
}
|
|
@@ -1781,43 +2264,45 @@ const run = async (init) => {
|
|
|
1781
2264
|
}
|
|
1782
2265
|
};
|
|
1783
2266
|
const runTask = async (coreCompiler, config, task, sys) => {
|
|
1784
|
-
|
|
1785
|
-
|
|
2267
|
+
var _a, _b;
|
|
2268
|
+
const logger = (_a = config.logger) !== null && _a !== void 0 ? _a : createLogger();
|
|
2269
|
+
const strictConfig = { ...config, flags: createConfigFlags((_b = config.flags) !== null && _b !== void 0 ? _b : { task }), logger };
|
|
2270
|
+
strictConfig.outputTargets = strictConfig.outputTargets || [];
|
|
1786
2271
|
switch (task) {
|
|
1787
2272
|
case 'build':
|
|
1788
|
-
await taskBuild(coreCompiler,
|
|
2273
|
+
await taskBuild(coreCompiler, strictConfig, sys);
|
|
1789
2274
|
break;
|
|
1790
2275
|
case 'docs':
|
|
1791
|
-
await taskDocs(coreCompiler,
|
|
2276
|
+
await taskDocs(coreCompiler, strictConfig);
|
|
1792
2277
|
break;
|
|
1793
2278
|
case 'generate':
|
|
1794
2279
|
case 'g':
|
|
1795
|
-
await taskGenerate(coreCompiler,
|
|
2280
|
+
await taskGenerate(coreCompiler, strictConfig);
|
|
1796
2281
|
break;
|
|
1797
2282
|
case 'help':
|
|
1798
|
-
await taskHelp(
|
|
2283
|
+
await taskHelp(strictConfig.flags, strictConfig.logger, sys);
|
|
1799
2284
|
break;
|
|
1800
2285
|
case 'prerender':
|
|
1801
|
-
await taskPrerender(coreCompiler,
|
|
2286
|
+
await taskPrerender(coreCompiler, strictConfig);
|
|
1802
2287
|
break;
|
|
1803
2288
|
case 'serve':
|
|
1804
|
-
await taskServe(
|
|
2289
|
+
await taskServe(strictConfig);
|
|
1805
2290
|
break;
|
|
1806
2291
|
case 'telemetry':
|
|
1807
2292
|
// TODO(STENCIL-148) make this parameter no longer optional, remove the surrounding if statement
|
|
1808
2293
|
if (sys) {
|
|
1809
|
-
await taskTelemetry(
|
|
2294
|
+
await taskTelemetry(strictConfig.flags, sys, strictConfig.logger);
|
|
1810
2295
|
}
|
|
1811
2296
|
break;
|
|
1812
2297
|
case 'test':
|
|
1813
|
-
await taskTest(
|
|
2298
|
+
await taskTest(strictConfig);
|
|
1814
2299
|
break;
|
|
1815
2300
|
case 'version':
|
|
1816
2301
|
console.log(coreCompiler.version);
|
|
1817
2302
|
break;
|
|
1818
2303
|
default:
|
|
1819
|
-
|
|
1820
|
-
await taskHelp(
|
|
2304
|
+
strictConfig.logger.error(`${strictConfig.logger.emoji('❌ ')}Invalid stencil command, please see the options below:`);
|
|
2305
|
+
await taskHelp(strictConfig.flags, strictConfig.logger, sys);
|
|
1821
2306
|
return config.sys.exit(1);
|
|
1822
2307
|
}
|
|
1823
2308
|
};
|