UNPKG

9.31 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", { value: true });
2var node_1 = require("./node");
3var string_1 = require("./string");
4var fallbackGlobalObject = {};
5/**
6 * Safely get global scope object
7 *
8 * @returns Global scope object
9 */
10function getGlobalObject() {
11 return (node_1.isNodeEnv()
12 ? global
13 : typeof window !== 'undefined'
14 ? window
15 : typeof self !== 'undefined'
16 ? self
17 : fallbackGlobalObject);
18}
19exports.getGlobalObject = getGlobalObject;
20/**
21 * UUID4 generator
22 *
23 * @returns string Generated UUID4.
24 */
25function uuid4() {
26 var global = getGlobalObject();
27 var crypto = global.crypto || global.msCrypto;
28 if (!(crypto === void 0) && crypto.getRandomValues) {
29 // Use window.crypto API if available
30 var arr = new Uint16Array(8);
31 crypto.getRandomValues(arr);
32 // set 4 in byte 7
33 // eslint-disable-next-line no-bitwise
34 arr[3] = (arr[3] & 0xfff) | 0x4000;
35 // set 2 most significant bits of byte 9 to '10'
36 // eslint-disable-next-line no-bitwise
37 arr[4] = (arr[4] & 0x3fff) | 0x8000;
38 var pad = function (num) {
39 var v = num.toString(16);
40 while (v.length < 4) {
41 v = "0" + v;
42 }
43 return v;
44 };
45 return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + pad(arr[5]) + pad(arr[6]) + pad(arr[7]));
46 }
47 // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
48 return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
49 // eslint-disable-next-line no-bitwise
50 var r = (Math.random() * 16) | 0;
51 // eslint-disable-next-line no-bitwise
52 var v = c === 'x' ? r : (r & 0x3) | 0x8;
53 return v.toString(16);
54 });
55}
56exports.uuid4 = uuid4;
57/**
58 * Parses string form of URL into an object
59 * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
60 * // intentionally using regex and not <a/> href parsing trick because React Native and other
61 * // environments where DOM might not be available
62 * @returns parsed URL object
63 */
64function parseUrl(url) {
65 if (!url) {
66 return {};
67 }
68 var match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
69 if (!match) {
70 return {};
71 }
72 // coerce to undefined values to empty string so we don't get 'undefined'
73 var query = match[6] || '';
74 var fragment = match[8] || '';
75 return {
76 host: match[4],
77 path: match[5],
78 protocol: match[2],
79 relative: match[5] + query + fragment,
80 };
81}
82exports.parseUrl = parseUrl;
83/**
84 * Extracts either message or type+value from an event that can be used for user-facing logs
85 * @returns event's description
86 */
87function getEventDescription(event) {
88 if (event.message) {
89 return event.message;
90 }
91 if (event.exception && event.exception.values && event.exception.values[0]) {
92 var exception = event.exception.values[0];
93 if (exception.type && exception.value) {
94 return exception.type + ": " + exception.value;
95 }
96 return exception.type || exception.value || event.event_id || '<unknown>';
97 }
98 return event.event_id || '<unknown>';
99}
100exports.getEventDescription = getEventDescription;
101/** JSDoc */
102function consoleSandbox(callback) {
103 var global = getGlobalObject();
104 var levels = ['debug', 'info', 'warn', 'error', 'log', 'assert'];
105 if (!('console' in global)) {
106 return callback();
107 }
108 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
109 var originalConsole = global.console;
110 var wrappedLevels = {};
111 // Restore all wrapped console methods
112 levels.forEach(function (level) {
113 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
114 if (level in global.console && originalConsole[level].__sentry_original__) {
115 wrappedLevels[level] = originalConsole[level];
116 originalConsole[level] = originalConsole[level].__sentry_original__;
117 }
118 });
119 // Perform callback manipulations
120 var result = callback();
121 // Revert restoration to wrapped state
122 Object.keys(wrappedLevels).forEach(function (level) {
123 originalConsole[level] = wrappedLevels[level];
124 });
125 return result;
126}
127exports.consoleSandbox = consoleSandbox;
128/**
129 * Adds exception values, type and value to an synthetic Exception.
130 * @param event The event to modify.
131 * @param value Value of the exception.
132 * @param type Type of the exception.
133 * @hidden
134 */
135function addExceptionTypeValue(event, value, type) {
136 event.exception = event.exception || {};
137 event.exception.values = event.exception.values || [];
138 event.exception.values[0] = event.exception.values[0] || {};
139 event.exception.values[0].value = event.exception.values[0].value || value || '';
140 event.exception.values[0].type = event.exception.values[0].type || type || 'Error';
141}
142exports.addExceptionTypeValue = addExceptionTypeValue;
143/**
144 * Adds exception mechanism to a given event.
145 * @param event The event to modify.
146 * @param mechanism Mechanism of the mechanism.
147 * @hidden
148 */
149function addExceptionMechanism(event, mechanism) {
150 if (mechanism === void 0) { mechanism = {}; }
151 // TODO: Use real type with `keyof Mechanism` thingy and maybe make it better?
152 try {
153 // @ts-ignore Type 'Mechanism | {}' is not assignable to type 'Mechanism | undefined'
154 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
155 event.exception.values[0].mechanism = event.exception.values[0].mechanism || {};
156 Object.keys(mechanism).forEach(function (key) {
157 // @ts-ignore Mechanism has no index signature
158 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
159 event.exception.values[0].mechanism[key] = mechanism[key];
160 });
161 }
162 catch (_oO) {
163 // no-empty
164 }
165}
166exports.addExceptionMechanism = addExceptionMechanism;
167/**
168 * A safe form of location.href
169 */
170function getLocationHref() {
171 try {
172 return document.location.href;
173 }
174 catch (oO) {
175 return '';
176 }
177}
178exports.getLocationHref = getLocationHref;
179// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
180var SEMVER_REGEXP = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
181/**
182 * Parses input into a SemVer interface
183 * @param input string representation of a semver version
184 */
185function parseSemver(input) {
186 var match = input.match(SEMVER_REGEXP) || [];
187 var major = parseInt(match[1], 10);
188 var minor = parseInt(match[2], 10);
189 var patch = parseInt(match[3], 10);
190 return {
191 buildmetadata: match[5],
192 major: isNaN(major) ? undefined : major,
193 minor: isNaN(minor) ? undefined : minor,
194 patch: isNaN(patch) ? undefined : patch,
195 prerelease: match[4],
196 };
197}
198exports.parseSemver = parseSemver;
199var defaultRetryAfter = 60 * 1000; // 60 seconds
200/**
201 * Extracts Retry-After value from the request header or returns default value
202 * @param now current unix timestamp
203 * @param header string representation of 'Retry-After' header
204 */
205function parseRetryAfterHeader(now, header) {
206 if (!header) {
207 return defaultRetryAfter;
208 }
209 var headerDelay = parseInt("" + header, 10);
210 if (!isNaN(headerDelay)) {
211 return headerDelay * 1000;
212 }
213 var headerDate = Date.parse("" + header);
214 if (!isNaN(headerDate)) {
215 return headerDate - now;
216 }
217 return defaultRetryAfter;
218}
219exports.parseRetryAfterHeader = parseRetryAfterHeader;
220/**
221 * This function adds context (pre/post/line) lines to the provided frame
222 *
223 * @param lines string[] containing all lines
224 * @param frame StackFrame that will be mutated
225 * @param linesOfContext number of context lines we want to add pre/post
226 */
227function addContextToFrame(lines, frame, linesOfContext) {
228 if (linesOfContext === void 0) { linesOfContext = 5; }
229 var lineno = frame.lineno || 0;
230 var maxLines = lines.length;
231 var sourceLine = Math.max(Math.min(maxLines, lineno - 1), 0);
232 frame.pre_context = lines
233 .slice(Math.max(0, sourceLine - linesOfContext), sourceLine)
234 .map(function (line) { return string_1.snipLine(line, 0); });
235 frame.context_line = string_1.snipLine(lines[Math.min(maxLines - 1, sourceLine)], frame.colno || 0);
236 frame.post_context = lines
237 .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext)
238 .map(function (line) { return string_1.snipLine(line, 0); });
239}
240exports.addContextToFrame = addContextToFrame;
241/**
242 * Strip the query string and fragment off of a given URL or path (if present)
243 *
244 * @param urlPath Full URL or path, including possible query string and/or fragment
245 * @returns URL or path without query string or fragment
246 */
247function stripUrlQueryAndFragment(urlPath) {
248 // eslint-disable-next-line no-useless-escape
249 return urlPath.split(/[\?#]/, 1)[0];
250}
251exports.stripUrlQueryAndFragment = stripUrlQueryAndFragment;
252//# sourceMappingURL=misc.js.map
\No newline at end of file