@sentry/bundler-plugin-core 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -4,14 +4,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var unplugin$1 = require('unplugin');
6
6
  var MagicString = require('magic-string');
7
+ var SentryCli = require('@sentry/cli');
7
8
  var node = require('@sentry/node');
8
9
  require('@sentry/tracing');
9
- var SentryCli = require('@sentry/cli');
10
+ var path = require('path');
10
11
 
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
13
 
13
14
  var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
14
15
  var SentryCli__default = /*#__PURE__*/_interopDefaultLegacy(SentryCli);
16
+ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
15
17
 
16
18
  function _regeneratorRuntime() {
17
19
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
@@ -827,29 +829,25 @@ function normalizeUserOptions(userOptions) {
827
829
  // Optional options
828
830
  setCommits: userOptions.setCommits,
829
831
  deploy: userOptions.deploy,
830
- entries: normalizeEntries(userOptions.entries),
832
+ releaseInjectionTargets: normalizeReleaseInjectionTargets(userOptions.releaseInjectionTargets),
831
833
  dist: userOptions.dist,
832
834
  errorHandler: userOptions.errorHandler,
833
835
  configFile: userOptions.configFile
834
- }; // We only want to enable telemetry for SaaS users
835
- // This is not the final check (we need to call Sentry CLI at a later point)
836
- // but we can already at this point make a first decision.
837
- // @see `turnOffTelemetryForSelfHostedSentry` (telemetry.ts) for the second check.
838
-
839
- options.telemetry = options.telemetry && options.url === SENTRY_SAAS_URL;
836
+ };
840
837
  return options;
841
838
  }
842
839
  /**
843
- * Converts the user-facing `entries` option to the internal `entries` option
840
+ * Converts the user-facing `releaseInjectionTargets` option to the internal
841
+ * `releaseInjectionTargets` option
844
842
  */
845
843
 
846
- function normalizeEntries(userEntries) {
847
- if (userEntries === undefined) {
844
+ function normalizeReleaseInjectionTargets(userReleaseInjectionTargets) {
845
+ if (userReleaseInjectionTargets === undefined) {
848
846
  return undefined;
849
- } else if (typeof userEntries === "function") {
850
- return userEntries;
847
+ } else if (typeof userReleaseInjectionTargets === "function") {
848
+ return userReleaseInjectionTargets;
851
849
  } else {
852
- return arrayify(userEntries);
850
+ return arrayify(userReleaseInjectionTargets);
853
851
  }
854
852
  }
855
853
  /**
@@ -948,30 +946,68 @@ function validateOptions(options, logger) {
948
946
  return true;
949
947
  }
950
948
 
951
- function makeSentryClient(dsn, telemetryEnabled) {
949
+ var SENTRY_SAAS_HOSTNAME = "sentry.io";
950
+ function makeSentryClient(dsn, allowedToSendTelemetryPromise) {
952
951
  var client = new node.NodeClient({
953
952
  dsn: dsn,
954
- enabled: telemetryEnabled,
955
- tracesSampleRate: telemetryEnabled ? 1.0 : 0.0,
956
- sampleRate: telemetryEnabled ? 1.0 : 0.0,
957
- release: "0.1.0",
958
- integrations: [new node.Integrations.Http({
959
- tracing: true
960
- })],
953
+ tracesSampleRate: 1,
954
+ sampleRate: 1,
955
+ release: "0.2.1",
956
+ integrations: [],
961
957
  tracePropagationTargets: ["sentry.io/api"],
962
958
  stackParser: node.defaultStackParser,
963
- transport: node.makeNodeTransport
964
- });
965
- var hub = new node.Hub(client); //TODO: This call is problematic because as soon as we set our hub as the current hub
966
- // we might interfere with other plugins that use Sentry. However, for now, we'll
967
- // leave it in because without it, we can't get distributed traces (which are pretty nice)
968
- // Let's keep it until someone complains about interference.
969
- // The ideal solution would be a code change in the JS SDK but it's not a straight-forward fix.
959
+ // We create a transport that stalls sending events until we know that we're allowed to (i.e. when Sentry CLI told
960
+ // us that the upload URL is the Sentry SaaS URL)
961
+ transport: function transport(nodeTransportOptions) {
962
+ var nodeTransport = node.makeNodeTransport(nodeTransportOptions);
963
+ return {
964
+ flush: function flush(timeout) {
965
+ return nodeTransport.flush(timeout);
966
+ },
967
+ send: function () {
968
+ var _send = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(request) {
969
+ var isAllowedToSend;
970
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
971
+ while (1) {
972
+ switch (_context.prev = _context.next) {
973
+ case 0:
974
+ _context.next = 2;
975
+ return allowedToSendTelemetryPromise;
976
+
977
+ case 2:
978
+ isAllowedToSend = _context.sent;
979
+
980
+ if (!isAllowedToSend) {
981
+ _context.next = 7;
982
+ break;
983
+ }
984
+
985
+ return _context.abrupt("return", nodeTransport.send(request));
986
+
987
+ case 7:
988
+ return _context.abrupt("return", undefined);
989
+
990
+ case 8:
991
+ case "end":
992
+ return _context.stop();
993
+ }
994
+ }
995
+ }, _callee);
996
+ }));
997
+
998
+ function send(_x) {
999
+ return _send.apply(this, arguments);
1000
+ }
970
1001
 
971
- node.makeMain(hub);
1002
+ return send;
1003
+ }()
1004
+ };
1005
+ }
1006
+ });
1007
+ var hub = new node.Hub(client);
972
1008
  return {
973
- client: client,
974
- hub: hub
1009
+ sentryClient: client,
1010
+ sentryHub: hub
975
1011
  };
976
1012
  }
977
1013
  /**
@@ -1013,8 +1049,10 @@ function captureMinimalError(error, hub) {
1013
1049
 
1014
1050
  hub.captureException(sentryError);
1015
1051
  }
1016
- function addPluginOptionTags(options, hub) {
1017
- var cleanArtifacts = options.cleanArtifacts,
1052
+ function addPluginOptionInformationToHub(options, hub, bundler) {
1053
+ var org = options.org,
1054
+ project = options.project,
1055
+ cleanArtifacts = options.cleanArtifacts,
1018
1056
  finalize = options.finalize,
1019
1057
  setCommits = options.setCommits,
1020
1058
  injectReleasesMap = options.injectReleasesMap,
@@ -1054,61 +1092,107 @@ function addPluginOptionTags(options, hub) {
1054
1092
  }
1055
1093
 
1056
1094
  hub.setTag("node", process.version);
1095
+ hub.setTags({
1096
+ organization: org,
1097
+ project: project,
1098
+ bundler: bundler
1099
+ });
1100
+ hub.setUser({
1101
+ id: org
1102
+ });
1057
1103
  }
1058
- /**
1059
- * Makes a call to SentryCLI to get the Sentry server URL the CLI uses.
1060
- *
1061
- * We need to check and decide to use telemetry based on the CLI's respone to this call
1062
- * because only at this time we checked a possibly existing .sentryclirc file. This file
1063
- * could point to another URL than the default URL.
1064
- */
1065
-
1066
- function turnOffTelemetryForSelfHostedSentry(_x, _x2) {
1067
- return _turnOffTelemetryForSelfHostedSentry.apply(this, arguments);
1104
+ function shouldSendTelemetry(_x2) {
1105
+ return _shouldSendTelemetry.apply(this, arguments);
1068
1106
  }
1069
1107
 
1070
- function _turnOffTelemetryForSelfHostedSentry() {
1071
- _turnOffTelemetryForSelfHostedSentry = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cli, hub) {
1108
+ function _shouldSendTelemetry() {
1109
+ _shouldSendTelemetry = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
1072
1110
  var _cliInfo$split$, _cliInfo$split$$repla;
1073
1111
 
1074
- var cliInfo, url, client;
1075
- return _regeneratorRuntime().wrap(function _callee$(_context) {
1112
+ var silent, org, project, authToken, url, vcsRemote, customHeader, dist, telemetry, dryRun, cli, cliInfo, cliInfoUrl;
1113
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
1076
1114
  while (1) {
1077
- switch (_context.prev = _context.next) {
1115
+ switch (_context2.prev = _context2.next) {
1078
1116
  case 0:
1079
- _context.next = 2;
1080
- return cli.execute(["info"], false);
1117
+ silent = options.silent, org = options.org, project = options.project, authToken = options.authToken, url = options.url, vcsRemote = options.vcsRemote, customHeader = options.customHeader, dist = options.dist, telemetry = options.telemetry, dryRun = options.dryRun; // `options.telemetry` defaults to true
1081
1118
 
1082
- case 2:
1083
- cliInfo = _context.sent;
1084
- url = cliInfo === null || cliInfo === void 0 ? void 0 : (_cliInfo$split$ = cliInfo.split(/(\r\n|\n|\r)/)[0]) === null || _cliInfo$split$ === void 0 ? void 0 : (_cliInfo$split$$repla = _cliInfo$split$.replace(/^Sentry Server: /, "")) === null || _cliInfo$split$$repla === void 0 ? void 0 : _cliInfo$split$$repla.trim();
1119
+ if (!(telemetry === false)) {
1120
+ _context2.next = 3;
1121
+ break;
1122
+ }
1085
1123
 
1086
- if (url !== SENTRY_SAAS_URL) {
1087
- client = hub.getClient();
1124
+ return _context2.abrupt("return", false);
1088
1125
 
1089
- if (client) {
1090
- client.getOptions().enabled = false;
1091
- client.getOptions().tracesSampleRate = 0;
1092
- client.getOptions().sampleRate = 0;
1093
- }
1126
+ case 3:
1127
+ if (!dryRun) {
1128
+ _context2.next = 5;
1129
+ break;
1094
1130
  }
1095
1131
 
1132
+ return _context2.abrupt("return", false);
1133
+
1096
1134
  case 5:
1135
+ if (!(url === SENTRY_SAAS_URL)) {
1136
+ _context2.next = 7;
1137
+ break;
1138
+ }
1139
+
1140
+ return _context2.abrupt("return", true);
1141
+
1142
+ case 7:
1143
+ cli = new SentryCli__default["default"](options.configFile, {
1144
+ url: url,
1145
+ authToken: authToken,
1146
+ org: org,
1147
+ project: project,
1148
+ vcsRemote: vcsRemote,
1149
+ dist: dist,
1150
+ silent: silent,
1151
+ customHeader: customHeader
1152
+ });
1153
+ _context2.prev = 8;
1154
+ _context2.next = 11;
1155
+ return cli.execute(["info"], false);
1156
+
1157
+ case 11:
1158
+ cliInfo = _context2.sent;
1159
+ _context2.next = 17;
1160
+ break;
1161
+
1162
+ case 14:
1163
+ _context2.prev = 14;
1164
+ _context2.t0 = _context2["catch"](8);
1165
+ throw new Error('Sentry CLI "info" command failed, make sure you have an auth token configured, and your `url` option is correct.');
1166
+
1167
+ case 17:
1168
+ cliInfoUrl = (_cliInfo$split$ = cliInfo.split(/(\r\n|\n|\r)/)[0]) === null || _cliInfo$split$ === void 0 ? void 0 : (_cliInfo$split$$repla = _cliInfo$split$.replace(/^Sentry Server: /, "")) === null || _cliInfo$split$$repla === void 0 ? void 0 : _cliInfo$split$$repla.trim();
1169
+
1170
+ if (!(cliInfoUrl === undefined)) {
1171
+ _context2.next = 20;
1172
+ break;
1173
+ }
1174
+
1175
+ return _context2.abrupt("return", false);
1176
+
1177
+ case 20:
1178
+ return _context2.abrupt("return", new URL(cliInfoUrl).hostname === SENTRY_SAAS_HOSTNAME);
1179
+
1180
+ case 21:
1097
1181
  case "end":
1098
- return _context.stop();
1182
+ return _context2.stop();
1099
1183
  }
1100
1184
  }
1101
- }, _callee);
1185
+ }, _callee2, null, [[8, 14]]);
1102
1186
  }));
1103
- return _turnOffTelemetryForSelfHostedSentry.apply(this, arguments);
1187
+ return _shouldSendTelemetry.apply(this, arguments);
1104
1188
  }
1105
1189
 
1106
- function createNewRelease(_x, _x2) {
1190
+ function createNewRelease(_x, _x2, _x3) {
1107
1191
  return _createNewRelease.apply(this, arguments);
1108
1192
  }
1109
1193
 
1110
1194
  function _createNewRelease() {
1111
- _createNewRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(options, ctx) {
1195
+ _createNewRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(options, ctx, releaseName) {
1112
1196
  var span;
1113
1197
  return _regeneratorRuntime().wrap(function _callee$(_context) {
1114
1198
  while (1) {
@@ -1116,7 +1200,7 @@ function _createNewRelease() {
1116
1200
  case 0:
1117
1201
  span = addSpanToTransaction(ctx, "function.plugin.create_release");
1118
1202
  _context.next = 3;
1119
- return ctx.cli.releases["new"](options.release);
1203
+ return ctx.cli.releases["new"](releaseName);
1120
1204
 
1121
1205
  case 3:
1122
1206
  ctx.logger.info("Successfully created release.");
@@ -1132,12 +1216,12 @@ function _createNewRelease() {
1132
1216
  return _createNewRelease.apply(this, arguments);
1133
1217
  }
1134
1218
 
1135
- function cleanArtifacts(_x3, _x4) {
1219
+ function cleanArtifacts(_x4, _x5, _x6) {
1136
1220
  return _cleanArtifacts.apply(this, arguments);
1137
1221
  }
1138
1222
 
1139
1223
  function _cleanArtifacts() {
1140
- _cleanArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options, ctx) {
1224
+ _cleanArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options, ctx, releaseName) {
1141
1225
  var span;
1142
1226
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
1143
1227
  while (1) {
@@ -1154,7 +1238,7 @@ function _cleanArtifacts() {
1154
1238
  case 3:
1155
1239
  span = addSpanToTransaction(ctx, "function.plugin.clean_artifacts");
1156
1240
  _context2.next = 6;
1157
- return ctx.cli.releases.execute(["releases", "files", options.release, "delete", "--all"], true);
1241
+ return ctx.cli.releases.execute(["releases", "files", releaseName, "delete", "--all"], true);
1158
1242
 
1159
1243
  case 6:
1160
1244
  ctx.logger.info("Successfully cleaned previous artifacts.");
@@ -1170,12 +1254,12 @@ function _cleanArtifacts() {
1170
1254
  return _cleanArtifacts.apply(this, arguments);
1171
1255
  }
1172
1256
 
1173
- function uploadSourceMaps(_x5, _x6) {
1257
+ function uploadSourceMaps(_x7, _x8, _x9) {
1174
1258
  return _uploadSourceMaps.apply(this, arguments);
1175
1259
  }
1176
1260
 
1177
1261
  function _uploadSourceMaps() {
1178
- _uploadSourceMaps = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(options, ctx) {
1262
+ _uploadSourceMaps = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(options, ctx, releaseName) {
1179
1263
  var span;
1180
1264
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
1181
1265
  while (1) {
@@ -1186,7 +1270,7 @@ function _uploadSourceMaps() {
1186
1270
  // we only need to pass the include option here.
1187
1271
 
1188
1272
  _context3.next = 4;
1189
- return ctx.cli.releases.uploadSourceMaps(options.release, {
1273
+ return ctx.cli.releases.uploadSourceMaps(releaseName, {
1190
1274
  include: options.include
1191
1275
  });
1192
1276
 
@@ -1204,12 +1288,12 @@ function _uploadSourceMaps() {
1204
1288
  return _uploadSourceMaps.apply(this, arguments);
1205
1289
  }
1206
1290
 
1207
- function setCommits(_x7, _x8) {
1291
+ function setCommits(_x10, _x11, _x12) {
1208
1292
  return _setCommits.apply(this, arguments);
1209
1293
  }
1210
1294
 
1211
1295
  function _setCommits() {
1212
- _setCommits = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(options, ctx) {
1296
+ _setCommits = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(options, ctx, releaseName) {
1213
1297
  var span, _options$setCommits, auto, repo, commit, previousCommit, ignoreMissing, ignoreEmpty;
1214
1298
 
1215
1299
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
@@ -1228,7 +1312,7 @@ function _setCommits() {
1228
1312
  span = addSpanToTransaction(ctx, "function.plugin.set_commits");
1229
1313
  _options$setCommits = options.setCommits, auto = _options$setCommits.auto, repo = _options$setCommits.repo, commit = _options$setCommits.commit, previousCommit = _options$setCommits.previousCommit, ignoreMissing = _options$setCommits.ignoreMissing, ignoreEmpty = _options$setCommits.ignoreEmpty;
1230
1314
  _context4.next = 7;
1231
- return ctx.cli.releases.setCommits(options.release, {
1315
+ return ctx.cli.releases.setCommits(releaseName, {
1232
1316
  commit: commit,
1233
1317
  previousCommit: previousCommit,
1234
1318
  repo: repo,
@@ -1251,12 +1335,12 @@ function _setCommits() {
1251
1335
  return _setCommits.apply(this, arguments);
1252
1336
  }
1253
1337
 
1254
- function finalizeRelease(_x9, _x10) {
1338
+ function finalizeRelease(_x13, _x14, _x15) {
1255
1339
  return _finalizeRelease.apply(this, arguments);
1256
1340
  }
1257
1341
 
1258
1342
  function _finalizeRelease() {
1259
- _finalizeRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(options, ctx) {
1343
+ _finalizeRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(options, ctx, releaseName) {
1260
1344
  var span;
1261
1345
  return _regeneratorRuntime().wrap(function _callee5$(_context5) {
1262
1346
  while (1) {
@@ -1273,7 +1357,7 @@ function _finalizeRelease() {
1273
1357
  case 3:
1274
1358
  span = addSpanToTransaction(ctx, "function.plugin.finalize_release");
1275
1359
  _context5.next = 6;
1276
- return ctx.cli.releases.finalize(options.release);
1360
+ return ctx.cli.releases.finalize(releaseName);
1277
1361
 
1278
1362
  case 6:
1279
1363
  ctx.logger.info("Successfully finalized release.");
@@ -1289,12 +1373,12 @@ function _finalizeRelease() {
1289
1373
  return _finalizeRelease.apply(this, arguments);
1290
1374
  }
1291
1375
 
1292
- function addDeploy(_x11, _x12) {
1376
+ function addDeploy(_x16, _x17, _x18) {
1293
1377
  return _addDeploy.apply(this, arguments);
1294
1378
  }
1295
1379
 
1296
1380
  function _addDeploy() {
1297
- _addDeploy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(options, ctx) {
1381
+ _addDeploy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(options, ctx, releaseName) {
1298
1382
  var span, _options$deploy, env, started, finished, time, name, url;
1299
1383
 
1300
1384
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
@@ -1313,7 +1397,7 @@ function _addDeploy() {
1313
1397
  span = addSpanToTransaction(ctx, "function.plugin.deploy");
1314
1398
  _options$deploy = options.deploy, env = _options$deploy.env, started = _options$deploy.started, finished = _options$deploy.finished, time = _options$deploy.time, name = _options$deploy.name, url = _options$deploy.url;
1315
1399
  _context6.next = 7;
1316
- return ctx.cli.releases.newDeploy(options.release, {
1400
+ return ctx.cli.releases.newDeploy(releaseName, {
1317
1401
  env: env,
1318
1402
  started: started,
1319
1403
  finished: finished,
@@ -1397,10 +1481,9 @@ function createLogger(options) {
1397
1481
  }
1398
1482
 
1399
1483
  // eslint-disable-next-line no-console
1400
- (_console4 = console).log.apply(_console4, ["".concat(options.prefix, " Debug: ").concat(message)].concat(params));
1401
- }
1484
+ (_console4 = console).log.apply(_console4, ["".concat(options.prefix, " Debug: ").concat(message)].concat(params)); // We're not creating breadcrumbs for debug logs because it is super spammy
1402
1485
 
1403
- addBreadcrumb("debug", message);
1486
+ }
1404
1487
  }
1405
1488
  };
1406
1489
  }
@@ -1480,10 +1563,11 @@ function getDryRunCLI(cli, logger) {
1480
1563
  };
1481
1564
  }
1482
1565
 
1483
- // We prefix the polyfill id with \0 to tell other plugins not to try to load or transform it.
1484
1566
  // This hack is taken straight from https://rollupjs.org/guide/en/#resolveid.
1485
1567
  // This probably doesn't work for all bundlers but for rollup it does.
1568
+
1486
1569
  var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1570
+ var ALLOWED_TRANSFORMATION_FILE_ENDINGS = [".js", ".ts", ".jsx", ".tsx", ".cjs", ".mjs"];
1487
1571
  /**
1488
1572
  * The sentry bundler plugin concerns itself with two things:
1489
1573
  * - Release injection
@@ -1491,45 +1575,11 @@ var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1491
1575
  *
1492
1576
  * Release injection:
1493
1577
  *
1494
- * Per default the sentry bundler plugin will inject a global `SENTRY_RELEASE` variable into the entrypoint of all bundles.
1495
- * On a technical level this is done by appending an import (`import "sentry-release-injector;"`) to all entrypoint files
1496
- * of the user code (see `transformInclude` and `transform` hooks). This import is then resolved by the sentry plugin
1497
- * to a virtual module that sets the global variable (see `resolveId` and `load` hooks).
1498
- *
1499
- * The resulting output approximately looks like this:
1500
- *
1501
- * ```text
1502
- * entrypoint1.js (user file)
1503
- * ┌─────────────────────────┐ ┌─────────────────────────────────────────────────┐
1504
- * │ │ │ import { myFunction } from "./my-library.js"; │
1505
- * │ sentry-bundler-plugin │ │ │
1506
- * │ │ │ const myResult = myFunction(); │
1507
- * └---------│--------------- │ export { myResult }; │
1508
- * │ │ │
1509
- * │ injects │ // injected by sentry plugin │
1510
- * ├───────────────────► import "sentry-release-injector"; ─────────────────────┐
1511
- * │ └─────────────────────────────────────────────────┘ │
1512
- * │ │
1513
- * │ │
1514
- * │ entrypoint2.js (user file) │
1515
- * │ ┌─────────────────────────────────────────────────┐ │
1516
- * │ │ export function myFunction() { │ │
1517
- * │ │ return "Hello world!"; │ │
1518
- * │ │ } │ │
1519
- * │ │ │ │
1520
- * │ injects │ // injected by sentry plugin │ │
1521
- * └───────────────────► import "sentry-release-injector"; ─────────────────────┤
1522
- * └─────────────────────────────────────────────────┘ │
1523
- * │
1524
- * │
1525
- * sentry-release-injector │
1526
- * ┌──────────────────────────────────┐ │
1527
- * │ │ is resolved │
1528
- * │ global.SENTRY_RELEASE = { ... } │ by plugin │
1529
- * │ // + a little more logic │<─────────────────────┘
1530
- * │ │ (only once)
1531
- * └──────────────────────────────────┘
1532
- * ```
1578
+ * Per default the sentry bundler plugin will inject a global `SENTRY_RELEASE` into each JavaScript/TypeScript module
1579
+ * that is part of the bundle. On a technical level this is done by appending an import (`import "sentry-release-injector;"`)
1580
+ * to all entrypoint files of the user code (see `transformInclude` and `transform` hooks). This import is then resolved
1581
+ * by the sentry plugin to a virtual module that sets the global variable (see `resolveId` and `load` hooks).
1582
+ * If a user wants to inject the release into a particular set of modules they can use the `releaseInjectionTargets` option.
1533
1583
  *
1534
1584
  * Source maps upload:
1535
1585
  *
@@ -1548,11 +1598,19 @@ var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1548
1598
 
1549
1599
  var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext) {
1550
1600
  var internalOptions = normalizeUserOptions(options);
1601
+ var allowedToSendTelemetryPromise = shouldSendTelemetry(internalOptions);
1602
+
1603
+ var _makeSentryClient = makeSentryClient("https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737", allowedToSendTelemetryPromise),
1604
+ sentryHub = _makeSentryClient.sentryHub,
1605
+ sentryClient = _makeSentryClient.sentryClient;
1551
1606
 
1552
- var _makeSentryClient = makeSentryClient("https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737", internalOptions.telemetry),
1553
- sentryHub = _makeSentryClient.hub;
1607
+ addPluginOptionInformationToHub(internalOptions, sentryHub, unpluginMetaContext.framework); //TODO: This call is problematic because as soon as we set our hub as the current hub
1608
+ // we might interfere with other plugins that use Sentry. However, for now, we'll
1609
+ // leave it in because without it, we can't get distributed traces (which are pretty nice)
1610
+ // Let's keep it until someone complains about interference.
1611
+ // The ideal solution would be a code change in the JS SDK but it's not a straight-forward fix.
1554
1612
 
1555
- addPluginOptionTags(internalOptions, sentryHub);
1613
+ node.makeMain(sentryHub);
1556
1614
  var logger = createLogger({
1557
1615
  hub: sentryHub,
1558
1616
  prefix: "[sentry-".concat(unpluginMetaContext.framework, "-plugin]"),
@@ -1565,25 +1623,13 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1565
1623
  }
1566
1624
 
1567
1625
  var cli = getSentryCli(internalOptions, logger);
1568
-
1569
- if (internalOptions.telemetry) {
1570
- logger.info("Sending error and performance telemetry data to Sentry.");
1571
- logger.info("To disable telemetry, set `options.telemetry` to `false`.");
1572
- }
1573
-
1574
- sentryHub.setTags({
1575
- organization: internalOptions.org,
1576
- project: internalOptions.project,
1577
- bundler: unpluginMetaContext.framework
1626
+ var releaseNamePromise = new Promise(function (resolve) {
1627
+ if (options.release) {
1628
+ resolve(options.release);
1629
+ } else {
1630
+ resolve(cli.releases.proposeVersion());
1631
+ }
1578
1632
  });
1579
- sentryHub.setUser({
1580
- id: internalOptions.org
1581
- }); // This is `nonEntrypointSet` instead of `entrypointSet` because this set is filled in the `resolveId` hook and there
1582
- // we don't have guaranteed access to *absolute* paths of files if they're entrypoints. For non-entrypoints we're
1583
- // guaranteed to have absolute paths - we're then using the paths in later hooks to make decisions about whether a
1584
- // file is an entrypoint or a non-entrypoint.
1585
-
1586
- var nonEntrypointSet = new Set();
1587
1633
  var transaction;
1588
1634
  var releaseInjectionSpan;
1589
1635
  return {
@@ -1596,28 +1642,31 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1596
1642
  */
1597
1643
  buildStart: function buildStart() {
1598
1644
  return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
1645
+ var isAllowedToSendToSendTelemetry, releaseName;
1599
1646
  return _regeneratorRuntime().wrap(function _callee$(_context) {
1600
1647
  while (1) {
1601
1648
  switch (_context.prev = _context.next) {
1602
1649
  case 0:
1603
- _context.next = 2;
1604
- return turnOffTelemetryForSelfHostedSentry(cli, sentryHub);
1650
+ logger.debug("Called 'buildStart'");
1651
+ _context.next = 3;
1652
+ return allowedToSendTelemetryPromise;
1605
1653
 
1606
- case 2:
1607
- if (internalOptions.release) {
1608
- _context.next = 6;
1609
- break;
1654
+ case 3:
1655
+ isAllowedToSendToSendTelemetry = _context.sent;
1656
+
1657
+ if (isAllowedToSendToSendTelemetry) {
1658
+ logger.info("Sending error and performance telemetry data to Sentry.");
1659
+ logger.info("To disable telemetry, set `options.telemetry` to `false`.");
1610
1660
  }
1611
1661
 
1612
- _context.next = 5;
1613
- return cli.releases.proposeVersion();
1662
+ _context.next = 7;
1663
+ return releaseNamePromise;
1614
1664
 
1615
- case 5:
1616
- internalOptions.release = _context.sent;
1665
+ case 7:
1666
+ releaseName = _context.sent;
1617
1667
 
1618
- case 6:
1619
1668
  // At this point, we either have determined a release or we have to bail
1620
- if (!internalOptions.release) {
1669
+ if (!releaseName) {
1621
1670
  handleError(new Error("Unable to determine a release name. Make sure to set the `release` option or use an environment that supports auto-detection https://docs.sentry.io/cli/releases/#creating-releases`"), logger, internalOptions.errorHandler, sentryHub);
1622
1671
  }
1623
1672
 
@@ -1632,7 +1681,7 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1632
1681
  cli: cli
1633
1682
  }, "function.plugin.inject_release", "Release injection");
1634
1683
 
1635
- case 9:
1684
+ case 11:
1636
1685
  case "end":
1637
1686
  return _context.stop();
1638
1687
  }
@@ -1654,16 +1703,12 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1654
1703
  */
1655
1704
  resolveId: function resolveId(id, importer, _ref) {
1656
1705
  var isEntry = _ref.isEntry;
1657
- sentryHub.addBreadcrumb({
1658
- category: "resolveId",
1659
- message: "isEntry: ".concat(String(isEntry)),
1660
- level: "info"
1706
+ logger.debug('Called "resolveId":', {
1707
+ id: id,
1708
+ importer: importer,
1709
+ isEntry: isEntry
1661
1710
  });
1662
1711
 
1663
- if (!isEntry) {
1664
- nonEntrypointSet.add(id);
1665
- }
1666
-
1667
1712
  if (id === RELEASE_INJECTOR_ID) {
1668
1713
  return RELEASE_INJECTOR_ID;
1669
1714
  } else {
@@ -1671,9 +1716,9 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1671
1716
  }
1672
1717
  },
1673
1718
  loadInclude: function loadInclude(id) {
1674
- logger.info("Called \"loadInclude\": ".concat(JSON.stringify({
1719
+ logger.debug('Called "loadInclude":', {
1675
1720
  id: id
1676
- })));
1721
+ });
1677
1722
  return id === RELEASE_INJECTOR_ID;
1678
1723
  },
1679
1724
 
@@ -1685,75 +1730,109 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1685
1730
  * @returns The global injector code when we load the "sentry-release-injector" module. Otherwise returns `undefined`.
1686
1731
  */
1687
1732
  load: function load(id) {
1688
- sentryHub.addBreadcrumb({
1689
- category: "load",
1690
- level: "info"
1691
- });
1733
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
1734
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
1735
+ while (1) {
1736
+ switch (_context2.prev = _context2.next) {
1737
+ case 0:
1738
+ logger.debug('Called "load":', {
1739
+ id: id
1740
+ });
1692
1741
 
1693
- if (id === RELEASE_INJECTOR_ID) {
1694
- return generateGlobalInjectorCode({
1695
- release: internalOptions.release,
1696
- injectReleasesMap: internalOptions.injectReleasesMap,
1697
- org: internalOptions.org,
1698
- project: internalOptions.project
1699
- });
1700
- } else {
1701
- return undefined;
1702
- }
1742
+ if (!(id === RELEASE_INJECTOR_ID)) {
1743
+ _context2.next = 13;
1744
+ break;
1745
+ }
1746
+
1747
+ _context2.t0 = generateGlobalInjectorCode;
1748
+ _context2.next = 5;
1749
+ return releaseNamePromise;
1750
+
1751
+ case 5:
1752
+ _context2.t1 = _context2.sent;
1753
+ _context2.t2 = internalOptions.injectReleasesMap;
1754
+ _context2.t3 = internalOptions.org;
1755
+ _context2.t4 = internalOptions.project;
1756
+ _context2.t5 = {
1757
+ release: _context2.t1,
1758
+ injectReleasesMap: _context2.t2,
1759
+ org: _context2.t3,
1760
+ project: _context2.t4
1761
+ };
1762
+ return _context2.abrupt("return", (0, _context2.t0)(_context2.t5));
1763
+
1764
+ case 13:
1765
+ return _context2.abrupt("return", undefined);
1766
+
1767
+ case 14:
1768
+ case "end":
1769
+ return _context2.stop();
1770
+ }
1771
+ }
1772
+ }, _callee2);
1773
+ }))();
1703
1774
  },
1704
1775
 
1705
1776
  /**
1706
1777
  * This hook determines whether we want to transform a module. In the sentry bundler plugin we want to transform every entrypoint
1707
- * unless configured otherwise with the `entries` option.
1778
+ * unless configured otherwise with the `releaseInjectionTargets` option.
1708
1779
  *
1709
1780
  * @param id Always the absolute (fully resolved) path to the module.
1710
1781
  * @returns `true` or `false` depending on whether we want to transform the module. For the sentry bundler plugin we only
1711
1782
  * want to transform the release injector file.
1712
1783
  */
1713
1784
  transformInclude: function transformInclude(id) {
1714
- sentryHub.addBreadcrumb({
1715
- category: "transformInclude",
1716
- level: "info"
1717
- });
1785
+ logger.debug('Called "transformInclude":', {
1786
+ id: id
1787
+ }); // We normalize the id because vite always passes `id` as a unix style path which causes problems when a user passes
1788
+ // a windows style path to `releaseInjectionTargets`
1718
1789
 
1719
- if (internalOptions.entries) {
1720
- // If there's an `entries` option transform (ie. inject the release varible) when the file path matches the option.
1721
- if (typeof internalOptions.entries === "function") {
1722
- return internalOptions.entries(id);
1790
+ var normalizedId = path__default["default"].normalize(id); // We don't want to transform our injected code.
1791
+
1792
+ if (normalizedId === RELEASE_INJECTOR_ID) {
1793
+ return false;
1794
+ }
1795
+
1796
+ if (internalOptions.releaseInjectionTargets) {
1797
+ // If there's an `releaseInjectionTargets` option transform (ie. inject the release varible) when the file path matches the option.
1798
+ if (typeof internalOptions.releaseInjectionTargets === "function") {
1799
+ return internalOptions.releaseInjectionTargets(normalizedId);
1723
1800
  }
1724
1801
 
1725
- return internalOptions.entries.some(function (entry) {
1802
+ return internalOptions.releaseInjectionTargets.some(function (entry) {
1726
1803
  if (entry instanceof RegExp) {
1727
- return entry.test(id);
1804
+ return entry.test(normalizedId);
1728
1805
  } else {
1729
- return id === entry;
1806
+ var normalizedEntry = path__default["default"].normalize(entry);
1807
+ return normalizedId === normalizedEntry;
1730
1808
  }
1731
1809
  });
1732
- } // We want to transform (release injection) every module except for "sentry-release-injector".
1733
-
1734
-
1735
- return id !== RELEASE_INJECTOR_ID && !nonEntrypointSet.has(id);
1810
+ } else {
1811
+ var pathIsOrdinary = !normalizedId.includes("?") && !normalizedId.includes("#");
1812
+ var pathHasAllowedFileEnding = ALLOWED_TRANSFORMATION_FILE_ENDINGS.some(function (allowedFileEnding) {
1813
+ return normalizedId.endsWith(allowedFileEnding);
1814
+ });
1815
+ return pathIsOrdinary && pathHasAllowedFileEnding;
1816
+ }
1736
1817
  },
1737
1818
 
1738
1819
  /**
1739
1820
  * This hook is responsible for injecting the "sentry release injector" imoprt statement into each entrypoint unless
1740
- * configured otherwise with the `entries` option (logic for that is in the `transformInclude` hook).
1821
+ * configured otherwise with the `releaseInjectionTargets` option (logic for that is in the `transformInclude` hook).
1741
1822
  *
1742
1823
  * @param code Code of the file to transform.
1743
1824
  * @param id Always the absolute (fully resolved) path to the module.
1744
1825
  * @returns transformed code + source map
1745
1826
  */
1746
- transform: function transform(code) {
1747
- sentryHub.addBreadcrumb({
1748
- category: "transform",
1749
- level: "info"
1827
+ transform: function transform(code, id) {
1828
+ logger.debug('Called "transform":', {
1829
+ id: id
1750
1830
  }); // The MagicString library allows us to generate sourcemaps for the changes we make to the user code.
1751
1831
 
1752
- var ms = new MagicString__default["default"](code); // Very stupid author's note: For some absurd reason, when we add a JSDoc to this hook, the TS language server starts complaining about `ms` and adding a type annotation helped so that's why it's here. (┛ಠ_ಠ)┛彡┻━┻
1753
- // appending instead of prepending has less probability of mucking with user'sadly
1754
- // source maps and import statements get to the top anyways
1832
+ var ms = new MagicString__default["default"](code); // Appending instead of prepending has less probability of mucking with user's source maps.
1833
+ // Luckily import statements get hoisted to the top anyways.
1755
1834
 
1756
- ms.append("import \"".concat(RELEASE_INJECTOR_ID, "\";"));
1835
+ ms.append(";\nimport \"".concat(RELEASE_INJECTOR_ID, "\";"));
1757
1836
 
1758
1837
  if (unpluginMetaContext.framework === "esbuild") {
1759
1838
  // esbuild + unplugin is buggy at the moment when we return an object with a `map` (sourcemap) property.
@@ -1773,69 +1852,119 @@ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext)
1773
1852
  * Sentry.io, uploading sourcemaps, associating commits and deploys and finalizing the release)
1774
1853
  */
1775
1854
  writeBundle: function writeBundle() {
1776
- var _releaseInjectionSpan;
1777
-
1778
- (_releaseInjectionSpan = releaseInjectionSpan) === null || _releaseInjectionSpan === void 0 ? void 0 : _releaseInjectionSpan.finish();
1779
- var releasePipelineSpan = transaction && addSpanToTransaction({
1780
- hub: sentryHub,
1781
- parentSpan: transaction,
1782
- logger: logger,
1783
- cli: cli
1784
- }, "function.plugin.release", "Release pipeline");
1785
- sentryHub.addBreadcrumb({
1786
- category: "writeBundle:start",
1787
- level: "info"
1788
- });
1789
- var ctx = {
1790
- hub: sentryHub,
1791
- parentSpan: releasePipelineSpan,
1792
- logger: logger,
1793
- cli: cli
1794
- };
1795
- createNewRelease(internalOptions, ctx).then(function () {
1796
- return cleanArtifacts(internalOptions, ctx);
1797
- }).then(function () {
1798
- return uploadSourceMaps(internalOptions, ctx);
1799
- }).then(function () {
1800
- return setCommits(internalOptions, ctx);
1801
- }).then(function () {
1802
- return finalizeRelease(internalOptions, ctx);
1803
- }).then(function () {
1804
- return addDeploy(internalOptions, ctx);
1805
- }).then(function () {
1806
- var _transaction;
1807
-
1808
- return (_transaction = transaction) === null || _transaction === void 0 ? void 0 : _transaction.setStatus("ok");
1809
- })["catch"](function (e) {
1810
- var _transaction2;
1811
-
1812
- (_transaction2 = transaction) === null || _transaction2 === void 0 ? void 0 : _transaction2.setStatus("cancelled");
1813
- handleError(e, logger, internalOptions.errorHandler, sentryHub);
1814
- })["finally"](function () {
1815
- var _transaction3;
1816
-
1817
- sentryHub.addBreadcrumb({
1818
- category: "writeBundle:finish",
1819
- level: "info"
1820
- });
1821
- releasePipelineSpan === null || releasePipelineSpan === void 0 ? void 0 : releasePipelineSpan.finish();
1822
- (_transaction3 = transaction) === null || _transaction3 === void 0 ? void 0 : _transaction3.finish();
1823
- });
1855
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
1856
+ var _releaseInjectionSpan;
1857
+
1858
+ var releasePipelineSpan, ctx, releaseName, _transaction, _transaction2, _transaction3;
1859
+
1860
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
1861
+ while (1) {
1862
+ switch (_context3.prev = _context3.next) {
1863
+ case 0:
1864
+ logger.debug('Called "writeBundle"');
1865
+ (_releaseInjectionSpan = releaseInjectionSpan) === null || _releaseInjectionSpan === void 0 ? void 0 : _releaseInjectionSpan.finish();
1866
+ releasePipelineSpan = transaction && addSpanToTransaction({
1867
+ hub: sentryHub,
1868
+ parentSpan: transaction,
1869
+ logger: logger,
1870
+ cli: cli
1871
+ }, "function.plugin.release", "Release pipeline");
1872
+ sentryHub.addBreadcrumb({
1873
+ category: "writeBundle:start",
1874
+ level: "info"
1875
+ });
1876
+ ctx = {
1877
+ hub: sentryHub,
1878
+ parentSpan: releasePipelineSpan,
1879
+ logger: logger,
1880
+ cli: cli
1881
+ };
1882
+ _context3.next = 7;
1883
+ return releaseNamePromise;
1884
+
1885
+ case 7:
1886
+ releaseName = _context3.sent;
1887
+ _context3.prev = 8;
1888
+ _context3.next = 11;
1889
+ return createNewRelease(internalOptions, ctx, releaseName);
1890
+
1891
+ case 11:
1892
+ _context3.next = 13;
1893
+ return cleanArtifacts(internalOptions, ctx, releaseName);
1894
+
1895
+ case 13:
1896
+ _context3.next = 15;
1897
+ return uploadSourceMaps(internalOptions, ctx, releaseName);
1898
+
1899
+ case 15:
1900
+ _context3.next = 17;
1901
+ return setCommits(internalOptions, ctx, releaseName);
1902
+
1903
+ case 17:
1904
+ _context3.next = 19;
1905
+ return finalizeRelease(internalOptions, ctx, releaseName);
1906
+
1907
+ case 19:
1908
+ _context3.next = 21;
1909
+ return addDeploy(internalOptions, ctx, releaseName);
1910
+
1911
+ case 21:
1912
+ (_transaction = transaction) === null || _transaction === void 0 ? void 0 : _transaction.setStatus("ok");
1913
+ _context3.next = 28;
1914
+ break;
1915
+
1916
+ case 24:
1917
+ _context3.prev = 24;
1918
+ _context3.t0 = _context3["catch"](8);
1919
+ (_transaction2 = transaction) === null || _transaction2 === void 0 ? void 0 : _transaction2.setStatus("cancelled");
1920
+ handleError(_context3.t0, logger, internalOptions.errorHandler, sentryHub);
1921
+
1922
+ case 28:
1923
+ _context3.prev = 28;
1924
+ sentryHub.addBreadcrumb({
1925
+ category: "writeBundle:finish",
1926
+ level: "info"
1927
+ });
1928
+ releasePipelineSpan === null || releasePipelineSpan === void 0 ? void 0 : releasePipelineSpan.finish();
1929
+ (_transaction3 = transaction) === null || _transaction3 === void 0 ? void 0 : _transaction3.finish();
1930
+ _context3.next = 34;
1931
+ return sentryClient.flush().then(null, function () {
1932
+ logger.warn("Sending of telemetry failed");
1933
+ });
1934
+
1935
+ case 34:
1936
+ return _context3.finish(28);
1937
+
1938
+ case 35:
1939
+ case "end":
1940
+ return _context3.stop();
1941
+ }
1942
+ }
1943
+ }, _callee3, null, [[8, 24, 28, 35]]);
1944
+ }))();
1824
1945
  }
1825
1946
  };
1826
1947
  });
1827
1948
 
1828
- function handleError(error, logger, errorHandler, sentryHub) {
1829
- logger.error(error.message);
1949
+ function handleError(unknownError, logger, errorHandler, sentryHub) {
1950
+ if (unknownError instanceof Error) {
1951
+ logger.error(unknownError.message);
1952
+ } else {
1953
+ logger.error(String(unknownError));
1954
+ }
1830
1955
 
1831
1956
  if (sentryHub) {
1832
- captureMinimalError(error, sentryHub);
1957
+ captureMinimalError(unknownError, sentryHub);
1833
1958
  }
1834
1959
 
1835
1960
  if (errorHandler) {
1836
- errorHandler(error);
1961
+ if (unknownError instanceof Error) {
1962
+ errorHandler(unknownError);
1963
+ } else {
1964
+ errorHandler(new Error("An unknown error occured"));
1965
+ }
1837
1966
  } else {
1838
- throw error;
1967
+ throw unknownError;
1839
1968
  }
1840
1969
  }
1841
1970
  /**