@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 +999 -707
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +998 -684
- package/dist/esm/index.js.map +1 -1
- package/dist/types/options-mapping.d.ts +30 -0
- package/dist/types/sentry/cli.d.ts +16 -0
- package/dist/types/sentry/logger.d.ts +8 -5
- package/dist/types/sentry/releasePipeline.d.ts +8 -7
- package/dist/types/sentry/telemetry.d.ts +14 -5
- package/dist/types/types.d.ts +292 -14
- package/dist/types/utils.d.ts +7 -0
- package/package.json +21 -12
- package/dist/types/getReleaseName.d.ts +0 -1
- package/dist/types/sentry/api.d.ts +0 -39
- package/dist/types/sentry/sourcemaps.d.ts +0 -5
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
|
|
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
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
|
|
538
|
+
CONSOLE_LEVELS.forEach(name => {
|
|
539
|
+
logger[name] = () => undefined;
|
|
540
|
+
});
|
|
459
541
|
}
|
|
460
542
|
|
|
461
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
467
|
-
|
|
468
|
-
|
|
690
|
+
const perfHooks = dynamicRequire(module, 'perf_hooks') ;
|
|
691
|
+
return perfHooks.performance;
|
|
692
|
+
} catch (_) {
|
|
469
693
|
return undefined;
|
|
470
694
|
}
|
|
471
695
|
}
|
|
472
696
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
-
|
|
481
|
-
|
|
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
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
"
|
|
488
|
-
|
|
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
|
-
|
|
495
|
-
|
|
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
|
|
931
|
+
var setCommits = options.setCommits;
|
|
499
932
|
|
|
500
|
-
if (
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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
|
|
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.
|
|
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
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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
|
-
|
|
569
|
-
|
|
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
|
-
|
|
583
|
-
|
|
584
|
-
}
|
|
1036
|
+
if (finalize) {
|
|
1037
|
+
hub.setTag("finalize-release", true);
|
|
1038
|
+
}
|
|
585
1039
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
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
|
-
|
|
615
|
-
|
|
616
|
-
|
|
1045
|
+
if (dryRun) {
|
|
1046
|
+
hub.setTag("dry-run", true);
|
|
1047
|
+
}
|
|
617
1048
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
captureMinimalError(_context.t0, sentryHub);
|
|
622
|
-
throw _context.t0;
|
|
1049
|
+
if (injectReleasesMap) {
|
|
1050
|
+
hub.setTag("inject-releases-map", true);
|
|
1051
|
+
}
|
|
623
1052
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
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
|
-
|
|
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
|
|
639
|
-
|
|
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
|
|
679
|
-
|
|
680
|
-
|
|
1071
|
+
function _turnOffTelemetryForSelfHostedSentry() {
|
|
1072
|
+
_turnOffTelemetryForSelfHostedSentry = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cli, hub) {
|
|
1073
|
+
var _cliInfo$split$, _cliInfo$split$$repla;
|
|
681
1074
|
|
|
682
|
-
|
|
683
|
-
|
|
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 (
|
|
1078
|
+
switch (_context.prev = _context.next) {
|
|
688
1079
|
case 0:
|
|
689
|
-
|
|
690
|
-
|
|
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
|
|
706
|
-
|
|
707
|
-
|
|
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
|
-
|
|
710
|
-
|
|
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
|
-
|
|
716
|
-
|
|
717
|
-
|
|
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
|
|
1097
|
+
case 5:
|
|
766
1098
|
case "end":
|
|
767
|
-
return
|
|
1099
|
+
return _context.stop();
|
|
768
1100
|
}
|
|
769
1101
|
}
|
|
770
|
-
},
|
|
1102
|
+
}, _callee);
|
|
771
1103
|
}));
|
|
772
|
-
return
|
|
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
|
|
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(
|
|
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");
|
|
1118
|
+
span = addSpanToTransaction(ctx, "function.plugin.create_release");
|
|
1119
|
+
_context.next = 3;
|
|
1120
|
+
return ctx.cli.releases["new"](options.release);
|
|
818
1121
|
|
|
819
|
-
|
|
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
|
|
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
|
|
882
|
-
return
|
|
1136
|
+
function cleanArtifacts(_x3, _x4) {
|
|
1137
|
+
return _cleanArtifacts.apply(this, arguments);
|
|
883
1138
|
}
|
|
884
1139
|
|
|
885
|
-
function
|
|
886
|
-
|
|
887
|
-
var span
|
|
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
|
-
|
|
893
|
-
|
|
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
|
-
|
|
925
|
-
return _context2.abrupt("return"
|
|
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
|
-
|
|
934
|
-
|
|
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
|
|
937
|
-
|
|
938
|
-
|
|
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
|
-
|
|
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
|
|
1171
|
+
return _cleanArtifacts.apply(this, arguments);
|
|
977
1172
|
}
|
|
978
1173
|
|
|
979
|
-
function
|
|
980
|
-
return
|
|
1174
|
+
function uploadSourceMaps(_x5, _x6) {
|
|
1175
|
+
return _uploadSourceMaps.apply(this, arguments);
|
|
981
1176
|
}
|
|
982
1177
|
|
|
983
|
-
function
|
|
984
|
-
|
|
985
|
-
var span
|
|
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.
|
|
991
|
-
|
|
992
|
-
|
|
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
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
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
|
|
1020
|
-
ctx.logger.info("Successfully
|
|
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
|
|
1198
|
+
case 6:
|
|
1027
1199
|
case "end":
|
|
1028
1200
|
return _context3.stop();
|
|
1029
1201
|
}
|
|
1030
1202
|
}
|
|
1031
1203
|
}, _callee3);
|
|
1032
1204
|
}));
|
|
1033
|
-
return
|
|
1205
|
+
return _uploadSourceMaps.apply(this, arguments);
|
|
1034
1206
|
}
|
|
1035
1207
|
|
|
1036
|
-
function
|
|
1037
|
-
return
|
|
1038
|
-
}
|
|
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
|
-
|
|
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
|
-
|
|
1069
|
-
return _context4.abrupt("return"
|
|
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
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
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
|
|
1102
|
-
ctx.logger.info("Successfully
|
|
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
|
|
1245
|
+
case 9:
|
|
1109
1246
|
case "end":
|
|
1110
1247
|
return _context4.stop();
|
|
1111
1248
|
}
|
|
1112
1249
|
}
|
|
1113
1250
|
}, _callee4);
|
|
1114
1251
|
}));
|
|
1115
|
-
return
|
|
1252
|
+
return _setCommits.apply(this, arguments);
|
|
1116
1253
|
}
|
|
1117
1254
|
|
|
1118
|
-
function
|
|
1119
|
-
return
|
|
1255
|
+
function finalizeRelease(_x9, _x10) {
|
|
1256
|
+
return _finalizeRelease.apply(this, arguments);
|
|
1120
1257
|
}
|
|
1121
1258
|
|
|
1122
|
-
function
|
|
1123
|
-
|
|
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
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
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
|
|
1290
|
+
return _finalizeRelease.apply(this, arguments);
|
|
1143
1291
|
}
|
|
1144
1292
|
|
|
1145
|
-
function addDeploy(
|
|
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
|
-
|
|
1152
|
-
|
|
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
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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
|
-
|
|
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
|
|
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
|
|
1231
|
-
* a technical level this is done by appending an import (`import "sentry-release-injector;"`)
|
|
1232
|
-
* of the user code (see `transformInclude` and `transform` hooks). This import is then resolved
|
|
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
|
-
*
|
|
1502
|
+
* Source maps upload:
|
|
1236
1503
|
*
|
|
1237
|
-
*
|
|
1238
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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 (
|
|
1277
|
-
var
|
|
1278
|
-
|
|
1517
|
+
var unplugin = unplugin$1.createUnplugin(function (options, unpluginMetaContext) {
|
|
1518
|
+
var internalOptions = normalizeUserOptions(options);
|
|
1279
1519
|
|
|
1280
|
-
var
|
|
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:
|
|
1527
|
+
silent: internalOptions.silent,
|
|
1528
|
+
debug: internalOptions.debug
|
|
1289
1529
|
});
|
|
1290
1530
|
|
|
1291
|
-
if (
|
|
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:
|
|
1298
|
-
project:
|
|
1543
|
+
organization: internalOptions.org,
|
|
1544
|
+
project: internalOptions.project,
|
|
1299
1545
|
bundler: unpluginMetaContext.framework
|
|
1300
1546
|
});
|
|
1301
1547
|
sentryHub.setUser({
|
|
1302
|
-
id:
|
|
1303
|
-
});
|
|
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
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
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:
|
|
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
|
|
1391
|
-
* unless configured otherwise with the `
|
|
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
|
|
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 (
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
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 `
|
|
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); //
|
|
1438
|
-
//
|
|
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("
|
|
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
|
-
|
|
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: "
|
|
1751
|
+
category: "writeBundle:start",
|
|
1472
1752
|
level: "info"
|
|
1473
|
-
});
|
|
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(
|
|
1485
|
-
return cleanArtifacts(
|
|
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
|
|
1765
|
+
return setCommits(internalOptions, ctx);
|
|
1488
1766
|
}).then(function () {
|
|
1489
|
-
return
|
|
1490
|
-
})
|
|
1491
|
-
|
|
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
|
-
|
|
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: "
|
|
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
|
-
|
|
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
|
|