@sentry/bundler-plugin-core 0.0.1-alpha.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -4,66 +4,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var unplugin$1 = require('unplugin');
6
6
  var MagicString = require('magic-string');
7
- var child_process = require('child_process');
8
- var axios = require('axios');
9
- var FormData = require('form-data');
10
7
  var node = require('@sentry/node');
11
- var path = require('path');
12
- var fs = require('fs');
13
8
  require('@sentry/tracing');
9
+ var SentryCli = require('@sentry/cli');
14
10
 
15
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
16
12
 
17
- function _interopNamespace(e) {
18
- if (e && e.__esModule) return e;
19
- var n = Object.create(null);
20
- if (e) {
21
- Object.keys(e).forEach(function (k) {
22
- if (k !== 'default') {
23
- var d = Object.getOwnPropertyDescriptor(e, k);
24
- Object.defineProperty(n, k, d.get ? d : {
25
- enumerable: true,
26
- get: function () { return e[k]; }
27
- });
28
- }
29
- });
30
- }
31
- n["default"] = e;
32
- return Object.freeze(n);
33
- }
34
-
35
13
  var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
36
- var child_process__namespace = /*#__PURE__*/_interopNamespace(child_process);
37
- var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
38
- var FormData__default = /*#__PURE__*/_interopDefaultLegacy(FormData);
39
- var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
40
- var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
41
-
42
- function ownKeys(object, enumerableOnly) {
43
- var keys = Object.keys(object);
44
-
45
- if (Object.getOwnPropertySymbols) {
46
- var symbols = Object.getOwnPropertySymbols(object);
47
- enumerableOnly && (symbols = symbols.filter(function (sym) {
48
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
49
- })), keys.push.apply(keys, symbols);
50
- }
51
-
52
- return keys;
53
- }
54
-
55
- function _objectSpread2(target) {
56
- for (var i = 1; i < arguments.length; i++) {
57
- var source = null != arguments[i] ? arguments[i] : {};
58
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
59
- _defineProperty(target, key, source[key]);
60
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
61
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
62
- });
63
- }
64
-
65
- return target;
66
- }
14
+ var SentryCli__default = /*#__PURE__*/_interopDefaultLegacy(SentryCli);
67
15
 
68
16
  function _regeneratorRuntime() {
69
17
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
@@ -410,6 +358,16 @@ function _regeneratorRuntime() {
410
358
  }, exports;
411
359
  }
412
360
 
361
+ function _typeof(obj) {
362
+ "@babel/helpers - typeof";
363
+
364
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
365
+ return typeof obj;
366
+ } : function (obj) {
367
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
368
+ }, _typeof(obj);
369
+ }
370
+
413
371
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
414
372
  try {
415
373
  var info = gen[key](arg);
@@ -446,85 +404,566 @@ function _asyncToGenerator(fn) {
446
404
  };
447
405
  }
448
406
 
449
- function _defineProperty(obj, key, value) {
450
- if (key in obj) {
451
- Object.defineProperty(obj, key, {
452
- value: value,
453
- enumerable: true,
454
- configurable: true,
455
- writable: true
407
+ /** Internal global with common properties and Sentry extensions */
408
+
409
+ // The code below for 'isGlobalObj' and 'GLOBAL_OBJ' was copied from core-js before modification
410
+ // https://github.com/zloirock/core-js/blob/1b944df55282cdc99c90db5f49eb0b6eda2cc0a3/packages/core-js/internals/global.js
411
+ // core-js has the following licence:
412
+ //
413
+ // Copyright (c) 2014-2022 Denis Pushkarev
414
+ //
415
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
416
+ // of this software and associated documentation files (the "Software"), to deal
417
+ // in the Software without restriction, including without limitation the rights
418
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
419
+ // copies of the Software, and to permit persons to whom the Software is
420
+ // furnished to do so, subject to the following conditions:
421
+ //
422
+ // The above copyright notice and this permission notice shall be included in
423
+ // all copies or substantial portions of the Software.
424
+ //
425
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
426
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
427
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
428
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
429
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
430
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
431
+ // THE SOFTWARE.
432
+
433
+ /** Returns 'obj' if it's the global object, otherwise returns undefined */
434
+ function isGlobalObj(obj) {
435
+ return obj && obj.Math == Math ? obj : undefined;
436
+ }
437
+
438
+ /** Get's the global object for the current JavaScript runtime */
439
+ const GLOBAL_OBJ =
440
+ (typeof globalThis == 'object' && isGlobalObj(globalThis)) ||
441
+ // eslint-disable-next-line no-restricted-globals
442
+ (typeof window == 'object' && isGlobalObj(window)) ||
443
+ (typeof self == 'object' && isGlobalObj(self)) ||
444
+ (typeof global == 'object' && isGlobalObj(global)) ||
445
+ (function () {
446
+ return this;
447
+ })() ||
448
+ {};
449
+
450
+ /**
451
+ * @deprecated Use GLOBAL_OBJ instead or WINDOW from @sentry/browser. This will be removed in v8
452
+ */
453
+ function getGlobalObject() {
454
+ return GLOBAL_OBJ ;
455
+ }
456
+
457
+ /**
458
+ * Returns a global singleton contained in the global `__SENTRY__` object.
459
+ *
460
+ * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
461
+ * function and added to the `__SENTRY__` object.
462
+ *
463
+ * @param name name of the global singleton on __SENTRY__
464
+ * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
465
+ * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value
466
+ * @returns the singleton
467
+ */
468
+ function getGlobalSingleton(name, creator, obj) {
469
+ const gbl = (obj || GLOBAL_OBJ) ;
470
+ const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});
471
+ const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
472
+ return singleton;
473
+ }
474
+
475
+ /** Prefix for logging strings */
476
+ const PREFIX = 'Sentry Logger ';
477
+
478
+ const CONSOLE_LEVELS = ['debug', 'info', 'warn', 'error', 'log', 'assert', 'trace'] ;
479
+
480
+ /**
481
+ * Temporarily disable sentry console instrumentations.
482
+ *
483
+ * @param callback The function to run against the original `console` messages
484
+ * @returns The results of the callback
485
+ */
486
+ function consoleSandbox(callback) {
487
+ if (!('console' in GLOBAL_OBJ)) {
488
+ return callback();
489
+ }
490
+
491
+ const originalConsole = GLOBAL_OBJ.console ;
492
+ const wrappedLevels = {};
493
+
494
+ // Restore all wrapped console methods
495
+ CONSOLE_LEVELS.forEach(level => {
496
+ // TODO(v7): Remove this check as it's only needed for Node 6
497
+ const originalWrappedFunc =
498
+ originalConsole[level] && (originalConsole[level] ).__sentry_original__;
499
+ if (level in originalConsole && originalWrappedFunc) {
500
+ wrappedLevels[level] = originalConsole[level] ;
501
+ originalConsole[level] = originalWrappedFunc ;
502
+ }
503
+ });
504
+
505
+ try {
506
+ return callback();
507
+ } finally {
508
+ // Revert restoration to wrapped state
509
+ Object.keys(wrappedLevels).forEach(level => {
510
+ originalConsole[level] = wrappedLevels[level ];
511
+ });
512
+ }
513
+ }
514
+
515
+ function makeLogger() {
516
+ let enabled = false;
517
+ const logger = {
518
+ enable: () => {
519
+ enabled = true;
520
+ },
521
+ disable: () => {
522
+ enabled = false;
523
+ },
524
+ };
525
+
526
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
527
+ CONSOLE_LEVELS.forEach(name => {
528
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
529
+ logger[name] = (...args) => {
530
+ if (enabled) {
531
+ consoleSandbox(() => {
532
+ GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);
533
+ });
534
+ }
535
+ };
456
536
  });
457
537
  } else {
458
- obj[key] = value;
538
+ CONSOLE_LEVELS.forEach(name => {
539
+ logger[name] = () => undefined;
540
+ });
459
541
  }
460
542
 
461
- return obj;
543
+ return logger ;
544
+ }
545
+
546
+ // Ensure we only have a single logger instance, even if multiple versions of @sentry/utils are being used
547
+ let logger;
548
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
549
+ logger = getGlobalSingleton('logger', makeLogger);
550
+ } else {
551
+ logger = makeLogger();
462
552
  }
463
553
 
464
- function getGitBranchHead() {
554
+ /*
555
+ * This module exists for optimizations in the build process through rollup and terser. We define some global
556
+ * constants, which can be overridden during build. By guarding certain pieces of code with functions that return these
557
+ * constants, we can control whether or not they appear in the final bundle. (Any code guarded by a false condition will
558
+ * never run, and will hence be dropped during treeshaking.) The two primary uses for this are stripping out calls to
559
+ * `logger` and preventing node-related code from appearing in browser bundles.
560
+ *
561
+ * Attention:
562
+ * This file should not be used to define constants/flags that are intended to be used for tree-shaking conducted by
563
+ * users. These fags should live in their respective packages, as we identified user tooling (specifically webpack)
564
+ * having issues tree-shaking these constants across package boundaries.
565
+ * An example for this is the __SENTRY_DEBUG__ constant. It is declared in each package individually because we want
566
+ * users to be able to shake away expressions that it guards.
567
+ */
568
+
569
+ /**
570
+ * Figures out if we're building a browser bundle.
571
+ *
572
+ * @returns true if this is a browser bundle build.
573
+ */
574
+ function isBrowserBundle() {
575
+ return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
576
+ }
577
+
578
+ /**
579
+ * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
580
+ * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
581
+ */
582
+
583
+ /**
584
+ * Checks whether we're in the Node.js or Browser environment
585
+ *
586
+ * @returns Answer to given question
587
+ */
588
+ function isNodeEnv() {
589
+ // explicitly check for browser bundles as those can be optimized statically
590
+ // by terser/rollup.
591
+ return (
592
+ !isBrowserBundle() &&
593
+ Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'
594
+ );
595
+ }
596
+
597
+ /**
598
+ * Requires a module which is protected against bundler minification.
599
+ *
600
+ * @param request The module path to resolve
601
+ */
602
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
603
+ function dynamicRequire(mod, request) {
604
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
605
+ return mod.require(request);
606
+ }
607
+
608
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
609
+
610
+ /** SyncPromise internal states */
611
+ var States; (function (States) {
612
+ /** Pending */
613
+ const PENDING = 0; States[States["PENDING"] = PENDING] = "PENDING";
614
+ /** Resolved / OK */
615
+ const RESOLVED = 1; States[States["RESOLVED"] = RESOLVED] = "RESOLVED";
616
+ /** Rejected / Error */
617
+ const REJECTED = 2; States[States["REJECTED"] = REJECTED] = "REJECTED";
618
+ })(States || (States = {}));
619
+
620
+ // eslint-disable-next-line deprecation/deprecation
621
+ const WINDOW = getGlobalObject();
622
+
623
+ /**
624
+ * An object that can return the current timestamp in seconds since the UNIX epoch.
625
+ */
626
+
627
+ /**
628
+ * A TimestampSource implementation for environments that do not support the Performance Web API natively.
629
+ *
630
+ * Note that this TimestampSource does not use a monotonic clock. A call to `nowSeconds` may return a timestamp earlier
631
+ * than a previously returned value. We do not try to emulate a monotonic behavior in order to facilitate debugging. It
632
+ * is more obvious to explain "why does my span have negative duration" than "why my spans have zero duration".
633
+ */
634
+ const dateTimestampSource = {
635
+ nowSeconds: () => Date.now() / 1000,
636
+ };
637
+
638
+ /**
639
+ * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}
640
+ * for accessing a high-resolution monotonic clock.
641
+ */
642
+
643
+ /**
644
+ * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not
645
+ * support the API.
646
+ *
647
+ * Wrapping the native API works around differences in behavior from different browsers.
648
+ */
649
+ function getBrowserPerformance() {
650
+ const { performance } = WINDOW;
651
+ if (!performance || !performance.now) {
652
+ return undefined;
653
+ }
654
+
655
+ // Replace performance.timeOrigin with our own timeOrigin based on Date.now().
656
+ //
657
+ // This is a partial workaround for browsers reporting performance.timeOrigin such that performance.timeOrigin +
658
+ // performance.now() gives a date arbitrarily in the past.
659
+ //
660
+ // Additionally, computing timeOrigin in this way fills the gap for browsers where performance.timeOrigin is
661
+ // undefined.
662
+ //
663
+ // The assumption that performance.timeOrigin + performance.now() ~= Date.now() is flawed, but we depend on it to
664
+ // interact with data coming out of performance entries.
665
+ //
666
+ // Note that despite recommendations against it in the spec, browsers implement the Performance API with a clock that
667
+ // might stop when the computer is asleep (and perhaps under other circumstances). Such behavior causes
668
+ // performance.timeOrigin + performance.now() to have an arbitrary skew over Date.now(). In laptop computers, we have
669
+ // observed skews that can be as long as days, weeks or months.
670
+ //
671
+ // See https://github.com/getsentry/sentry-javascript/issues/2590.
672
+ //
673
+ // BUG: despite our best intentions, this workaround has its limitations. It mostly addresses timings of pageload
674
+ // transactions, but ignores the skew built up over time that can aversely affect timestamps of navigation
675
+ // transactions of long-lived web pages.
676
+ const timeOrigin = Date.now() - performance.now();
677
+
678
+ return {
679
+ now: () => performance.now(),
680
+ timeOrigin,
681
+ };
682
+ }
683
+
684
+ /**
685
+ * Returns the native Performance API implementation from Node.js. Returns undefined in old Node.js versions that don't
686
+ * implement the API.
687
+ */
688
+ function getNodePerformance() {
465
689
  try {
466
- return child_process__namespace.execSync("git rev-parse HEAD").toString().trim();
467
- } catch (e) {
468
- // no git installed
690
+ const perfHooks = dynamicRequire(module, 'perf_hooks') ;
691
+ return perfHooks.performance;
692
+ } catch (_) {
469
693
  return undefined;
470
694
  }
471
695
  }
472
696
 
473
- function getReleaseName(releaseName) {
474
- if (releaseName) {
475
- return releaseName;
476
- } // Env var SENTRY_RELEASE takes presendace over other env vars listed below
477
- // this is why we are looking for it before proceeding with others
697
+ /**
698
+ * The Performance API implementation for the current platform, if available.
699
+ */
700
+ const platformPerformance = isNodeEnv() ? getNodePerformance() : getBrowserPerformance();
701
+
702
+ const timestampSource =
703
+ platformPerformance === undefined
704
+ ? dateTimestampSource
705
+ : {
706
+ nowSeconds: () => (platformPerformance.timeOrigin + platformPerformance.now()) / 1000,
707
+ };
708
+
709
+ /**
710
+ * Returns a timestamp in seconds since the UNIX epoch using the Date API.
711
+ */
712
+ dateTimestampSource.nowSeconds.bind(dateTimestampSource);
478
713
 
714
+ /**
715
+ * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the
716
+ * availability of the Performance API.
717
+ *
718
+ * See `usingPerformanceAPI` to test whether the Performance API is used.
719
+ *
720
+ * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is
721
+ * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The
722
+ * skew can grow to arbitrary amounts like days, weeks or months.
723
+ * See https://github.com/getsentry/sentry-javascript/issues/2590.
724
+ */
725
+ timestampSource.nowSeconds.bind(timestampSource);
479
726
 
480
- if (process.env["SENTRY_RELEASE"]) {
481
- return process.env["SENTRY_RELEASE"];
727
+ /**
728
+ * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the
729
+ * performance API is available.
730
+ */
731
+ (() => {
732
+ // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or
733
+ // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin
734
+ // data as reliable if they are within a reasonable threshold of the current time.
735
+
736
+ const { performance } = WINDOW;
737
+ if (!performance || !performance.now) {
738
+ return undefined;
739
+ }
740
+
741
+ const threshold = 3600 * 1000;
742
+ const performanceNow = performance.now();
743
+ const dateNow = Date.now();
744
+
745
+ // if timeOrigin isn't available set delta to threshold so it isn't used
746
+ const timeOriginDelta = performance.timeOrigin
747
+ ? Math.abs(performance.timeOrigin + performanceNow - dateNow)
748
+ : threshold;
749
+ const timeOriginIsReliable = timeOriginDelta < threshold;
750
+
751
+ // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
752
+ // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
753
+ // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
754
+ // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
755
+ // Date API.
756
+ // eslint-disable-next-line deprecation/deprecation
757
+ const navigationStart = performance.timing && performance.timing.navigationStart;
758
+ const hasNavigationStart = typeof navigationStart === 'number';
759
+ // if navigationStart isn't available set delta to threshold so it isn't used
760
+ const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;
761
+ const navigationStartIsReliable = navigationStartDelta < threshold;
762
+
763
+ if (timeOriginIsReliable || navigationStartIsReliable) {
764
+ // Use the more reliable time origin
765
+ if (timeOriginDelta <= navigationStartDelta) {
766
+ return performance.timeOrigin;
767
+ } else {
768
+ return navigationStart;
769
+ }
482
770
  }
771
+ return dateNow;
772
+ })();
773
+
774
+ /**
775
+ * Checks whether the given input is already an array, and if it isn't, wraps it in one.
776
+ *
777
+ * @param maybeArray Input to turn into an array, if necessary
778
+ * @returns The input, if already an array, or an array with the input as the only element, if not
779
+ */
780
+ function arrayify(maybeArray) {
781
+ return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
782
+ }
783
+
784
+ var SENTRY_SAAS_URL = "https://sentry.io";
785
+ function normalizeUserOptions(userOptions) {
786
+ var _userOptions$org, _userOptions$project, _ref, _userOptions$release, _ref2, _userOptions$url, _userOptions$finalize, _userOptions$cleanArt, _userOptions$dryRun, _userOptions$debug, _userOptions$silent, _userOptions$telemetr, _userOptions$injectRe, _ref3, _userOptions$customHe;
787
+
788
+ var options = {
789
+ // include is the only strictly required option
790
+ // (normalizeInclude needs all userOptions to access top-level include options)
791
+ include: normalizeInclude(userOptions),
792
+ // These options must be set b/c we need them for release injection.
793
+ // They can also be set as environment variables. Technically, they
794
+ // could be set in the config file but this would be too late for
795
+ // release injection because we only pass the config file path
796
+ // to the CLI
797
+ org: (_userOptions$org = userOptions.org) !== null && _userOptions$org !== void 0 ? _userOptions$org : process.env["SENTRY_ORG"],
798
+ project: (_userOptions$project = userOptions.project) !== null && _userOptions$project !== void 0 ? _userOptions$project : process.env["SENTRY_PROJECT"],
799
+ // Falling back to the empty string here b/c at a later point, we use
800
+ // Sentry CLI to determine a release if none was specified via options
801
+ // or env vars. In case we don't find one, we'll bail at that point.
802
+ release: (_ref = (_userOptions$release = userOptions.release) !== null && _userOptions$release !== void 0 ? _userOptions$release : process.env["SENTRY_RELEASE"]) !== null && _ref !== void 0 ? _ref : "",
803
+ // We technically don't need the URL for anything release-specific
804
+ // but we want to make sure that we're only sending Sentry data
805
+ // of SaaS customers. Hence we want to read it anyway.
806
+ url: (_ref2 = (_userOptions$url = userOptions.url) !== null && _userOptions$url !== void 0 ? _userOptions$url : process.env["SENTRY_URL"]) !== null && _ref2 !== void 0 ? _ref2 : SENTRY_SAAS_URL,
807
+ // Options with default values
808
+ finalize: (_userOptions$finalize = userOptions.finalize) !== null && _userOptions$finalize !== void 0 ? _userOptions$finalize : true,
809
+ cleanArtifacts: (_userOptions$cleanArt = userOptions.cleanArtifacts) !== null && _userOptions$cleanArt !== void 0 ? _userOptions$cleanArt : false,
810
+ dryRun: (_userOptions$dryRun = userOptions.dryRun) !== null && _userOptions$dryRun !== void 0 ? _userOptions$dryRun : false,
811
+ debug: (_userOptions$debug = userOptions.debug) !== null && _userOptions$debug !== void 0 ? _userOptions$debug : false,
812
+ silent: (_userOptions$silent = userOptions.silent) !== null && _userOptions$silent !== void 0 ? _userOptions$silent : false,
813
+ telemetry: (_userOptions$telemetr = userOptions.telemetry) !== null && _userOptions$telemetr !== void 0 ? _userOptions$telemetr : true,
814
+ injectReleasesMap: (_userOptions$injectRe = userOptions.injectReleasesMap) !== null && _userOptions$injectRe !== void 0 ? _userOptions$injectRe : false,
815
+ // These options and can also be set via env variables or the config file.
816
+ // If they're set in the options, we simply pass them to the CLI constructor.
817
+ // Sentry CLI will internally query env variables and read its config file if
818
+ // the passed options are undefined.
819
+ authToken: userOptions.authToken,
820
+ // env var: `SENTRY_AUTH_TOKEN`
821
+ // CLI v1 (and the "old" webpack plugin) use `CUSTOM_HEADER`,
822
+ // but CLI v2 uses `SENTRY_HEADER` (which is also better aligned with other naming)
823
+ // In the spirit of maximum compatibility, we allow both here.
824
+ customHeader: (_ref3 = (_userOptions$customHe = userOptions.customHeader) !== null && _userOptions$customHe !== void 0 ? _userOptions$customHe : process.env["SENTRY_HEADER"]) !== null && _ref3 !== void 0 ? _ref3 : process.env["CUSTOM_HEADER"],
825
+ vcsRemote: userOptions.vcsRemote,
826
+ // env var: `SENTRY_VSC_REMOTE`
827
+ // Optional options
828
+ setCommits: userOptions.setCommits,
829
+ deploy: userOptions.deploy,
830
+ releaseInjectionTargets: normalizeReleaseInjectionTargets(userOptions.releaseInjectionTargets),
831
+ dist: userOptions.dist,
832
+ errorHandler: userOptions.errorHandler,
833
+ 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;
840
+ return options;
841
+ }
842
+ /**
843
+ * Converts the user-facing `releaseInjectionTargets` option to the internal
844
+ * `releaseInjectionTargets` option
845
+ */
846
+
847
+ function normalizeReleaseInjectionTargets(userReleaseInjectionTargets) {
848
+ if (userReleaseInjectionTargets === undefined) {
849
+ return undefined;
850
+ } else if (typeof userReleaseInjectionTargets === "function") {
851
+ return userReleaseInjectionTargets;
852
+ } else {
853
+ return arrayify(userReleaseInjectionTargets);
854
+ }
855
+ }
856
+ /**
857
+ * Converts the user-facing `include` option to the internal `include` option,
858
+ * resulting in an array of `InternalIncludeEntry` objects. This later on lets us
859
+ * work with only one type of include data structure instead of multiple.
860
+ *
861
+ * During the process, we hoist top-level include options (e.g. urlPrefix) into each
862
+ * object if they were not alrady specified in an `IncludeEntry`, making every object
863
+ * fully self-contained. This is also the reason why we pass the entire options
864
+ * object and not just `include`.
865
+ *
866
+ * @param userOptions the entire user-facing `options` object
867
+ *
868
+ * @return an array of `InternalIncludeEntry` objects.
869
+ */
870
+
871
+
872
+ function normalizeInclude(userOptions) {
873
+ return arrayify(userOptions.include).map(function (includeItem) {
874
+ return typeof includeItem === "string" ? {
875
+ paths: [includeItem]
876
+ } : includeItem;
877
+ }).map(function (userIncludeEntry) {
878
+ return normalizeIncludeEntry(userOptions, userIncludeEntry);
879
+ });
880
+ }
881
+ /**
882
+ * Besides array-ifying the `ignore` option, this function hoists top level options into the items of the `include`
883
+ * option. This is to simplify the handling of of the `include` items later on.
884
+ */
885
+
886
+
887
+ function normalizeIncludeEntry(userOptions, includeEntry) {
888
+ var _ref4, _includeEntry$ignore, _ref5, _includeEntry$ext, _includeEntry$ignoreF, _includeEntry$urlPref, _includeEntry$urlSuff, _includeEntry$stripPr, _ref6, _includeEntry$stripCo, _ref7, _includeEntry$sourceM, _ref8, _includeEntry$rewrite, _ref9, _includeEntry$validat;
483
889
 
484
- var ENV_VARS = ["SOURCE_VERSION", // Heroku #1 https://devcenter.heroku.com/changelog-items/630
485
- "HEROKU_SLUG_COMMIT", // Heroku #2: https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases
486
- "CODEBUILD_RESOLVED_SOURCE_VERSION", // AWS CodeBuild: https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
487
- "CIRCLE_SHA1", // CircleCI: https://circleci.com/docs/2.0/env-vars/
488
- "VERCEL_GIT_COMMIT_SHA" // Vercel docs: https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables
489
- ];
490
- var releaseFromEnvironmentVar = ENV_VARS.find(function (key) {
491
- return Object.keys(process.env).includes(key);
890
+ var ignoreOption = (_ref4 = (_includeEntry$ignore = includeEntry.ignore) !== null && _includeEntry$ignore !== void 0 ? _includeEntry$ignore : userOptions.ignore) !== null && _ref4 !== void 0 ? _ref4 : ["node_modules"];
891
+ var ignore = Array.isArray(ignoreOption) ? ignoreOption : [ignoreOption]; // We're prefixing all entries in the `ext` option with a `.` (if it isn't already) to align with Node.js' `path.extname()`
892
+
893
+ var ext = (_ref5 = (_includeEntry$ext = includeEntry.ext) !== null && _includeEntry$ext !== void 0 ? _includeEntry$ext : userOptions.ext) !== null && _ref5 !== void 0 ? _ref5 : ["js", "map", "jsbundle", "bundle"];
894
+ var dotPrefixedExt = ext.map(function (extension) {
895
+ return ".".concat(extension.replace(/^\./, ""));
492
896
  });
897
+ return {
898
+ paths: includeEntry.paths,
899
+ ignore: ignore,
900
+ ignoreFile: (_includeEntry$ignoreF = includeEntry.ignoreFile) !== null && _includeEntry$ignoreF !== void 0 ? _includeEntry$ignoreF : userOptions.ignoreFile,
901
+ ext: dotPrefixedExt,
902
+ urlPrefix: (_includeEntry$urlPref = includeEntry.urlPrefix) !== null && _includeEntry$urlPref !== void 0 ? _includeEntry$urlPref : userOptions.urlPrefix,
903
+ urlSuffix: (_includeEntry$urlSuff = includeEntry.urlSuffix) !== null && _includeEntry$urlSuff !== void 0 ? _includeEntry$urlSuff : userOptions.urlSuffix,
904
+ stripPrefix: (_includeEntry$stripPr = includeEntry.stripPrefix) !== null && _includeEntry$stripPr !== void 0 ? _includeEntry$stripPr : userOptions.stripPrefix,
905
+ stripCommonPrefix: (_ref6 = (_includeEntry$stripCo = includeEntry.stripCommonPrefix) !== null && _includeEntry$stripCo !== void 0 ? _includeEntry$stripCo : userOptions.stripCommonPrefix) !== null && _ref6 !== void 0 ? _ref6 : false,
906
+ sourceMapReference: (_ref7 = (_includeEntry$sourceM = includeEntry.sourceMapReference) !== null && _includeEntry$sourceM !== void 0 ? _includeEntry$sourceM : userOptions.sourceMapReference) !== null && _ref7 !== void 0 ? _ref7 : true,
907
+ rewrite: (_ref8 = (_includeEntry$rewrite = includeEntry.rewrite) !== null && _includeEntry$rewrite !== void 0 ? _includeEntry$rewrite : userOptions.rewrite) !== null && _ref8 !== void 0 ? _ref8 : true,
908
+ validate: (_ref9 = (_includeEntry$validat = includeEntry.validate) !== null && _includeEntry$validat !== void 0 ? _includeEntry$validat : userOptions.validate) !== null && _ref9 !== void 0 ? _ref9 : false
909
+ };
910
+ }
911
+ /**
912
+ * Validates a few combinations of options that are not checked by Sentry CLI.
913
+ *
914
+ * For all other options, we can rely on Sentry CLI to validate them. In fact,
915
+ * we can't validate them in the plugin because Sentry CLI might pick up options from
916
+ * its config file.
917
+ *
918
+ * @param options the internal options
919
+ * @param logger the logger
920
+ *
921
+ * @returns `true` if the options are valid, `false` otherwise
922
+ */
923
+
493
924
 
494
- if (releaseFromEnvironmentVar) {
495
- return process.env[releaseFromEnvironmentVar];
925
+ function validateOptions(options, logger) {
926
+ if (options.injectReleasesMap && !options.org) {
927
+ logger.error("The `injectReleasesMap` option was set but it is only supported when the `org` option is also specified.", "Please set the `org` option (you can also set the SENTRY_ORG environment variable) or disable the `injectReleasesMap` option.");
928
+ return false;
496
929
  }
497
930
 
498
- var gitBranchHead = getGitBranchHead();
931
+ var setCommits = options.setCommits;
499
932
 
500
- if (gitBranchHead) {
501
- return gitBranchHead;
502
- } else {
503
- throw new Error("Could not return a release name");
933
+ if (setCommits) {
934
+ if (!setCommits.auto && !(setCommits.repo && setCommits.commit)) {
935
+ logger.error("The `setCommits` option was specified but is missing required properties.", "Please set either `auto` or both, `repo` and `commit`.");
936
+ return false;
937
+ }
938
+
939
+ if (setCommits.auto && setCommits.repo && setCommits) {
940
+ logger.warn("The `setCommits` options includes `auto` but also `repo` and `commit`.", "Ignoring `repo` and `commit`.", "Please only set either `auto` or both, `repo` and `commit`.");
941
+ }
504
942
  }
943
+
944
+ if (options.deploy && !options.deploy.env) {
945
+ logger.error("The `deploy` option was specified but is missing the required `env` property.", "Please set the `env` property.");
946
+ return false;
947
+ }
948
+
949
+ return true;
505
950
  }
506
951
 
507
- function makeSentryClient(dsn, telemetryEnabled, org) {
952
+ function makeSentryClient(dsn, telemetryEnabled) {
508
953
  var client = new node.NodeClient({
509
954
  dsn: dsn,
510
955
  enabled: telemetryEnabled,
511
956
  tracesSampleRate: telemetryEnabled ? 1.0 : 0.0,
512
957
  sampleRate: telemetryEnabled ? 1.0 : 0.0,
513
- release: "0.0.1-alpha.0",
958
+ release: "0.2.0",
514
959
  integrations: [new node.Integrations.Http({
515
960
  tracing: true
516
961
  })],
517
962
  tracePropagationTargets: ["sentry.io/api"],
518
963
  stackParser: node.defaultStackParser,
519
- transport: node.makeNodeTransport,
520
- debug: true
964
+ transport: node.makeNodeTransport
521
965
  });
522
- var hub = new node.Hub(client);
523
- hub.configureScope(function (scope) {
524
- if (org) {
525
- scope.setTag("org", org);
526
- }
527
- }); //TODO: This call is problematic because as soon as we set our hub as the current hub
966
+ var hub = new node.Hub(client); //TODO: This call is problematic because as soon as we set our hub as the current hub
528
967
  // we might interfere with other plugins that use Sentry. However, for now, we'll
529
968
  // leave it in because without it, we can't get distributed traces (which are pretty nice)
530
969
  // Let's keep it until someone complains about interference.
@@ -556,319 +995,135 @@ function addSpanToTransaction(ctx, op, description) {
556
995
  return span;
557
996
  }
558
997
  function captureMinimalError(error, hub) {
559
- var isAxiosError = error instanceof axios.AxiosError;
560
- var sentryError = error instanceof Error ? {
561
- name: "".concat(isAxiosError && error.status ? error.status : "", ": ").concat(error.name),
562
- message: error.message,
563
- stack: error.stack
564
- } : {};
998
+ var sentryError;
999
+
1000
+ if (error && _typeof(error) === "object") {
1001
+ var e = error;
1002
+ sentryError = {
1003
+ name: e.name,
1004
+ message: e.message,
1005
+ stack: e.stack
1006
+ };
1007
+ } else {
1008
+ sentryError = {
1009
+ name: "Error",
1010
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1011
+ message: "".concat(error)
1012
+ };
1013
+ }
1014
+
565
1015
  hub.captureException(sentryError);
566
1016
  }
1017
+ function addPluginOptionTags(options, hub) {
1018
+ var cleanArtifacts = options.cleanArtifacts,
1019
+ finalize = options.finalize,
1020
+ setCommits = options.setCommits,
1021
+ injectReleasesMap = options.injectReleasesMap,
1022
+ dryRun = options.dryRun,
1023
+ errorHandler = options.errorHandler,
1024
+ deploy = options.deploy,
1025
+ include = options.include;
1026
+ hub.setTag("include", include.length > 1 ? "multiple-entries" : "single-entry"); // Optional release pipeline steps
1027
+
1028
+ if (cleanArtifacts) {
1029
+ hub.setTag("clean-artifacts", true);
1030
+ }
567
1031
 
568
- var API_PATH = "/api/0";
569
- var USER_AGENT = "sentry-bundler-plugin/".concat("0.0.1-alpha.0");
570
-
571
- var sentryApiAxiosInstance = function sentryApiAxiosInstance(_ref) {
572
- var authToken = _ref.authToken,
573
- customHeaders = _ref.customHeaders;
574
- return axios__default["default"].create({
575
- headers: _objectSpread2(_objectSpread2({}, customHeaders), {}, {
576
- "User-Agent": USER_AGENT,
577
- Authorization: "Bearer ".concat(authToken)
578
- })
579
- });
580
- };
1032
+ if (setCommits) {
1033
+ hub.setTag("set-commits", setCommits.auto === true ? "auto" : "manual");
1034
+ }
581
1035
 
582
- function createRelease(_x) {
583
- return _createRelease.apply(this, arguments);
584
- }
1036
+ if (finalize) {
1037
+ hub.setTag("finalize-release", true);
1038
+ }
585
1039
 
586
- function _createRelease() {
587
- _createRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref2) {
588
- var org, project, release, authToken, sentryUrl, sentryHub, customHeaders, requestUrl, releasePayload;
589
- return _regeneratorRuntime().wrap(function _callee$(_context) {
590
- while (1) {
591
- switch (_context.prev = _context.next) {
592
- case 0:
593
- org = _ref2.org, project = _ref2.project, release = _ref2.release, authToken = _ref2.authToken, sentryUrl = _ref2.sentryUrl, sentryHub = _ref2.sentryHub, customHeaders = _ref2.customHeaders;
594
- requestUrl = "".concat(sentryUrl).concat(API_PATH, "/organizations/").concat(org, "/releases/");
595
- releasePayload = {
596
- version: release,
597
- projects: [project],
598
- // we currently only support creating releases for a single project
599
- dateStarted: new Date(),
600
- dateReleased: new Date() //TODO: figure out if these dates are set correctly
1040
+ if (deploy) {
1041
+ hub.setTag("add-deploy", true);
1042
+ } // Miscelaneous options
601
1043
 
602
- };
603
- _context.prev = 3;
604
- _context.next = 6;
605
- return sentryApiAxiosInstance({
606
- authToken: authToken,
607
- customHeaders: customHeaders
608
- }).post(requestUrl, releasePayload, {
609
- headers: {
610
- Authorization: "Bearer ".concat(authToken)
611
- }
612
- });
613
1044
 
614
- case 6:
615
- _context.next = 12;
616
- break;
1045
+ if (dryRun) {
1046
+ hub.setTag("dry-run", true);
1047
+ }
617
1048
 
618
- case 8:
619
- _context.prev = 8;
620
- _context.t0 = _context["catch"](3);
621
- captureMinimalError(_context.t0, sentryHub);
622
- throw _context.t0;
1049
+ if (injectReleasesMap) {
1050
+ hub.setTag("inject-releases-map", true);
1051
+ }
623
1052
 
624
- case 12:
625
- case "end":
626
- return _context.stop();
627
- }
628
- }
629
- }, _callee, null, [[3, 8]]);
630
- }));
631
- return _createRelease.apply(this, arguments);
632
- }
1053
+ if (errorHandler) {
1054
+ hub.setTag("error-handler", "custom");
1055
+ }
633
1056
 
634
- function deleteAllReleaseArtifacts(_x2) {
635
- return _deleteAllReleaseArtifacts.apply(this, arguments);
1057
+ hub.setTag("node", process.version);
636
1058
  }
1059
+ /**
1060
+ * Makes a call to SentryCLI to get the Sentry server URL the CLI uses.
1061
+ *
1062
+ * We need to check and decide to use telemetry based on the CLI's respone to this call
1063
+ * because only at this time we checked a possibly existing .sentryclirc file. This file
1064
+ * could point to another URL than the default URL.
1065
+ */
637
1066
 
638
- function _deleteAllReleaseArtifacts() {
639
- _deleteAllReleaseArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(_ref3) {
640
- var org, project, release, authToken, sentryUrl, sentryHub, customHeaders, requestUrl;
641
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
642
- while (1) {
643
- switch (_context2.prev = _context2.next) {
644
- case 0:
645
- org = _ref3.org, project = _ref3.project, release = _ref3.release, authToken = _ref3.authToken, sentryUrl = _ref3.sentryUrl, sentryHub = _ref3.sentryHub, customHeaders = _ref3.customHeaders;
646
- requestUrl = "".concat(sentryUrl).concat(API_PATH, "/projects/").concat(org, "/").concat(project, "/files/source-maps/?name=").concat(release);
647
- _context2.prev = 2;
648
- _context2.next = 5;
649
- return sentryApiAxiosInstance({
650
- authToken: authToken,
651
- customHeaders: customHeaders
652
- })["delete"](requestUrl, {
653
- headers: {
654
- Authorization: "Bearer ".concat(authToken)
655
- }
656
- });
657
-
658
- case 5:
659
- _context2.next = 11;
660
- break;
661
-
662
- case 7:
663
- _context2.prev = 7;
664
- _context2.t0 = _context2["catch"](2);
665
- captureMinimalError(_context2.t0, sentryHub);
666
- throw _context2.t0;
667
-
668
- case 11:
669
- case "end":
670
- return _context2.stop();
671
- }
672
- }
673
- }, _callee2, null, [[2, 7]]);
674
- }));
675
- return _deleteAllReleaseArtifacts.apply(this, arguments);
1067
+ function turnOffTelemetryForSelfHostedSentry(_x, _x2) {
1068
+ return _turnOffTelemetryForSelfHostedSentry.apply(this, arguments);
676
1069
  }
677
1070
 
678
- function updateRelease(_x3) {
679
- return _updateRelease.apply(this, arguments);
680
- }
1071
+ function _turnOffTelemetryForSelfHostedSentry() {
1072
+ _turnOffTelemetryForSelfHostedSentry = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cli, hub) {
1073
+ var _cliInfo$split$, _cliInfo$split$$repla;
681
1074
 
682
- function _updateRelease() {
683
- _updateRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_ref4) {
684
- var release, org, authToken, sentryUrl, project, sentryHub, customHeaders, requestUrl, releasePayload;
685
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
1075
+ var cliInfo, url, client;
1076
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
686
1077
  while (1) {
687
- switch (_context3.prev = _context3.next) {
1078
+ switch (_context.prev = _context.next) {
688
1079
  case 0:
689
- release = _ref4.release, org = _ref4.org, authToken = _ref4.authToken, sentryUrl = _ref4.sentryUrl, project = _ref4.project, sentryHub = _ref4.sentryHub, customHeaders = _ref4.customHeaders;
690
- requestUrl = "".concat(sentryUrl).concat(API_PATH, "/projects/").concat(org, "/").concat(project, "/releases/").concat(release, "/");
691
- releasePayload = {
692
- dateReleased: new Date().toISOString()
693
- };
694
- _context3.prev = 3;
695
- _context3.next = 6;
696
- return sentryApiAxiosInstance({
697
- authToken: authToken,
698
- customHeaders: customHeaders
699
- }).put(requestUrl, releasePayload, {
700
- headers: {
701
- Authorization: "Bearer ".concat(authToken)
702
- }
703
- });
1080
+ _context.next = 2;
1081
+ return cli.execute(["info"], false);
704
1082
 
705
- case 6:
706
- _context3.next = 12;
707
- break;
1083
+ case 2:
1084
+ cliInfo = _context.sent;
1085
+ 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();
708
1086
 
709
- case 8:
710
- _context3.prev = 8;
711
- _context3.t0 = _context3["catch"](3);
712
- captureMinimalError(_context3.t0, sentryHub);
713
- throw _context3.t0;
1087
+ if (url !== SENTRY_SAAS_URL) {
1088
+ client = hub.getClient();
714
1089
 
715
- case 12:
716
- case "end":
717
- return _context3.stop();
718
- }
719
- }
720
- }, _callee3, null, [[3, 8]]);
721
- }));
722
- return _updateRelease.apply(this, arguments);
723
- }
724
-
725
- function uploadReleaseFile(_x4) {
726
- return _uploadReleaseFile.apply(this, arguments);
727
- }
728
-
729
- function _uploadReleaseFile() {
730
- _uploadReleaseFile = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(_ref5) {
731
- var org, project, release, authToken, sentryUrl, filename, fileContent, sentryHub, customHeaders, requestUrl, form;
732
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
733
- while (1) {
734
- switch (_context4.prev = _context4.next) {
735
- case 0:
736
- org = _ref5.org, project = _ref5.project, release = _ref5.release, authToken = _ref5.authToken, sentryUrl = _ref5.sentryUrl, filename = _ref5.filename, fileContent = _ref5.fileContent, sentryHub = _ref5.sentryHub, customHeaders = _ref5.customHeaders;
737
- requestUrl = "".concat(sentryUrl).concat(API_PATH, "/projects/").concat(org, "/").concat(project, "/releases/").concat(release, "/files/");
738
- form = new FormData__default["default"]();
739
- form.append("name", filename);
740
- form.append("file", Buffer.from(fileContent, "utf-8"), {
741
- filename: filename
742
- });
743
- _context4.prev = 5;
744
- _context4.next = 8;
745
- return sentryApiAxiosInstance({
746
- authToken: authToken,
747
- customHeaders: customHeaders
748
- }).post(requestUrl, form, {
749
- headers: {
750
- Authorization: "Bearer ".concat(authToken),
751
- "Content-Type": "multipart/form-data"
1090
+ if (client) {
1091
+ client.getOptions().enabled = false;
1092
+ client.getOptions().tracesSampleRate = 0;
1093
+ client.getOptions().sampleRate = 0;
752
1094
  }
753
- });
754
-
755
- case 8:
756
- _context4.next = 14;
757
- break;
758
-
759
- case 10:
760
- _context4.prev = 10;
761
- _context4.t0 = _context4["catch"](5);
762
- captureMinimalError(_context4.t0, sentryHub);
763
- throw _context4.t0;
1095
+ }
764
1096
 
765
- case 14:
1097
+ case 5:
766
1098
  case "end":
767
- return _context4.stop();
1099
+ return _context.stop();
768
1100
  }
769
1101
  }
770
- }, _callee4, null, [[5, 10]]);
1102
+ }, _callee);
771
1103
  }));
772
- return _uploadReleaseFile.apply(this, arguments);
773
- }
774
-
775
- function getFiles(path, allowedExtensions) {
776
- var includedFiles = getAllIncludedFileNames(path, allowedExtensions, []);
777
- return includedFiles.map(function (filename) {
778
- var content = fs__default["default"].readFileSync(filename, {
779
- encoding: "utf-8"
780
- });
781
- return {
782
- name: "~" + filename.replace(new RegExp("^".concat(path)), ""),
783
- content: content
784
- };
785
- });
786
- }
787
-
788
- function getAllIncludedFileNames(dirPath, allowedExtensions, accFiles) {
789
- var files = fs__default["default"].readdirSync(dirPath);
790
- files.map(function (file) {
791
- return path__default["default"].join(dirPath, "/", file);
792
- }).forEach(function (file) {
793
- if (fs__default["default"].statSync(file).isDirectory()) {
794
- accFiles = accFiles.concat(getAllIncludedFileNames(file, allowedExtensions, accFiles));
795
- } else {
796
- if (allowedExtensions.some(function (e) {
797
- return file.endsWith(e);
798
- })) {
799
- accFiles.push(file);
800
- }
801
- }
802
- });
803
- return accFiles;
1104
+ return _turnOffTelemetryForSelfHostedSentry.apply(this, arguments);
804
1105
  }
805
1106
 
806
- function createNewRelease(_x, _x2, _x3) {
1107
+ function createNewRelease(_x, _x2) {
807
1108
  return _createNewRelease.apply(this, arguments);
808
1109
  }
809
1110
 
810
1111
  function _createNewRelease() {
811
- _createNewRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(release, options, ctx) {
1112
+ _createNewRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(options, ctx) {
812
1113
  var span;
813
1114
  return _regeneratorRuntime().wrap(function _callee$(_context) {
814
1115
  while (1) {
815
1116
  switch (_context.prev = _context.next) {
816
1117
  case 0:
817
- span = addSpanToTransaction(ctx, "function.plugin.create_release"); // TODO: pull these checks out of here and simplify them
1118
+ span = addSpanToTransaction(ctx, "function.plugin.create_release");
1119
+ _context.next = 3;
1120
+ return ctx.cli.releases["new"](options.release);
818
1121
 
819
- if (!(options.authToken === undefined)) {
820
- _context.next = 6;
821
- break;
822
- }
823
-
824
- ctx.logger.warn('Missing "authToken" option. Will not create release.');
825
- return _context.abrupt("return", Promise.resolve("nothing to do here"));
826
-
827
- case 6:
828
- if (!(options.org === undefined)) {
829
- _context.next = 11;
830
- break;
831
- }
832
-
833
- ctx.logger.warn('Missing "org" option. Will not create release.');
834
- return _context.abrupt("return", Promise.resolve("nothing to do here"));
835
-
836
- case 11:
837
- if (!(options.url === undefined)) {
838
- _context.next = 16;
839
- break;
840
- }
841
-
842
- ctx.logger.warn('Missing "url" option. Will not create release.');
843
- return _context.abrupt("return", Promise.resolve("nothing to do here"));
844
-
845
- case 16:
846
- if (!(options.project === undefined)) {
847
- _context.next = 19;
848
- break;
849
- }
850
-
851
- ctx.logger.warn('Missing "project" option. Will not create release.');
852
- return _context.abrupt("return", Promise.resolve("nothing to do here"));
853
-
854
- case 19:
855
- _context.next = 21;
856
- return createRelease({
857
- release: release,
858
- authToken: options.authToken,
859
- org: options.org,
860
- project: options.project,
861
- sentryUrl: options.url,
862
- sentryHub: ctx.hub,
863
- customHeaders: options.customHeaders
864
- });
865
-
866
- case 21:
1122
+ case 3:
867
1123
  ctx.logger.info("Successfully created release.");
868
1124
  span === null || span === void 0 ? void 0 : span.finish();
869
- return _context.abrupt("return", Promise.resolve("nothing to do here"));
870
1125
 
871
- case 24:
1126
+ case 5:
872
1127
  case "end":
873
1128
  return _context.stop();
874
1129
  }
@@ -878,288 +1133,201 @@ function _createNewRelease() {
878
1133
  return _createNewRelease.apply(this, arguments);
879
1134
  }
880
1135
 
881
- function uploadSourceMaps(_x4, _x5, _x6) {
882
- return _uploadSourceMaps.apply(this, arguments);
1136
+ function cleanArtifacts(_x3, _x4) {
1137
+ return _cleanArtifacts.apply(this, arguments);
883
1138
  }
884
1139
 
885
- function _uploadSourceMaps() {
886
- _uploadSourceMaps = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(release, options, ctx) {
887
- var span, include, ext, org, project, authToken, url, fileExtensions, files;
1140
+ function _cleanArtifacts() {
1141
+ _cleanArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options, ctx) {
1142
+ var span;
888
1143
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
889
1144
  while (1) {
890
1145
  switch (_context2.prev = _context2.next) {
891
1146
  case 0:
892
- span = addSpanToTransaction(ctx, "function.plugin.upload_sourcemaps"); // This is what Sentry CLI does:
893
- // TODO: 0. Preprocess source maps
894
- // - (Out of scope for now)
895
- // - For rewriting source maps see https://github.com/getsentry/rust-sourcemap/blob/master/src/types.rs#L763
896
- // TODO: 1. Creates a new release to make sure it exists
897
- // - can we assume that the release will exist b/c we don't give unplugin users the
898
- // option to skip this step?
899
- // TODO: 2. download already uploaded files and get their checksums
900
- // TODO: 3. identify new or changed files (by comparing checksums)
901
- // TODO: 4. upload new and changed files
902
- // - CLI asks API for chunk options https://github.com/getsentry/sentry-cli/blob/7b8466885d9cfd51aee6fdc041eca9f645026303/src/utils/file_upload.rs#L106-L112
903
- // - WTF?
904
- // - don't upload more than 20k files
905
- // - upload files concurrently
906
- // - 2 options: chunked upload (multiple files per chunk) or single file upload
907
-
908
- include = options.include, ext = options.ext, org = options.org, project = options.project, authToken = options.authToken, url = options.url; // TODO: pull these checks out of here and simplify them
909
-
910
- if (!(authToken === undefined)) {
911
- _context2.next = 7;
912
- break;
913
- }
914
-
915
- ctx.logger.warn('Missing "authToken" option. Will not create release.');
916
- return _context2.abrupt("return", Promise.resolve("nothing to do here"));
917
-
918
- case 7:
919
- if (!(org === undefined)) {
920
- _context2.next = 12;
1147
+ if (options.cleanArtifacts) {
1148
+ _context2.next = 3;
921
1149
  break;
922
1150
  }
923
1151
 
924
- ctx.logger.warn('Missing "org" option. Will not create release.');
925
- return _context2.abrupt("return", Promise.resolve("nothing to do here"));
926
-
927
- case 12:
928
- if (!(url === undefined)) {
929
- _context2.next = 17;
930
- break;
931
- }
1152
+ logger.debug("Skipping artifact cleanup.");
1153
+ return _context2.abrupt("return");
932
1154
 
933
- ctx.logger.warn('Missing "url" option. Will not create release.');
934
- return _context2.abrupt("return", Promise.resolve("nothing to do here"));
1155
+ case 3:
1156
+ span = addSpanToTransaction(ctx, "function.plugin.clean_artifacts");
1157
+ _context2.next = 6;
1158
+ return ctx.cli.releases.execute(["releases", "files", options.release, "delete", "--all"], true);
935
1159
 
936
- case 17:
937
- if (!(project === undefined)) {
938
- _context2.next = 20;
939
- break;
940
- }
1160
+ case 6:
1161
+ ctx.logger.info("Successfully cleaned previous artifacts.");
1162
+ span === null || span === void 0 ? void 0 : span.finish();
941
1163
 
942
- ctx.logger.warn('Missing "project" option. Will not create release.');
943
- return _context2.abrupt("return", Promise.resolve("nothing to do here"));
944
-
945
- case 20:
946
- ctx.logger.info("Uploading Sourcemaps."); //TODO: Remove this once we have internal options. this property must always be present
947
-
948
- fileExtensions = ext || [];
949
- files = getFiles(include, fileExtensions);
950
- ctx.logger.info("Found ".concat(files.length, " files to upload."));
951
- return _context2.abrupt("return", Promise.all(files.map(function (file) {
952
- return uploadReleaseFile({
953
- org: org,
954
- project: project,
955
- release: release,
956
- authToken: authToken,
957
- sentryUrl: url,
958
- filename: file.name,
959
- fileContent: file.content,
960
- sentryHub: ctx.hub,
961
- customHeaders: options.customHeaders
962
- });
963
- })).then(function () {
964
- ctx.logger.info("Successfully uploaded sourcemaps.");
965
- span === null || span === void 0 ? void 0 : span.finish();
966
- return "done";
967
- }));
968
-
969
- case 25:
1164
+ case 8:
970
1165
  case "end":
971
1166
  return _context2.stop();
972
1167
  }
973
1168
  }
974
1169
  }, _callee2);
975
1170
  }));
976
- return _uploadSourceMaps.apply(this, arguments);
1171
+ return _cleanArtifacts.apply(this, arguments);
977
1172
  }
978
1173
 
979
- function finalizeRelease(_x7, _x8, _x9) {
980
- return _finalizeRelease.apply(this, arguments);
1174
+ function uploadSourceMaps(_x5, _x6) {
1175
+ return _uploadSourceMaps.apply(this, arguments);
981
1176
  }
982
1177
 
983
- function _finalizeRelease() {
984
- _finalizeRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(release, options, ctx) {
985
- var span, authToken, org, url, project;
1178
+ function _uploadSourceMaps() {
1179
+ _uploadSourceMaps = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(options, ctx) {
1180
+ var span;
986
1181
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
987
1182
  while (1) {
988
1183
  switch (_context3.prev = _context3.next) {
989
1184
  case 0:
990
- span = addSpanToTransaction(ctx, "function.plugin.finalize_release");
991
-
992
- if (!options.finalize) {
993
- _context3.next = 9;
994
- break;
995
- }
996
-
997
- authToken = options.authToken, org = options.org, url = options.url, project = options.project;
1185
+ span = addSpanToTransaction(ctx, "function.plugin.upload_sourcemaps");
1186
+ ctx.logger.info("Uploading Sourcemaps."); // Since our internal include entries contain all top-level sourcemaps options,
1187
+ // we only need to pass the include option here.
998
1188
 
999
- if (!(!authToken || !org || !url || !project)) {
1000
- _context3.next = 6;
1001
- break;
1002
- }
1003
-
1004
- ctx.logger.warn("Missing required option. Will not clean existing artifacts.");
1005
- return _context3.abrupt("return", Promise.resolve("nothing to do here"));
1006
-
1007
- case 6:
1008
- _context3.next = 8;
1009
- return updateRelease({
1010
- authToken: authToken,
1011
- org: org,
1012
- release: release,
1013
- sentryUrl: url,
1014
- project: project,
1015
- sentryHub: ctx.hub,
1016
- customHeaders: options.customHeaders
1189
+ _context3.next = 4;
1190
+ return ctx.cli.releases.uploadSourceMaps(options.release, {
1191
+ include: options.include
1017
1192
  });
1018
1193
 
1019
- case 8:
1020
- ctx.logger.info("Successfully finalized release.");
1021
-
1022
- case 9:
1194
+ case 4:
1195
+ ctx.logger.info("Successfully uploaded Sourcemaps.");
1023
1196
  span === null || span === void 0 ? void 0 : span.finish();
1024
- return _context3.abrupt("return", Promise.resolve("nothing to do here"));
1025
1197
 
1026
- case 11:
1198
+ case 6:
1027
1199
  case "end":
1028
1200
  return _context3.stop();
1029
1201
  }
1030
1202
  }
1031
1203
  }, _callee3);
1032
1204
  }));
1033
- return _finalizeRelease.apply(this, arguments);
1205
+ return _uploadSourceMaps.apply(this, arguments);
1034
1206
  }
1035
1207
 
1036
- function cleanArtifacts(_x10, _x11, _x12) {
1037
- return _cleanArtifacts.apply(this, arguments);
1038
- } // TODO: Stuff we worry about later:
1208
+ function setCommits(_x7, _x8) {
1209
+ return _setCommits.apply(this, arguments);
1210
+ }
1211
+
1212
+ function _setCommits() {
1213
+ _setCommits = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(options, ctx) {
1214
+ var span, _options$setCommits, auto, repo, commit, previousCommit, ignoreMissing, ignoreEmpty;
1039
1215
 
1040
- function _cleanArtifacts() {
1041
- _cleanArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(release, options, ctx) {
1042
- var span;
1043
1216
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
1044
1217
  while (1) {
1045
1218
  switch (_context4.prev = _context4.next) {
1046
1219
  case 0:
1047
- span = addSpanToTransaction(ctx, "function.plugin.clean_artifacts");
1048
-
1049
- if (!options.cleanArtifacts) {
1050
- _context4.next = 23;
1051
- break;
1052
- }
1053
-
1054
- if (!(options.authToken === undefined)) {
1055
- _context4.next = 7;
1056
- break;
1057
- }
1058
-
1059
- ctx.logger.warn('Missing "authToken" option. Will not clean existing artifacts.');
1060
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1061
-
1062
- case 7:
1063
- if (!(options.org === undefined)) {
1064
- _context4.next = 12;
1220
+ if (options.setCommits) {
1221
+ _context4.next = 3;
1065
1222
  break;
1066
1223
  }
1067
1224
 
1068
- ctx.logger.warn('Missing "org" option. Will not clean existing artifacts.');
1069
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1070
-
1071
- case 12:
1072
- if (!(options.url === undefined)) {
1073
- _context4.next = 17;
1074
- break;
1075
- }
1076
-
1077
- ctx.logger.warn('Missing "url" option. Will not clean existing artifacts.');
1078
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1079
-
1080
- case 17:
1081
- if (!(options.project === undefined)) {
1082
- _context4.next = 20;
1083
- break;
1084
- }
1225
+ logger.debug("Skipping setting commits to release.");
1226
+ return _context4.abrupt("return");
1085
1227
 
1086
- ctx.logger.warn('Missing "project" option. Will not clean existing artifacts.');
1087
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1088
-
1089
- case 20:
1090
- _context4.next = 22;
1091
- return deleteAllReleaseArtifacts({
1092
- authToken: options.authToken,
1093
- org: options.org,
1094
- release: release,
1095
- sentryUrl: options.url,
1096
- project: options.project,
1097
- sentryHub: ctx.hub,
1098
- customHeaders: options.customHeaders
1228
+ case 3:
1229
+ span = addSpanToTransaction(ctx, "function.plugin.set_commits");
1230
+ _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;
1231
+ _context4.next = 7;
1232
+ return ctx.cli.releases.setCommits(options.release, {
1233
+ commit: commit,
1234
+ previousCommit: previousCommit,
1235
+ repo: repo,
1236
+ auto: auto,
1237
+ ignoreMissing: ignoreMissing,
1238
+ ignoreEmpty: ignoreEmpty
1099
1239
  });
1100
1240
 
1101
- case 22:
1102
- ctx.logger.info("Successfully cleaned previous artifacts.");
1103
-
1104
- case 23:
1241
+ case 7:
1242
+ ctx.logger.info("Successfully set commits.");
1105
1243
  span === null || span === void 0 ? void 0 : span.finish();
1106
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1107
1244
 
1108
- case 25:
1245
+ case 9:
1109
1246
  case "end":
1110
1247
  return _context4.stop();
1111
1248
  }
1112
1249
  }
1113
1250
  }, _callee4);
1114
1251
  }));
1115
- return _cleanArtifacts.apply(this, arguments);
1252
+ return _setCommits.apply(this, arguments);
1116
1253
  }
1117
1254
 
1118
- function setCommits(_x13) {
1119
- return _setCommits.apply(this, arguments);
1255
+ function finalizeRelease(_x9, _x10) {
1256
+ return _finalizeRelease.apply(this, arguments);
1120
1257
  }
1121
1258
 
1122
- function _setCommits() {
1123
- _setCommits = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(
1124
- /* version: string, */
1125
- ctx) {
1259
+ function _finalizeRelease() {
1260
+ _finalizeRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(options, ctx) {
1126
1261
  var span;
1127
1262
  return _regeneratorRuntime().wrap(function _callee5$(_context5) {
1128
1263
  while (1) {
1129
1264
  switch (_context5.prev = _context5.next) {
1130
1265
  case 0:
1131
- span = addSpanToTransaction(ctx, "function.plugin.set_commits");
1132
- span === null || span === void 0 ? void 0 : span.finish();
1133
- return _context5.abrupt("return", Promise.resolve("Noop"));
1266
+ if (options.finalize) {
1267
+ _context5.next = 3;
1268
+ break;
1269
+ }
1270
+
1271
+ logger.debug("Skipping release finalization.");
1272
+ return _context5.abrupt("return");
1134
1273
 
1135
1274
  case 3:
1275
+ span = addSpanToTransaction(ctx, "function.plugin.finalize_release");
1276
+ _context5.next = 6;
1277
+ return ctx.cli.releases.finalize(options.release);
1278
+
1279
+ case 6:
1280
+ ctx.logger.info("Successfully finalized release.");
1281
+ span === null || span === void 0 ? void 0 : span.finish();
1282
+
1283
+ case 8:
1136
1284
  case "end":
1137
1285
  return _context5.stop();
1138
1286
  }
1139
1287
  }
1140
1288
  }, _callee5);
1141
1289
  }));
1142
- return _setCommits.apply(this, arguments);
1290
+ return _finalizeRelease.apply(this, arguments);
1143
1291
  }
1144
1292
 
1145
- function addDeploy(_x14) {
1293
+ function addDeploy(_x11, _x12) {
1146
1294
  return _addDeploy.apply(this, arguments);
1147
1295
  }
1148
1296
 
1149
1297
  function _addDeploy() {
1150
- _addDeploy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(
1151
- /* version: string, */
1152
- ctx) {
1153
- var span;
1298
+ _addDeploy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(options, ctx) {
1299
+ var span, _options$deploy, env, started, finished, time, name, url;
1300
+
1154
1301
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
1155
1302
  while (1) {
1156
1303
  switch (_context6.prev = _context6.next) {
1157
1304
  case 0:
1158
- span = addSpanToTransaction(ctx, "function.plugin.add_deploy");
1159
- span === null || span === void 0 ? void 0 : span.finish();
1160
- return _context6.abrupt("return", Promise.resolve("Noop"));
1305
+ if (options.deploy) {
1306
+ _context6.next = 3;
1307
+ break;
1308
+ }
1309
+
1310
+ logger.debug("Skipping adding deploy info to release.");
1311
+ return _context6.abrupt("return");
1161
1312
 
1162
1313
  case 3:
1314
+ span = addSpanToTransaction(ctx, "function.plugin.deploy");
1315
+ _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;
1316
+ _context6.next = 7;
1317
+ return ctx.cli.releases.newDeploy(options.release, {
1318
+ env: env,
1319
+ started: started,
1320
+ finished: finished,
1321
+ time: time,
1322
+ name: name,
1323
+ url: url
1324
+ });
1325
+
1326
+ case 7:
1327
+ ctx.logger.info("Successfully added deploy.");
1328
+ span === null || span === void 0 ? void 0 : span.finish();
1329
+
1330
+ case 9:
1163
1331
  case "end":
1164
1332
  return _context6.stop();
1165
1333
  }
@@ -1180,132 +1348,205 @@ function createLogger(options) {
1180
1348
 
1181
1349
  return {
1182
1350
  info: function info(message) {
1183
- if (!(options !== null && options !== void 0 && options.silent)) {
1351
+ if (!options.silent) {
1352
+ var _console;
1353
+
1354
+ for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1355
+ params[_key - 1] = arguments[_key];
1356
+ }
1357
+
1184
1358
  // eslint-disable-next-line no-console
1185
- console.log("".concat(options.prefix, " ").concat(message));
1359
+ (_console = console).log.apply(_console, ["".concat(options.prefix, " Info: ").concat(message)].concat(params));
1186
1360
  }
1187
1361
 
1188
1362
  addBreadcrumb("info", message);
1189
1363
  },
1190
1364
  warn: function warn(message) {
1191
- if (!(options !== null && options !== void 0 && options.silent)) {
1365
+ if (!options.silent) {
1366
+ var _console2;
1367
+
1368
+ for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1369
+ params[_key2 - 1] = arguments[_key2];
1370
+ }
1371
+
1192
1372
  // eslint-disable-next-line no-console
1193
- console.log("".concat(options.prefix, " Warning! ").concat(message));
1373
+ (_console2 = console).log.apply(_console2, ["".concat(options.prefix, " Warning: ").concat(message)].concat(params));
1194
1374
  }
1195
1375
 
1196
1376
  addBreadcrumb("warning", message);
1197
1377
  },
1198
1378
  error: function error(message) {
1199
- if (!(options !== null && options !== void 0 && options.silent)) {
1379
+ if (!options.silent) {
1380
+ var _console3;
1381
+
1382
+ for (var _len3 = arguments.length, params = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1383
+ params[_key3 - 1] = arguments[_key3];
1384
+ }
1385
+
1200
1386
  // eslint-disable-next-line no-console
1201
- console.log("".concat(options.prefix, " Error: ").concat(message));
1387
+ (_console3 = console).log.apply(_console3, ["".concat(options.prefix, " Error: ").concat(message)].concat(params));
1202
1388
  }
1203
1389
 
1204
1390
  addBreadcrumb("error", message);
1391
+ },
1392
+ debug: function debug(message) {
1393
+ if (!options.silent && options.debug) {
1394
+ var _console4;
1395
+
1396
+ for (var _len4 = arguments.length, params = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
1397
+ params[_key4 - 1] = arguments[_key4];
1398
+ }
1399
+
1400
+ // eslint-disable-next-line no-console
1401
+ (_console4 = console).log.apply(_console4, ["".concat(options.prefix, " Debug: ").concat(message)].concat(params));
1402
+ }
1403
+
1404
+ addBreadcrumb("debug", message);
1405
+ }
1406
+ };
1407
+ }
1408
+
1409
+ /**
1410
+ * Creates a new Sentry CLI instance.
1411
+ *
1412
+ * In case, users selected the `dryRun` options, this returns a stub
1413
+ * that makes no-ops out of most CLI operations
1414
+ */
1415
+ function getSentryCli(internalOptions, logger) {
1416
+ var silent = internalOptions.silent,
1417
+ org = internalOptions.org,
1418
+ project = internalOptions.project,
1419
+ authToken = internalOptions.authToken,
1420
+ url = internalOptions.url,
1421
+ vcsRemote = internalOptions.vcsRemote,
1422
+ customHeader = internalOptions.customHeader,
1423
+ dist = internalOptions.dist;
1424
+ var cli = new SentryCli__default["default"](internalOptions.configFile, {
1425
+ url: url,
1426
+ authToken: authToken,
1427
+ org: org,
1428
+ project: project,
1429
+ vcsRemote: vcsRemote,
1430
+ dist: dist,
1431
+ silent: silent,
1432
+ customHeader: customHeader
1433
+ });
1434
+
1435
+ if (internalOptions.dryRun) {
1436
+ logger.info("In DRY RUN Mode");
1437
+ return getDryRunCLI(cli, logger);
1438
+ }
1439
+
1440
+ return cli;
1441
+ }
1442
+
1443
+ function getDryRunCLI(cli, logger) {
1444
+ return {
1445
+ releases: {
1446
+ proposeVersion: function proposeVersion() {
1447
+ return cli.releases.proposeVersion().then(function (version) {
1448
+ logger.info("Proposed version:\n", version);
1449
+ return version;
1450
+ });
1451
+ },
1452
+ "new": function _new(release) {
1453
+ logger.info("Creating new release:\n", release);
1454
+ return Promise.resolve(release);
1455
+ },
1456
+ uploadSourceMaps: function uploadSourceMaps(release, config) {
1457
+ logger.info("Calling upload-sourcemaps with:\n", config);
1458
+ return Promise.resolve(release);
1459
+ },
1460
+ finalize: function finalize(release) {
1461
+ logger.info("Finalizing release:\n", release);
1462
+ return Promise.resolve(release);
1463
+ },
1464
+ setCommits: function setCommits(release, config) {
1465
+ logger.info("Calling set-commits with:\n", config);
1466
+ return Promise.resolve(release);
1467
+ },
1468
+ newDeploy: function newDeploy(release, config) {
1469
+ logger.info("Calling deploy with:\n", config);
1470
+ return Promise.resolve(release);
1471
+ },
1472
+ execute: function execute(args, live) {
1473
+ logger.info("Executing", args, "live:", live);
1474
+ return Promise.resolve("");
1475
+ }
1476
+ },
1477
+ execute: function execute(args, live) {
1478
+ logger.info("Executing", args, "live:", live);
1479
+ return Promise.resolve("Executed");
1205
1480
  }
1206
1481
  };
1207
1482
  }
1208
1483
 
1209
- var defaultOptions = {
1210
- //TODO: add default options here as we port over options from the webpack plugin
1211
- // validate: false
1212
- debug: false,
1213
- cleanArtifacts: false,
1214
- finalize: true,
1215
- url: "https://sentry.io",
1216
- ext: ["js", "map", "jsbundle", "bundle"],
1217
- telemetry: true
1218
- }; // We prefix the polyfill id with \0 to tell other plugins not to try to load or transform it.
1484
+ // We prefix the polyfill id with \0 to tell other plugins not to try to load or transform it.
1219
1485
  // This hack is taken straight from https://rollupjs.org/guide/en/#resolveid.
1220
1486
  // This probably doesn't work for all bundlers but for rollup it does.
1221
-
1222
1487
  var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1488
+ var ALLOWED_TRANSFORMATION_FILE_ENDINGS = [".js", ".ts", ".jsx", ".tsx", ".cjs", ".mjs"];
1223
1489
  /**
1224
- * The sentry-unplugin concerns itself with two things:
1490
+ * The sentry bundler plugin concerns itself with two things:
1225
1491
  * - Release injection
1226
1492
  * - Sourcemaps upload
1227
1493
  *
1228
1494
  * Release injection:
1229
1495
  *
1230
- * Per default the sentry-unpugin will inject a global `SENTRY_RELEASE` variable into the entrypoint of all bundles. On
1231
- * a technical level this is done by appending an import (`import "sentry-release-injector;"`) to all entrypoint files
1232
- * of the user code (see `transformInclude` and `transform` hooks). This import is then resolved by the sentry-unplugin
1233
- * to a virtual module that sets the global variable (see `resolveId` and `load` hooks).
1496
+ * Per default the sentry bundler plugin will inject a global `SENTRY_RELEASE` into each JavaScript/TypeScript module
1497
+ * that is part of the bundle. On a technical level this is done by appending an import (`import "sentry-release-injector;"`)
1498
+ * to all entrypoint files of the user code (see `transformInclude` and `transform` hooks). This import is then resolved
1499
+ * by the sentry plugin to a virtual module that sets the global variable (see `resolveId` and `load` hooks).
1500
+ * If a user wants to inject the release into a particular set of modules they can use the `releaseInjectionTargets` option.
1234
1501
  *
1235
- * The resulting output approximately looks like this:
1502
+ * Source maps upload:
1236
1503
  *
1237
- * ```text
1238
- * entrypoint1.js (user file)
1239
- * ┌───────────────────┐ ┌─────────────────────────────────────────────────┐
1240
- * │ │ │ import { myFunction } from "./my-library.js"; │
1241
- * │ sentry-unplugin │ │ │
1242
- * │ │ │ const myResult = myFunction(); │
1243
- * └---------│---------┘ │ export { myResult }; │
1244
- * │ │ │
1245
- * │ injects │ // injected by sentry-unplugin │
1246
- * ├───────────────────► import "sentry-release-injector"; ─────────────────────┐
1247
- * │ └─────────────────────────────────────────────────┘ │
1248
- * │ │
1249
- * │ │
1250
- * │ entrypoint2.js (user file) │
1251
- * │ ┌─────────────────────────────────────────────────┐ │
1252
- * │ │ export function myFunction() { │ │
1253
- * │ │ return "Hello world!"; │ │
1254
- * │ │ } │ │
1255
- * │ │ │ │
1256
- * │ injects │ // injected by sentry-unplugin │ │
1257
- * └───────────────────► import "sentry-release-injector"; ─────────────────────┤
1258
- * └─────────────────────────────────────────────────┘ │
1259
- * │
1260
- * │
1261
- * sentry-release-injector │
1262
- * ┌──────────────────────────────────┐ │
1263
- * │ │ is resolved │
1264
- * │ global.SENTRY_RELEASE = { ... } │ by unplugin │
1265
- * │ // + a little more logic │<─────────────────────┘
1266
- * │ │ (only once)
1267
- * └──────────────────────────────────┘
1268
- * ```
1504
+ * The sentry bundler plugin will also take care of uploading source maps to Sentry. This is all done in the
1505
+ * `writeBundle` hook. In this hook the sentry plugin will execute the release creation pipeline:
1269
1506
  *
1270
- * Source maps upload:
1507
+ * 1. Create a new release
1508
+ * 2. Delete already uploaded artifacts for this release (if `cleanArtifacts` is enabled)
1509
+ * 3. Upload sourcemaps based on `include` and source-map-specific options
1510
+ * 4. Associate a range of commits with the release (if `setCommits` is specified)
1511
+ * 5. Finalize the release (unless `finalize` is disabled)
1512
+ * 6. Add deploy information to the release (if `deploy` is specified)
1271
1513
  *
1272
- * The sentry-unplugin will also take care of uploading source maps to Sentry. This is all done in the `buildEnd` hook.
1273
- * TODO: elaborate a bit on how sourcemaps upload works
1514
+ * This release creation pipeline relies on Sentry CLI to execute the different steps.
1274
1515
  */
1275
1516
 
1276
- var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMetaContext) {
1277
- var options = _objectSpread2(_objectSpread2({}, defaultOptions), originalOptions); //TODO: We can get rid of this variable once we have internal plugin options
1278
-
1517
+ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext) {
1518
+ var internalOptions = normalizeUserOptions(options);
1279
1519
 
1280
- var telemetryEnabled = options.telemetry === true;
1281
-
1282
- var _makeSentryClient = makeSentryClient("https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737", telemetryEnabled, options.org),
1520
+ var _makeSentryClient = makeSentryClient("https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737", internalOptions.telemetry),
1283
1521
  sentryHub = _makeSentryClient.hub;
1284
1522
 
1523
+ addPluginOptionTags(internalOptions, sentryHub);
1285
1524
  var logger = createLogger({
1286
1525
  hub: sentryHub,
1287
1526
  prefix: "[sentry-".concat(unpluginMetaContext.framework, "-plugin]"),
1288
- silent: options.silent
1527
+ silent: internalOptions.silent,
1528
+ debug: internalOptions.debug
1289
1529
  });
1290
1530
 
1291
- if (telemetryEnabled) {
1531
+ if (!validateOptions(internalOptions, logger)) {
1532
+ handleError(new Error("Options were not set correctly. See output above for more details."), logger, internalOptions.errorHandler);
1533
+ }
1534
+
1535
+ var cli = getSentryCli(internalOptions, logger);
1536
+
1537
+ if (internalOptions.telemetry) {
1292
1538
  logger.info("Sending error and performance telemetry data to Sentry.");
1293
1539
  logger.info("To disable telemetry, set `options.telemetry` to `false`.");
1294
1540
  }
1295
1541
 
1296
1542
  sentryHub.setTags({
1297
- organization: options.org,
1298
- project: options.project,
1543
+ organization: internalOptions.org,
1544
+ project: internalOptions.project,
1299
1545
  bundler: unpluginMetaContext.framework
1300
1546
  });
1301
1547
  sentryHub.setUser({
1302
- id: options.org
1303
- }); // This is `nonEntrypointSet` instead of `entrypointSet` because this set is filled in the `resolveId` hook and there
1304
- // we don't have guaranteed access to *absolute* paths of files if they're entrypoints. For non-entrypoints we're
1305
- // guaranteed to have absolute paths - we're then using the paths in later hooks to make decisions about whether a
1306
- // file is an entrypoint or a non-entrypoint.
1307
-
1308
- var nonEntrypointSet = new Set();
1548
+ id: internalOptions.org
1549
+ });
1309
1550
  var transaction;
1310
1551
  var releaseInjectionSpan;
1311
1552
  return {
@@ -1317,15 +1558,50 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1317
1558
  * Responsible for starting the plugin execution transaction and the release injection span
1318
1559
  */
1319
1560
  buildStart: function buildStart() {
1320
- transaction = sentryHub.startTransaction({
1321
- op: "function.plugin",
1322
- name: "Sentry Bundler Plugin execution"
1323
- });
1324
- releaseInjectionSpan = addSpanToTransaction({
1325
- hub: sentryHub,
1326
- parentSpan: transaction,
1327
- logger: logger
1328
- }, "function.plugin.inject_release", "Release injection");
1561
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
1562
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
1563
+ while (1) {
1564
+ switch (_context.prev = _context.next) {
1565
+ case 0:
1566
+ _context.next = 2;
1567
+ return turnOffTelemetryForSelfHostedSentry(cli, sentryHub);
1568
+
1569
+ case 2:
1570
+ if (internalOptions.release) {
1571
+ _context.next = 6;
1572
+ break;
1573
+ }
1574
+
1575
+ _context.next = 5;
1576
+ return cli.releases.proposeVersion();
1577
+
1578
+ case 5:
1579
+ internalOptions.release = _context.sent;
1580
+
1581
+ case 6:
1582
+ // At this point, we either have determined a release or we have to bail
1583
+ if (!internalOptions.release) {
1584
+ 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);
1585
+ }
1586
+
1587
+ transaction = sentryHub.startTransaction({
1588
+ op: "function.plugin",
1589
+ name: "Sentry Bundler Plugin execution"
1590
+ });
1591
+ releaseInjectionSpan = addSpanToTransaction({
1592
+ hub: sentryHub,
1593
+ parentSpan: transaction,
1594
+ logger: logger,
1595
+ cli: cli
1596
+ }, "function.plugin.inject_release", "Release injection");
1597
+
1598
+ case 9:
1599
+ case "end":
1600
+ return _context.stop();
1601
+ }
1602
+ }
1603
+ }, _callee);
1604
+ }))();
1329
1605
  },
1330
1606
 
1331
1607
  /**
@@ -1347,10 +1623,6 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1347
1623
  level: "info"
1348
1624
  });
1349
1625
 
1350
- if (!isEntry) {
1351
- nonEntrypointSet.add(id);
1352
- }
1353
-
1354
1626
  if (id === RELEASE_INJECTOR_ID) {
1355
1627
  return RELEASE_INJECTOR_ID;
1356
1628
  } else {
@@ -1379,7 +1651,10 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1379
1651
 
1380
1652
  if (id === RELEASE_INJECTOR_ID) {
1381
1653
  return generateGlobalInjectorCode({
1382
- release: getReleaseName(options.release)
1654
+ release: internalOptions.release,
1655
+ injectReleasesMap: internalOptions.injectReleasesMap,
1656
+ org: internalOptions.org,
1657
+ project: internalOptions.project
1383
1658
  });
1384
1659
  } else {
1385
1660
  return undefined;
@@ -1387,42 +1662,48 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1387
1662
  },
1388
1663
 
1389
1664
  /**
1390
- * This hook determines whether we want to transform a module. In the unplugin we want to transform every entrypoint
1391
- * unless configured otherwise with the `entries` option.
1665
+ * This hook determines whether we want to transform a module. In the sentry bundler plugin we want to transform every entrypoint
1666
+ * unless configured otherwise with the `releaseInjectionTargets` option.
1392
1667
  *
1393
1668
  * @param id Always the absolute (fully resolved) path to the module.
1394
- * @returns `true` or `false` depending on whether we want to transform the module. For the sentry-unplugin we only
1669
+ * @returns `true` or `false` depending on whether we want to transform the module. For the sentry bundler plugin we only
1395
1670
  * want to transform the release injector file.
1396
1671
  */
1397
1672
  transformInclude: function transformInclude(id) {
1398
1673
  sentryHub.addBreadcrumb({
1399
1674
  category: "transformInclude",
1400
1675
  level: "info"
1401
- });
1676
+ }); // We don't want to transform our injected code.
1402
1677
 
1403
- if (options.entries) {
1404
- // If there's an `entries` option transform (ie. inject the release varible) when the file path matches the option.
1405
- if (typeof options.entries === "function") {
1406
- return options.entries(id);
1678
+ if (id === RELEASE_INJECTOR_ID) {
1679
+ return false;
1680
+ }
1681
+
1682
+ if (internalOptions.releaseInjectionTargets) {
1683
+ // If there's an `releaseInjectionTargets` option transform (ie. inject the release varible) when the file path matches the option.
1684
+ if (typeof internalOptions.releaseInjectionTargets === "function") {
1685
+ return internalOptions.releaseInjectionTargets(id);
1407
1686
  }
1408
1687
 
1409
- var arrayifiedEntriesOption = Array.isArray(options.entries) ? options.entries : [options.entries];
1410
- return arrayifiedEntriesOption.some(function (entry) {
1688
+ return internalOptions.releaseInjectionTargets.some(function (entry) {
1411
1689
  if (entry instanceof RegExp) {
1412
1690
  return entry.test(id);
1413
1691
  } else {
1414
1692
  return id === entry;
1415
1693
  }
1416
1694
  });
1417
- } // We want to transform (release injection) every module except for "sentry-release-injector".
1418
-
1419
-
1420
- return id !== RELEASE_INJECTOR_ID && !nonEntrypointSet.has(id);
1695
+ } else {
1696
+ var pathIsOrdinary = !id.includes("?") && !id.includes("#");
1697
+ var pathHasAllowedFileEnding = ALLOWED_TRANSFORMATION_FILE_ENDINGS.some(function (allowedFileEnding) {
1698
+ return id.endsWith(allowedFileEnding);
1699
+ });
1700
+ return pathIsOrdinary && pathHasAllowedFileEnding;
1701
+ }
1421
1702
  },
1422
1703
 
1423
1704
  /**
1424
1705
  * This hook is responsible for injecting the "sentry release injector" imoprt statement into each entrypoint unless
1425
- * configured otherwise with the `entries` option (logic for that is in the `transformInclude` hook).
1706
+ * configured otherwise with the `releaseInjectionTargets` option (logic for that is in the `transformInclude` hook).
1426
1707
  *
1427
1708
  * @param code Code of the file to transform.
1428
1709
  * @param id Always the absolute (fully resolved) path to the module.
@@ -1434,11 +1715,10 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1434
1715
  level: "info"
1435
1716
  }); // The MagicString library allows us to generate sourcemaps for the changes we make to the user code.
1436
1717
 
1437
- 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. (┛ಠ_ಠ)┛彡┻━┻
1438
- // appending instead of prepending has less probability of mucking with user'sadly
1439
- // source maps and import statements get to the top anyways
1718
+ var ms = new MagicString__default["default"](code); // Appending instead of prepending has less probability of mucking with user's source maps.
1719
+ // Luckily import statements get hoisted to the top anyways.
1440
1720
 
1441
- ms.append("import \"".concat(RELEASE_INJECTOR_ID, "\";"));
1721
+ ms.append(";\nimport \"".concat(RELEASE_INJECTOR_ID, "\";"));
1442
1722
 
1443
1723
  if (unpluginMetaContext.framework === "esbuild") {
1444
1724
  // esbuild + unplugin is buggy at the moment when we return an object with a `map` (sourcemap) property.
@@ -1457,63 +1737,50 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1457
1737
  * Responsible for executing the sentry release creation pipeline (i.e. creating a release on
1458
1738
  * Sentry.io, uploading sourcemaps, associating commits and deploys and finalizing the release)
1459
1739
  */
1460
- buildEnd: function buildEnd() {
1740
+ writeBundle: function writeBundle() {
1461
1741
  var _releaseInjectionSpan;
1462
1742
 
1463
1743
  (_releaseInjectionSpan = releaseInjectionSpan) === null || _releaseInjectionSpan === void 0 ? void 0 : _releaseInjectionSpan.finish();
1464
1744
  var releasePipelineSpan = transaction && addSpanToTransaction({
1465
1745
  hub: sentryHub,
1466
1746
  parentSpan: transaction,
1467
- logger: logger
1747
+ logger: logger,
1748
+ cli: cli
1468
1749
  }, "function.plugin.release", "Release pipeline");
1469
- var release = getReleaseName(options.release);
1470
1750
  sentryHub.addBreadcrumb({
1471
- category: "buildEnd:start",
1751
+ category: "writeBundle:start",
1472
1752
  level: "info"
1473
- }); //TODO:
1474
- // 1. validate options to see if we get a valid include property, release name, etc.
1475
- // 2. normalize the include property: Users can pass string | string [] | IncludeEntry[].
1476
- // That's good for them but a hassle for us. Let's try to normalize this into one data type
1477
- // (I vote IncludeEntry[]) and continue with that down the line
1478
-
1753
+ });
1479
1754
  var ctx = {
1480
1755
  hub: sentryHub,
1481
1756
  parentSpan: releasePipelineSpan,
1482
- logger: logger
1757
+ logger: logger,
1758
+ cli: cli
1483
1759
  };
1484
- createNewRelease(release, options, ctx).then(function () {
1485
- return cleanArtifacts(release, options, ctx);
1760
+ createNewRelease(internalOptions, ctx).then(function () {
1761
+ return cleanArtifacts(internalOptions, ctx);
1762
+ }).then(function () {
1763
+ return uploadSourceMaps(internalOptions, ctx);
1486
1764
  }).then(function () {
1487
- return uploadSourceMaps(release, options, ctx);
1765
+ return setCommits(internalOptions, ctx);
1488
1766
  }).then(function () {
1489
- return setCommits(ctx);
1490
- }) // this is a noop for now
1491
- .then(function () {
1492
- return finalizeRelease(release, options, ctx);
1767
+ return finalizeRelease(internalOptions, ctx);
1768
+ }).then(function () {
1769
+ return addDeploy(internalOptions, ctx);
1493
1770
  }).then(function () {
1494
- return addDeploy(ctx);
1495
- }) // this is a noop for now
1496
- .then(function () {
1497
1771
  var _transaction;
1498
1772
 
1499
- (_transaction = transaction) === null || _transaction === void 0 ? void 0 : _transaction.setStatus("ok");
1773
+ return (_transaction = transaction) === null || _transaction === void 0 ? void 0 : _transaction.setStatus("ok");
1500
1774
  })["catch"](function (e) {
1501
1775
  var _transaction2;
1502
1776
 
1503
- captureMinimalError(e, sentryHub);
1504
1777
  (_transaction2 = transaction) === null || _transaction2 === void 0 ? void 0 : _transaction2.setStatus("cancelled");
1505
- logger.error(e.message);
1506
-
1507
- if (options.errorHandler) {
1508
- options.errorHandler(e);
1509
- } else {
1510
- throw e;
1511
- }
1778
+ handleError(e, logger, internalOptions.errorHandler, sentryHub);
1512
1779
  })["finally"](function () {
1513
1780
  var _transaction3;
1514
1781
 
1515
1782
  sentryHub.addBreadcrumb({
1516
- category: "buildEnd:finish",
1783
+ category: "writeBundle:finish",
1517
1784
  level: "info"
1518
1785
  });
1519
1786
  releasePipelineSpan === null || releasePipelineSpan === void 0 ? void 0 : releasePipelineSpan.finish();
@@ -1522,16 +1789,41 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1522
1789
  }
1523
1790
  };
1524
1791
  });
1792
+
1793
+ function handleError(error, logger, errorHandler, sentryHub) {
1794
+ logger.error(error.message);
1795
+
1796
+ if (sentryHub) {
1797
+ captureMinimalError(error, sentryHub);
1798
+ }
1799
+
1800
+ if (errorHandler) {
1801
+ errorHandler(error);
1802
+ } else {
1803
+ throw error;
1804
+ }
1805
+ }
1525
1806
  /**
1526
1807
  * Generates code for the "sentry-release-injector" which is responsible for setting the global `SENTRY_RELEASE`
1527
1808
  * variable.
1528
1809
  */
1529
1810
 
1811
+
1530
1812
  function generateGlobalInjectorCode(_ref2) {
1531
- var release = _ref2.release;
1813
+ var release = _ref2.release,
1814
+ injectReleasesMap = _ref2.injectReleasesMap,
1815
+ org = _ref2.org,
1816
+ project = _ref2.project;
1532
1817
  // The code below is mostly ternary operators because it saves bundle size.
1533
1818
  // The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.)
1534
- return "\n var _global =\n typeof window !== 'undefined' ?\n window :\n typeof global !== 'undefined' ?\n global :\n typeof self !== 'undefined' ?\n self :\n {};\n\n _global.SENTRY_RELEASE={id:\"".concat(release, "\"};");
1819
+ var code = "\n var _global =\n typeof window !== 'undefined' ?\n window :\n typeof global !== 'undefined' ?\n global :\n typeof self !== 'undefined' ?\n self :\n {};\n\n _global.SENTRY_RELEASE={id:\"".concat(release, "\"};");
1820
+
1821
+ if (injectReleasesMap && project) {
1822
+ var key = org ? "".concat(project, "@").concat(org) : project;
1823
+ code += "\n _global.SENTRY_RELEASES=_global.SENTRY_RELEASES || {};\n _global.SENTRY_RELEASES[\"".concat(key, "\"]={id:\"").concat(release, "\"};\n ");
1824
+ }
1825
+
1826
+ return code;
1535
1827
  } // eslint-disable-next-line @typescript-eslint/no-explicit-any
1536
1828
 
1537
1829