Upgrade Sentry to v8 and remove custom Dependabot grouping

As part of the upgrade process, we need to rework the tracing instrumentation. Now, we are just wrapping all async functions in a new sentry transaction, which will automatically end once the function returns.

Further, the structure of the Sentry packages got reworked, so that we only need a single package by now. This removes the need to group dependabot updates.

Co-authored-by: Jan Graichen <jgraichen@altimos.de>
This commit is contained in:
Sebastian Serth
2024-05-20 14:00:55 +02:00
committed by Sebastian Serth
parent 86c67f3c9a
commit 94404370c4
12 changed files with 234 additions and 300 deletions

View File

@ -22,10 +22,6 @@ updates:
labels: labels:
- dependencies - dependencies
- javascript - javascript
groups:
sentry-javascript:
patterns:
- "@sentry*"
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: "/" directory: "/"

View File

@ -13,9 +13,3 @@ jobs:
uses: ahmadnassri/action-dependabot-auto-merge@v2 uses: ahmadnassri/action-dependabot-auto-merge@v2
with: with:
github-token: ${{ secrets.OPENHPI_BOT_TOKEN }} github-token: ${{ secrets.OPENHPI_BOT_TOKEN }}
- name: Automerge Sentry PRs
run: gh pr merge --auto --rebase "$PR_URL" # Use Github CLI to merge automatically the PR
if: contains(github.event.pull_request.title, 'sentry')
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ secrets.OPENHPI_BOT_TOKEN }}

View File

@ -46,7 +46,7 @@ $(document).on('turbolinks:load', function() {
const sentrySettings = $('meta[name="sentry"]') const sentrySettings = $('meta[name="sentry"]')
// Workaround for Turbolinks: We must not re-initialize the Relay object when visiting another page // Workaround for Turbolinks: We must not re-initialize the Relay object when visiting another page
if (sentrySettings && sentrySettings.data()['enabled'] && !Sentry.Replay.prototype._isInitialized) { if (sentrySettings && sentrySettings.data()['enabled'] && Sentry.getReplay() === undefined) {
Sentry.init({ Sentry.init({
dsn: sentrySettings.data('dsn'), dsn: sentrySettings.data('dsn'),
attachStacktrace: true, attachStacktrace: true,

View File

@ -27,14 +27,15 @@ $(document).on('turbolinks:load', function() {
function submitCode(event) { function submitCode(event) {
const button = $(event.target) || $('#submit'); const button = $(event.target) || $('#submit');
this.startSentryTransaction(button); this.newSentryTransaction(button, async () => {
const submission = await this.createSubmission(button, null).catch(this.ajaxError.bind(this)); const submission = await this.createSubmission(button, null).catch(this.ajaxError.bind(this));
if (!submission) return; if (!submission) return;
if (!submission.redirect) return; if (!submission.redirect) return;
this.autosaveIfChanged(); this.autosaveIfChanged();
this.stopCode(event); this.stopCode(event);
this.editors = []; this.editors = [];
Turbolinks.clearCache(); Turbolinks.clearCache();
Turbolinks.visit(submission.redirect); Turbolinks.visit(submission.redirect);
});
} }

View File

@ -202,15 +202,25 @@ var CodeOceanEditor = {
$('button i.fa-spin').removeClass('d-inline-block').addClass('d-none'); $('button i.fa-spin').removeClass('d-inline-block').addClass('d-none');
}, },
startSentryTransaction: function (initiator) { newSentryTransaction: function (initiator, callback) {
const cause = initiator.data('cause') || initiator.prop('id'); // based on Sentry recommendation.
this.sentryTransaction = window.SentryUtils.startIdleTransaction( // See https://github.com/getsentry/sentry-javascript/issues/12116
Sentry.getCurrentHub(), return Sentry.continueTrace({ sentryTrace: '', baggage: '' }, () => {
{ name: cause, op: "transaction" }, // inside of this we have a new trace!
0, // Idle Timeout return Sentry.withActiveSpan(null, () => {
window.SentryUtils.TRACING_DEFAULTS.finalTimeout, // inside of this there is no parent span, no matter what!
true); // onContext const cause = initiator.data('cause') || initiator.prop('id');
Sentry.getCurrentHub().configureScope(scope => scope.setSpan(this.sentryTransaction)); return Sentry.startSpan({name: cause, op: "transaction", forceTransaction: true}, async () => {
// Execute the desired custom code
try {
return await callback();
} catch (error) {
console.error(error);
Sentry.captureException(error, {mechanism: {handled: false}});
}
});
});
});
}, },
resizeAceEditors: function (own_solution = false) { resizeAceEditors: function (own_solution = false) {

View File

@ -2,7 +2,6 @@ CodeOceanEditorEvaluation = {
// A list of non-printable characters that are not allowed in the code output. // A list of non-printable characters that are not allowed in the code output.
// Taken from https://stackoverflow.com/a/69024306 // Taken from https://stackoverflow.com/a/69024306
nonPrintableRegEx: /[\u0000-\u0008\u000B\u000C\u000F-\u001F\u007F-\u009F\u2000-\u200F\u2028-\u202F\u205F-\u206F\u3000\uFEFF]/g, nonPrintableRegEx: /[\u0000-\u0008\u000B\u000C\u000F-\u001F\u007F-\u009F\u2000-\u200F\u2028-\u202F\u205F-\u206F\u3000\uFEFF]/g,
sentryTransaction: null,
/** /**
* Scoring-Functions * Scoring-Functions
@ -10,17 +9,18 @@ CodeOceanEditorEvaluation = {
scoreCode: function (event) { scoreCode: function (event) {
event.preventDefault(); event.preventDefault();
const cause = $('#assess'); const cause = $('#assess');
this.startSentryTransaction(cause); this.newSentryTransaction(cause, async () => {
this.stopCode(event); this.stopCode(event);
this.clearScoringOutput(); this.clearScoringOutput();
$('#submit').addClass("d-none"); $('#submit').addClass("d-none");
const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this));
if (!submission) return; if (!submission) return;
this.showSpinner($('#assess')); this.showSpinner($('#assess'));
$('#score_div').removeClass('d-none'); $('#score_div').removeClass('d-none');
await this.socketScoreCode(submission.id); await this.socketScoreCode(submission.id);
});
}, },
handleScoringResponse: function (results) { handleScoringResponse: function (results) {

View File

@ -8,7 +8,7 @@ CodeOceanEditorWebsocket = {
params.protocol = this.webSocketProtocol; params.protocol = this.webSocketProtocol;
params._options = true; params._options = true;
// 2. Create a new Sentry transaction. // 2. Create a new Sentry span.
// Since we want to group similar URLs, we use the URL without the ID and filename as the description. // Since we want to group similar URLs, we use the URL without the ID and filename as the description.
const cleanedUrl = urlHelper({ const cleanedUrl = urlHelper({
...params, ...params,
@ -16,54 +16,54 @@ CodeOceanEditorWebsocket = {
...(params.filename && {filename: '*'}), // Overwrite the filename with a wildcard only if it is present. ...(params.filename && {filename: '*'}), // Overwrite the filename with a wildcard only if it is present.
}); });
const sentryDescription = `WebSocket ${cleanedUrl}`; const sentryDescription = `WebSocket ${cleanedUrl}`;
const span = this.sentryTransaction?.startChild({op: 'websocket.client', description: sentryDescription, data: {...params}}) return Sentry.startSpan({op: 'websocket.client', name: sentryDescription, attributes: {...params}}, async webSocketSpan => {
// 3. Create the actual WebSocket URL. // 3. Create the actual WebSocket URL.
// This URL might contain Sentry Tracing headers to propagate the Sentry transaction. // This URL might contain Sentry Tracing headers to propagate the Sentry transaction.
if (span) { if (webSocketSpan) {
const dynamicContext = this.sentryTransaction.getDynamicSamplingContext(); params.HTTP_SENTRY_TRACE = Sentry.spanToTraceHeader(webSocketSpan);
const baggage = SentryUtils.dynamicSamplingContextToSentryBaggageHeader(dynamicContext);
if (baggage) { const baggage = Sentry.spanToBaggageHeader(webSocketSpan);
params.HTTP_SENTRY_TRACE = span.toTraceparent(); if (baggage) {
params.HTTP_BAGGAGE = baggage; params.HTTP_BAGGAGE = Sentry.spanToBaggageHeader(webSocketSpan);
}
} }
} const url = urlHelper({...params});
const url = urlHelper({...params});
// 4. Connect to the given URL. // 4. Connect to the given URL.
this.websocket = new CommandSocket(url, this.websocket = new CommandSocket(url,
function (evt) { function (evt) {
this.resetOutputTab(); this.resetOutputTab();
}.bind(this) }.bind(this)
); );
// Attach custom handlers for messages received. // Attach custom handlers for messages received.
setupFunction(this.websocket); setupFunction(this.websocket);
CodeOceanEditorWebsocket.websocket = this.websocket; CodeOceanEditorWebsocket.websocket = this.websocket;
// Create and return a new Promise. It will only resolve (or fail) once the connection has ended. // Create and return a new Promise. It will only resolve (or fail) once the connection has ended.
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.websocket.onError(this.showWebsocketError.bind(this)); this.websocket.onError(this.showWebsocketError.bind(this));
// Remove event listeners for Promise handling. // Remove event listeners for Promise handling.
// This is especially useful in case of an error, where a `close` event might follow the `error` event. // This is especially useful in case of an error, where a `close` event might follow the `error` event.
const teardown = () => { const teardown = () => {
this.websocket.websocket.removeEventListener(closeListener); this.websocket.websocket.removeEventListener(closeListener);
this.websocket.websocket.removeEventListener(errorListener); this.websocket.websocket.removeEventListener(errorListener);
}; };
// We are using event listeners (and not `onError` or `onClose`) here, since these listeners should never be overwritten. // We are using event listeners (and not `onError` or `onClose`) here, since these listeners should never be overwritten.
// With `onError` or `onClose`, a new assignment would overwrite a previous one. // With `onError` or `onClose`, a new assignment would overwrite a previous one.
const closeListener = this.websocket.websocket.addEventListener('close', () => { const closeListener = this.websocket.websocket.addEventListener('close', () => {
span?.finish(); resolve();
resolve(); teardown();
teardown(); });
}); const errorListener = this.websocket.websocket.addEventListener('error', (error) => {
const errorListener = this.websocket.websocket.addEventListener('error', (error) => { reject(error);
reject(error); teardown();
teardown(); this.websocket.killWebSocket(); // In case of error, ensure we always close the connection.
this.websocket.killWebSocket(); // In case of error, ensure we always close the connection. });
}); });
}); });
}, },

View File

@ -110,46 +110,47 @@ CodeOceanEditorRequestForComments = {
const cause = $('#requestComments'); const cause = $('#requestComments');
const editor = $('#editor') const editor = $('#editor')
const questionElement = $('#question') const questionElement = $('#question')
this.startSentryTransaction(cause); this.newSentryTransaction(cause, async () => {
questionElement.prop("disabled", true); questionElement.prop("disabled", true);
$('#closeAskForCommentsButton').addClass('d-none'); $('#closeAskForCommentsButton').addClass('d-none');
const exercise_id = editor.data('exercise-id'); const exercise_id = editor.data('exercise-id');
const file_id = $('.editor').data('id'); const file_id = $('.editor').data('id');
const question = questionElement.val(); const question = questionElement.val();
const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this));
if (!submission) return; if (!submission) return;
this.showSpinner($('#askForCommentsButton')); this.showSpinner($('#askForCommentsButton'));
const response = await $.ajax({ const response = await $.ajax({
method: 'POST', method: 'POST',
url: Routes.request_for_comments_path(), url: Routes.request_for_comments_path(),
data: { data: {
request_for_comment: { request_for_comment: {
exercise_id: exercise_id, exercise_id: exercise_id,
file_id: file_id, file_id: file_id,
submission_id: submission.id, submission_id: submission.id,
question: question question: question
}
} }
}).catch(this.ajaxError.bind(this));
bootstrap.Modal.getInstance($('#comment-modal')).hide();
this.hideSpinner();
$('#question').prop("disabled", false).val('');
$('#closeAskForCommentsButton').removeClass('d-none');
$('#askForCommentsButton').one('click', this.requestComments.bind(this));
// we disabled the button to prevent that the user spams RFCs, but decided against this now.
//var button = $('#requestComments');
//button.prop('disabled', true);
if (response) {
await this.runSubmission(submission);
$.flash.success({text: $('#askForCommentsButton').data('message-success')});
} }
}).catch(this.ajaxError.bind(this)); });
bootstrap.Modal.getInstance($('#comment-modal')).hide();
this.hideSpinner();
$('#question').prop("disabled", false).val('');
$('#closeAskForCommentsButton').removeClass('d-none');
$('#askForCommentsButton').one('click', this.requestComments.bind(this));
// we disabled the button to prevent that the user spams RFCs, but decided against this now.
//var button = $('#requestComments');
//button.prop('disabled', true);
if (response) {
await this.runSubmission(submission);
$.flash.success({text: $('#askForCommentsButton').data('message-success')});
}
} }
}; };

View File

@ -108,19 +108,20 @@ CodeOceanEditorSubmissions = {
}, },
resetCode: function(initiator, onlyActiveFile = false) { resetCode: function(initiator, onlyActiveFile = false) {
this.startSentryTransaction(initiator); this.newSentryTransaction(initiator, async () => {
this.showSpinner(initiator); this.showSpinner(initiator);
const response = await this.ajax({ const response = await this.ajax({
method: 'GET', method: 'GET',
url: $('#start-over').data('url') || $('#start-over-active-file').data('url') url: $('#start-over').data('url') || $('#start-over-active-file').data('url')
}).catch(this.ajaxError.bind(this)); }).catch(this.ajaxError.bind(this));
this.hideSpinner(); this.hideSpinner();
if (!response) return; if (!response) return;
App.synchronized_editor?.reset_content(response); App.synchronized_editor?.reset_content(response);
this.setEditorContent(response, onlyActiveFile); this.setEditorContent(response, onlyActiveFile);
});
}, },
setEditorContent: function(new_content, onlyActiveFile = false) { setEditorContent: function(new_content, onlyActiveFile = false) {
@ -140,32 +141,33 @@ CodeOceanEditorSubmissions = {
renderCode: function(event) { renderCode: function(event) {
event.preventDefault(); event.preventDefault();
const cause = $('#render'); const cause = $('#render');
this.startSentryTransaction(cause); this.newSentryTransaction(cause, async () => {
if (!cause.is(':visible')) return; if (!cause.is(':visible')) return;
const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this));
if (!submission) return; if (!submission) return;
if (submission.render_url === undefined) return; if (submission.render_url === undefined) return;
const active_file = CodeOceanEditor.active_file.filename; const active_file = CodeOceanEditor.active_file.filename;
const desired_file = submission.render_url.filter(hash => hash.filepath === active_file); const desired_file = submission.render_url.filter(hash => hash.filepath === active_file);
const url = desired_file[0].url; const url = desired_file[0].url;
// Allow to open the new tab even in Safari. // Allow to open the new tab even in Safari.
// See: https://stackoverflow.com/a/70463940 // See: https://stackoverflow.com/a/70463940
setTimeout(() => { setTimeout(() => {
var pop_up_window = window.open(url, '_blank'); var pop_up_window = window.open(url, '_blank');
if (pop_up_window) { if (pop_up_window) {
pop_up_window.onerror = function (message) { pop_up_window.onerror = function (message) {
this.clearOutput(); this.clearOutput();
this.printOutput({ this.printOutput({
stderr: message stderr: message
}, true, 0); }, true, 0);
this.sendError(message, submission.id); this.sendError(message, submission.id);
this.showOutputBar(); this.showOutputBar();
}; };
} }
}) })
});
}, },
/** /**
@ -174,14 +176,15 @@ CodeOceanEditorSubmissions = {
runCode: function(event) { runCode: function(event) {
event.preventDefault(); event.preventDefault();
const cause = $('#run'); const cause = $('#run');
this.startSentryTransaction(cause); this.newSentryTransaction(cause, async () => {
this.stopCode(event); this.stopCode(event);
if (!cause.is(':visible')) return; if (!cause.is(':visible')) return;
const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this));
if (!submission) return; if (!submission) return;
await this.runSubmission(submission); await this.runSubmission(submission);
});
}, },
runSubmission: async function (submission) { runSubmission: async function (submission) {
@ -196,15 +199,16 @@ CodeOceanEditorSubmissions = {
testCode: function(event) { testCode: function(event) {
event.preventDefault(); event.preventDefault();
const cause = $('#test'); const cause = $('#test');
this.startSentryTransaction(cause); this.newSentryTransaction(cause, async () => {
if (!cause.is(':visible')) return; if (!cause.is(':visible')) return;
const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this));
if (!submission) return; if (!submission) return;
this.showSpinner($('#test')); this.showSpinner($('#test'));
$('#score_div').addClass('d-none'); $('#score_div').addClass('d-none');
await this.socketTestCode(submission.id, CodeOceanEditor.active_file.filename); await this.socketTestCode(submission.id, CodeOceanEditor.active_file.filename);
});
}, },
/** /**

View File

@ -16,9 +16,6 @@ import 'jstree';
import * as _ from 'underscore'; import * as _ from 'underscore';
import * as d3 from 'd3'; import * as d3 from 'd3';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import * as SentryIntegration from '@sentry/integrations';
import { startIdleTransaction, TRACING_DEFAULTS } from '@sentry/core';
import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils';
import 'sorttable'; import 'sorttable';
window.bootstrap = bootstrap; // Publish bootstrap in global namespace window.bootstrap = bootstrap; // Publish bootstrap in global namespace
window._ = _; // Publish underscore's `_` in global namespace window._ = _; // Publish underscore's `_` in global namespace
@ -26,15 +23,15 @@ window.d3 = d3; // Publish d3 in global namespace
window.Sentry = Sentry; // Publish sentry in global namespace window.Sentry = Sentry; // Publish sentry in global namespace
window.SentryIntegrations = function() { // Publish sentry integration in global namespace window.SentryIntegrations = function() { // Publish sentry integration in global namespace
return [ return [
new SentryIntegration.ReportingObserver(), Sentry.browserProfilingIntegration(),
new SentryIntegration.ExtraErrorData(), Sentry.browserTracingIntegration(),
new SentryIntegration.HttpClient(), Sentry.extraErrorDataIntegration(),
new Sentry.BrowserProfilingIntegration(), Sentry.httpClientIntegration(),
new Sentry.BrowserTracing(), Sentry.replayIntegration(),
new Sentry.Replay(), Sentry.reportingObserverIntegration(),
Sentry.sessionTimingIntegration(),
] ]
}; };
window.SentryUtils = { dynamicSamplingContextToSentryBaggageHeader, startIdleTransaction, TRACING_DEFAULTS };
// CSS // CSS
import 'chosen-js/chosen.css'; import 'chosen-js/chosen.css';

View File

@ -9,10 +9,7 @@
"@egjs/hammerjs": "^2.0.17", "@egjs/hammerjs": "^2.0.17",
"@fortawesome/fontawesome-free": "^6.5.2", "@fortawesome/fontawesome-free": "^6.5.2",
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"@sentry/browser": "^7.110.1", "@sentry/browser": "^8.4.0",
"@sentry/core": "^7.114.0",
"@sentry/integrations": "^7.114.0",
"@sentry/utils": "^7.114.0",
"@toast-ui/editor": "^3.2.2", "@toast-ui/editor": "^3.2.2",
"@webpack-cli/serve": "^2.0.5", "@webpack-cli/serve": "^2.0.5",
"ace-builds": "^1.34.0", "ace-builds": "^1.34.0",

186
yarn.lock
View File

@ -1813,128 +1813,90 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry-internal/feedback@npm:7.110.1": "@sentry-internal/browser-utils@npm:8.4.0":
version: 7.110.1 version: 8.4.0
resolution: "@sentry-internal/feedback@npm:7.110.1" resolution: "@sentry-internal/browser-utils@npm:8.4.0"
dependencies: dependencies:
"@sentry/core": "npm:7.110.1" "@sentry/core": "npm:8.4.0"
"@sentry/types": "npm:7.110.1" "@sentry/types": "npm:8.4.0"
"@sentry/utils": "npm:7.110.1" "@sentry/utils": "npm:8.4.0"
checksum: 10c0/5429a7dcd14986770647392558ed0d09f31d33d6771688304f90e88feff9b0af6edaa0195e60c5bdce6a8518409f6314b9d03293b661fc3e1b74ef1c154e4595 checksum: 10c0/9e6709100182f8586ef24d304632eedee1f0f257a588bd861df779dee41064cc97afce53b22a4b669e05581f25bc61d7fdae901d238f93569e7042e07d9fbf50
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry-internal/replay-canvas@npm:7.110.1": "@sentry-internal/feedback@npm:8.4.0":
version: 7.110.1 version: 8.4.0
resolution: "@sentry-internal/replay-canvas@npm:7.110.1" resolution: "@sentry-internal/feedback@npm:8.4.0"
dependencies: dependencies:
"@sentry/core": "npm:7.110.1" "@sentry/core": "npm:8.4.0"
"@sentry/replay": "npm:7.110.1" "@sentry/types": "npm:8.4.0"
"@sentry/types": "npm:7.110.1" "@sentry/utils": "npm:8.4.0"
"@sentry/utils": "npm:7.110.1" checksum: 10c0/028eb28770eb85f1d09caa3ec98420cdb691d2de06be261106876efed572f7d83bfddf6d289468c0f1bbf551d5a75e7b01fe2c2bbac4b0da882c8e655a166b5c
checksum: 10c0/125b8247db4631e298f3c8c6d8b486669dfa6356490cc7464a23131a5518d9d7ef314f2c1cbbbadad4f9738ba451fbf5f9457170f4bc899b8275e15ae28cb610
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry-internal/tracing@npm:7.110.1": "@sentry-internal/replay-canvas@npm:8.4.0":
version: 7.110.1 version: 8.4.0
resolution: "@sentry-internal/tracing@npm:7.110.1" resolution: "@sentry-internal/replay-canvas@npm:8.4.0"
dependencies: dependencies:
"@sentry/core": "npm:7.110.1" "@sentry-internal/replay": "npm:8.4.0"
"@sentry/types": "npm:7.110.1" "@sentry/core": "npm:8.4.0"
"@sentry/utils": "npm:7.110.1" "@sentry/types": "npm:8.4.0"
checksum: 10c0/ee901b99b838a932f2adb1b085364c816fb0b3f61643ca368af37dd2aa9faf702ea1f3d28f7b0e2e79c57794e3260c8ce34376da0f8658b6ee844b28676ecd55 "@sentry/utils": "npm:8.4.0"
checksum: 10c0/6e62557e88f1422f645b022c33c034eccf53469dcdea8e1fbdef34f087e8e986411f50bbf384b7d41f83298b1f339866c8a024456ecf74f1158811f9b91d225b
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry/browser@npm:^7.110.1": "@sentry-internal/replay@npm:8.4.0":
version: 7.110.1 version: 8.4.0
resolution: "@sentry/browser@npm:7.110.1" resolution: "@sentry-internal/replay@npm:8.4.0"
dependencies: dependencies:
"@sentry-internal/feedback": "npm:7.110.1" "@sentry-internal/browser-utils": "npm:8.4.0"
"@sentry-internal/replay-canvas": "npm:7.110.1" "@sentry/core": "npm:8.4.0"
"@sentry-internal/tracing": "npm:7.110.1" "@sentry/types": "npm:8.4.0"
"@sentry/core": "npm:7.110.1" "@sentry/utils": "npm:8.4.0"
"@sentry/replay": "npm:7.110.1" checksum: 10c0/e9e6398eb3e245470bd464022a9e147038e6adc97212a8e0a28496093f8ed018f8c417bc0d73715f6e63a7506a2d199fadddd23a80246abc8c54d5875d8552c3
"@sentry/types": "npm:7.110.1"
"@sentry/utils": "npm:7.110.1"
checksum: 10c0/085a2cbd2b60dbb596b68d3cf7d0059e226bc8892aa90a50680fa9a9256889a715ff234e9210738a3205ce5513e52290e440ffa4f2d2e2429471ea584d075493
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry/core@npm:7.110.1": "@sentry/browser@npm:^8.4.0":
version: 7.110.1 version: 8.4.0
resolution: "@sentry/core@npm:7.110.1" resolution: "@sentry/browser@npm:8.4.0"
dependencies: dependencies:
"@sentry/types": "npm:7.110.1" "@sentry-internal/browser-utils": "npm:8.4.0"
"@sentry/utils": "npm:7.110.1" "@sentry-internal/feedback": "npm:8.4.0"
checksum: 10c0/8eee39697a1173f233a83fa07b5099c2fdc1f345ec0ac0304ed38c7159214e6a0615fb2fe4dcd4152dbe11cf5ec14bfe3d7da19706e90b13a8bd7984256c4b2f "@sentry-internal/replay": "npm:8.4.0"
"@sentry-internal/replay-canvas": "npm:8.4.0"
"@sentry/core": "npm:8.4.0"
"@sentry/types": "npm:8.4.0"
"@sentry/utils": "npm:8.4.0"
checksum: 10c0/bd1162ad13f246c30c1af2d65b798d729cfd4c94c50cc08bdb848a95cd734cedae235c2c2554863c81bc4e639c3d9b8120b6d6988fe6e3437ca45f3dbcf67de6
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry/core@npm:7.114.0, @sentry/core@npm:^7.114.0": "@sentry/core@npm:8.4.0":
version: 7.114.0 version: 8.4.0
resolution: "@sentry/core@npm:7.114.0" resolution: "@sentry/core@npm:8.4.0"
dependencies: dependencies:
"@sentry/types": "npm:7.114.0" "@sentry/types": "npm:8.4.0"
"@sentry/utils": "npm:7.114.0" "@sentry/utils": "npm:8.4.0"
checksum: 10c0/9ef9cd6e536180a53fdd11dfb30f19a1bf51115b6a828aae4f9dacb92233ced238e3100065429cdb50a654609519722b6cf99721cac21f09dd5d57f123aa4f3c checksum: 10c0/7c9ffc15a5cbc6cc9811b1444c2ea956dd42b576e63606e3064af0d617fd9c3d97b6ba878f14fc13818d2001a3cf07b73ecde648e31fdb8d9b7e316bd5549470
languageName: node languageName: node
linkType: hard linkType: hard
"@sentry/integrations@npm:^7.114.0": "@sentry/types@npm:8.4.0":
version: 7.114.0 version: 8.4.0
resolution: "@sentry/integrations@npm:7.114.0" resolution: "@sentry/types@npm:8.4.0"
checksum: 10c0/0fd8790b8b6c353029feb47caf4b85f3a972f6a37f90ab6719f6d9425919c53069e9e15976da4690a4c738c2c0c3fbebd00749ae3568aaa719e02552c38e3feb
languageName: node
linkType: hard
"@sentry/utils@npm:8.4.0":
version: 8.4.0
resolution: "@sentry/utils@npm:8.4.0"
dependencies: dependencies:
"@sentry/core": "npm:7.114.0" "@sentry/types": "npm:8.4.0"
"@sentry/types": "npm:7.114.0" checksum: 10c0/3306ba659874344b63ca72dbf7172641b38f590abf8c15291c6f98b2752dcfa9569a209cf83f7a83601acd1c22bc4ab8ead4bb55f7698b9b9b6690cfa6e5ebb5
"@sentry/utils": "npm:7.114.0"
localforage: "npm:^1.8.1"
checksum: 10c0/180fedbd474d1141d90882446de023da38df906489e9abeee4d659b9e5498922b66271c6e85b154c0c393a9157329b3e36c4fa98ba88d1741644797dbeedec1d
languageName: node
linkType: hard
"@sentry/replay@npm:7.110.1":
version: 7.110.1
resolution: "@sentry/replay@npm:7.110.1"
dependencies:
"@sentry-internal/tracing": "npm:7.110.1"
"@sentry/core": "npm:7.110.1"
"@sentry/types": "npm:7.110.1"
"@sentry/utils": "npm:7.110.1"
checksum: 10c0/ffb300d229d6447ea0f2b99a21ab3d6fae6136cdef33fb9daaac417b1a6b070f385139c934a2acff68562a6f5acdcf96a6e606ddf3893b7a9d44955597343841
languageName: node
linkType: hard
"@sentry/types@npm:7.110.1":
version: 7.110.1
resolution: "@sentry/types@npm:7.110.1"
checksum: 10c0/6892ae1bed6426ef10dba075d0bd68247bac7c024a7860f3385d320759e152bd9e7bb4b3eeec2600a58d81bb30084fd01e9586da09e372fb48d615c24c86fd10
languageName: node
linkType: hard
"@sentry/types@npm:7.114.0":
version: 7.114.0
resolution: "@sentry/types@npm:7.114.0"
checksum: 10c0/25564ee09beb2362f43a4f96270acdb4e1c9d999ab4fd37b6e340717433b3e685301dc0c55a7e8883226f2f20023b99055cea04f68eaaf22f4d5f9c5d6976b43
languageName: node
linkType: hard
"@sentry/utils@npm:7.110.1":
version: 7.110.1
resolution: "@sentry/utils@npm:7.110.1"
dependencies:
"@sentry/types": "npm:7.110.1"
checksum: 10c0/ab84862283881808e94e68d4abe19a38024fbe8de0bd55ddbb1238123772ce633fd507af7f636427333c6376767a85f6e665ece647c43183fdcac6a8e7ba3c77
languageName: node
linkType: hard
"@sentry/utils@npm:7.114.0, @sentry/utils@npm:^7.114.0":
version: 7.114.0
resolution: "@sentry/utils@npm:7.114.0"
dependencies:
"@sentry/types": "npm:7.114.0"
checksum: 10c0/b20283d62df7ea3c71988e9fc2a6b7d3d04dd4a92a3599605413e2da3ff3cb408b84d65ee7c8e0bd8f99a92dd6e364c37485023e8d2c7cbcbd3f31dfb2d15383
languageName: node languageName: node
linkType: hard linkType: hard
@ -3074,10 +3036,7 @@ __metadata:
"@egjs/hammerjs": "npm:^2.0.17" "@egjs/hammerjs": "npm:^2.0.17"
"@fortawesome/fontawesome-free": "npm:^6.5.2" "@fortawesome/fontawesome-free": "npm:^6.5.2"
"@popperjs/core": "npm:^2.11.8" "@popperjs/core": "npm:^2.11.8"
"@sentry/browser": "npm:^7.110.1" "@sentry/browser": "npm:^8.4.0"
"@sentry/core": "npm:^7.114.0"
"@sentry/integrations": "npm:^7.114.0"
"@sentry/utils": "npm:^7.114.0"
"@toast-ui/editor": "npm:^3.2.2" "@toast-ui/editor": "npm:^3.2.2"
"@webpack-cli/serve": "npm:^2.0.5" "@webpack-cli/serve": "npm:^2.0.5"
ace-builds: "npm:^1.34.0" ace-builds: "npm:^1.34.0"
@ -4771,13 +4730,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"immediate@npm:~3.0.5":
version: 3.0.6
resolution: "immediate@npm:3.0.6"
checksum: 10c0/f8ba7ede69bee9260241ad078d2d535848745ff5f6995c7c7cb41cfdc9ccc213f66e10fa5afb881f90298b24a3f7344b637b592beb4f54e582770cdce3f1f039
languageName: node
linkType: hard
"immutable@npm:^4.0.0": "immutable@npm:^4.0.0":
version: 4.3.4 version: 4.3.4
resolution: "immutable@npm:4.3.4" resolution: "immutable@npm:4.3.4"
@ -5200,15 +5152,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lie@npm:3.1.1":
version: 3.1.1
resolution: "lie@npm:3.1.1"
dependencies:
immediate: "npm:~3.0.5"
checksum: 10c0/d62685786590351b8e407814acdd89efe1cb136f05cb9236c5a97b2efdca1f631d2997310ad2d565c753db7596799870140e4777c9c9b8c44a0f6bf42d1804a1
languageName: node
linkType: hard
"lilconfig@npm:^3.1.1": "lilconfig@npm:^3.1.1":
version: 3.1.1 version: 3.1.1
resolution: "lilconfig@npm:3.1.1" resolution: "lilconfig@npm:3.1.1"
@ -5234,15 +5177,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"localforage@npm:^1.8.1":
version: 1.10.0
resolution: "localforage@npm:1.10.0"
dependencies:
lie: "npm:3.1.1"
checksum: 10c0/00f19f1f97002e6721587ed5017f502d58faf80dae567d5065d4d1ee0caf0762f40d2e2dba7f0ef7d3f14ee6203242daae9ecad97359bfc10ecff36df11d85a3
languageName: node
linkType: hard
"locate-path@npm:^5.0.0": "locate-path@npm:^5.0.0":
version: 5.0.0 version: 5.0.0
resolution: "locate-path@npm:5.0.0" resolution: "locate-path@npm:5.0.0"