@rindo/core 2.16.1 → 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 CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Rindo CLI (CommonJS) v2.16.1 | MIT Licensed | https://rindojs.web.app
2
+ Rindo CLI (CommonJS) v2.17.0 | MIT Licensed | https://rindojs.web.app
3
3
  */
4
4
  'use strict';
5
5
 
@@ -532,7 +532,7 @@ const getNpmConfigEnvArgs = (sys) => {
532
532
  const dependencies = [
533
533
  {
534
534
  name: "@rindo/core",
535
- version: "2.16.1",
535
+ version: "2.17.0",
536
536
  main: "compiler/rindo.js",
537
537
  resources: [
538
538
  "package.json",
@@ -966,7 +966,9 @@ async function updateConfig(sys, newOptions) {
966
966
  return await writeConfig(sys, Object.assign(config, newOptions));
967
967
  }
968
968
 
969
+ const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
969
970
  const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
971
+ const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
970
972
  const DOCS_CUSTOM = 'docs-custom';
971
973
  const DOCS_JSON = 'docs-json';
972
974
  const DOCS_README = 'docs-readme';
@@ -994,6 +996,7 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
994
996
  }
995
997
  /**
996
998
  * A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
999
+ *
997
1000
  * @param sys The system where the command is invoked
998
1001
  * @param config The config passed into the Rindo command
999
1002
  * @param logger The tool used to do logging
@@ -1039,6 +1042,16 @@ async function getActiveTargets(config) {
1039
1042
  const result = config.outputTargets.map((t) => t.type);
1040
1043
  return Array.from(new Set(result));
1041
1044
  }
1045
+ /**
1046
+ * Prepare data for telemetry
1047
+ *
1048
+ * @param coreCompiler the core compiler
1049
+ * @param config the current Rindo config
1050
+ * @param sys the compiler system instance in use
1051
+ * @param duration_ms the duration of the action being tracked
1052
+ * @param component_count the number of components being built (optional)
1053
+ * @returns a Promise wrapping data for the telemetry endpoint
1054
+ */
1042
1055
  const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
1043
1056
  const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
1044
1057
  const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
@@ -1051,6 +1064,7 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
1051
1064
  const cpu_model = sys.details.cpuModel;
1052
1065
  const build = coreCompiler.buildId || 'unknown';
1053
1066
  const has_app_pwa_config = hasAppTarget(config);
1067
+ const anonymizedConfig = anonymizeConfigForTelemetry(config);
1054
1068
  return {
1055
1069
  yarn,
1056
1070
  duration_ms,
@@ -1070,12 +1084,83 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
1070
1084
  typescript,
1071
1085
  rollup,
1072
1086
  has_app_pwa_config,
1087
+ config: anonymizedConfig,
1073
1088
  };
1074
1089
  };
1090
+ // props in output targets for which we retain their original values when
1091
+ // preparing a config for telemetry
1092
+ //
1093
+ // we omit the values of all other fields on output targets.
1094
+ const OUTPUT_TARGET_KEYS_TO_KEEP = ['type'];
1095
+ // top-level config props that we anonymize for telemetry
1096
+ const CONFIG_PROPS_TO_ANONYMIZE = [
1097
+ 'rootDir',
1098
+ 'fsNamespace',
1099
+ 'packageJsonFilePath',
1100
+ 'namespace',
1101
+ 'srcDir',
1102
+ 'srcIndexHtml',
1103
+ 'buildLogFilePath',
1104
+ 'cacheDir',
1105
+ 'configPath',
1106
+ 'tsconfig',
1107
+ ];
1108
+ // Props we delete entirely from the config for telemetry
1109
+ //
1110
+ // TODO: Investigate improving anonymization for tsCompilerOptions and devServer
1111
+ const CONFIG_PROPS_TO_DELETE = ['sys', 'logger', 'tsCompilerOptions', 'devServer'];
1112
+ /**
1113
+ * Anonymize the config for telemetry, replacing potentially revealing config props
1114
+ * with a placeholder string if they are present (this lets us still track how frequently
1115
+ * these config options are being used)
1116
+ *
1117
+ * @param config the config to anonymize
1118
+ * @returns an anonymized copy of the same config
1119
+ */
1120
+ const anonymizeConfigForTelemetry = (config) => {
1121
+ var _a;
1122
+ const anonymizedConfig = { ...config };
1123
+ for (const prop of CONFIG_PROPS_TO_ANONYMIZE) {
1124
+ if (anonymizedConfig[prop] !== undefined) {
1125
+ anonymizedConfig[prop] = 'omitted';
1126
+ }
1127
+ }
1128
+ anonymizedConfig.outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).map((target) => {
1129
+ // Anonymize the outputTargets on our configuration, taking advantage of the
1130
+ // optional 2nd argument to `JSON.stringify`. If anything is not a string
1131
+ // we retain it so that any nested properties are handled, else we check
1132
+ // whether it's in our 'keep' list to decide whether to keep it or replace it
1133
+ // with `"omitted"`.
1134
+ const anonymizedOT = JSON.parse(JSON.stringify(target, (key, value) => {
1135
+ if (!(typeof value === 'string')) {
1136
+ return value;
1137
+ }
1138
+ if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) {
1139
+ return value;
1140
+ }
1141
+ return 'omitted';
1142
+ }));
1143
+ // this prop has to be handled separately because it is an array
1144
+ // so the replace function above will be called with all of its
1145
+ // members, giving us `["omitted", "omitted", ...]`.
1146
+ //
1147
+ // Instead, we check for its presence and manually copy over.
1148
+ if (isOutputTargetHydrate(target) && target.external) {
1149
+ anonymizedOT['external'] = target.external.concat();
1150
+ }
1151
+ return anonymizedOT;
1152
+ });
1153
+ // TODO: Investigate improving anonymization for tsCompilerOptions and devServer
1154
+ for (const prop of CONFIG_PROPS_TO_DELETE) {
1155
+ delete anonymizedConfig[prop];
1156
+ }
1157
+ return anonymizedConfig;
1158
+ };
1075
1159
  /**
1076
1160
  * Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
1077
1161
  * the dependencies and devDependencies properties. Pulls up the current installed version
1078
1162
  * of each package under the @rindo, @navify, and @jigra scopes.
1163
+ *
1079
1164
  * @param sys the system instance where telemetry is invoked
1080
1165
  * @param config the Rindo configuration associated with the current task that triggered telemetry
1081
1166
  * @returns an object listing all dev and production dependencies under the aforementioned scopes
@@ -1158,6 +1243,7 @@ function sanitizeDeclaredVersion(version) {
1158
1243
  }
1159
1244
  /**
1160
1245
  * If telemetry is enabled, send a metric to an external data store
1246
+ *
1161
1247
  * @param sys the system instance where telemetry is invoked
1162
1248
  * @param config the Rindo configuration associated with the current task that triggered telemetry
1163
1249
  * @param name the name of a trackable metric. Note this name is not necessarily a scalar value to track, like
@@ -1173,10 +1259,11 @@ async function sendMetric(sys, config, name, value) {
1173
1259
  value,
1174
1260
  session_id,
1175
1261
  };
1176
- await sendTelemetry(sys, config, { type: 'telemetry', message });
1262
+ await sendTelemetry(sys, config, message);
1177
1263
  }
1178
1264
  /**
1179
1265
  * Used to read the config file's tokens.telemetry property.
1266
+ *
1180
1267
  * @param sys The system where the command is invoked
1181
1268
  * @returns string
1182
1269
  */
@@ -1198,7 +1285,7 @@ async function sendTelemetry(sys, config, data) {
1198
1285
  try {
1199
1286
  const now = new Date().toISOString();
1200
1287
  const body = {
1201
- metrics: [data.message],
1288
+ metrics: [data],
1202
1289
  sent_at: now,
1203
1290
  };
1204
1291
  // This request is only made if telemetry is on.
@@ -1210,7 +1297,7 @@ async function sendTelemetry(sys, config, data) {
1210
1297
  body: JSON.stringify(body),
1211
1298
  });
1212
1299
  hasVerbose(config) &&
1213
- console.debug('\nSent %O metric to events service (status: %O)', data.message.name, response.status, '\n');
1300
+ console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
1214
1301
  if (response.status !== 204) {
1215
1302
  hasVerbose(config) &&
1216
1303
  console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
@@ -1361,7 +1448,8 @@ const taskGenerate = async (coreCompiler, config) => {
1361
1448
  if (!writtenFiles) {
1362
1449
  return config.sys.exit(1);
1363
1450
  }
1364
- // TODO: Investigate moving these console.log calls to config.logger.info
1451
+ // We use `console.log` here rather than our `config.logger` because we don't want
1452
+ // our TUI messages to be prefixed with timestamps and so on.
1365
1453
  console.log();
1366
1454
  console.log(`${config.logger.gray('$')} rindo generate ${input}`);
1367
1455
  console.log();
package/cli/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Rindo CLI v2.16.1 | MIT Licensed | https://rindojs.web.app
2
+ Rindo CLI v2.17.0 | MIT Licensed | https://rindojs.web.app
3
3
  */
4
4
  const toLowerCase = (str) => str.toLowerCase();
5
5
  const dashToPascalCase = (str) => toLowerCase(str)
@@ -508,7 +508,7 @@ const getNpmConfigEnvArgs = (sys) => {
508
508
  const dependencies = [
509
509
  {
510
510
  name: "@rindo/core",
511
- version: "2.16.1",
511
+ version: "2.17.0",
512
512
  main: "compiler/rindo.js",
513
513
  resources: [
514
514
  "package.json",
@@ -942,7 +942,9 @@ async function updateConfig(sys, newOptions) {
942
942
  return await writeConfig(sys, Object.assign(config, newOptions));
943
943
  }
944
944
 
945
+ const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
945
946
  const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
947
+ const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
946
948
  const DOCS_CUSTOM = 'docs-custom';
947
949
  const DOCS_JSON = 'docs-json';
948
950
  const DOCS_README = 'docs-readme';
@@ -970,6 +972,7 @@ async function telemetryBuildFinishedAction(sys, config, logger, coreCompiler, r
970
972
  }
971
973
  /**
972
974
  * A function to wrap a compiler task function around. Will send telemetry if, and only if, the machine allows.
975
+ *
973
976
  * @param sys The system where the command is invoked
974
977
  * @param config The config passed into the Rindo command
975
978
  * @param logger The tool used to do logging
@@ -1015,6 +1018,16 @@ async function getActiveTargets(config) {
1015
1018
  const result = config.outputTargets.map((t) => t.type);
1016
1019
  return Array.from(new Set(result));
1017
1020
  }
1021
+ /**
1022
+ * Prepare data for telemetry
1023
+ *
1024
+ * @param coreCompiler the core compiler
1025
+ * @param config the current Rindo config
1026
+ * @param sys the compiler system instance in use
1027
+ * @param duration_ms the duration of the action being tracked
1028
+ * @param component_count the number of components being built (optional)
1029
+ * @returns a Promise wrapping data for the telemetry endpoint
1030
+ */
1018
1031
  const prepareData = async (coreCompiler, config, sys, duration_ms, component_count = undefined) => {
1019
1032
  const { typescript, rollup } = coreCompiler.versions || { typescript: 'unknown', rollup: 'unknown' };
1020
1033
  const { packages, packagesNoVersions } = await getInstalledPackages(sys, config);
@@ -1027,6 +1040,7 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
1027
1040
  const cpu_model = sys.details.cpuModel;
1028
1041
  const build = coreCompiler.buildId || 'unknown';
1029
1042
  const has_app_pwa_config = hasAppTarget(config);
1043
+ const anonymizedConfig = anonymizeConfigForTelemetry(config);
1030
1044
  return {
1031
1045
  yarn,
1032
1046
  duration_ms,
@@ -1046,12 +1060,83 @@ const prepareData = async (coreCompiler, config, sys, duration_ms, component_cou
1046
1060
  typescript,
1047
1061
  rollup,
1048
1062
  has_app_pwa_config,
1063
+ config: anonymizedConfig,
1049
1064
  };
1050
1065
  };
1066
+ // props in output targets for which we retain their original values when
1067
+ // preparing a config for telemetry
1068
+ //
1069
+ // we omit the values of all other fields on output targets.
1070
+ const OUTPUT_TARGET_KEYS_TO_KEEP = ['type'];
1071
+ // top-level config props that we anonymize for telemetry
1072
+ const CONFIG_PROPS_TO_ANONYMIZE = [
1073
+ 'rootDir',
1074
+ 'fsNamespace',
1075
+ 'packageJsonFilePath',
1076
+ 'namespace',
1077
+ 'srcDir',
1078
+ 'srcIndexHtml',
1079
+ 'buildLogFilePath',
1080
+ 'cacheDir',
1081
+ 'configPath',
1082
+ 'tsconfig',
1083
+ ];
1084
+ // Props we delete entirely from the config for telemetry
1085
+ //
1086
+ // TODO: Investigate improving anonymization for tsCompilerOptions and devServer
1087
+ const CONFIG_PROPS_TO_DELETE = ['sys', 'logger', 'tsCompilerOptions', 'devServer'];
1088
+ /**
1089
+ * Anonymize the config for telemetry, replacing potentially revealing config props
1090
+ * with a placeholder string if they are present (this lets us still track how frequently
1091
+ * these config options are being used)
1092
+ *
1093
+ * @param config the config to anonymize
1094
+ * @returns an anonymized copy of the same config
1095
+ */
1096
+ const anonymizeConfigForTelemetry = (config) => {
1097
+ var _a;
1098
+ const anonymizedConfig = { ...config };
1099
+ for (const prop of CONFIG_PROPS_TO_ANONYMIZE) {
1100
+ if (anonymizedConfig[prop] !== undefined) {
1101
+ anonymizedConfig[prop] = 'omitted';
1102
+ }
1103
+ }
1104
+ anonymizedConfig.outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).map((target) => {
1105
+ // Anonymize the outputTargets on our configuration, taking advantage of the
1106
+ // optional 2nd argument to `JSON.stringify`. If anything is not a string
1107
+ // we retain it so that any nested properties are handled, else we check
1108
+ // whether it's in our 'keep' list to decide whether to keep it or replace it
1109
+ // with `"omitted"`.
1110
+ const anonymizedOT = JSON.parse(JSON.stringify(target, (key, value) => {
1111
+ if (!(typeof value === 'string')) {
1112
+ return value;
1113
+ }
1114
+ if (OUTPUT_TARGET_KEYS_TO_KEEP.includes(key)) {
1115
+ return value;
1116
+ }
1117
+ return 'omitted';
1118
+ }));
1119
+ // this prop has to be handled separately because it is an array
1120
+ // so the replace function above will be called with all of its
1121
+ // members, giving us `["omitted", "omitted", ...]`.
1122
+ //
1123
+ // Instead, we check for its presence and manually copy over.
1124
+ if (isOutputTargetHydrate(target) && target.external) {
1125
+ anonymizedOT['external'] = target.external.concat();
1126
+ }
1127
+ return anonymizedOT;
1128
+ });
1129
+ // TODO: Investigate improving anonymization for tsCompilerOptions and devServer
1130
+ for (const prop of CONFIG_PROPS_TO_DELETE) {
1131
+ delete anonymizedConfig[prop];
1132
+ }
1133
+ return anonymizedConfig;
1134
+ };
1051
1135
  /**
1052
1136
  * Reads package-lock.json, yarn.lock, and package.json files in order to cross-reference
1053
1137
  * the dependencies and devDependencies properties. Pulls up the current installed version
1054
1138
  * of each package under the @rindo, @navify, and @jigra scopes.
1139
+ *
1055
1140
  * @param sys the system instance where telemetry is invoked
1056
1141
  * @param config the Rindo configuration associated with the current task that triggered telemetry
1057
1142
  * @returns an object listing all dev and production dependencies under the aforementioned scopes
@@ -1134,6 +1219,7 @@ function sanitizeDeclaredVersion(version) {
1134
1219
  }
1135
1220
  /**
1136
1221
  * If telemetry is enabled, send a metric to an external data store
1222
+ *
1137
1223
  * @param sys the system instance where telemetry is invoked
1138
1224
  * @param config the Rindo configuration associated with the current task that triggered telemetry
1139
1225
  * @param name the name of a trackable metric. Note this name is not necessarily a scalar value to track, like
@@ -1149,10 +1235,11 @@ async function sendMetric(sys, config, name, value) {
1149
1235
  value,
1150
1236
  session_id,
1151
1237
  };
1152
- await sendTelemetry(sys, config, { type: 'telemetry', message });
1238
+ await sendTelemetry(sys, config, message);
1153
1239
  }
1154
1240
  /**
1155
1241
  * Used to read the config file's tokens.telemetry property.
1242
+ *
1156
1243
  * @param sys The system where the command is invoked
1157
1244
  * @returns string
1158
1245
  */
@@ -1174,7 +1261,7 @@ async function sendTelemetry(sys, config, data) {
1174
1261
  try {
1175
1262
  const now = new Date().toISOString();
1176
1263
  const body = {
1177
- metrics: [data.message],
1264
+ metrics: [data],
1178
1265
  sent_at: now,
1179
1266
  };
1180
1267
  // This request is only made if telemetry is on.
@@ -1186,7 +1273,7 @@ async function sendTelemetry(sys, config, data) {
1186
1273
  body: JSON.stringify(body),
1187
1274
  });
1188
1275
  hasVerbose(config) &&
1189
- console.debug('\nSent %O metric to events service (status: %O)', data.message.name, response.status, '\n');
1276
+ console.debug('\nSent %O metric to events service (status: %O)', data.name, response.status, '\n');
1190
1277
  if (response.status !== 204) {
1191
1278
  hasVerbose(config) &&
1192
1279
  console.debug('\nBad response from events service. Request body: %O', response.body.toString(), '\n');
@@ -1337,7 +1424,8 @@ const taskGenerate = async (coreCompiler, config) => {
1337
1424
  if (!writtenFiles) {
1338
1425
  return config.sys.exit(1);
1339
1426
  }
1340
- // TODO: Investigate moving these console.log calls to config.logger.info
1427
+ // We use `console.log` here rather than our `config.logger` because we don't want
1428
+ // our TUI messages to be prefixed with timestamps and so on.
1341
1429
  console.log();
1342
1430
  console.log(`${config.logger.gray('$')} rindo generate ${input}`);
1343
1431
  console.log();
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rindo/core/cli",
3
- "version": "2.16.1",
3
+ "version": "2.17.0",
4
4
  "description": "Rindo CLI.",
5
5
  "main": "./index.cjs",
6
6
  "module": "./index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rindo/core/compiler",
3
- "version": "2.16.1",
3
+ "version": "2.17.0",
4
4
  "description": "Rindo Compiler.",
5
5
  "main": "./rindo.js",
6
6
  "types": "./rindo.d.ts",