@sentry/bundler-plugin-core 2.1.0 → 2.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
@@ -13,6 +13,7 @@ var crypto = require('crypto');
13
13
  var childProcess = require('child_process');
14
14
  var glob = require('glob');
15
15
  var util = require('util');
16
+ var utils = require('@sentry/utils');
16
17
  var node = require('@sentry/node');
17
18
 
18
19
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -704,16 +705,22 @@ function createDebugIdUploadFunction(_ref) {
704
705
  deleteFilesAfterUpload = _ref.deleteFilesAfterUpload;
705
706
  return /*#__PURE__*/function () {
706
707
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(buildArtifactPaths) {
707
- var folderToCleanUp, cliInstance, tmpUploadFolder, globAssets, debugIdChunkFilePaths, filePathsToDelete;
708
+ var artifactBundleUploadTransaction, folderToCleanUp, mkdtempSpan, tmpUploadFolder, globAssets, globSpan, globResult, debugIdChunkFilePaths, prepareSpan, files, stats, uploadSize, uploadSpan, cliInstance, deleteGlobSpan, filePathsToDelete, deleteSpan, cleanupSpan;
708
709
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
709
710
  while (1) switch (_context2.prev = _context2.next) {
710
711
  case 0:
711
- cliInstance = new SentryCli__default["default"](null, sentryCliOptions);
712
+ artifactBundleUploadTransaction = sentryHub.startTransaction({
713
+ name: "debug-id-sourcemap-upload"
714
+ });
712
715
  _context2.prev = 1;
713
- _context2.next = 4;
716
+ mkdtempSpan = artifactBundleUploadTransaction.startChild({
717
+ description: "mkdtemp"
718
+ });
719
+ _context2.next = 5;
714
720
  return fs__default["default"].promises.mkdtemp(path__default["default"].join(os__default["default"].tmpdir(), "sentry-bundler-plugin-upload-"));
715
- case 4:
721
+ case 5:
716
722
  tmpUploadFolder = _context2.sent;
723
+ mkdtempSpan.finish();
717
724
  folderToCleanUp = tmpUploadFolder;
718
725
  if (assets) {
719
726
  globAssets = assets;
@@ -721,33 +728,41 @@ function createDebugIdUploadFunction(_ref) {
721
728
  logger.debug("No `sourcemaps.assets` option provided, falling back to uploading detected build artifacts.");
722
729
  globAssets = buildArtifactPaths;
723
730
  }
724
- _context2.next = 9;
731
+ globSpan = artifactBundleUploadTransaction.startChild({
732
+ description: "glob"
733
+ });
734
+ _context2.next = 12;
725
735
  return glob.glob(globAssets, {
726
736
  absolute: true,
727
737
  nodir: true,
728
738
  ignore: ignore
729
739
  });
730
- case 9:
731
- debugIdChunkFilePaths = _context2.sent.filter(function (debugIdChunkFilePath) {
740
+ case 12:
741
+ globResult = _context2.sent;
742
+ globSpan.finish();
743
+ debugIdChunkFilePaths = globResult.filter(function (debugIdChunkFilePath) {
732
744
  return debugIdChunkFilePath.endsWith(".js") || debugIdChunkFilePath.endsWith(".mjs") || debugIdChunkFilePath.endsWith(".cjs");
733
745
  });
734
746
  if (!(Array.isArray(assets) && assets.length === 0)) {
735
- _context2.next = 14;
747
+ _context2.next = 19;
736
748
  break;
737
749
  }
738
750
  logger.debug("Empty `sourcemaps.assets` option provided. Will not upload sourcemaps with debug ID.");
739
- _context2.next = 22;
751
+ _context2.next = 41;
740
752
  break;
741
- case 14:
753
+ case 19:
742
754
  if (!(debugIdChunkFilePaths.length === 0)) {
743
- _context2.next = 18;
755
+ _context2.next = 23;
744
756
  break;
745
757
  }
746
758
  logger.warn("Didn't find any matching sources for debug ID upload. Please check the `sourcemaps.assets` option.");
747
- _context2.next = 22;
759
+ _context2.next = 41;
748
760
  break;
749
- case 18:
750
- _context2.next = 20;
761
+ case 23:
762
+ prepareSpan = artifactBundleUploadTransaction.startChild({
763
+ description: "prepare-bundles"
764
+ });
765
+ _context2.next = 26;
751
766
  return Promise.all(debugIdChunkFilePaths.map( /*#__PURE__*/function () {
752
767
  var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(chunkFilePath, chunkIndex) {
753
768
  return _regeneratorRuntime().wrap(function _callee$(_context) {
@@ -765,8 +780,35 @@ function createDebugIdUploadFunction(_ref) {
765
780
  return _ref3.apply(this, arguments);
766
781
  };
767
782
  }()));
768
- case 20:
769
- _context2.next = 22;
783
+ case 26:
784
+ prepareSpan.finish();
785
+ _context2.next = 29;
786
+ return fs__default["default"].promises.readdir(tmpUploadFolder);
787
+ case 29:
788
+ files = _context2.sent;
789
+ stats = files.map(function (file) {
790
+ return fs__default["default"].promises.stat(path__default["default"].join(tmpUploadFolder, file));
791
+ });
792
+ _context2.next = 33;
793
+ return Promise.all(stats);
794
+ case 33:
795
+ uploadSize = _context2.sent.reduce(function (accumulator, _ref4) {
796
+ var size = _ref4.size;
797
+ return accumulator + size;
798
+ }, 0);
799
+ artifactBundleUploadTransaction.setMeasurement("files", files.length, "none");
800
+ artifactBundleUploadTransaction.setMeasurement("upload_size", uploadSize, "byte");
801
+ uploadSpan = artifactBundleUploadTransaction.startChild({
802
+ description: "upload"
803
+ });
804
+ cliInstance = new SentryCli__default["default"](null, _objectSpread2(_objectSpread2({}, sentryCliOptions), {}, {
805
+ headers: _objectSpread2({
806
+ "sentry-trace": uploadSpan.toTraceparent(),
807
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
808
+ baggage: utils.dynamicSamplingContextToSentryBaggageHeader(artifactBundleUploadTransaction.getDynamicSamplingContext())
809
+ }, sentryCliOptions.headers)
810
+ }));
811
+ _context2.next = 40;
770
812
  return cliInstance.releases.uploadSourceMaps(releaseName !== null && releaseName !== void 0 ? releaseName : "undefined",
771
813
  // unfortunetly this needs a value for now but it will not matter since debug IDs overpower releases anyhow
772
814
  {
@@ -777,52 +819,71 @@ function createDebugIdUploadFunction(_ref) {
777
819
  }],
778
820
  useArtifactBundle: true
779
821
  });
780
- case 22:
822
+ case 40:
823
+ uploadSpan.finish();
824
+ case 41:
781
825
  if (!deleteFilesAfterUpload) {
782
- _context2.next = 29;
826
+ _context2.next = 52;
783
827
  break;
784
828
  }
785
- _context2.next = 25;
829
+ deleteGlobSpan = artifactBundleUploadTransaction.startChild({
830
+ description: "delete-glob"
831
+ });
832
+ _context2.next = 45;
786
833
  return glob.glob(deleteFilesAfterUpload, {
787
834
  absolute: true,
788
835
  nodir: true
789
836
  });
790
- case 25:
837
+ case 45:
791
838
  filePathsToDelete = _context2.sent;
839
+ deleteGlobSpan.finish();
792
840
  filePathsToDelete.forEach(function (filePathToDelete) {
793
841
  logger.debug("Deleting asset after upload: ".concat(filePathToDelete));
794
842
  });
795
- _context2.next = 29;
843
+ deleteSpan = artifactBundleUploadTransaction.startChild({
844
+ description: "delete-files-after-upload"
845
+ });
846
+ _context2.next = 51;
796
847
  return Promise.all(filePathsToDelete.map(function (filePathToDelete) {
797
848
  return fs__default["default"].promises.rm(filePathToDelete, {
798
849
  force: true
799
850
  });
800
851
  }));
801
- case 29:
802
- _context2.next = 37;
852
+ case 51:
853
+ deleteSpan.finish();
854
+ case 52:
855
+ _context2.next = 58;
803
856
  break;
804
- case 31:
805
- _context2.prev = 31;
857
+ case 54:
858
+ _context2.prev = 54;
806
859
  _context2.t0 = _context2["catch"](1);
807
- sentryHub.captureException('Error in "debugIdUploadPlugin" writeBundle hook');
808
- _context2.next = 36;
809
- return sentryClient.flush();
810
- case 36:
860
+ sentryHub.withScope(function (scope) {
861
+ scope.setSpan(artifactBundleUploadTransaction);
862
+ sentryHub.captureException('Error in "debugIdUploadPlugin" writeBundle hook');
863
+ });
811
864
  handleRecoverableError(_context2.t0);
812
- case 37:
813
- _context2.prev = 37;
865
+ case 58:
866
+ _context2.prev = 58;
814
867
  if (folderToCleanUp) {
868
+ cleanupSpan = artifactBundleUploadTransaction.startChild({
869
+ description: "cleanup"
870
+ });
815
871
  void fs__default["default"].promises.rm(folderToCleanUp, {
816
872
  recursive: true,
817
873
  force: true
818
874
  });
875
+ cleanupSpan.finish();
819
876
  }
820
- return _context2.finish(37);
821
- case 40:
877
+ artifactBundleUploadTransaction.finish();
878
+ _context2.next = 63;
879
+ return sentryClient.flush();
880
+ case 63:
881
+ return _context2.finish(58);
882
+ case 64:
822
883
  case "end":
823
884
  return _context2.stop();
824
885
  }
825
- }, _callee2, null, [[1, 31, 37, 40]]);
886
+ }, _callee2, null, [[1, 54, 58, 64]]);
826
887
  }));
827
888
  return function (_x) {
828
889
  return _ref2.apply(this, arguments);
@@ -870,7 +931,7 @@ function _prepareBundleForDebugIdUpload() {
870
931
  bundleContent += "\n//# debugId=".concat(debugId);
871
932
  writeSourceFilePromise = fs__default["default"].promises.writeFile(path__default["default"].join(uploadFolder, "".concat(uniqueUploadName, ".js")), bundleContent, "utf-8");
872
933
  writeSourceMapFilePromise = determineSourceMapPathFromBundle(bundleFilePath, bundleContent, logger).then( /*#__PURE__*/function () {
873
- var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(sourceMapPath) {
934
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(sourceMapPath) {
874
935
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
875
936
  while (1) switch (_context3.prev = _context3.next) {
876
937
  case 0:
@@ -889,7 +950,7 @@ function _prepareBundleForDebugIdUpload() {
889
950
  }, _callee3);
890
951
  }));
891
952
  return function (_x17) {
892
- return _ref4.apply(this, arguments);
953
+ return _ref5.apply(this, arguments);
893
954
  };
894
955
  }());
895
956
  return _context4.abrupt("return", Promise.all([writeSourceFilePromise, writeSourceMapFilePromise]));
@@ -953,7 +1014,7 @@ function _determineSourceMapPathFromBundle() {
953
1014
  _context5.t0 = _context5["catch"](8);
954
1015
  case 17:
955
1016
  // This is just a debug message because it can be quite spammy for some frameworks
956
- logger.debug("Could not determine source map path for bundle: ".concat(bundlePath));
1017
+ logger.debug("Could not determine source map path for bundle: ".concat(bundlePath, " - Did you turn on source map generation in your bundler?"));
957
1018
  return _context5.abrupt("return", undefined);
958
1019
  case 19:
959
1020
  case "end":
@@ -1138,29 +1199,31 @@ function releaseManagementPlugin(_ref) {
1138
1199
  }
1139
1200
 
1140
1201
  function telemetryPlugin(_ref) {
1141
- var sentryClient = _ref.sentryClient,
1142
- pluginExecutionTransaction = _ref.pluginExecutionTransaction,
1202
+ var sentryHub = _ref.sentryHub,
1203
+ sentryClient = _ref.sentryClient,
1143
1204
  shouldSendTelemetry = _ref.shouldSendTelemetry,
1144
1205
  logger = _ref.logger;
1145
1206
  return {
1146
1207
  name: "sentry-telemetry-plugin",
1147
1208
  buildStart: function buildStart() {
1148
- void shouldSendTelemetry.then(function (willSendTelemetry) {
1149
- if (willSendTelemetry) {
1150
- logger.info("Sending error and performance telemetry data to Sentry. To disable telemetry, set `options.telemetry` to `false`.");
1151
- }
1152
- });
1153
- pluginExecutionTransaction.startTimestamp = Date.now() / 1000;
1154
- },
1155
- writeBundle: function writeBundle() {
1156
1209
  return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
1157
1210
  return _regeneratorRuntime().wrap(function _callee$(_context) {
1158
1211
  while (1) switch (_context.prev = _context.next) {
1159
1212
  case 0:
1160
- pluginExecutionTransaction.finish();
1161
- _context.next = 3;
1162
- return sentryClient.flush();
1163
- case 3:
1213
+ _context.next = 2;
1214
+ return shouldSendTelemetry;
1215
+ case 2:
1216
+ if (!_context.sent) {
1217
+ _context.next = 7;
1218
+ break;
1219
+ }
1220
+ logger.info("Sending error and performance telemetry data to Sentry. To disable telemetry, set `options.telemetry` to `false`.");
1221
+ sentryHub.startTransaction({
1222
+ name: "Sentry Bundler Plugin execution"
1223
+ }).finish();
1224
+ _context.next = 7;
1225
+ return sentryClient.flush(3000);
1226
+ case 7:
1164
1227
  case "end":
1165
1228
  return _context.stop();
1166
1229
  }
@@ -1221,7 +1284,7 @@ function createSentryInstance(options, shouldSendTelemetry, bundler) {
1221
1284
  dsn: "https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737",
1222
1285
  tracesSampleRate: 1,
1223
1286
  sampleRate: 1,
1224
- release: "2.1.0",
1287
+ release: "2.2.1",
1225
1288
  integrations: [],
1226
1289
  tracePropagationTargets: ["sentry.io/api"],
1227
1290
  stackParser: node.defaultStackParser,
@@ -1287,35 +1350,27 @@ function setTelemetryDataOnHub(options, hub, bundler) {
1287
1350
  release = options.release,
1288
1351
  errorHandler = options.errorHandler,
1289
1352
  sourcemaps = options.sourcemaps;
1353
+ hub.setTag("upload-legacy-sourcemaps", !!release.uploadLegacySourcemaps);
1290
1354
  if (release.uploadLegacySourcemaps) {
1291
1355
  hub.setTag("uploadLegacySourcemapsEntries", Array.isArray(release.uploadLegacySourcemaps) ? release.uploadLegacySourcemaps.length : 1);
1292
1356
  }
1293
1357
 
1294
1358
  // Optional release pipeline steps
1295
- if (release.cleanArtifacts) {
1296
- hub.setTag("clean-artifacts", true);
1297
- }
1359
+ hub.setTag("clean-artifacts", release.cleanArtifacts);
1298
1360
  if (release.setCommits) {
1299
1361
  hub.setTag("set-commits", release.setCommits.auto === true ? "auto" : "manual");
1362
+ } else {
1363
+ hub.setTag("set-commits", "undefined");
1300
1364
  }
1301
- if (release.finalize) {
1302
- hub.setTag("finalize-release", true);
1303
- }
1304
- if (release.deploy) {
1305
- hub.setTag("add-deploy", true);
1306
- }
1365
+ hub.setTag("finalize-release", release.finalize);
1366
+ hub.setTag("deploy-options", !!release.deploy);
1307
1367
 
1308
1368
  // Miscelaneous options
1309
- if (errorHandler) {
1310
- hub.setTag("error-handler", "custom");
1311
- }
1312
- if (sourcemaps !== null && sourcemaps !== void 0 && sourcemaps.assets) {
1313
- hub.setTag("debug-id-upload", true);
1314
- }
1315
- if (sourcemaps !== null && sourcemaps !== void 0 && sourcemaps.deleteFilesAfterUpload) {
1316
- hub.setTag("delete-after-upload", true);
1317
- }
1369
+ hub.setTag("custom-error-handler", !!errorHandler);
1370
+ hub.setTag("sourcemaps-assets", !!(sourcemaps !== null && sourcemaps !== void 0 && sourcemaps.assets));
1371
+ hub.setTag("delete-after-upload", !!(sourcemaps !== null && sourcemaps !== void 0 && sourcemaps.deleteFilesAfterUpload));
1318
1372
  hub.setTag("node", process.version);
1373
+ hub.setTag("platform", process.platform);
1319
1374
  hub.setTags({
1320
1375
  organization: org,
1321
1376
  project: project,
@@ -1428,25 +1483,44 @@ function sentryUnpluginFactory(_ref) {
1428
1483
  var _createSentryInstance = createSentryInstance(options, shouldSendTelemetry, unpluginMetaContext.framework),
1429
1484
  sentryHub = _createSentryInstance.sentryHub,
1430
1485
  sentryClient = _createSentryInstance.sentryClient;
1431
- var pluginExecutionTransaction = sentryHub.startTransaction({
1432
- name: "Sentry Bundler Plugin execution"
1486
+ var sentrySession = sentryHub.startSession();
1487
+ sentryHub.captureSession();
1488
+ var sentEndSession = false; // Just to prevent infinite loops with beforeExit, which is called whenever the event loop empties out
1489
+ // We also need to manually end sesisons on errors because beforeExit is not called on crashes
1490
+ process.on("beforeExit", function () {
1491
+ if (!sentEndSession) {
1492
+ sentryHub.endSession();
1493
+ sentEndSession = true;
1494
+ }
1433
1495
  });
1434
- sentryHub.getScope().setSpan(pluginExecutionTransaction);
1435
1496
  var logger = createLogger({
1436
1497
  prefix: "[sentry-".concat(unpluginMetaContext.framework, "-plugin]"),
1437
1498
  silent: options.silent,
1438
1499
  debug: options.debug
1439
1500
  });
1501
+
1502
+ // Set the User-Agent that Sentry CLI will use when interacting with Sentry
1503
+ process.env["SENTRY_PIPELINE"] = "".concat(unpluginMetaContext.framework, "-plugin/", "2.2.1");
1440
1504
  function handleRecoverableError(unknownError) {
1441
- pluginExecutionTransaction.setStatus("internal_error");
1442
- if (options.errorHandler) {
1443
- if (unknownError instanceof Error) {
1444
- options.errorHandler(unknownError);
1505
+ sentrySession.status = "abnormal";
1506
+ try {
1507
+ if (options.errorHandler) {
1508
+ try {
1509
+ if (unknownError instanceof Error) {
1510
+ options.errorHandler(unknownError);
1511
+ } else {
1512
+ options.errorHandler(new Error("An unknown error occured"));
1513
+ }
1514
+ } catch (e) {
1515
+ sentrySession.status = "crashed";
1516
+ throw e;
1517
+ }
1445
1518
  } else {
1446
- options.errorHandler(new Error("An unknown error occured"));
1519
+ sentrySession.status = "crashed";
1520
+ throw unknownError;
1447
1521
  }
1448
- } else {
1449
- throw unknownError;
1522
+ } finally {
1523
+ sentryHub.endSession();
1450
1524
  }
1451
1525
  }
1452
1526
  if (!validateOptions(options, logger)) {
@@ -1457,10 +1531,10 @@ function sentryUnpluginFactory(_ref) {
1457
1531
  }
1458
1532
  var plugins = [];
1459
1533
  plugins.push(telemetryPlugin({
1460
- pluginExecutionTransaction: pluginExecutionTransaction,
1534
+ sentryClient: sentryClient,
1535
+ sentryHub: sentryHub,
1461
1536
  logger: logger,
1462
- shouldSendTelemetry: shouldSendTelemetry,
1463
- sentryClient: sentryClient
1537
+ shouldSendTelemetry: shouldSendTelemetry
1464
1538
  }));
1465
1539
  if (!options.release.inject) {
1466
1540
  logger.debug("Release injection disabled via `release.inject` option. Will not inject release.");
@@ -1630,11 +1704,10 @@ function createRollupDebugIdInjectionHooks() {
1630
1704
  var commentUseStrictRegex =
1631
1705
  // Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
1632
1706
  /^(?:\s*|\/\*(?:.|\r|\n)*\*\/|\/\/.*[\n\r])*(?:"[^"]*";|'[^']*';)?/;
1633
- if ((_code$match = code.match(commentUseStrictRegex)) !== null && _code$match !== void 0 && _code$match[0]) {
1707
+ var match = (_code$match = code.match(commentUseStrictRegex)) === null || _code$match === void 0 ? void 0 : _code$match[0];
1708
+ if (match) {
1634
1709
  // Add injected code after any comments or "use strict" at the beginning of the bundle.
1635
- ms.replace(commentUseStrictRegex, function (match) {
1636
- return "".concat(match).concat(codeToInject);
1637
- });
1710
+ ms.appendLeft(match.length, codeToInject);
1638
1711
  } else {
1639
1712
  // ms.replace() doesn't work when there is an empty string match (which happens if
1640
1713
  // there is neither, a comment, nor a "use strict" at the top of the chunk) so we