@sentry/bundler-plugin-core 0.0.1-alpha.0 → 0.1.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,565 @@ 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 ;
462
544
  }
463
545
 
464
- function getGitBranchHead() {
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();
552
+ }
553
+
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);
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);
726
+
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.
478
735
 
736
+ const { performance } = WINDOW;
737
+ if (!performance || !performance.now) {
738
+ return undefined;
739
+ }
479
740
 
480
- if (process.env["SENTRY_RELEASE"]) {
481
- return process.env["SENTRY_RELEASE"];
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
+ entries: normalizeEntries(userOptions.entries),
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 `entries` option to the internal `entries` option
844
+ */
845
+
846
+ function normalizeEntries(userEntries) {
847
+ if (userEntries === undefined) {
848
+ return undefined;
849
+ } else if (typeof userEntries === "function") {
850
+ return userEntries;
851
+ } else {
852
+ return arrayify(userEntries);
853
+ }
854
+ }
855
+ /**
856
+ * Converts the user-facing `include` option to the internal `include` option,
857
+ * resulting in an array of `InternalIncludeEntry` objects. This later on lets us
858
+ * work with only one type of include data structure instead of multiple.
859
+ *
860
+ * During the process, we hoist top-level include options (e.g. urlPrefix) into each
861
+ * object if they were not alrady specified in an `IncludeEntry`, making every object
862
+ * fully self-contained. This is also the reason why we pass the entire options
863
+ * object and not just `include`.
864
+ *
865
+ * @param userOptions the entire user-facing `options` object
866
+ *
867
+ * @return an array of `InternalIncludeEntry` objects.
868
+ */
483
869
 
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);
870
+
871
+ function normalizeInclude(userOptions) {
872
+ return arrayify(userOptions.include).map(function (includeItem) {
873
+ return typeof includeItem === "string" ? {
874
+ paths: [includeItem]
875
+ } : includeItem;
876
+ }).map(function (userIncludeEntry) {
877
+ return normalizeIncludeEntry(userOptions, userIncludeEntry);
878
+ });
879
+ }
880
+ /**
881
+ * Besides array-ifying the `ignore` option, this function hoists top level options into the items of the `include`
882
+ * option. This is to simplify the handling of of the `include` items later on.
883
+ */
884
+
885
+
886
+ function normalizeIncludeEntry(userOptions, includeEntry) {
887
+ 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;
888
+
889
+ var ignoreOption = (_ref4 = (_includeEntry$ignore = includeEntry.ignore) !== null && _includeEntry$ignore !== void 0 ? _includeEntry$ignore : userOptions.ignore) !== null && _ref4 !== void 0 ? _ref4 : ["node_modules"];
890
+ 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()`
891
+
892
+ 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"];
893
+ var dotPrefixedExt = ext.map(function (extension) {
894
+ return ".".concat(extension.replace(/^\./, ""));
492
895
  });
896
+ return {
897
+ paths: includeEntry.paths,
898
+ ignore: ignore,
899
+ ignoreFile: (_includeEntry$ignoreF = includeEntry.ignoreFile) !== null && _includeEntry$ignoreF !== void 0 ? _includeEntry$ignoreF : userOptions.ignoreFile,
900
+ ext: dotPrefixedExt,
901
+ urlPrefix: (_includeEntry$urlPref = includeEntry.urlPrefix) !== null && _includeEntry$urlPref !== void 0 ? _includeEntry$urlPref : userOptions.urlPrefix,
902
+ urlSuffix: (_includeEntry$urlSuff = includeEntry.urlSuffix) !== null && _includeEntry$urlSuff !== void 0 ? _includeEntry$urlSuff : userOptions.urlSuffix,
903
+ stripPrefix: (_includeEntry$stripPr = includeEntry.stripPrefix) !== null && _includeEntry$stripPr !== void 0 ? _includeEntry$stripPr : userOptions.stripPrefix,
904
+ stripCommonPrefix: (_ref6 = (_includeEntry$stripCo = includeEntry.stripCommonPrefix) !== null && _includeEntry$stripCo !== void 0 ? _includeEntry$stripCo : userOptions.stripCommonPrefix) !== null && _ref6 !== void 0 ? _ref6 : false,
905
+ sourceMapReference: (_ref7 = (_includeEntry$sourceM = includeEntry.sourceMapReference) !== null && _includeEntry$sourceM !== void 0 ? _includeEntry$sourceM : userOptions.sourceMapReference) !== null && _ref7 !== void 0 ? _ref7 : true,
906
+ rewrite: (_ref8 = (_includeEntry$rewrite = includeEntry.rewrite) !== null && _includeEntry$rewrite !== void 0 ? _includeEntry$rewrite : userOptions.rewrite) !== null && _ref8 !== void 0 ? _ref8 : true,
907
+ validate: (_ref9 = (_includeEntry$validat = includeEntry.validate) !== null && _includeEntry$validat !== void 0 ? _includeEntry$validat : userOptions.validate) !== null && _ref9 !== void 0 ? _ref9 : false
908
+ };
909
+ }
910
+ /**
911
+ * Validates a few combinations of options that are not checked by Sentry CLI.
912
+ *
913
+ * For all other options, we can rely on Sentry CLI to validate them. In fact,
914
+ * we can't validate them in the plugin because Sentry CLI might pick up options from
915
+ * its config file.
916
+ *
917
+ * @param options the internal options
918
+ * @param logger the logger
919
+ *
920
+ * @returns `true` if the options are valid, `false` otherwise
921
+ */
922
+
493
923
 
494
- if (releaseFromEnvironmentVar) {
495
- return process.env[releaseFromEnvironmentVar];
924
+ function validateOptions(options, logger) {
925
+ if (options.injectReleasesMap && !options.org) {
926
+ 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.");
927
+ return false;
496
928
  }
497
929
 
498
- var gitBranchHead = getGitBranchHead();
930
+ var setCommits = options.setCommits;
499
931
 
500
- if (gitBranchHead) {
501
- return gitBranchHead;
502
- } else {
503
- throw new Error("Could not return a release name");
932
+ if (setCommits) {
933
+ if (!setCommits.auto && !(setCommits.repo && setCommits.commit)) {
934
+ logger.error("The `setCommits` option was specified but is missing required properties.", "Please set either `auto` or both, `repo` and `commit`.");
935
+ return false;
936
+ }
937
+
938
+ if (setCommits.auto && setCommits.repo && setCommits) {
939
+ 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`.");
940
+ }
941
+ }
942
+
943
+ if (options.deploy && !options.deploy.env) {
944
+ logger.error("The `deploy` option was specified but is missing the required `env` property.", "Please set the `env` property.");
945
+ return false;
504
946
  }
947
+
948
+ return true;
505
949
  }
506
950
 
507
- function makeSentryClient(dsn, telemetryEnabled, org) {
951
+ function makeSentryClient(dsn, telemetryEnabled) {
508
952
  var client = new node.NodeClient({
509
953
  dsn: dsn,
510
954
  enabled: telemetryEnabled,
511
955
  tracesSampleRate: telemetryEnabled ? 1.0 : 0.0,
512
956
  sampleRate: telemetryEnabled ? 1.0 : 0.0,
513
- release: "0.0.1-alpha.0",
957
+ release: "0.1.0",
514
958
  integrations: [new node.Integrations.Http({
515
959
  tracing: true
516
960
  })],
517
961
  tracePropagationTargets: ["sentry.io/api"],
518
962
  stackParser: node.defaultStackParser,
519
- transport: node.makeNodeTransport,
520
- debug: true
963
+ transport: node.makeNodeTransport
521
964
  });
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
965
+ var hub = new node.Hub(client); //TODO: This call is problematic because as soon as we set our hub as the current hub
528
966
  // we might interfere with other plugins that use Sentry. However, for now, we'll
529
967
  // leave it in because without it, we can't get distributed traces (which are pretty nice)
530
968
  // Let's keep it until someone complains about interference.
@@ -556,319 +994,135 @@ function addSpanToTransaction(ctx, op, description) {
556
994
  return span;
557
995
  }
558
996
  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
- } : {};
997
+ var sentryError;
998
+
999
+ if (error && _typeof(error) === "object") {
1000
+ var e = error;
1001
+ sentryError = {
1002
+ name: e.name,
1003
+ message: e.message,
1004
+ stack: e.stack
1005
+ };
1006
+ } else {
1007
+ sentryError = {
1008
+ name: "Error",
1009
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
1010
+ message: "".concat(error)
1011
+ };
1012
+ }
1013
+
565
1014
  hub.captureException(sentryError);
566
1015
  }
1016
+ function addPluginOptionTags(options, hub) {
1017
+ var cleanArtifacts = options.cleanArtifacts,
1018
+ finalize = options.finalize,
1019
+ setCommits = options.setCommits,
1020
+ injectReleasesMap = options.injectReleasesMap,
1021
+ dryRun = options.dryRun,
1022
+ errorHandler = options.errorHandler,
1023
+ deploy = options.deploy,
1024
+ include = options.include;
1025
+ hub.setTag("include", include.length > 1 ? "multiple-entries" : "single-entry"); // Optional release pipeline steps
1026
+
1027
+ if (cleanArtifacts) {
1028
+ hub.setTag("clean-artifacts", true);
1029
+ }
567
1030
 
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
- };
1031
+ if (setCommits) {
1032
+ hub.setTag("set-commits", setCommits.auto === true ? "auto" : "manual");
1033
+ }
581
1034
 
582
- function createRelease(_x) {
583
- return _createRelease.apply(this, arguments);
584
- }
1035
+ if (finalize) {
1036
+ hub.setTag("finalize-release", true);
1037
+ }
585
1038
 
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
1039
+ if (deploy) {
1040
+ hub.setTag("add-deploy", true);
1041
+ } // Miscelaneous options
601
1042
 
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
1043
 
614
- case 6:
615
- _context.next = 12;
616
- break;
1044
+ if (dryRun) {
1045
+ hub.setTag("dry-run", true);
1046
+ }
617
1047
 
618
- case 8:
619
- _context.prev = 8;
620
- _context.t0 = _context["catch"](3);
621
- captureMinimalError(_context.t0, sentryHub);
622
- throw _context.t0;
1048
+ if (injectReleasesMap) {
1049
+ hub.setTag("inject-releases-map", true);
1050
+ }
623
1051
 
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
- }
1052
+ if (errorHandler) {
1053
+ hub.setTag("error-handler", "custom");
1054
+ }
633
1055
 
634
- function deleteAllReleaseArtifacts(_x2) {
635
- return _deleteAllReleaseArtifacts.apply(this, arguments);
1056
+ hub.setTag("node", process.version);
636
1057
  }
1058
+ /**
1059
+ * Makes a call to SentryCLI to get the Sentry server URL the CLI uses.
1060
+ *
1061
+ * We need to check and decide to use telemetry based on the CLI's respone to this call
1062
+ * because only at this time we checked a possibly existing .sentryclirc file. This file
1063
+ * could point to another URL than the default URL.
1064
+ */
637
1065
 
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);
1066
+ function turnOffTelemetryForSelfHostedSentry(_x, _x2) {
1067
+ return _turnOffTelemetryForSelfHostedSentry.apply(this, arguments);
676
1068
  }
677
1069
 
678
- function updateRelease(_x3) {
679
- return _updateRelease.apply(this, arguments);
680
- }
1070
+ function _turnOffTelemetryForSelfHostedSentry() {
1071
+ _turnOffTelemetryForSelfHostedSentry = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cli, hub) {
1072
+ var _cliInfo$split$, _cliInfo$split$$repla;
681
1073
 
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) {
1074
+ var cliInfo, url, client;
1075
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
686
1076
  while (1) {
687
- switch (_context3.prev = _context3.next) {
1077
+ switch (_context.prev = _context.next) {
688
1078
  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
- });
704
-
705
- case 6:
706
- _context3.next = 12;
707
- break;
1079
+ _context.next = 2;
1080
+ return cli.execute(["info"], false);
708
1081
 
709
- case 8:
710
- _context3.prev = 8;
711
- _context3.t0 = _context3["catch"](3);
712
- captureMinimalError(_context3.t0, sentryHub);
713
- throw _context3.t0;
1082
+ case 2:
1083
+ cliInfo = _context.sent;
1084
+ url = cliInfo === null || cliInfo === void 0 ? void 0 : (_cliInfo$split$ = cliInfo.split(/(\r\n|\n|\r)/)[0]) === null || _cliInfo$split$ === void 0 ? void 0 : (_cliInfo$split$$repla = _cliInfo$split$.replace(/^Sentry Server: /, "")) === null || _cliInfo$split$$repla === void 0 ? void 0 : _cliInfo$split$$repla.trim();
714
1085
 
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
- }
1086
+ if (url !== SENTRY_SAAS_URL) {
1087
+ client = hub.getClient();
724
1088
 
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"
1089
+ if (client) {
1090
+ client.getOptions().enabled = false;
1091
+ client.getOptions().tracesSampleRate = 0;
1092
+ client.getOptions().sampleRate = 0;
752
1093
  }
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;
1094
+ }
764
1095
 
765
- case 14:
1096
+ case 5:
766
1097
  case "end":
767
- return _context4.stop();
1098
+ return _context.stop();
768
1099
  }
769
1100
  }
770
- }, _callee4, null, [[5, 10]]);
1101
+ }, _callee);
771
1102
  }));
772
- return _uploadReleaseFile.apply(this, arguments);
1103
+ return _turnOffTelemetryForSelfHostedSentry.apply(this, arguments);
773
1104
  }
774
1105
 
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;
804
- }
805
-
806
- function createNewRelease(_x, _x2, _x3) {
1106
+ function createNewRelease(_x, _x2) {
807
1107
  return _createNewRelease.apply(this, arguments);
808
1108
  }
809
1109
 
810
1110
  function _createNewRelease() {
811
- _createNewRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(release, options, ctx) {
1111
+ _createNewRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(options, ctx) {
812
1112
  var span;
813
1113
  return _regeneratorRuntime().wrap(function _callee$(_context) {
814
1114
  while (1) {
815
1115
  switch (_context.prev = _context.next) {
816
1116
  case 0:
817
- span = addSpanToTransaction(ctx, "function.plugin.create_release"); // TODO: pull these checks out of here and simplify them
818
-
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
- });
1117
+ span = addSpanToTransaction(ctx, "function.plugin.create_release");
1118
+ _context.next = 3;
1119
+ return ctx.cli.releases["new"](options.release);
865
1120
 
866
- case 21:
1121
+ case 3:
867
1122
  ctx.logger.info("Successfully created release.");
868
1123
  span === null || span === void 0 ? void 0 : span.finish();
869
- return _context.abrupt("return", Promise.resolve("nothing to do here"));
870
1124
 
871
- case 24:
1125
+ case 5:
872
1126
  case "end":
873
1127
  return _context.stop();
874
1128
  }
@@ -878,288 +1132,201 @@ function _createNewRelease() {
878
1132
  return _createNewRelease.apply(this, arguments);
879
1133
  }
880
1134
 
881
- function uploadSourceMaps(_x4, _x5, _x6) {
882
- return _uploadSourceMaps.apply(this, arguments);
1135
+ function cleanArtifacts(_x3, _x4) {
1136
+ return _cleanArtifacts.apply(this, arguments);
883
1137
  }
884
1138
 
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;
1139
+ function _cleanArtifacts() {
1140
+ _cleanArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options, ctx) {
1141
+ var span;
888
1142
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
889
1143
  while (1) {
890
1144
  switch (_context2.prev = _context2.next) {
891
1145
  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;
1146
+ if (options.cleanArtifacts) {
1147
+ _context2.next = 3;
921
1148
  break;
922
1149
  }
923
1150
 
924
- ctx.logger.warn('Missing "org" option. Will not create release.');
925
- return _context2.abrupt("return", Promise.resolve("nothing to do here"));
1151
+ logger.debug("Skipping artifact cleanup.");
1152
+ return _context2.abrupt("return");
926
1153
 
927
- case 12:
928
- if (!(url === undefined)) {
929
- _context2.next = 17;
930
- break;
931
- }
932
-
933
- ctx.logger.warn('Missing "url" option. Will not create release.');
934
- return _context2.abrupt("return", Promise.resolve("nothing to do here"));
1154
+ case 3:
1155
+ span = addSpanToTransaction(ctx, "function.plugin.clean_artifacts");
1156
+ _context2.next = 6;
1157
+ return ctx.cli.releases.execute(["releases", "files", options.release, "delete", "--all"], true);
935
1158
 
936
- case 17:
937
- if (!(project === undefined)) {
938
- _context2.next = 20;
939
- break;
940
- }
1159
+ case 6:
1160
+ ctx.logger.info("Successfully cleaned previous artifacts.");
1161
+ span === null || span === void 0 ? void 0 : span.finish();
941
1162
 
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:
1163
+ case 8:
970
1164
  case "end":
971
1165
  return _context2.stop();
972
1166
  }
973
1167
  }
974
1168
  }, _callee2);
975
1169
  }));
976
- return _uploadSourceMaps.apply(this, arguments);
1170
+ return _cleanArtifacts.apply(this, arguments);
977
1171
  }
978
1172
 
979
- function finalizeRelease(_x7, _x8, _x9) {
980
- return _finalizeRelease.apply(this, arguments);
1173
+ function uploadSourceMaps(_x5, _x6) {
1174
+ return _uploadSourceMaps.apply(this, arguments);
981
1175
  }
982
1176
 
983
- function _finalizeRelease() {
984
- _finalizeRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(release, options, ctx) {
985
- var span, authToken, org, url, project;
1177
+ function _uploadSourceMaps() {
1178
+ _uploadSourceMaps = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(options, ctx) {
1179
+ var span;
986
1180
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
987
1181
  while (1) {
988
1182
  switch (_context3.prev = _context3.next) {
989
1183
  case 0:
990
- span = addSpanToTransaction(ctx, "function.plugin.finalize_release");
1184
+ span = addSpanToTransaction(ctx, "function.plugin.upload_sourcemaps");
1185
+ ctx.logger.info("Uploading Sourcemaps."); // Since our internal include entries contain all top-level sourcemaps options,
1186
+ // we only need to pass the include option here.
991
1187
 
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;
998
-
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
1188
+ _context3.next = 4;
1189
+ return ctx.cli.releases.uploadSourceMaps(options.release, {
1190
+ include: options.include
1017
1191
  });
1018
1192
 
1019
- case 8:
1020
- ctx.logger.info("Successfully finalized release.");
1021
-
1022
- case 9:
1193
+ case 4:
1194
+ ctx.logger.info("Successfully uploaded Sourcemaps.");
1023
1195
  span === null || span === void 0 ? void 0 : span.finish();
1024
- return _context3.abrupt("return", Promise.resolve("nothing to do here"));
1025
1196
 
1026
- case 11:
1197
+ case 6:
1027
1198
  case "end":
1028
1199
  return _context3.stop();
1029
1200
  }
1030
1201
  }
1031
1202
  }, _callee3);
1032
1203
  }));
1033
- return _finalizeRelease.apply(this, arguments);
1204
+ return _uploadSourceMaps.apply(this, arguments);
1034
1205
  }
1035
1206
 
1036
- function cleanArtifacts(_x10, _x11, _x12) {
1037
- return _cleanArtifacts.apply(this, arguments);
1038
- } // TODO: Stuff we worry about later:
1207
+ function setCommits(_x7, _x8) {
1208
+ return _setCommits.apply(this, arguments);
1209
+ }
1210
+
1211
+ function _setCommits() {
1212
+ _setCommits = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(options, ctx) {
1213
+ var span, _options$setCommits, auto, repo, commit, previousCommit, ignoreMissing, ignoreEmpty;
1039
1214
 
1040
- function _cleanArtifacts() {
1041
- _cleanArtifacts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(release, options, ctx) {
1042
- var span;
1043
1215
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
1044
1216
  while (1) {
1045
1217
  switch (_context4.prev = _context4.next) {
1046
1218
  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;
1219
+ if (options.setCommits) {
1220
+ _context4.next = 3;
1056
1221
  break;
1057
1222
  }
1058
1223
 
1059
- ctx.logger.warn('Missing "authToken" option. Will not clean existing artifacts.');
1060
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1224
+ logger.debug("Skipping setting commits to release.");
1225
+ return _context4.abrupt("return");
1061
1226
 
1062
- case 7:
1063
- if (!(options.org === undefined)) {
1064
- _context4.next = 12;
1065
- break;
1066
- }
1067
-
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
- }
1085
-
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
1227
+ case 3:
1228
+ span = addSpanToTransaction(ctx, "function.plugin.set_commits");
1229
+ _options$setCommits = options.setCommits, auto = _options$setCommits.auto, repo = _options$setCommits.repo, commit = _options$setCommits.commit, previousCommit = _options$setCommits.previousCommit, ignoreMissing = _options$setCommits.ignoreMissing, ignoreEmpty = _options$setCommits.ignoreEmpty;
1230
+ _context4.next = 7;
1231
+ return ctx.cli.releases.setCommits(options.release, {
1232
+ commit: commit,
1233
+ previousCommit: previousCommit,
1234
+ repo: repo,
1235
+ auto: auto,
1236
+ ignoreMissing: ignoreMissing,
1237
+ ignoreEmpty: ignoreEmpty
1099
1238
  });
1100
1239
 
1101
- case 22:
1102
- ctx.logger.info("Successfully cleaned previous artifacts.");
1103
-
1104
- case 23:
1240
+ case 7:
1241
+ ctx.logger.info("Successfully set commits.");
1105
1242
  span === null || span === void 0 ? void 0 : span.finish();
1106
- return _context4.abrupt("return", Promise.resolve("nothing to do here"));
1107
1243
 
1108
- case 25:
1244
+ case 9:
1109
1245
  case "end":
1110
1246
  return _context4.stop();
1111
1247
  }
1112
1248
  }
1113
1249
  }, _callee4);
1114
1250
  }));
1115
- return _cleanArtifacts.apply(this, arguments);
1251
+ return _setCommits.apply(this, arguments);
1116
1252
  }
1117
1253
 
1118
- function setCommits(_x13) {
1119
- return _setCommits.apply(this, arguments);
1254
+ function finalizeRelease(_x9, _x10) {
1255
+ return _finalizeRelease.apply(this, arguments);
1120
1256
  }
1121
1257
 
1122
- function _setCommits() {
1123
- _setCommits = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(
1124
- /* version: string, */
1125
- ctx) {
1258
+ function _finalizeRelease() {
1259
+ _finalizeRelease = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(options, ctx) {
1126
1260
  var span;
1127
1261
  return _regeneratorRuntime().wrap(function _callee5$(_context5) {
1128
1262
  while (1) {
1129
1263
  switch (_context5.prev = _context5.next) {
1130
1264
  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"));
1265
+ if (options.finalize) {
1266
+ _context5.next = 3;
1267
+ break;
1268
+ }
1269
+
1270
+ logger.debug("Skipping release finalization.");
1271
+ return _context5.abrupt("return");
1134
1272
 
1135
1273
  case 3:
1274
+ span = addSpanToTransaction(ctx, "function.plugin.finalize_release");
1275
+ _context5.next = 6;
1276
+ return ctx.cli.releases.finalize(options.release);
1277
+
1278
+ case 6:
1279
+ ctx.logger.info("Successfully finalized release.");
1280
+ span === null || span === void 0 ? void 0 : span.finish();
1281
+
1282
+ case 8:
1136
1283
  case "end":
1137
1284
  return _context5.stop();
1138
1285
  }
1139
1286
  }
1140
1287
  }, _callee5);
1141
1288
  }));
1142
- return _setCommits.apply(this, arguments);
1289
+ return _finalizeRelease.apply(this, arguments);
1143
1290
  }
1144
1291
 
1145
- function addDeploy(_x14) {
1292
+ function addDeploy(_x11, _x12) {
1146
1293
  return _addDeploy.apply(this, arguments);
1147
1294
  }
1148
1295
 
1149
1296
  function _addDeploy() {
1150
- _addDeploy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(
1151
- /* version: string, */
1152
- ctx) {
1153
- var span;
1297
+ _addDeploy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(options, ctx) {
1298
+ var span, _options$deploy, env, started, finished, time, name, url;
1299
+
1154
1300
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
1155
1301
  while (1) {
1156
1302
  switch (_context6.prev = _context6.next) {
1157
1303
  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"));
1304
+ if (options.deploy) {
1305
+ _context6.next = 3;
1306
+ break;
1307
+ }
1308
+
1309
+ logger.debug("Skipping adding deploy info to release.");
1310
+ return _context6.abrupt("return");
1161
1311
 
1162
1312
  case 3:
1313
+ span = addSpanToTransaction(ctx, "function.plugin.deploy");
1314
+ _options$deploy = options.deploy, env = _options$deploy.env, started = _options$deploy.started, finished = _options$deploy.finished, time = _options$deploy.time, name = _options$deploy.name, url = _options$deploy.url;
1315
+ _context6.next = 7;
1316
+ return ctx.cli.releases.newDeploy(options.release, {
1317
+ env: env,
1318
+ started: started,
1319
+ finished: finished,
1320
+ time: time,
1321
+ name: name,
1322
+ url: url
1323
+ });
1324
+
1325
+ case 7:
1326
+ ctx.logger.info("Successfully added deploy.");
1327
+ span === null || span === void 0 ? void 0 : span.finish();
1328
+
1329
+ case 9:
1163
1330
  case "end":
1164
1331
  return _context6.stop();
1165
1332
  }
@@ -1180,69 +1347,166 @@ function createLogger(options) {
1180
1347
 
1181
1348
  return {
1182
1349
  info: function info(message) {
1183
- if (!(options !== null && options !== void 0 && options.silent)) {
1350
+ if (!options.silent) {
1351
+ var _console;
1352
+
1353
+ for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1354
+ params[_key - 1] = arguments[_key];
1355
+ }
1356
+
1184
1357
  // eslint-disable-next-line no-console
1185
- console.log("".concat(options.prefix, " ").concat(message));
1358
+ (_console = console).log.apply(_console, ["".concat(options.prefix, " Info: ").concat(message)].concat(params));
1186
1359
  }
1187
1360
 
1188
1361
  addBreadcrumb("info", message);
1189
1362
  },
1190
1363
  warn: function warn(message) {
1191
- if (!(options !== null && options !== void 0 && options.silent)) {
1364
+ if (!options.silent) {
1365
+ var _console2;
1366
+
1367
+ for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1368
+ params[_key2 - 1] = arguments[_key2];
1369
+ }
1370
+
1192
1371
  // eslint-disable-next-line no-console
1193
- console.log("".concat(options.prefix, " Warning! ").concat(message));
1372
+ (_console2 = console).log.apply(_console2, ["".concat(options.prefix, " Warning: ").concat(message)].concat(params));
1194
1373
  }
1195
1374
 
1196
1375
  addBreadcrumb("warning", message);
1197
1376
  },
1198
1377
  error: function error(message) {
1199
- if (!(options !== null && options !== void 0 && options.silent)) {
1378
+ if (!options.silent) {
1379
+ var _console3;
1380
+
1381
+ for (var _len3 = arguments.length, params = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1382
+ params[_key3 - 1] = arguments[_key3];
1383
+ }
1384
+
1200
1385
  // eslint-disable-next-line no-console
1201
- console.log("".concat(options.prefix, " Error: ").concat(message));
1386
+ (_console3 = console).log.apply(_console3, ["".concat(options.prefix, " Error: ").concat(message)].concat(params));
1202
1387
  }
1203
1388
 
1204
1389
  addBreadcrumb("error", message);
1390
+ },
1391
+ debug: function debug(message) {
1392
+ if (!options.silent && options.debug) {
1393
+ var _console4;
1394
+
1395
+ for (var _len4 = arguments.length, params = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
1396
+ params[_key4 - 1] = arguments[_key4];
1397
+ }
1398
+
1399
+ // eslint-disable-next-line no-console
1400
+ (_console4 = console).log.apply(_console4, ["".concat(options.prefix, " Debug: ").concat(message)].concat(params));
1401
+ }
1402
+
1403
+ addBreadcrumb("debug", message);
1404
+ }
1405
+ };
1406
+ }
1407
+
1408
+ /**
1409
+ * Creates a new Sentry CLI instance.
1410
+ *
1411
+ * In case, users selected the `dryRun` options, this returns a stub
1412
+ * that makes no-ops out of most CLI operations
1413
+ */
1414
+ function getSentryCli(internalOptions, logger) {
1415
+ var silent = internalOptions.silent,
1416
+ org = internalOptions.org,
1417
+ project = internalOptions.project,
1418
+ authToken = internalOptions.authToken,
1419
+ url = internalOptions.url,
1420
+ vcsRemote = internalOptions.vcsRemote,
1421
+ customHeader = internalOptions.customHeader,
1422
+ dist = internalOptions.dist;
1423
+ var cli = new SentryCli__default["default"](internalOptions.configFile, {
1424
+ url: url,
1425
+ authToken: authToken,
1426
+ org: org,
1427
+ project: project,
1428
+ vcsRemote: vcsRemote,
1429
+ dist: dist,
1430
+ silent: silent,
1431
+ customHeader: customHeader
1432
+ });
1433
+
1434
+ if (internalOptions.dryRun) {
1435
+ logger.info("In DRY RUN Mode");
1436
+ return getDryRunCLI(cli, logger);
1437
+ }
1438
+
1439
+ return cli;
1440
+ }
1441
+
1442
+ function getDryRunCLI(cli, logger) {
1443
+ return {
1444
+ releases: {
1445
+ proposeVersion: function proposeVersion() {
1446
+ return cli.releases.proposeVersion().then(function (version) {
1447
+ logger.info("Proposed version:\n", version);
1448
+ return version;
1449
+ });
1450
+ },
1451
+ "new": function _new(release) {
1452
+ logger.info("Creating new release:\n", release);
1453
+ return Promise.resolve(release);
1454
+ },
1455
+ uploadSourceMaps: function uploadSourceMaps(release, config) {
1456
+ logger.info("Calling upload-sourcemaps with:\n", config);
1457
+ return Promise.resolve(release);
1458
+ },
1459
+ finalize: function finalize(release) {
1460
+ logger.info("Finalizing release:\n", release);
1461
+ return Promise.resolve(release);
1462
+ },
1463
+ setCommits: function setCommits(release, config) {
1464
+ logger.info("Calling set-commits with:\n", config);
1465
+ return Promise.resolve(release);
1466
+ },
1467
+ newDeploy: function newDeploy(release, config) {
1468
+ logger.info("Calling deploy with:\n", config);
1469
+ return Promise.resolve(release);
1470
+ },
1471
+ execute: function execute(args, live) {
1472
+ logger.info("Executing", args, "live:", live);
1473
+ return Promise.resolve("");
1474
+ }
1475
+ },
1476
+ execute: function execute(args, live) {
1477
+ logger.info("Executing", args, "live:", live);
1478
+ return Promise.resolve("Executed");
1205
1479
  }
1206
1480
  };
1207
1481
  }
1208
1482
 
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.
1483
+ // We prefix the polyfill id with \0 to tell other plugins not to try to load or transform it.
1219
1484
  // This hack is taken straight from https://rollupjs.org/guide/en/#resolveid.
1220
1485
  // This probably doesn't work for all bundlers but for rollup it does.
1221
-
1222
1486
  var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1223
1487
  /**
1224
- * The sentry-unplugin concerns itself with two things:
1488
+ * The sentry bundler plugin concerns itself with two things:
1225
1489
  * - Release injection
1226
1490
  * - Sourcemaps upload
1227
1491
  *
1228
1492
  * Release injection:
1229
1493
  *
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
1494
+ * Per default the sentry bundler plugin will inject a global `SENTRY_RELEASE` variable into the entrypoint of all bundles.
1495
+ * On a technical level this is done by appending an import (`import "sentry-release-injector;"`) to all entrypoint files
1496
+ * of the user code (see `transformInclude` and `transform` hooks). This import is then resolved by the sentry plugin
1233
1497
  * to a virtual module that sets the global variable (see `resolveId` and `load` hooks).
1234
1498
  *
1235
1499
  * The resulting output approximately looks like this:
1236
1500
  *
1237
1501
  * ```text
1238
1502
  * entrypoint1.js (user file)
1239
- * ┌───────────────────┐ ┌─────────────────────────────────────────────────┐
1240
- * │ │ import { myFunction } from "./my-library.js"; │
1241
- * │ sentry-unplugin │ │
1242
- * │ │ const myResult = myFunction(); │
1243
- * └---------│---------┘ │ export { myResult }; │
1503
+ * ┌─────────────────────────┐ ┌─────────────────────────────────────────────────┐
1504
+ * │ │ import { myFunction } from "./my-library.js"; │
1505
+ * │ sentry-bundler-plugin │ │
1506
+ * │ │ const myResult = myFunction(); │
1507
+ * └---------│--------------- │ export { myResult }; │
1244
1508
  * │ │ │
1245
- * │ injects │ // injected by sentry-unplugin
1509
+ * │ injects │ // injected by sentry plugin
1246
1510
  * ├───────────────────► import "sentry-release-injector"; ─────────────────────┐
1247
1511
  * │ └─────────────────────────────────────────────────┘ │
1248
1512
  * │ │
@@ -1253,7 +1517,7 @@ var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1253
1517
  * │ │ return "Hello world!"; │ │
1254
1518
  * │ │ } │ │
1255
1519
  * │ │ │ │
1256
- * │ injects │ // injected by sentry-unplugin │ │
1520
+ * │ injects │ // injected by sentry plugin │ │
1257
1521
  * └───────────────────► import "sentry-release-injector"; ─────────────────────┤
1258
1522
  * └─────────────────────────────────────────────────┘ │
1259
1523
  * │
@@ -1261,7 +1525,7 @@ var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1261
1525
  * sentry-release-injector │
1262
1526
  * ┌──────────────────────────────────┐ │
1263
1527
  * │ │ is resolved │
1264
- * │ global.SENTRY_RELEASE = { ... } │ by unplugin
1528
+ * │ global.SENTRY_RELEASE = { ... } │ by plugin
1265
1529
  * │ // + a little more logic │<─────────────────────┘
1266
1530
  * │ │ (only once)
1267
1531
  * └──────────────────────────────────┘
@@ -1269,37 +1533,51 @@ var RELEASE_INJECTOR_ID = "\0sentry-release-injector";
1269
1533
  *
1270
1534
  * Source maps upload:
1271
1535
  *
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
1536
+ * The sentry bundler plugin will also take care of uploading source maps to Sentry. This is all done in the
1537
+ * `writeBundle` hook. In this hook the sentry plugin will execute the release creation pipeline:
1538
+ *
1539
+ * 1. Create a new release
1540
+ * 2. Delete already uploaded artifacts for this release (if `cleanArtifacts` is enabled)
1541
+ * 3. Upload sourcemaps based on `include` and source-map-specific options
1542
+ * 4. Associate a range of commits with the release (if `setCommits` is specified)
1543
+ * 5. Finalize the release (unless `finalize` is disabled)
1544
+ * 6. Add deploy information to the release (if `deploy` is specified)
1545
+ *
1546
+ * This release creation pipeline relies on Sentry CLI to execute the different steps.
1274
1547
  */
1275
1548
 
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
-
1549
+ var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext) {
1550
+ var internalOptions = normalizeUserOptions(options);
1279
1551
 
1280
- var telemetryEnabled = options.telemetry === true;
1281
-
1282
- var _makeSentryClient = makeSentryClient("https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737", telemetryEnabled, options.org),
1552
+ var _makeSentryClient = makeSentryClient("https://4c2bae7d9fbc413e8f7385f55c515d51@o1.ingest.sentry.io/6690737", internalOptions.telemetry),
1283
1553
  sentryHub = _makeSentryClient.hub;
1284
1554
 
1555
+ addPluginOptionTags(internalOptions, sentryHub);
1285
1556
  var logger = createLogger({
1286
1557
  hub: sentryHub,
1287
1558
  prefix: "[sentry-".concat(unpluginMetaContext.framework, "-plugin]"),
1288
- silent: options.silent
1559
+ silent: internalOptions.silent,
1560
+ debug: internalOptions.debug
1289
1561
  });
1290
1562
 
1291
- if (telemetryEnabled) {
1563
+ if (!validateOptions(internalOptions, logger)) {
1564
+ handleError(new Error("Options were not set correctly. See output above for more details."), logger, internalOptions.errorHandler);
1565
+ }
1566
+
1567
+ var cli = getSentryCli(internalOptions, logger);
1568
+
1569
+ if (internalOptions.telemetry) {
1292
1570
  logger.info("Sending error and performance telemetry data to Sentry.");
1293
1571
  logger.info("To disable telemetry, set `options.telemetry` to `false`.");
1294
1572
  }
1295
1573
 
1296
1574
  sentryHub.setTags({
1297
- organization: options.org,
1298
- project: options.project,
1575
+ organization: internalOptions.org,
1576
+ project: internalOptions.project,
1299
1577
  bundler: unpluginMetaContext.framework
1300
1578
  });
1301
1579
  sentryHub.setUser({
1302
- id: options.org
1580
+ id: internalOptions.org
1303
1581
  }); // This is `nonEntrypointSet` instead of `entrypointSet` because this set is filled in the `resolveId` hook and there
1304
1582
  // we don't have guaranteed access to *absolute* paths of files if they're entrypoints. For non-entrypoints we're
1305
1583
  // guaranteed to have absolute paths - we're then using the paths in later hooks to make decisions about whether a
@@ -1317,15 +1595,50 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1317
1595
  * Responsible for starting the plugin execution transaction and the release injection span
1318
1596
  */
1319
1597
  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");
1598
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
1599
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
1600
+ while (1) {
1601
+ switch (_context.prev = _context.next) {
1602
+ case 0:
1603
+ _context.next = 2;
1604
+ return turnOffTelemetryForSelfHostedSentry(cli, sentryHub);
1605
+
1606
+ case 2:
1607
+ if (internalOptions.release) {
1608
+ _context.next = 6;
1609
+ break;
1610
+ }
1611
+
1612
+ _context.next = 5;
1613
+ return cli.releases.proposeVersion();
1614
+
1615
+ case 5:
1616
+ internalOptions.release = _context.sent;
1617
+
1618
+ case 6:
1619
+ // At this point, we either have determined a release or we have to bail
1620
+ if (!internalOptions.release) {
1621
+ handleError(new Error("Unable to determine a release name. Make sure to set the `release` option or use an environment that supports auto-detection https://docs.sentry.io/cli/releases/#creating-releases`"), logger, internalOptions.errorHandler, sentryHub);
1622
+ }
1623
+
1624
+ transaction = sentryHub.startTransaction({
1625
+ op: "function.plugin",
1626
+ name: "Sentry Bundler Plugin execution"
1627
+ });
1628
+ releaseInjectionSpan = addSpanToTransaction({
1629
+ hub: sentryHub,
1630
+ parentSpan: transaction,
1631
+ logger: logger,
1632
+ cli: cli
1633
+ }, "function.plugin.inject_release", "Release injection");
1634
+
1635
+ case 9:
1636
+ case "end":
1637
+ return _context.stop();
1638
+ }
1639
+ }
1640
+ }, _callee);
1641
+ }))();
1329
1642
  },
1330
1643
 
1331
1644
  /**
@@ -1379,7 +1692,10 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1379
1692
 
1380
1693
  if (id === RELEASE_INJECTOR_ID) {
1381
1694
  return generateGlobalInjectorCode({
1382
- release: getReleaseName(options.release)
1695
+ release: internalOptions.release,
1696
+ injectReleasesMap: internalOptions.injectReleasesMap,
1697
+ org: internalOptions.org,
1698
+ project: internalOptions.project
1383
1699
  });
1384
1700
  } else {
1385
1701
  return undefined;
@@ -1387,11 +1703,11 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1387
1703
  },
1388
1704
 
1389
1705
  /**
1390
- * This hook determines whether we want to transform a module. In the unplugin we want to transform every entrypoint
1706
+ * This hook determines whether we want to transform a module. In the sentry bundler plugin we want to transform every entrypoint
1391
1707
  * unless configured otherwise with the `entries` option.
1392
1708
  *
1393
1709
  * @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
1710
+ * @returns `true` or `false` depending on whether we want to transform the module. For the sentry bundler plugin we only
1395
1711
  * want to transform the release injector file.
1396
1712
  */
1397
1713
  transformInclude: function transformInclude(id) {
@@ -1400,14 +1716,13 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1400
1716
  level: "info"
1401
1717
  });
1402
1718
 
1403
- if (options.entries) {
1719
+ if (internalOptions.entries) {
1404
1720
  // 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);
1721
+ if (typeof internalOptions.entries === "function") {
1722
+ return internalOptions.entries(id);
1407
1723
  }
1408
1724
 
1409
- var arrayifiedEntriesOption = Array.isArray(options.entries) ? options.entries : [options.entries];
1410
- return arrayifiedEntriesOption.some(function (entry) {
1725
+ return internalOptions.entries.some(function (entry) {
1411
1726
  if (entry instanceof RegExp) {
1412
1727
  return entry.test(id);
1413
1728
  } else {
@@ -1457,63 +1772,50 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1457
1772
  * Responsible for executing the sentry release creation pipeline (i.e. creating a release on
1458
1773
  * Sentry.io, uploading sourcemaps, associating commits and deploys and finalizing the release)
1459
1774
  */
1460
- buildEnd: function buildEnd() {
1775
+ writeBundle: function writeBundle() {
1461
1776
  var _releaseInjectionSpan;
1462
1777
 
1463
1778
  (_releaseInjectionSpan = releaseInjectionSpan) === null || _releaseInjectionSpan === void 0 ? void 0 : _releaseInjectionSpan.finish();
1464
1779
  var releasePipelineSpan = transaction && addSpanToTransaction({
1465
1780
  hub: sentryHub,
1466
1781
  parentSpan: transaction,
1467
- logger: logger
1782
+ logger: logger,
1783
+ cli: cli
1468
1784
  }, "function.plugin.release", "Release pipeline");
1469
- var release = getReleaseName(options.release);
1470
1785
  sentryHub.addBreadcrumb({
1471
- category: "buildEnd:start",
1786
+ category: "writeBundle:start",
1472
1787
  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
-
1788
+ });
1479
1789
  var ctx = {
1480
1790
  hub: sentryHub,
1481
1791
  parentSpan: releasePipelineSpan,
1482
- logger: logger
1792
+ logger: logger,
1793
+ cli: cli
1483
1794
  };
1484
- createNewRelease(release, options, ctx).then(function () {
1485
- return cleanArtifacts(release, options, ctx);
1795
+ createNewRelease(internalOptions, ctx).then(function () {
1796
+ return cleanArtifacts(internalOptions, ctx);
1797
+ }).then(function () {
1798
+ return uploadSourceMaps(internalOptions, ctx);
1486
1799
  }).then(function () {
1487
- return uploadSourceMaps(release, options, ctx);
1800
+ return setCommits(internalOptions, ctx);
1488
1801
  }).then(function () {
1489
- return setCommits(ctx);
1490
- }) // this is a noop for now
1491
- .then(function () {
1492
- return finalizeRelease(release, options, ctx);
1802
+ return finalizeRelease(internalOptions, ctx);
1803
+ }).then(function () {
1804
+ return addDeploy(internalOptions, ctx);
1493
1805
  }).then(function () {
1494
- return addDeploy(ctx);
1495
- }) // this is a noop for now
1496
- .then(function () {
1497
1806
  var _transaction;
1498
1807
 
1499
- (_transaction = transaction) === null || _transaction === void 0 ? void 0 : _transaction.setStatus("ok");
1808
+ return (_transaction = transaction) === null || _transaction === void 0 ? void 0 : _transaction.setStatus("ok");
1500
1809
  })["catch"](function (e) {
1501
1810
  var _transaction2;
1502
1811
 
1503
- captureMinimalError(e, sentryHub);
1504
1812
  (_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
- }
1813
+ handleError(e, logger, internalOptions.errorHandler, sentryHub);
1512
1814
  })["finally"](function () {
1513
1815
  var _transaction3;
1514
1816
 
1515
1817
  sentryHub.addBreadcrumb({
1516
- category: "buildEnd:finish",
1818
+ category: "writeBundle:finish",
1517
1819
  level: "info"
1518
1820
  });
1519
1821
  releasePipelineSpan === null || releasePipelineSpan === void 0 ? void 0 : releasePipelineSpan.finish();
@@ -1522,16 +1824,41 @@ var unplugin = unplugin$1.createUnplugin(function (originalOptions, unpluginMeta
1522
1824
  }
1523
1825
  };
1524
1826
  });
1827
+
1828
+ function handleError(error, logger, errorHandler, sentryHub) {
1829
+ logger.error(error.message);
1830
+
1831
+ if (sentryHub) {
1832
+ captureMinimalError(error, sentryHub);
1833
+ }
1834
+
1835
+ if (errorHandler) {
1836
+ errorHandler(error);
1837
+ } else {
1838
+ throw error;
1839
+ }
1840
+ }
1525
1841
  /**
1526
1842
  * Generates code for the "sentry-release-injector" which is responsible for setting the global `SENTRY_RELEASE`
1527
1843
  * variable.
1528
1844
  */
1529
1845
 
1846
+
1530
1847
  function generateGlobalInjectorCode(_ref2) {
1531
- var release = _ref2.release;
1848
+ var release = _ref2.release,
1849
+ injectReleasesMap = _ref2.injectReleasesMap,
1850
+ org = _ref2.org,
1851
+ project = _ref2.project;
1532
1852
  // The code below is mostly ternary operators because it saves bundle size.
1533
1853
  // 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, "\"};");
1854
+ 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, "\"};");
1855
+
1856
+ if (injectReleasesMap && project) {
1857
+ var key = org ? "".concat(project, "@").concat(org) : project;
1858
+ code += "\n _global.SENTRY_RELEASES=_global.SENTRY_RELEASES || {};\n _global.SENTRY_RELEASES[\"".concat(key, "\"]={id:\"").concat(release, "\"};\n ");
1859
+ }
1860
+
1861
+ return code;
1535
1862
  } // eslint-disable-next-line @typescript-eslint/no-explicit-any
1536
1863
 
1537
1864