@stencil/core 2.16.0 → 2.17.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/index.cjs +124 -16
- package/cli/index.js +124 -16
- package/cli/package.json +1 -1
- package/compiler/package.json +1 -1
- package/compiler/stencil.js +728 -263
- 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 +3 -3
- package/dev-server/index.js +1 -1
- package/dev-server/package.json +1 -1
- package/dev-server/server-process.js +4 -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 +1 -1
- 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 +3 -3
- package/internal/hydrate/package.json +1 -1
- package/internal/package.json +1 -1
- package/internal/stencil-private.d.ts +4 -0
- package/internal/stencil-public-compiler.d.ts +3 -2
- package/internal/testing/index.js +1 -1
- package/internal/testing/package.json +1 -1
- package/mock-doc/index.cjs +142 -5
- package/mock-doc/index.d.ts +77 -1
- package/mock-doc/index.js +142 -5
- package/mock-doc/package.json +1 -1
- package/package.json +2 -1
- package/screenshot/index.js +2 -0
- 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 +105 -62
- package/testing/mocks.d.ts +22 -2
- package/testing/package.json +1 -1
package/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil CLI (CommonJS) v2.
|
|
2
|
+
Stencil CLI (CommonJS) v2.17.0 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
@@ -118,6 +118,8 @@ const TASK_CANCELED_MSG = `task canceled`;
|
|
|
118
118
|
* Forward-slash paths can be used in Windows as long as they're not
|
|
119
119
|
* extended-length paths and don't contain any non-ascii characters.
|
|
120
120
|
* This was created since the path methods in Node.js outputs \\ paths on Windows.
|
|
121
|
+
* @param path the Windows-based path to convert
|
|
122
|
+
* @returns the converted path
|
|
121
123
|
*/
|
|
122
124
|
const normalizePath = (path) => {
|
|
123
125
|
if (typeof path !== 'string') {
|
|
@@ -530,7 +532,7 @@ const getNpmConfigEnvArgs = (sys) => {
|
|
|
530
532
|
const dependencies = [
|
|
531
533
|
{
|
|
532
534
|
name: "@stencil/core",
|
|
533
|
-
version: "2.
|
|
535
|
+
version: "2.17.0",
|
|
534
536
|
main: "compiler/stencil.js",
|
|
535
537
|
resources: [
|
|
536
538
|
"package.json",
|
|
@@ -965,7 +967,9 @@ async function updateConfig(sys, newOptions) {
|
|
|
965
967
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
966
968
|
}
|
|
967
969
|
|
|
970
|
+
const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
|
|
968
971
|
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
972
|
+
const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
|
|
969
973
|
const DOCS_CUSTOM = 'docs-custom';
|
|
970
974
|
const DOCS_JSON = 'docs-json';
|
|
971
975
|
const DOCS_README = 'docs-readme';
|
|
@@ -993,6 +997,7 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
|
|
|
993
997
|
}
|
|
994
998
|
/**
|
|
995
999
|
* A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
|
|
1000
|
+
*
|
|
996
1001
|
* @param sys The system where the command is invoked
|
|
997
1002
|
* @param config The config passed into the Stencil command
|
|
998
1003
|
* @param logger The tool used to do logging
|
|
@@ -1038,6 +1043,16 @@ async function getActiveTargets(config) {
|
|
|
1038
1043
|
const result = config.outputTargets.map((t) => t.type);
|
|
1039
1044
|
return Array.from(new Set(result));
|
|
1040
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Prepare data for telemetry
|
|
1048
|
+
*
|
|
1049
|
+
* @param coreCompiler the core compiler
|
|
1050
|
+
* @param config the current Stencil config
|
|
1051
|
+
* @param sys the compiler system instance in use
|
|
1052
|
+
* @param duration_ms the duration of the action being tracked
|
|
1053
|
+
* @param component_count the number of components being built (optional)
|
|
1054
|
+
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1055
|
+
*/
|
|
1041
1056
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1042
1057
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1043
1058
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
@@ -1050,6 +1065,7 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1050
1065
|
const cpu_model = sys.details.cpuModel;
|
|
1051
1066
|
const build = coreCompiler.buildId || 'unknown';
|
|
1052
1067
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1068
|
+
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1053
1069
|
return {
|
|
1054
1070
|
yarn,
|
|
1055
1071
|
duration_ms,
|
|
@@ -1069,13 +1085,86 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1069
1085
|
typescript,
|
|
1070
1086
|
rollup,
|
|
1071
1087
|
has_app_pwa_config,
|
|
1088
|
+
config: anonymizedConfig,
|
|
1072
1089
|
};
|
|
1073
1090
|
};
|
|
1091
|
+
// props in output targets for which we retain their original values when
|
|
1092
|
+
// preparing a config for telemetry
|
|
1093
|
+
//
|
|
1094
|
+
// we omit the values of all other fields on output targets.
|
|
1095
|
+
const OUTPUT_TARGET_KEYS_TO_KEEP = ['type'];
|
|
1096
|
+
// top-level config props that we anonymize for telemetry
|
|
1097
|
+
const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
1098
|
+
'rootDir',
|
|
1099
|
+
'fsNamespace',
|
|
1100
|
+
'packageJsonFilePath',
|
|
1101
|
+
'namespace',
|
|
1102
|
+
'srcDir',
|
|
1103
|
+
'srcIndexHtml',
|
|
1104
|
+
'buildLogFilePath',
|
|
1105
|
+
'cacheDir',
|
|
1106
|
+
'configPath',
|
|
1107
|
+
'tsconfig',
|
|
1108
|
+
];
|
|
1109
|
+
// Props we delete entirely from the config for telemetry
|
|
1110
|
+
//
|
|
1111
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1112
|
+
const CONFIG_PROPS_TO_DELETE = ['sys', 'logger', 'tsCompilerOptions', 'devServer'];
|
|
1074
1113
|
/**
|
|
1075
|
-
*
|
|
1114
|
+
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1115
|
+
* with a placeholder string if they are present (this lets us still track how frequently
|
|
1116
|
+
* these config options are being used)
|
|
1117
|
+
*
|
|
1118
|
+
* @param config the config to anonymize
|
|
1119
|
+
* @returns an anonymized copy of the same config
|
|
1120
|
+
*/
|
|
1121
|
+
const anonymizeConfigForTelemetry = (config) => {
|
|
1122
|
+
var _a;
|
|
1123
|
+
const anonymizedConfig = { ...config };
|
|
1124
|
+
for (const prop of CONFIG_PROPS_TO_ANONYMIZE) {
|
|
1125
|
+
if (anonymizedConfig[prop] !== undefined) {
|
|
1126
|
+
anonymizedConfig[prop] = 'omitted';
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
anonymizedConfig.outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).map((target) => {
|
|
1130
|
+
// Anonymize the outputTargets on our configuration, taking advantage of the
|
|
1131
|
+
// optional 2nd argument to `JSON.stringify`. If anything is not a string
|
|
1132
|
+
// we retain it so that any nested properties are handled, else we check
|
|
1133
|
+
// whether it's in our 'keep' list to decide whether to keep it or replace it
|
|
1134
|
+
// with `"omitted"`.
|
|
1135
|
+
const anonymizedOT = JSON.parse(JSON.stringify(target, (key, value) => {
|
|
1136
|
+
if (!(typeof value === 'string')) {
|
|
1137
|
+
return value;
|
|
1138
|
+
}
|
|
1139
|
+
if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) {
|
|
1140
|
+
return value;
|
|
1141
|
+
}
|
|
1142
|
+
return 'omitted';
|
|
1143
|
+
}));
|
|
1144
|
+
// this prop has to be handled separately because it is an array
|
|
1145
|
+
// so the replace function above will be called with all of its
|
|
1146
|
+
// members, giving us `["omitted", "omitted", ...]`.
|
|
1147
|
+
//
|
|
1148
|
+
// Instead, we check for its presence and manually copy over.
|
|
1149
|
+
if (isOutputTargetHydrate(target) && target.external) {
|
|
1150
|
+
anonymizedOT['external'] = target.external.concat();
|
|
1151
|
+
}
|
|
1152
|
+
return anonymizedOT;
|
|
1153
|
+
});
|
|
1154
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1155
|
+
for (const prop of CONFIG_PROPS_TO_DELETE) {
|
|
1156
|
+
delete anonymizedConfig[prop];
|
|
1157
|
+
}
|
|
1158
|
+
return anonymizedConfig;
|
|
1159
|
+
};
|
|
1160
|
+
/**
|
|
1161
|
+
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1076
1162
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1077
1163
|
* of each package under the @stencil, @ionic, and @capacitor scopes.
|
|
1078
|
-
*
|
|
1164
|
+
*
|
|
1165
|
+
* @param sys the system instance where telemetry is invoked
|
|
1166
|
+
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1167
|
+
* @returns an object listing all dev and production dependencies under the aforementioned scopes
|
|
1079
1168
|
*/
|
|
1080
1169
|
async function getInstalledPackages(sys, config) {
|
|
1081
1170
|
let packages = [];
|
|
@@ -1154,7 +1243,13 @@ function sanitizeDeclaredVersion(version) {
|
|
|
1154
1243
|
return version.replace(/[*^~]/g, '');
|
|
1155
1244
|
}
|
|
1156
1245
|
/**
|
|
1157
|
-
* If telemetry is enabled, send a metric
|
|
1246
|
+
* If telemetry is enabled, send a metric to an external data store
|
|
1247
|
+
*
|
|
1248
|
+
* @param sys the system instance where telemetry is invoked
|
|
1249
|
+
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1250
|
+
* @param name the name of a trackable metric. Note this name is not necessarily a scalar value to track, like
|
|
1251
|
+
* "Stencil Version". For example, "stencil_cli_command" is a name that is used to track all CLI command information.
|
|
1252
|
+
* @param value the data to send to the external data store under the provided name argument
|
|
1158
1253
|
*/
|
|
1159
1254
|
async function sendMetric(sys, config, name, value) {
|
|
1160
1255
|
const session_id = await getTelemetryToken(sys);
|
|
@@ -1165,10 +1260,11 @@ async function sendMetric(sys, config, name, value) {
|
|
|
1165
1260
|
value,
|
|
1166
1261
|
session_id,
|
|
1167
1262
|
};
|
|
1168
|
-
await sendTelemetry(sys, config,
|
|
1263
|
+
await sendTelemetry(sys, config, message);
|
|
1169
1264
|
}
|
|
1170
1265
|
/**
|
|
1171
1266
|
* Used to read the config file's tokens.telemetry property.
|
|
1267
|
+
*
|
|
1172
1268
|
* @param sys The system where the command is invoked
|
|
1173
1269
|
* @returns string
|
|
1174
1270
|
*/
|
|
@@ -1190,7 +1286,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1190
1286
|
try {
|
|
1191
1287
|
const now = new Date().toISOString();
|
|
1192
1288
|
const body = {
|
|
1193
|
-
metrics: [data
|
|
1289
|
+
metrics: [data],
|
|
1194
1290
|
sent_at: now,
|
|
1195
1291
|
};
|
|
1196
1292
|
// This request is only made if telemetry is on.
|
|
@@ -1202,7 +1298,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1202
1298
|
body: JSON.stringify(body),
|
|
1203
1299
|
});
|
|
1204
1300
|
hasVerbose(config) &&
|
|
1205
|
-
console.debug('\nSent %O metric to events service (status: %O)', data.
|
|
1301
|
+
console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
|
|
1206
1302
|
if (response.status !== 204) {
|
|
1207
1303
|
hasVerbose(config) &&
|
|
1208
1304
|
console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
|
|
@@ -1353,7 +1449,10 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1353
1449
|
if (!writtenFiles) {
|
|
1354
1450
|
return config.sys.exit(1);
|
|
1355
1451
|
}
|
|
1356
|
-
//
|
|
1452
|
+
// We use `console.log` here rather than our `config.logger` because we don't want
|
|
1453
|
+
// our TUI messages to be prefixed with timestamps and so on.
|
|
1454
|
+
//
|
|
1455
|
+
// See STENCIL-424 for details.
|
|
1357
1456
|
console.log();
|
|
1358
1457
|
console.log(`${config.logger.gray('$')} stencil generate ${input}`);
|
|
1359
1458
|
console.log();
|
|
@@ -1467,7 +1566,10 @@ const getBoilerplateByExtension = (tagName, extension, withCss) => {
|
|
|
1467
1566
|
}
|
|
1468
1567
|
};
|
|
1469
1568
|
/**
|
|
1470
|
-
* Get the boilerplate for a component
|
|
1569
|
+
* Get the boilerplate for a file containing the definition of a component
|
|
1570
|
+
* @param tagName the name of the tag to give the component
|
|
1571
|
+
* @param hasStyle designates if the component has an external stylesheet or not
|
|
1572
|
+
* @returns the contents of a file that defines a component
|
|
1471
1573
|
*/
|
|
1472
1574
|
const getComponentBoilerplate = (tagName, hasStyle) => {
|
|
1473
1575
|
const decorator = [`{`];
|
|
@@ -1501,7 +1603,9 @@ const getStyleUrlBoilerplate = () => `:host {
|
|
|
1501
1603
|
}
|
|
1502
1604
|
`;
|
|
1503
1605
|
/**
|
|
1504
|
-
* Get the boilerplate for a spec test
|
|
1606
|
+
* Get the boilerplate for a file containing a spec (unit) test for a component
|
|
1607
|
+
* @param tagName the name of the tag associated with the component under test
|
|
1608
|
+
* @returns the contents of a file that unit tests a component
|
|
1505
1609
|
*/
|
|
1506
1610
|
const getSpecTestBoilerplate = (tagName) => `import { newSpecPage } from '@stencil/core/testing';
|
|
1507
1611
|
import { ${toPascalCase(tagName)} } from '../${tagName}';
|
|
@@ -1523,22 +1627,26 @@ describe('${tagName}', () => {
|
|
|
1523
1627
|
});
|
|
1524
1628
|
`;
|
|
1525
1629
|
/**
|
|
1526
|
-
* Get the boilerplate for an E2E test
|
|
1630
|
+
* Get the boilerplate for a file containing an end-to-end (E2E) test for a component
|
|
1631
|
+
* @param tagName the name of the tag associated with the component under test
|
|
1632
|
+
* @returns the contents of a file that E2E tests a component
|
|
1527
1633
|
*/
|
|
1528
|
-
const getE2eTestBoilerplate = (
|
|
1634
|
+
const getE2eTestBoilerplate = (tagName) => `import { newE2EPage } from '@stencil/core/testing';
|
|
1529
1635
|
|
|
1530
|
-
describe('${
|
|
1636
|
+
describe('${tagName}', () => {
|
|
1531
1637
|
it('renders', async () => {
|
|
1532
1638
|
const page = await newE2EPage();
|
|
1533
|
-
await page.setContent('<${
|
|
1639
|
+
await page.setContent('<${tagName}></${tagName}>');
|
|
1534
1640
|
|
|
1535
|
-
const element = await page.find('${
|
|
1641
|
+
const element = await page.find('${tagName}');
|
|
1536
1642
|
expect(element).toHaveClass('hydrated');
|
|
1537
1643
|
});
|
|
1538
1644
|
});
|
|
1539
1645
|
`;
|
|
1540
1646
|
/**
|
|
1541
1647
|
* Convert a dash case string to pascal case.
|
|
1648
|
+
* @param str the string to convert
|
|
1649
|
+
* @returns the converted input as pascal case
|
|
1542
1650
|
*/
|
|
1543
1651
|
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
|
|
1544
1652
|
|
package/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil CLI v2.
|
|
2
|
+
Stencil CLI v2.17.0 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
4
|
const toLowerCase = (str) => str.toLowerCase();
|
|
5
5
|
const dashToPascalCase = (str) => toLowerCase(str)
|
|
@@ -94,6 +94,8 @@ const TASK_CANCELED_MSG = `task canceled`;
|
|
|
94
94
|
* Forward-slash paths can be used in Windows as long as they're not
|
|
95
95
|
* extended-length paths and don't contain any non-ascii characters.
|
|
96
96
|
* This was created since the path methods in Node.js outputs \\ paths on Windows.
|
|
97
|
+
* @param path the Windows-based path to convert
|
|
98
|
+
* @returns the converted path
|
|
97
99
|
*/
|
|
98
100
|
const normalizePath = (path) => {
|
|
99
101
|
if (typeof path !== 'string') {
|
|
@@ -506,7 +508,7 @@ const getNpmConfigEnvArgs = (sys) => {
|
|
|
506
508
|
const dependencies = [
|
|
507
509
|
{
|
|
508
510
|
name: "@stencil/core",
|
|
509
|
-
version: "2.
|
|
511
|
+
version: "2.17.0",
|
|
510
512
|
main: "compiler/stencil.js",
|
|
511
513
|
resources: [
|
|
512
514
|
"package.json",
|
|
@@ -941,7 +943,9 @@ async function updateConfig(sys, newOptions) {
|
|
|
941
943
|
return await writeConfig(sys, Object.assign(config, newOptions));
|
|
942
944
|
}
|
|
943
945
|
|
|
946
|
+
const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
|
|
944
947
|
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
948
|
+
const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
|
|
945
949
|
const DOCS_CUSTOM = 'docs-custom';
|
|
946
950
|
const DOCS_JSON = 'docs-json';
|
|
947
951
|
const DOCS_README = 'docs-readme';
|
|
@@ -969,6 +973,7 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
|
|
|
969
973
|
}
|
|
970
974
|
/**
|
|
971
975
|
* A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
|
|
976
|
+
*
|
|
972
977
|
* @param sys The system where the command is invoked
|
|
973
978
|
* @param config The config passed into the Stencil command
|
|
974
979
|
* @param logger The tool used to do logging
|
|
@@ -1014,6 +1019,16 @@ async function getActiveTargets(config) {
|
|
|
1014
1019
|
const result = config.outputTargets.map((t) => t.type);
|
|
1015
1020
|
return Array.from(new Set(result));
|
|
1016
1021
|
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Prepare data for telemetry
|
|
1024
|
+
*
|
|
1025
|
+
* @param coreCompiler the core compiler
|
|
1026
|
+
* @param config the current Stencil config
|
|
1027
|
+
* @param sys the compiler system instance in use
|
|
1028
|
+
* @param duration_ms the duration of the action being tracked
|
|
1029
|
+
* @param component_count the number of components being built (optional)
|
|
1030
|
+
* @returns a Promise wrapping data for the telemetry endpoint
|
|
1031
|
+
*/
|
|
1017
1032
|
const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
|
|
1018
1033
|
const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
|
|
1019
1034
|
const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
|
|
@@ -1026,6 +1041,7 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1026
1041
|
const cpu_model = sys.details.cpuModel;
|
|
1027
1042
|
const build = coreCompiler.buildId || 'unknown';
|
|
1028
1043
|
const has_app_pwa_config = hasAppTarget(config);
|
|
1044
|
+
const anonymizedConfig = anonymizeConfigForTelemetry(config);
|
|
1029
1045
|
return {
|
|
1030
1046
|
yarn,
|
|
1031
1047
|
duration_ms,
|
|
@@ -1045,13 +1061,86 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
|
|
|
1045
1061
|
typescript,
|
|
1046
1062
|
rollup,
|
|
1047
1063
|
has_app_pwa_config,
|
|
1064
|
+
config: anonymizedConfig,
|
|
1048
1065
|
};
|
|
1049
1066
|
};
|
|
1067
|
+
// props in output targets for which we retain their original values when
|
|
1068
|
+
// preparing a config for telemetry
|
|
1069
|
+
//
|
|
1070
|
+
// we omit the values of all other fields on output targets.
|
|
1071
|
+
const OUTPUT_TARGET_KEYS_TO_KEEP = ['type'];
|
|
1072
|
+
// top-level config props that we anonymize for telemetry
|
|
1073
|
+
const CONFIG_PROPS_TO_ANONYMIZE = [
|
|
1074
|
+
'rootDir',
|
|
1075
|
+
'fsNamespace',
|
|
1076
|
+
'packageJsonFilePath',
|
|
1077
|
+
'namespace',
|
|
1078
|
+
'srcDir',
|
|
1079
|
+
'srcIndexHtml',
|
|
1080
|
+
'buildLogFilePath',
|
|
1081
|
+
'cacheDir',
|
|
1082
|
+
'configPath',
|
|
1083
|
+
'tsconfig',
|
|
1084
|
+
];
|
|
1085
|
+
// Props we delete entirely from the config for telemetry
|
|
1086
|
+
//
|
|
1087
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1088
|
+
const CONFIG_PROPS_TO_DELETE = ['sys', 'logger', 'tsCompilerOptions', 'devServer'];
|
|
1050
1089
|
/**
|
|
1051
|
-
*
|
|
1090
|
+
* Anonymize the config for telemetry, replacing potentially revealing config props
|
|
1091
|
+
* with a placeholder string if they are present (this lets us still track how frequently
|
|
1092
|
+
* these config options are being used)
|
|
1093
|
+
*
|
|
1094
|
+
* @param config the config to anonymize
|
|
1095
|
+
* @returns an anonymized copy of the same config
|
|
1096
|
+
*/
|
|
1097
|
+
const anonymizeConfigForTelemetry = (config) => {
|
|
1098
|
+
var _a;
|
|
1099
|
+
const anonymizedConfig = { ...config };
|
|
1100
|
+
for (const prop of CONFIG_PROPS_TO_ANONYMIZE) {
|
|
1101
|
+
if (anonymizedConfig[prop] !== undefined) {
|
|
1102
|
+
anonymizedConfig[prop] = 'omitted';
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
anonymizedConfig.outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).map((target) => {
|
|
1106
|
+
// Anonymize the outputTargets on our configuration, taking advantage of the
|
|
1107
|
+
// optional 2nd argument to `JSON.stringify`. If anything is not a string
|
|
1108
|
+
// we retain it so that any nested properties are handled, else we check
|
|
1109
|
+
// whether it's in our 'keep' list to decide whether to keep it or replace it
|
|
1110
|
+
// with `"omitted"`.
|
|
1111
|
+
const anonymizedOT = JSON.parse(JSON.stringify(target, (key, value) => {
|
|
1112
|
+
if (!(typeof value === 'string')) {
|
|
1113
|
+
return value;
|
|
1114
|
+
}
|
|
1115
|
+
if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) {
|
|
1116
|
+
return value;
|
|
1117
|
+
}
|
|
1118
|
+
return 'omitted';
|
|
1119
|
+
}));
|
|
1120
|
+
// this prop has to be handled separately because it is an array
|
|
1121
|
+
// so the replace function above will be called with all of its
|
|
1122
|
+
// members, giving us `["omitted", "omitted", ...]`.
|
|
1123
|
+
//
|
|
1124
|
+
// Instead, we check for its presence and manually copy over.
|
|
1125
|
+
if (isOutputTargetHydrate(target) && target.external) {
|
|
1126
|
+
anonymizedOT['external'] = target.external.concat();
|
|
1127
|
+
}
|
|
1128
|
+
return anonymizedOT;
|
|
1129
|
+
});
|
|
1130
|
+
// TODO(STENCIL-469): Investigate improving anonymization for tsCompilerOptions and devServer
|
|
1131
|
+
for (const prop of CONFIG_PROPS_TO_DELETE) {
|
|
1132
|
+
delete anonymizedConfig[prop];
|
|
1133
|
+
}
|
|
1134
|
+
return anonymizedConfig;
|
|
1135
|
+
};
|
|
1136
|
+
/**
|
|
1137
|
+
* Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
|
|
1052
1138
|
* the dependencies and devDependencies properties. Pulls up the current installed version
|
|
1053
1139
|
* of each package under the @stencil, @ionic, and @capacitor scopes.
|
|
1054
|
-
*
|
|
1140
|
+
*
|
|
1141
|
+
* @param sys the system instance where telemetry is invoked
|
|
1142
|
+
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1143
|
+
* @returns an object listing all dev and production dependencies under the aforementioned scopes
|
|
1055
1144
|
*/
|
|
1056
1145
|
async function getInstalledPackages(sys, config) {
|
|
1057
1146
|
let packages = [];
|
|
@@ -1130,7 +1219,13 @@ function sanitizeDeclaredVersion(version) {
|
|
|
1130
1219
|
return version.replace(/[*^~]/g, '');
|
|
1131
1220
|
}
|
|
1132
1221
|
/**
|
|
1133
|
-
* If telemetry is enabled, send a metric
|
|
1222
|
+
* If telemetry is enabled, send a metric to an external data store
|
|
1223
|
+
*
|
|
1224
|
+
* @param sys the system instance where telemetry is invoked
|
|
1225
|
+
* @param config the Stencil configuration associated with the current task that triggered telemetry
|
|
1226
|
+
* @param name the name of a trackable metric. Note this name is not necessarily a scalar value to track, like
|
|
1227
|
+
* "Stencil Version". For example, "stencil_cli_command" is a name that is used to track all CLI command information.
|
|
1228
|
+
* @param value the data to send to the external data store under the provided name argument
|
|
1134
1229
|
*/
|
|
1135
1230
|
async function sendMetric(sys, config, name, value) {
|
|
1136
1231
|
const session_id = await getTelemetryToken(sys);
|
|
@@ -1141,10 +1236,11 @@ async function sendMetric(sys, config, name, value) {
|
|
|
1141
1236
|
value,
|
|
1142
1237
|
session_id,
|
|
1143
1238
|
};
|
|
1144
|
-
await sendTelemetry(sys, config,
|
|
1239
|
+
await sendTelemetry(sys, config, message);
|
|
1145
1240
|
}
|
|
1146
1241
|
/**
|
|
1147
1242
|
* Used to read the config file's tokens.telemetry property.
|
|
1243
|
+
*
|
|
1148
1244
|
* @param sys The system where the command is invoked
|
|
1149
1245
|
* @returns string
|
|
1150
1246
|
*/
|
|
@@ -1166,7 +1262,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1166
1262
|
try {
|
|
1167
1263
|
const now = new Date().toISOString();
|
|
1168
1264
|
const body = {
|
|
1169
|
-
metrics: [data
|
|
1265
|
+
metrics: [data],
|
|
1170
1266
|
sent_at: now,
|
|
1171
1267
|
};
|
|
1172
1268
|
// This request is only made if telemetry is on.
|
|
@@ -1178,7 +1274,7 @@ async function sendTelemetry(sys, config, data) {
|
|
|
1178
1274
|
body: JSON.stringify(body),
|
|
1179
1275
|
});
|
|
1180
1276
|
hasVerbose(config) &&
|
|
1181
|
-
console.debug('\nSent %O metric to events service (status: %O)', data.
|
|
1277
|
+
console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
|
|
1182
1278
|
if (response.status !== 204) {
|
|
1183
1279
|
hasVerbose(config) &&
|
|
1184
1280
|
console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
|
|
@@ -1329,7 +1425,10 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1329
1425
|
if (!writtenFiles) {
|
|
1330
1426
|
return config.sys.exit(1);
|
|
1331
1427
|
}
|
|
1332
|
-
//
|
|
1428
|
+
// We use `console.log` here rather than our `config.logger` because we don't want
|
|
1429
|
+
// our TUI messages to be prefixed with timestamps and so on.
|
|
1430
|
+
//
|
|
1431
|
+
// See STENCIL-424 for details.
|
|
1333
1432
|
console.log();
|
|
1334
1433
|
console.log(`${config.logger.gray('$')} stencil generate ${input}`);
|
|
1335
1434
|
console.log();
|
|
@@ -1443,7 +1542,10 @@ const getBoilerplateByExtension = (tagName, extension, withCss) => {
|
|
|
1443
1542
|
}
|
|
1444
1543
|
};
|
|
1445
1544
|
/**
|
|
1446
|
-
* Get the boilerplate for a component
|
|
1545
|
+
* Get the boilerplate for a file containing the definition of a component
|
|
1546
|
+
* @param tagName the name of the tag to give the component
|
|
1547
|
+
* @param hasStyle designates if the component has an external stylesheet or not
|
|
1548
|
+
* @returns the contents of a file that defines a component
|
|
1447
1549
|
*/
|
|
1448
1550
|
const getComponentBoilerplate = (tagName, hasStyle) => {
|
|
1449
1551
|
const decorator = [`{`];
|
|
@@ -1477,7 +1579,9 @@ const getStyleUrlBoilerplate = () => `:host {
|
|
|
1477
1579
|
}
|
|
1478
1580
|
`;
|
|
1479
1581
|
/**
|
|
1480
|
-
* Get the boilerplate for a spec test
|
|
1582
|
+
* Get the boilerplate for a file containing a spec (unit) test for a component
|
|
1583
|
+
* @param tagName the name of the tag associated with the component under test
|
|
1584
|
+
* @returns the contents of a file that unit tests a component
|
|
1481
1585
|
*/
|
|
1482
1586
|
const getSpecTestBoilerplate = (tagName) => `import { newSpecPage } from '@stencil/core/testing';
|
|
1483
1587
|
import { ${toPascalCase(tagName)} } from '../${tagName}';
|
|
@@ -1499,22 +1603,26 @@ describe('${tagName}', () => {
|
|
|
1499
1603
|
});
|
|
1500
1604
|
`;
|
|
1501
1605
|
/**
|
|
1502
|
-
* Get the boilerplate for an E2E test
|
|
1606
|
+
* Get the boilerplate for a file containing an end-to-end (E2E) test for a component
|
|
1607
|
+
* @param tagName the name of the tag associated with the component under test
|
|
1608
|
+
* @returns the contents of a file that E2E tests a component
|
|
1503
1609
|
*/
|
|
1504
|
-
const getE2eTestBoilerplate = (
|
|
1610
|
+
const getE2eTestBoilerplate = (tagName) => `import { newE2EPage } from '@stencil/core/testing';
|
|
1505
1611
|
|
|
1506
|
-
describe('${
|
|
1612
|
+
describe('${tagName}', () => {
|
|
1507
1613
|
it('renders', async () => {
|
|
1508
1614
|
const page = await newE2EPage();
|
|
1509
|
-
await page.setContent('<${
|
|
1615
|
+
await page.setContent('<${tagName}></${tagName}>');
|
|
1510
1616
|
|
|
1511
|
-
const element = await page.find('${
|
|
1617
|
+
const element = await page.find('${tagName}');
|
|
1512
1618
|
expect(element).toHaveClass('hydrated');
|
|
1513
1619
|
});
|
|
1514
1620
|
});
|
|
1515
1621
|
`;
|
|
1516
1622
|
/**
|
|
1517
1623
|
* Convert a dash case string to pascal case.
|
|
1624
|
+
* @param str the string to convert
|
|
1625
|
+
* @returns the converted input as pascal case
|
|
1518
1626
|
*/
|
|
1519
1627
|
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
|
|
1520
1628
|
|
package/cli/package.json
CHANGED