diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9a23cbff..edcccbaf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -22,10 +22,6 @@ updates: labels: - dependencies - javascript - groups: - sentry-javascript: - patterns: - - "@sentry*" - package-ecosystem: github-actions directory: "/" diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml index 4d70d8f9..66e3c584 100644 --- a/.github/workflows/dependabot.yml +++ b/.github/workflows/dependabot.yml @@ -13,9 +13,3 @@ jobs: uses: ahmadnassri/action-dependabot-auto-merge@v2 with: 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 }} diff --git a/app/assets/javascripts/base.js b/app/assets/javascripts/base.js index 1cf0effc..62a08df5 100644 --- a/app/assets/javascripts/base.js +++ b/app/assets/javascripts/base.js @@ -46,7 +46,7 @@ $(document).on('turbolinks:load', function() { const sentrySettings = $('meta[name="sentry"]') // 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({ dsn: sentrySettings.data('dsn'), attachStacktrace: true, diff --git a/app/assets/javascripts/community_solution.js b/app/assets/javascripts/community_solution.js index d2730b19..d9638acc 100644 --- a/app/assets/javascripts/community_solution.js +++ b/app/assets/javascripts/community_solution.js @@ -27,14 +27,15 @@ $(document).on('turbolinks:load', function() { function submitCode(event) { const button = $(event.target) || $('#submit'); - this.startSentryTransaction(button); - const submission = await this.createSubmission(button, null).catch(this.ajaxError.bind(this)); - if (!submission) return; - if (!submission.redirect) return; + this.newSentryTransaction(button, async () => { + const submission = await this.createSubmission(button, null).catch(this.ajaxError.bind(this)); + if (!submission) return; + if (!submission.redirect) return; - this.autosaveIfChanged(); - this.stopCode(event); - this.editors = []; - Turbolinks.clearCache(); - Turbolinks.visit(submission.redirect); + this.autosaveIfChanged(); + this.stopCode(event); + this.editors = []; + Turbolinks.clearCache(); + Turbolinks.visit(submission.redirect); + }); } diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb index e9bd9e5d..4734e3e6 100644 --- a/app/assets/javascripts/editor/editor.js.erb +++ b/app/assets/javascripts/editor/editor.js.erb @@ -202,15 +202,25 @@ var CodeOceanEditor = { $('button i.fa-spin').removeClass('d-inline-block').addClass('d-none'); }, - startSentryTransaction: function (initiator) { - const cause = initiator.data('cause') || initiator.prop('id'); - this.sentryTransaction = window.SentryUtils.startIdleTransaction( - Sentry.getCurrentHub(), - { name: cause, op: "transaction" }, - 0, // Idle Timeout - window.SentryUtils.TRACING_DEFAULTS.finalTimeout, - true); // onContext - Sentry.getCurrentHub().configureScope(scope => scope.setSpan(this.sentryTransaction)); + newSentryTransaction: function (initiator, callback) { + // based on Sentry recommendation. + // See https://github.com/getsentry/sentry-javascript/issues/12116 + return Sentry.continueTrace({ sentryTrace: '', baggage: '' }, () => { + // inside of this we have a new trace! + return Sentry.withActiveSpan(null, () => { + // inside of this there is no parent span, no matter what! + const cause = initiator.data('cause') || initiator.prop('id'); + 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) { diff --git a/app/assets/javascripts/editor/evaluation.js b/app/assets/javascripts/editor/evaluation.js index 8f7a7fcd..2c2d143f 100644 --- a/app/assets/javascripts/editor/evaluation.js +++ b/app/assets/javascripts/editor/evaluation.js @@ -2,7 +2,6 @@ CodeOceanEditorEvaluation = { // A list of non-printable characters that are not allowed in the code output. // 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, - sentryTransaction: null, /** * Scoring-Functions @@ -10,17 +9,18 @@ CodeOceanEditorEvaluation = { scoreCode: function (event) { event.preventDefault(); const cause = $('#assess'); - this.startSentryTransaction(cause); - this.stopCode(event); - this.clearScoringOutput(); - $('#submit').addClass("d-none"); + this.newSentryTransaction(cause, async () => { + this.stopCode(event); + this.clearScoringOutput(); + $('#submit').addClass("d-none"); - const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); - if (!submission) return; + const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); + if (!submission) return; - this.showSpinner($('#assess')); - $('#score_div').removeClass('d-none'); - await this.socketScoreCode(submission.id); + this.showSpinner($('#assess')); + $('#score_div').removeClass('d-none'); + await this.socketScoreCode(submission.id); + }); }, handleScoringResponse: function (results) { diff --git a/app/assets/javascripts/editor/execution.js b/app/assets/javascripts/editor/execution.js index 1622ee98..ca8a52d2 100644 --- a/app/assets/javascripts/editor/execution.js +++ b/app/assets/javascripts/editor/execution.js @@ -8,7 +8,7 @@ CodeOceanEditorWebsocket = { params.protocol = this.webSocketProtocol; 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. const cleanedUrl = urlHelper({ ...params, @@ -16,54 +16,54 @@ CodeOceanEditorWebsocket = { ...(params.filename && {filename: '*'}), // Overwrite the filename with a wildcard only if it is present. }); 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. - // This URL might contain Sentry Tracing headers to propagate the Sentry transaction. - if (span) { - const dynamicContext = this.sentryTransaction.getDynamicSamplingContext(); - const baggage = SentryUtils.dynamicSamplingContextToSentryBaggageHeader(dynamicContext); - if (baggage) { - params.HTTP_SENTRY_TRACE = span.toTraceparent(); - params.HTTP_BAGGAGE = baggage; + // 3. Create the actual WebSocket URL. + // This URL might contain Sentry Tracing headers to propagate the Sentry transaction. + if (webSocketSpan) { + params.HTTP_SENTRY_TRACE = Sentry.spanToTraceHeader(webSocketSpan); + + const baggage = Sentry.spanToBaggageHeader(webSocketSpan); + if (baggage) { + params.HTTP_BAGGAGE = Sentry.spanToBaggageHeader(webSocketSpan); + } } - } - const url = urlHelper({...params}); + const url = urlHelper({...params}); - // 4. Connect to the given URL. - this.websocket = new CommandSocket(url, - function (evt) { - this.resetOutputTab(); - }.bind(this) - ); + // 4. Connect to the given URL. + this.websocket = new CommandSocket(url, + function (evt) { + this.resetOutputTab(); + }.bind(this) + ); - // Attach custom handlers for messages received. - setupFunction(this.websocket); + // Attach custom handlers for messages received. + 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. - return new Promise((resolve, reject) => { - this.websocket.onError(this.showWebsocketError.bind(this)); + // Create and return a new Promise. It will only resolve (or fail) once the connection has ended. + return new Promise((resolve, reject) => { + this.websocket.onError(this.showWebsocketError.bind(this)); - // Remove event listeners for Promise handling. - // This is especially useful in case of an error, where a `close` event might follow the `error` event. - const teardown = () => { - this.websocket.websocket.removeEventListener(closeListener); - this.websocket.websocket.removeEventListener(errorListener); - }; + // Remove event listeners for Promise handling. + // This is especially useful in case of an error, where a `close` event might follow the `error` event. + const teardown = () => { + this.websocket.websocket.removeEventListener(closeListener); + this.websocket.websocket.removeEventListener(errorListener); + }; - // 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. - const closeListener = this.websocket.websocket.addEventListener('close', () => { - span?.finish(); - resolve(); - teardown(); - }); - const errorListener = this.websocket.websocket.addEventListener('error', (error) => { - reject(error); - teardown(); - this.websocket.killWebSocket(); // In case of error, ensure we always close the connection. + // 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. + const closeListener = this.websocket.websocket.addEventListener('close', () => { + resolve(); + teardown(); + }); + const errorListener = this.websocket.websocket.addEventListener('error', (error) => { + reject(error); + teardown(); + this.websocket.killWebSocket(); // In case of error, ensure we always close the connection. + }); }); }); }, diff --git a/app/assets/javascripts/editor/participantsupport.js.erb b/app/assets/javascripts/editor/participantsupport.js.erb index a782ebe9..0afc3fa3 100644 --- a/app/assets/javascripts/editor/participantsupport.js.erb +++ b/app/assets/javascripts/editor/participantsupport.js.erb @@ -110,46 +110,47 @@ CodeOceanEditorRequestForComments = { const cause = $('#requestComments'); const editor = $('#editor') const questionElement = $('#question') - this.startSentryTransaction(cause); - questionElement.prop("disabled", true); - $('#closeAskForCommentsButton').addClass('d-none'); + this.newSentryTransaction(cause, async () => { + questionElement.prop("disabled", true); + $('#closeAskForCommentsButton').addClass('d-none'); - const exercise_id = editor.data('exercise-id'); - const file_id = $('.editor').data('id'); - const question = questionElement.val(); + const exercise_id = editor.data('exercise-id'); + const file_id = $('.editor').data('id'); + const question = questionElement.val(); - const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); - if (!submission) return; + const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); + if (!submission) return; - this.showSpinner($('#askForCommentsButton')); + this.showSpinner($('#askForCommentsButton')); - const response = await $.ajax({ - method: 'POST', - url: Routes.request_for_comments_path(), - data: { - request_for_comment: { - exercise_id: exercise_id, - file_id: file_id, - submission_id: submission.id, - question: question + const response = await $.ajax({ + method: 'POST', + url: Routes.request_for_comments_path(), + data: { + request_for_comment: { + exercise_id: exercise_id, + file_id: file_id, + submission_id: submission.id, + 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')}); - } + }); } }; diff --git a/app/assets/javascripts/editor/submissions.js b/app/assets/javascripts/editor/submissions.js index 909d3f50..0ed45b53 100644 --- a/app/assets/javascripts/editor/submissions.js +++ b/app/assets/javascripts/editor/submissions.js @@ -108,19 +108,20 @@ CodeOceanEditorSubmissions = { }, resetCode: function(initiator, onlyActiveFile = false) { - this.startSentryTransaction(initiator); - this.showSpinner(initiator); + this.newSentryTransaction(initiator, async () => { + this.showSpinner(initiator); - const response = await this.ajax({ - method: 'GET', - url: $('#start-over').data('url') || $('#start-over-active-file').data('url') - }).catch(this.ajaxError.bind(this)); + const response = await this.ajax({ + method: 'GET', + url: $('#start-over').data('url') || $('#start-over-active-file').data('url') + }).catch(this.ajaxError.bind(this)); - this.hideSpinner(); + this.hideSpinner(); - if (!response) return; - App.synchronized_editor?.reset_content(response); - this.setEditorContent(response, onlyActiveFile); + if (!response) return; + App.synchronized_editor?.reset_content(response); + this.setEditorContent(response, onlyActiveFile); + }); }, setEditorContent: function(new_content, onlyActiveFile = false) { @@ -140,32 +141,33 @@ CodeOceanEditorSubmissions = { renderCode: function(event) { event.preventDefault(); const cause = $('#render'); - this.startSentryTransaction(cause); - if (!cause.is(':visible')) return; + this.newSentryTransaction(cause, async () => { + if (!cause.is(':visible')) return; - const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); - if (!submission) return; - if (submission.render_url === undefined) return; + const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); + if (!submission) return; + if (submission.render_url === undefined) return; - const active_file = CodeOceanEditor.active_file.filename; - const desired_file = submission.render_url.filter(hash => hash.filepath === active_file); - const url = desired_file[0].url; + const active_file = CodeOceanEditor.active_file.filename; + const desired_file = submission.render_url.filter(hash => hash.filepath === active_file); + const url = desired_file[0].url; - // Allow to open the new tab even in Safari. - // See: https://stackoverflow.com/a/70463940 - setTimeout(() => { - var pop_up_window = window.open(url, '_blank'); - if (pop_up_window) { - pop_up_window.onerror = function (message) { - this.clearOutput(); - this.printOutput({ - stderr: message - }, true, 0); - this.sendError(message, submission.id); - this.showOutputBar(); - }; - } - }) + // Allow to open the new tab even in Safari. + // See: https://stackoverflow.com/a/70463940 + setTimeout(() => { + var pop_up_window = window.open(url, '_blank'); + if (pop_up_window) { + pop_up_window.onerror = function (message) { + this.clearOutput(); + this.printOutput({ + stderr: message + }, true, 0); + this.sendError(message, submission.id); + this.showOutputBar(); + }; + } + }) + }); }, /** @@ -174,14 +176,15 @@ CodeOceanEditorSubmissions = { runCode: function(event) { event.preventDefault(); const cause = $('#run'); - this.startSentryTransaction(cause); - this.stopCode(event); - if (!cause.is(':visible')) return; + this.newSentryTransaction(cause, async () => { + this.stopCode(event); + if (!cause.is(':visible')) return; - const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); - if (!submission) return; + const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); + if (!submission) return; - await this.runSubmission(submission); + await this.runSubmission(submission); + }); }, runSubmission: async function (submission) { @@ -196,15 +199,16 @@ CodeOceanEditorSubmissions = { testCode: function(event) { event.preventDefault(); const cause = $('#test'); - this.startSentryTransaction(cause); - if (!cause.is(':visible')) return; + this.newSentryTransaction(cause, async () => { + if (!cause.is(':visible')) return; - const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); - if (!submission) return; + const submission = await this.createSubmission(cause, null).catch(this.ajaxError.bind(this)); + if (!submission) return; - this.showSpinner($('#test')); - $('#score_div').addClass('d-none'); - await this.socketTestCode(submission.id, CodeOceanEditor.active_file.filename); + this.showSpinner($('#test')); + $('#score_div').addClass('d-none'); + await this.socketTestCode(submission.id, CodeOceanEditor.active_file.filename); + }); }, /** diff --git a/app/javascript/application.js b/app/javascript/application.js index 487e82fe..deff96f5 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -16,9 +16,6 @@ import 'jstree'; import * as _ from 'underscore'; import * as d3 from 'd3'; 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'; window.bootstrap = bootstrap; // Publish bootstrap 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.SentryIntegrations = function() { // Publish sentry integration in global namespace return [ - new SentryIntegration.ReportingObserver(), - new SentryIntegration.ExtraErrorData(), - new SentryIntegration.HttpClient(), - new Sentry.BrowserProfilingIntegration(), - new Sentry.BrowserTracing(), - new Sentry.Replay(), + Sentry.browserProfilingIntegration(), + Sentry.browserTracingIntegration(), + Sentry.extraErrorDataIntegration(), + Sentry.httpClientIntegration(), + Sentry.replayIntegration(), + Sentry.reportingObserverIntegration(), + Sentry.sessionTimingIntegration(), ] }; -window.SentryUtils = { dynamicSamplingContextToSentryBaggageHeader, startIdleTransaction, TRACING_DEFAULTS }; // CSS import 'chosen-js/chosen.css'; diff --git a/package.json b/package.json index 6862a54f..fd7f682a 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,7 @@ "@egjs/hammerjs": "^2.0.17", "@fortawesome/fontawesome-free": "^6.5.2", "@popperjs/core": "^2.11.8", - "@sentry/browser": "^7.110.1", - "@sentry/core": "^7.114.0", - "@sentry/integrations": "^7.114.0", - "@sentry/utils": "^7.114.0", + "@sentry/browser": "^8.4.0", "@toast-ui/editor": "^3.2.2", "@webpack-cli/serve": "^2.0.5", "ace-builds": "^1.34.0", diff --git a/yarn.lock b/yarn.lock index 2dcf132d..1692f7bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1813,128 +1813,90 @@ __metadata: languageName: node linkType: hard -"@sentry-internal/feedback@npm:7.110.1": - version: 7.110.1 - resolution: "@sentry-internal/feedback@npm:7.110.1" +"@sentry-internal/browser-utils@npm:8.4.0": + version: 8.4.0 + resolution: "@sentry-internal/browser-utils@npm:8.4.0" dependencies: - "@sentry/core": "npm:7.110.1" - "@sentry/types": "npm:7.110.1" - "@sentry/utils": "npm:7.110.1" - checksum: 10c0/5429a7dcd14986770647392558ed0d09f31d33d6771688304f90e88feff9b0af6edaa0195e60c5bdce6a8518409f6314b9d03293b661fc3e1b74ef1c154e4595 + "@sentry/core": "npm:8.4.0" + "@sentry/types": "npm:8.4.0" + "@sentry/utils": "npm:8.4.0" + checksum: 10c0/9e6709100182f8586ef24d304632eedee1f0f257a588bd861df779dee41064cc97afce53b22a4b669e05581f25bc61d7fdae901d238f93569e7042e07d9fbf50 languageName: node linkType: hard -"@sentry-internal/replay-canvas@npm:7.110.1": - version: 7.110.1 - resolution: "@sentry-internal/replay-canvas@npm:7.110.1" +"@sentry-internal/feedback@npm:8.4.0": + version: 8.4.0 + resolution: "@sentry-internal/feedback@npm:8.4.0" dependencies: - "@sentry/core": "npm:7.110.1" - "@sentry/replay": "npm:7.110.1" - "@sentry/types": "npm:7.110.1" - "@sentry/utils": "npm:7.110.1" - checksum: 10c0/125b8247db4631e298f3c8c6d8b486669dfa6356490cc7464a23131a5518d9d7ef314f2c1cbbbadad4f9738ba451fbf5f9457170f4bc899b8275e15ae28cb610 + "@sentry/core": "npm:8.4.0" + "@sentry/types": "npm:8.4.0" + "@sentry/utils": "npm:8.4.0" + checksum: 10c0/028eb28770eb85f1d09caa3ec98420cdb691d2de06be261106876efed572f7d83bfddf6d289468c0f1bbf551d5a75e7b01fe2c2bbac4b0da882c8e655a166b5c languageName: node linkType: hard -"@sentry-internal/tracing@npm:7.110.1": - version: 7.110.1 - resolution: "@sentry-internal/tracing@npm:7.110.1" +"@sentry-internal/replay-canvas@npm:8.4.0": + version: 8.4.0 + resolution: "@sentry-internal/replay-canvas@npm:8.4.0" dependencies: - "@sentry/core": "npm:7.110.1" - "@sentry/types": "npm:7.110.1" - "@sentry/utils": "npm:7.110.1" - checksum: 10c0/ee901b99b838a932f2adb1b085364c816fb0b3f61643ca368af37dd2aa9faf702ea1f3d28f7b0e2e79c57794e3260c8ce34376da0f8658b6ee844b28676ecd55 + "@sentry-internal/replay": "npm:8.4.0" + "@sentry/core": "npm:8.4.0" + "@sentry/types": "npm:8.4.0" + "@sentry/utils": "npm:8.4.0" + checksum: 10c0/6e62557e88f1422f645b022c33c034eccf53469dcdea8e1fbdef34f087e8e986411f50bbf384b7d41f83298b1f339866c8a024456ecf74f1158811f9b91d225b languageName: node linkType: hard -"@sentry/browser@npm:^7.110.1": - version: 7.110.1 - resolution: "@sentry/browser@npm:7.110.1" +"@sentry-internal/replay@npm:8.4.0": + version: 8.4.0 + resolution: "@sentry-internal/replay@npm:8.4.0" dependencies: - "@sentry-internal/feedback": "npm:7.110.1" - "@sentry-internal/replay-canvas": "npm:7.110.1" - "@sentry-internal/tracing": "npm:7.110.1" - "@sentry/core": "npm:7.110.1" - "@sentry/replay": "npm:7.110.1" - "@sentry/types": "npm:7.110.1" - "@sentry/utils": "npm:7.110.1" - checksum: 10c0/085a2cbd2b60dbb596b68d3cf7d0059e226bc8892aa90a50680fa9a9256889a715ff234e9210738a3205ce5513e52290e440ffa4f2d2e2429471ea584d075493 + "@sentry-internal/browser-utils": "npm:8.4.0" + "@sentry/core": "npm:8.4.0" + "@sentry/types": "npm:8.4.0" + "@sentry/utils": "npm:8.4.0" + checksum: 10c0/e9e6398eb3e245470bd464022a9e147038e6adc97212a8e0a28496093f8ed018f8c417bc0d73715f6e63a7506a2d199fadddd23a80246abc8c54d5875d8552c3 languageName: node linkType: hard -"@sentry/core@npm:7.110.1": - version: 7.110.1 - resolution: "@sentry/core@npm:7.110.1" +"@sentry/browser@npm:^8.4.0": + version: 8.4.0 + resolution: "@sentry/browser@npm:8.4.0" dependencies: - "@sentry/types": "npm:7.110.1" - "@sentry/utils": "npm:7.110.1" - checksum: 10c0/8eee39697a1173f233a83fa07b5099c2fdc1f345ec0ac0304ed38c7159214e6a0615fb2fe4dcd4152dbe11cf5ec14bfe3d7da19706e90b13a8bd7984256c4b2f + "@sentry-internal/browser-utils": "npm:8.4.0" + "@sentry-internal/feedback": "npm:8.4.0" + "@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 linkType: hard -"@sentry/core@npm:7.114.0, @sentry/core@npm:^7.114.0": - version: 7.114.0 - resolution: "@sentry/core@npm:7.114.0" +"@sentry/core@npm:8.4.0": + version: 8.4.0 + resolution: "@sentry/core@npm:8.4.0" dependencies: - "@sentry/types": "npm:7.114.0" - "@sentry/utils": "npm:7.114.0" - checksum: 10c0/9ef9cd6e536180a53fdd11dfb30f19a1bf51115b6a828aae4f9dacb92233ced238e3100065429cdb50a654609519722b6cf99721cac21f09dd5d57f123aa4f3c + "@sentry/types": "npm:8.4.0" + "@sentry/utils": "npm:8.4.0" + checksum: 10c0/7c9ffc15a5cbc6cc9811b1444c2ea956dd42b576e63606e3064af0d617fd9c3d97b6ba878f14fc13818d2001a3cf07b73ecde648e31fdb8d9b7e316bd5549470 languageName: node linkType: hard -"@sentry/integrations@npm:^7.114.0": - version: 7.114.0 - resolution: "@sentry/integrations@npm:7.114.0" +"@sentry/types@npm:8.4.0": + version: 8.4.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: - "@sentry/core": "npm:7.114.0" - "@sentry/types": "npm:7.114.0" - "@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 + "@sentry/types": "npm:8.4.0" + checksum: 10c0/3306ba659874344b63ca72dbf7172641b38f590abf8c15291c6f98b2752dcfa9569a209cf83f7a83601acd1c22bc4ab8ead4bb55f7698b9b9b6690cfa6e5ebb5 languageName: node linkType: hard @@ -3074,10 +3036,7 @@ __metadata: "@egjs/hammerjs": "npm:^2.0.17" "@fortawesome/fontawesome-free": "npm:^6.5.2" "@popperjs/core": "npm:^2.11.8" - "@sentry/browser": "npm:^7.110.1" - "@sentry/core": "npm:^7.114.0" - "@sentry/integrations": "npm:^7.114.0" - "@sentry/utils": "npm:^7.114.0" + "@sentry/browser": "npm:^8.4.0" "@toast-ui/editor": "npm:^3.2.2" "@webpack-cli/serve": "npm:^2.0.5" ace-builds: "npm:^1.34.0" @@ -4771,13 +4730,6 @@ __metadata: languageName: node 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": version: 4.3.4 resolution: "immutable@npm:4.3.4" @@ -5200,15 +5152,6 @@ __metadata: languageName: node 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": version: 3.1.1 resolution: "lilconfig@npm:3.1.1" @@ -5234,15 +5177,6 @@ __metadata: languageName: node 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": version: 5.0.0 resolution: "locate-path@npm:5.0.0"