From f3de07412f08d02b9e7c9f6b470255949a516793 Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:03:26 +0300 Subject: [PATCH 1/3] fix(releases): cover case with empty map body (#397) --- workers/release/src/index.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/workers/release/src/index.ts b/workers/release/src/index.ts index 3899ee55..17fe1fba 100644 --- a/workers/release/src/index.ts +++ b/workers/release/src/index.ts @@ -248,22 +248,30 @@ export default class ReleaseWorker extends Worker { * @param {SourcemapCollectedData[]} sourceMaps — source maps passed from user after bundle */ private extendReleaseInfo(sourceMaps: SourcemapCollectedData[]): SourceMapDataExtended[] { - return sourceMaps.map((file: SourcemapCollectedData) => { + return sourceMaps.flatMap((file: SourcemapCollectedData) => { /** * Decode base64 source map content */ const buffer = Buffer.from(file.payload, 'base64'); const mapBodyString = buffer.toString(); + + /** + * If content is empty, return nothing for this file + */ + if (!mapBodyString || mapBodyString.trim().length === 0) { + return []; + } + /** * @todo use more efficient method to extract "file" from big JSON */ const mapContent = JSON.parse(mapBodyString) as RawSourceMap; - return { + return [{ mapFileName: file.name, originFileName: mapContent.file, content: mapBodyString, - }; + }]; }); } From 8fb660dad47be08b61570c7ff91a0c9f6ec7a1cc Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 17:10:19 +0300 Subject: [PATCH 2/3] imp(email): link to billing (#398) * imp(email): link to billing * chore(email): update patterns --- .../emails/events-limit-almost-reached/html.twig | 10 ++++++---- .../emails/events-limit-almost-reached/subject.twig | 2 +- .../emails/events-limit-almost-reached/text.twig | 6 ++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/workers/email/src/templates/emails/events-limit-almost-reached/html.twig b/workers/email/src/templates/emails/events-limit-almost-reached/html.twig index 05dd0c35..d5b3a1d1 100644 --- a/workers/email/src/templates/emails/events-limit-almost-reached/html.twig +++ b/workers/email/src/templates/emails/events-limit-almost-reached/html.twig @@ -14,7 +14,7 @@ - Warning of the Used Volume + You’re almost out of your error tracking limit @@ -22,15 +22,17 @@ - You've used {{ eventsCount }} of {{ eventsLimit }} events available on {{ workspace.name | escape }} workspace. + You’ve used {{ eventsCount }} of {{ eventsLimit }} events this month in the {{ workspace.name | escape }} workspace. - Increase used volume and don't miss the new ones. + Your project is growing — that’s awesome! Let’s make sure you don’t miss any important errors. + + Upgrade your plan to stay on top of everything. - {% include '../../components/button.twig' with {href: host ~ '/workspace/' ~ workspace._id ~ '/settings/volume', label: 'Go to event usage settings'} %} + {% include '../../components/button.twig' with {href: host ~ '/workspace/' ~ workspace._id ~ '/settings/billing', label: 'Increase limit — from 99₽'} %} {% endblock %} diff --git a/workers/email/src/templates/emails/events-limit-almost-reached/subject.twig b/workers/email/src/templates/emails/events-limit-almost-reached/subject.twig index 4a43e8b9..7acf1826 100644 --- a/workers/email/src/templates/emails/events-limit-almost-reached/subject.twig +++ b/workers/email/src/templates/emails/events-limit-almost-reached/subject.twig @@ -1 +1 @@ -Warning of the Used Volume for workspace {{ workspace.name | escape }}! +You’re almost out of error tracking events in {{ workspace.name }} workspace \ No newline at end of file diff --git a/workers/email/src/templates/emails/events-limit-almost-reached/text.twig b/workers/email/src/templates/emails/events-limit-almost-reached/text.twig index 8e2cc7f0..c6c41314 100644 --- a/workers/email/src/templates/emails/events-limit-almost-reached/text.twig +++ b/workers/email/src/templates/emails/events-limit-almost-reached/text.twig @@ -1,6 +1,8 @@ -You've used {{ eventsCount }} of {{ eventsLimit }} events available on {{ workspace.name | escape }} workspace plan. +You’ve used {{ eventsCount }} of {{ eventsLimit }} events this month in the {{ workspace.name | escape }} workspace. -Upgrade the plan and don't miss the new ones: {{ host }}/workspace/{{ workspace._id }}/settings/billing +Your project is growing — that’s awesome! Let’s make sure you don’t miss any important errors. + +Upgrade your plan to stay on top of everything: {{ host }}/workspace/{{ workspace._id }}/settings/billing *** From b9aeb412af288d2134eb0d1b30efd85d9aa1528d Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Tue, 22 Apr 2025 21:39:44 +0300 Subject: [PATCH 3/3] imp(paymaster): add paid until field for workspace (#400) * feat(paymaster): support paid until workspace field * chore(paymaster): update types and test * chore(): lint fix * chore(): lint fix * imp(CI): update ubuntu version * test(paymaster): add new testcase * chore(paymaster): lint fix --- .../workflows/build-and-push-docker-image.yml | 2 +- .github/workflows/check-build.yaml | 2 +- .github/workflows/tests.yml | 2 +- .github/workflows/update-monorepository.yml | 2 +- jest.config.js | 2 +- jest.setup.mongo-repl-set.js | 19 +-- package.json | 2 +- workers/javascript/src/index.ts | 57 +++++---- workers/notifier/tests/redisHelper.test.ts | 9 +- workers/paymaster/src/index.ts | 37 +++--- workers/paymaster/tests/index.test.ts | 116 +++++++++++++++++- workers/release/src/index.ts | 4 +- workers/release/tests/index.test.ts | 13 +- workers/sentry/tests/index.test.ts | 10 +- yarn.lock | 16 +-- 15 files changed, 207 insertions(+), 86 deletions(-) diff --git a/.github/workflows/build-and-push-docker-image.yml b/.github/workflows/build-and-push-docker-image.yml index ee6a9af0..e50aa4e2 100644 --- a/.github/workflows/build-and-push-docker-image.yml +++ b/.github/workflows/build-and-push-docker-image.yml @@ -7,7 +7,7 @@ env: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: endsWith(github.ref, '/prod') || endsWith(github.ref, '/stage') || endsWith(github.ref, '/migration') steps: - name: Checkout repository diff --git a/.github/workflows/check-build.yaml b/.github/workflows/check-build.yaml index d940b734..f4e2c900 100644 --- a/.github/workflows/check-build.yaml +++ b/.github/workflows/check-build.yaml @@ -7,7 +7,7 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 75086ec1..c1576189 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,7 +5,7 @@ on: [push] jobs: lint: name: Unit testing - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Use Node.js 16.x diff --git a/.github/workflows/update-monorepository.yml b/.github/workflows/update-monorepository.yml index 0a6ed811..c86b5283 100644 --- a/.github/workflows/update-monorepository.yml +++ b/.github/workflows/update-monorepository.yml @@ -7,7 +7,7 @@ env: REPOSITORY_MONO_PATH: workers jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Mono repository update uses: peter-evans/repository-dispatch@v1 diff --git a/jest.config.js b/jest.config.js index 28aa802a..f805cf64 100644 --- a/jest.config.js +++ b/jest.config.js @@ -27,5 +27,5 @@ module.exports = { setupFiles: [ './jest.setup.js' ], - setupFilesAfterEnv: [ './jest.setup.redis-mock.js', './jest.setup.mongo-repl-set.js' ], + setupFilesAfterEnv: ['./jest.setup.redis-mock.js', './jest.setup.mongo-repl-set.js'], }; diff --git a/jest.setup.mongo-repl-set.js b/jest.setup.mongo-repl-set.js index 11480eba..2cb302f8 100644 --- a/jest.setup.mongo-repl-set.js +++ b/jest.setup.mongo-repl-set.js @@ -4,7 +4,7 @@ let admin; let connection; beforeAll(async () => { - connection = await MongoClient.connect("mongodb://127.0.0.1:55010/hawk?", { + connection = await MongoClient.connect('mongodb://127.0.0.1:55010/hawk?', { useNewUrlParser: true, useUnifiedTopology: true, }); @@ -13,11 +13,12 @@ beforeAll(async () => { try { let status = await admin.command({ replSetGetStatus: 1 }).catch(() => null); + if (status && status.ok) { - console.log("✅ Replica set already initialized"); + console.log('✅ Replica set already initialized'); } else { await admin.command({ replSetInitiate: {} }); - console.log("✅ Replica set initiated"); + console.log('✅ Replica set initiated'); } const startTime = Date.now(); @@ -30,15 +31,15 @@ beforeAll(async () => { await new Promise(resolve => setTimeout(resolve, 1000)); status = await admin.command({ replSetGetStatus: 1 }); - const primary = status.members.find(member => member.stateStr === "PRIMARY"); - const secondary = status.members.find(member => member.stateStr === "SECONDARY"); + const primary = status.members.find(member => member.stateStr === 'PRIMARY'); + const secondary = status.members.find(member => member.stateStr === 'SECONDARY'); - if (primary && secondary) break; + if (primary && secondary) { + break; + } } while (Date.now() - startTime < timeout); - - console.log("✅ Replica set is stable"); - + console.log('✅ Replica set is stable'); } catch (err) { console.error('❌ Failed to initiate replica set:', err); } diff --git a/package.json b/package.json index c81aee2e..174f356a 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ }, "dependencies": { "@hawk.so/nodejs": "^3.1.1", - "@hawk.so/types": "^0.1.28", + "@hawk.so/types": "^0.1.29", "@types/amqplib": "^0.8.2", "@types/jest": "^29.2.3", "@types/mongodb": "^3.5.15", diff --git a/workers/javascript/src/index.ts b/workers/javascript/src/index.ts index 9652be22..d1807d7e 100644 --- a/workers/javascript/src/index.ts +++ b/workers/javascript/src/index.ts @@ -228,7 +228,7 @@ export default class JavascriptEventWorker extends EventWorker { * Fixes bug: https://github.com/codex-team/hawk.workers/issues/121 */ if (originalLocation.source) { - console.log('original location source found') + console.log('original location source found'); /** * Get 5 lines above and 5 below */ @@ -247,9 +247,10 @@ export default class JavascriptEventWorker extends EventWorker { sourceCode: lines, }) as BacktraceFrame; } - + /** * Method that is used to parse full function context of the code position + * * @param sourceCode - content of the source file * @param line - number of the line from the stack trace * @returns - string of the function context or null if it could not be parsed @@ -257,30 +258,32 @@ export default class JavascriptEventWorker extends EventWorker { private getFunctionContext(sourceCode: string, line: number): string | null { let functionName: string | null = null; let className: string | null = null; - let isAsync: boolean = false; + let isAsync = false; try { const ast = parse(sourceCode, { - sourceType: "module", + sourceType: 'module', plugins: [ - "typescript", - "jsx", - "classProperties", - "decorators", - "optionalChaining", - "nullishCoalescingOperator", - "dynamicImport", - "bigInt", - "topLevelAwait" - ] + 'typescript', + 'jsx', + 'classProperties', + 'decorators', + 'optionalChaining', + 'nullishCoalescingOperator', + 'dynamicImport', + 'bigInt', + 'topLevelAwait', + ], }); traverse(ast as any, { /** * It is used to get class decorator of the position, it will save class that is related to original position + * + * @param path */ ClassDeclaration(path) { - console.log(`class declaration: loc: ${path.node.loc}, line: ${line}, node.start.line: ${path.node.loc.start.line}, node.end.line: ${path.node.loc.end.line}`) + console.log(`class declaration: loc: ${path.node.loc}, line: ${line}, node.start.line: ${path.node.loc.start.line}, node.end.line: ${path.node.loc.end.line}`); if (path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line) { className = path.node.id.name || null; @@ -289,9 +292,11 @@ export default class JavascriptEventWorker extends EventWorker { /** * It is used to get class and its method decorator of the position * It will save class and method, that are related to original position + * + * @param path */ ClassMethod(path) { - console.log(`class declaration: loc: ${path.node.loc}, line: ${line}, node.start.line: ${path.node.loc.start.line}, node.end.line: ${path.node.loc.end.line}`) + console.log(`class declaration: loc: ${path.node.loc}, line: ${line}, node.start.line: ${path.node.loc.start.line}, node.end.line: ${path.node.loc.end.line}`); if (path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line) { // Handle different key types @@ -303,10 +308,12 @@ export default class JavascriptEventWorker extends EventWorker { }, /** * It is used to get function name that is declared out of class + * + * @param path */ FunctionDeclaration(path) { - console.log(`function declaration: loc: ${path.node.loc}, line: ${line}, node.start.line: ${path.node.loc.start.line}, node.end.line: ${path.node.loc.end.line}`) - + console.log(`function declaration: loc: ${path.node.loc}, line: ${line}, node.start.line: ${path.node.loc.start.line}, node.end.line: ${path.node.loc.end.line}`); + if (path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line) { functionName = path.node.id.name || null; isAsync = path.node.async; @@ -314,13 +321,15 @@ export default class JavascriptEventWorker extends EventWorker { }, /** * It is used to get anonimous function names in function expressions or arrow function expressions + * + * @param path */ VariableDeclarator(path) { - console.log(`variable declaration: node.type: ${path.node.init.type}, line: ${line}, `) + console.log(`variable declaration: node.type: ${path.node.init.type}, line: ${line}, `); if ( path.node.init && - (path.node.init.type === "FunctionExpression" || path.node.init.type === "ArrowFunctionExpression") && + (path.node.init.type === 'FunctionExpression' || path.node.init.type === 'ArrowFunctionExpression') && path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line @@ -331,14 +340,14 @@ export default class JavascriptEventWorker extends EventWorker { } isAsync = (path.node.init as any).async; } - } + }, }); } catch (e) { - console.error(`Failed to parse source code: ${e.message}`); + console.error(`Failed to parse source code: ${e.message}`); } - return functionName ? `${isAsync ? "async " : ""}${className ? `${className}.` : ""}${functionName}` : null; -} + return functionName ? `${isAsync ? 'async ' : ''}${className ? `${className}.` : ''}${functionName}` : null; + } /** * Downloads source map file from Grid FS diff --git a/workers/notifier/tests/redisHelper.test.ts b/workers/notifier/tests/redisHelper.test.ts index 5dac298b..c059b610 100644 --- a/workers/notifier/tests/redisHelper.test.ts +++ b/workers/notifier/tests/redisHelper.test.ts @@ -103,15 +103,16 @@ describe('RedisHelper', () => { const thresholdPeriod = 2000; // 2 seconds in milliseconds const key = `${projectId}:${ruleId}:${groupHash}:${thresholdPeriod}:times`; - /** - * Call computeEventCountForPeriod to set the key - */ - await redisHelper.computeEventCountForPeriod(projectId, ruleId, groupHash, thresholdPeriod); + /** + * Call computeEventCountForPeriod to set the key + */ + await redisHelper.computeEventCountForPeriod(projectId, ruleId, groupHash, thresholdPeriod); /** * Verify, that key exists */ let value = await redisClient.hGet(key, 'eventsCount'); + expect(value).not.toBeNull(); /** diff --git a/workers/paymaster/src/index.ts b/workers/paymaster/src/index.ts index f9448242..45b4370b 100644 --- a/workers/paymaster/src/index.ts +++ b/workers/paymaster/src/index.ts @@ -63,14 +63,15 @@ export default class PaymasterWorker extends Worker { * Pay day is calculated by formula: last charge date + 30 days * * @param date - last charge date - * @param isDebug + * @param paidUntil - paid until date + * @param isDebug - flag for debug purposes */ - private static isTimeToPay(date: Date, isDebug = false): boolean { - const expectedPayDay = new Date(date); + private static isTimeToPay(date: Date, paidUntil: Date, isDebug = false): boolean { + const expectedPayDay = paidUntil ? new Date(paidUntil) : new Date(date); if (isDebug) { expectedPayDay.setDate(date.getDate() + 1); - } else { + } else if (!paidUntil) { expectedPayDay.setMonth(date.getMonth() + 1); } @@ -82,17 +83,18 @@ export default class PaymasterWorker extends Worker { /** * Returns difference between now and payday in days * - * Pay day is calculated by formula: last charge date + 30 days + * Pay day is calculated by formula: paidUntil date or last charge date + 1 month * * @param date - last charge date - * @param isDebug + * @param paidUntil - paid until date + * @param isDebug - flag for debug purposes */ - private static daysBeforePayday(date: Date, isDebug = false): number { - const expectedPayDay = new Date(date); + private static daysBeforePayday(date: Date, paidUntil: Date = null, isDebug = false): number { + const expectedPayDay = paidUntil ? new Date(paidUntil) : new Date(date); if (isDebug) { expectedPayDay.setDate(date.getDate() + 1); - } else { + } else if (!paidUntil) { expectedPayDay.setMonth(date.getMonth() + 1); } @@ -104,17 +106,18 @@ export default class PaymasterWorker extends Worker { /** * Returns difference between payday and now in days * - * Pay day is calculated by formula: last charge date + 30 days + * Pay day is calculated by formula: paidUntil date or last charge date + 1 month * * @param date - last charge date - * @param isDebug + * @param paidUntil - paid until date + * @param isDebug - flag for debug purposes */ - private static daysAfterPayday(date: Date, isDebug = false): number { - const expectedPayDay = new Date(date); + private static daysAfterPayday(date: Date, paidUntil: Date = null, isDebug = false): number { + const expectedPayDay = paidUntil ? new Date(paidUntil) : new Date(date); if (isDebug) { expectedPayDay.setDate(date.getDate() + 1); - } else { + } else if (!paidUntil) { expectedPayDay.setMonth(date.getMonth() + 1); } @@ -209,19 +212,19 @@ export default class PaymasterWorker extends Worker { * Is it time to pay */ // @ts-expect-error debug - const isTimeToPay = PaymasterWorker.isTimeToPay(workspace.lastChargeDate, workspace.isDebug); + const isTimeToPay = PaymasterWorker.isTimeToPay(workspace.lastChargeDate, workspace.paidUntil, workspace.isDebug); /** * How many days have passed since payments the expected day of payments */ // @ts-expect-error debug - const daysAfterPayday = PaymasterWorker.daysAfterPayday(workspace.lastChargeDate, workspace.isDebug); + const daysAfterPayday = PaymasterWorker.daysAfterPayday(workspace.lastChargeDate, workspace.paidUntil, workspace.isDebug); /** * How many days left for the expected day of payments */ // @ts-expect-error debug - const daysLeft = PaymasterWorker.daysBeforePayday(workspace.lastChargeDate, workspace.isDebug); + const daysLeft = PaymasterWorker.daysBeforePayday(workspace.lastChargeDate, workspace.paidUntil, workspace.isDebug); /** * Do we need to ask for money diff --git a/workers/paymaster/tests/index.test.ts b/workers/paymaster/tests/index.test.ts index 28fd54fb..7d7e1620 100644 --- a/workers/paymaster/tests/index.test.ts +++ b/workers/paymaster/tests/index.test.ts @@ -46,8 +46,9 @@ const createWorkspaceMock = (parameters: { lastChargeDate: Date | undefined; subscriptionId: string; isBlocked: boolean; + paidUntil?: Date; }): WorkspaceDBScheme => { - return { + const workspace: WorkspaceDBScheme = { _id: new ObjectId(), name: 'Mocked workspace', inviteHash: '', @@ -59,6 +60,12 @@ const createWorkspaceMock = (parameters: { subscriptionId: parameters.subscriptionId, isBlocked: parameters.isBlocked, }; + + if (parameters.paidUntil) { + workspace.paidUntil = parameters.paidUntil; + } + + return workspace; }; describe('PaymasterWorker', () => { @@ -92,6 +99,7 @@ describe('PaymasterWorker', () => { beforeEach(async () => { await workspacesCollection.deleteMany({}); await tariffCollection.deleteMany({}); + jest.clearAllMocks(); }); test('Should block workspace if it hasn\'t subscription and it\'s time to pay', async () => { @@ -352,7 +360,7 @@ describe('PaymasterWorker', () => { */ const currentDate = new Date('2005-12-22'); const plan = createPlanMock({ - monthlyCharge: 0, + monthlyCharge: 10, isDefault: true, }); const workspace = createWorkspaceMock({ @@ -397,8 +405,112 @@ describe('PaymasterWorker', () => { }); }); + test('Should not send notification if paidUntil is set to the several months in the future', async () => { + /** + * Arrange + */ + const currentDate = new Date(); + const paidUntil = new Date(currentDate.getTime()); + + paidUntil.setMonth(paidUntil.getMonth() + 3); + + const plan = createPlanMock({ + monthlyCharge: 100, + isDefault: true, + }); + const workspace = createWorkspaceMock({ + plan, + subscriptionId: null, + lastChargeDate: new Date('2005-11-22'), + isBlocked: false, + billingPeriodEventsCount: 10, + paidUntil, + }); + + const addTaskSpy = jest.spyOn(PaymasterWorker.prototype, 'addTask'); + + await fillDatabaseWithMockedData({ + workspace, + plan, + }); + + MockDate.set(currentDate); + + /** + * Act + */ + const worker = new PaymasterWorker(); + + await worker.start(); + await worker.handle(WORKSPACE_SUBSCRIPTION_CHECK); + await worker.finish(); + + /** + * Assert + */ + expect(addTaskSpy).not.toHaveBeenCalled(); + MockDate.reset(); + }); + afterAll(async () => { await connection.close(); MockDate.reset(); }); + + test('Should send notification if payday is coming for workspace with paidUntil value', async () => { + /** + * Arrange + */ + const currentDate = new Date(); + const paidUntil = new Date(currentDate.getTime()); + + paidUntil.setDate(paidUntil.getDate() + 1); + + const plan = createPlanMock({ + monthlyCharge: 1, + isDefault: true, + }); + const workspace = createWorkspaceMock({ + plan, + subscriptionId: null, + lastChargeDate: new Date('2005-11-22'), + isBlocked: false, + billingPeriodEventsCount: 10, + paidUntil, + }); + + await fillDatabaseWithMockedData({ + workspace, + plan, + }); + + const addTaskSpy = jest.spyOn(PaymasterWorker.prototype, 'addTask'); + + MockDate.set(currentDate); + + /** + * Act + */ + const worker = new PaymasterWorker(); + + await worker.start(); + await worker.handle(WORKSPACE_SUBSCRIPTION_CHECK); + await worker.finish(); + + /** + * Assert + */ + expect(addTaskSpy).toHaveBeenCalledWith( + 'sender/email', + { + type: 'days-limit-almost-reached', + payload: { + workspaceId: workspace._id, + daysLeft: 1, + }, + } + ); + + MockDate.reset(); + }); }); diff --git a/workers/release/src/index.ts b/workers/release/src/index.ts index 17fe1fba..9e8de3b4 100644 --- a/workers/release/src/index.ts +++ b/workers/release/src/index.ts @@ -267,11 +267,11 @@ export default class ReleaseWorker extends Worker { */ const mapContent = JSON.parse(mapBodyString) as RawSourceMap; - return [{ + return [ { mapFileName: file.name, originFileName: mapContent.file, content: mapBodyString, - }]; + } ]; }); } diff --git a/workers/release/tests/index.test.ts b/workers/release/tests/index.test.ts index f80345d2..24f5f46e 100644 --- a/workers/release/tests/index.test.ts +++ b/workers/release/tests/index.test.ts @@ -207,15 +207,16 @@ describe('Release Worker', () => { test('should correctly handle release with multiple source maps in a single transaction', async () => { const map = await mockBundle.getSourceMap(); - + /** * Create multiple files with the same content */ const numberOfFiles = 10; - const collectedData: SourcemapCollectedData[] = Array(numberOfFiles).fill(null).map((_, index) => ({ - name: `main${index}.js.map`, - payload: map, - })); + const collectedData: SourcemapCollectedData[] = Array(numberOfFiles).fill(null) + .map((_, index) => ({ + name: `main${index}.js.map`, + payload: map, + })); await worker.handle({ projectId, @@ -233,6 +234,7 @@ describe('Release Worker', () => { projectId: projectId, release: releasePayload.release, }); + await expect(releasesCount).toEqual(1); /** @@ -242,6 +244,7 @@ describe('Release Worker', () => { projectId: projectId, release: releasePayload.release, }); + await expect(release.files).toHaveLength(numberOfFiles); /** diff --git a/workers/sentry/tests/index.test.ts b/workers/sentry/tests/index.test.ts index bb851396..82732cb4 100644 --- a/workers/sentry/tests/index.test.ts +++ b/workers/sentry/tests/index.test.ts @@ -688,11 +688,11 @@ describe('SentryEventWorker', () => { describe('envelope parsing', () => { const event = { - "projectId": "67ed371b4196dcbd73537c64", - "payload": { - "envelope": "eyJldmVudF9pZCI6IjRiNjE0MGZiOTc1MDQ5NDU5MDhmZTUyYzViMGRkMTIzIiwic2RrIjp7Im5hbWUiOiJzZW50cnkuamF2YS5hbmRyb2lkIiwidmVyc2lvbiI6IjguNi4wIiwicGFja2FnZXMiOlt7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLWNvcmUiLCJ2ZXJzaW9uIjoiOC42LjAifSx7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5LWFuZHJvaWQtcmVwbGF5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1jb21wb3NlIiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLW5kayIsInZlcnNpb24iOiI4LjYuMCJ9XSwiaW50ZWdyYXRpb25zIjpbIkFwcFN0YXJ0SW5zdHJ1bWVudGF0aW9uIiwiQ29tcG9zZUluc3RydW1lbnRhdGlvbiIsIkRhdGFiYXNlSW5zdHJ1bWVudGF0aW9uIiwiRmlsZUlPSW5zdHJ1bWVudGF0aW9uIiwiTG9nY2F0SW5zdHJ1bWVudGF0aW9uIiwiVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIiwiU2h1dGRvd25Ib29rIiwiU2VuZENhY2hlZEVudmVsb3BlIiwiTmRrIiwiQXBwTGlmZWN5Y2xlIiwiQW5yVjIiLCJBcHBDb21wb25lbnRzQnJlYWRjcnVtYnMiLCJFbnZlbG9wZUZpbGVPYnNlcnZlciIsIlN5c3RlbUV2ZW50c0JyZWFkY3J1bWJzIl19LCJ0cmFjZSI6eyJ0cmFjZV9pZCI6IjM5YjFmYTQ0ZTFkNTQ1MWU5NmFiYTEwNjFhNTY2OTJmIiwicHVibGljX2tleSI6Ijc3ZThjYTBkMzllMzQ5NWZhN2UzNjBkOTYwYjc2ZTVmNzg5Mzc3ZjFmYTJiNGZlMmJmZmI2ODY0OTU5M2ExMjMiLCJyZWxlYXNlIjoiY29tLmV4YW1wbGUubXlhcHBsaWNhdGlvbkAxLjArMSIsImVudmlyb25tZW50IjoicHJvZHVjdGlvbiIsInNhbXBsZV9yYW5kIjoiMC4zNTY0MTc5MDcyOTI0NjMifSwic2VudF9hdCI6IjIwMjUtMDQtMDNUMTM6Mjc6MjcuMzQ4WiJ9CnsiY29udGVudF90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsInR5cGUiOiJldmVudCIsImxlbmd0aCI6ODQwM30KeyJ0aW1lc3RhbXAiOiIyMDI1LTA0LTAzVDEzOjE2OjM4LjQzMFoiLCJleGNlcHRpb24iOnsidmFsdWVzIjpbeyJ0eXBlIjoiRXhjZXB0aW9uIiwidmFsdWUiOiLQotC10YHRgtC+0LLQsNGPINC+0YjQuNCx0LrQsCAjMjg3IiwibW9kdWxlIjoiamF2YS5sYW5nIiwidGhyZWFkX2lkIjoyLCJzdGFja3RyYWNlIjp7ImZyYW1lcyI6W3siZmlsZW5hbWUiOiJaeWdvdGVJbml0LmphdmEiLCJmdW5jdGlvbiI6Im1haW4iLCJtb2R1bGUiOiJjb20uYW5kcm9pZC5pbnRlcm5hbC5vcy5aeWdvdGVJbml0IiwibGluZW5vIjo5MzIsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJSdW50aW1lSW5pdC5qYXZhIiwiZnVuY3Rpb24iOiJydW4iLCJtb2R1bGUiOiJjb20uYW5kcm9pZC5pbnRlcm5hbC5vcy5SdW50aW1lSW5pdCRNZXRob2RBbmRBcmdzQ2FsbGVyIiwibGluZW5vIjo1OTMsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJNZXRob2QuamF2YSIsImZ1bmN0aW9uIjoiaW52b2tlIiwibW9kdWxlIjoiamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIiwibmF0aXZlIjp0cnVlfSx7ImZpbGVuYW1lIjoiQWN0aXZpdHlUaHJlYWQuamF2YSIsImZ1bmN0aW9uIjoibWFpbiIsIm1vZHVsZSI6ImFuZHJvaWQuYXBwLkFjdGl2aXR5VGhyZWFkIiwibGluZW5vIjo4OTgyLCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiTG9vcGVyLmphdmEiLCJmdW5jdGlvbiI6Imxvb3AiLCJtb2R1bGUiOiJhbmRyb2lkLm9zLkxvb3BlciIsImxpbmVubyI6MzM4LCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiTG9vcGVyLmphdmEiLCJmdW5jdGlvbiI6Imxvb3BPbmNlIiwibW9kdWxlIjoiYW5kcm9pZC5vcy5Mb29wZXIiLCJsaW5lbm8iOjI0OCwibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6IkhhbmRsZXIuamF2YSIsImZ1bmN0aW9uIjoiZGlzcGF0Y2hNZXNzYWdlIiwibW9kdWxlIjoiYW5kcm9pZC5vcy5IYW5kbGVyIiwibGluZW5vIjoxMDMsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJIYW5kbGVyLmphdmEiLCJmdW5jdGlvbiI6ImhhbmRsZUNhbGxiYWNrIiwibW9kdWxlIjoiYW5kcm9pZC5vcy5IYW5kbGVyIiwibGluZW5vIjo5OTUsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJSdW5uYWJsZS5rdCIsImZ1bmN0aW9uIjoicnVuIiwibW9kdWxlIjoia290bGlueC5jb3JvdXRpbmVzLmFuZHJvaWQuSGFuZGxlckNvbnRleHQkc2NoZWR1bGVSZXN1bWVBZnRlckRlbGF5JCRpbmxpbmVkJFJ1bm5hYmxlJDEiLCJsaW5lbm8iOjE5LCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiQ2FuY2VsbGFibGVDb250aW51YXRpb25JbXBsLmt0IiwiZnVuY3Rpb24iOiJyZXN1bWVVbmRpc3BhdGNoZWQiLCJtb2R1bGUiOiJrb3RsaW54LmNvcm91dGluZXMuQ2FuY2VsbGFibGVDb250aW51YXRpb25JbXBsIiwibGluZW5vIjo1OTUsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJDYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGwua3QiLCJmdW5jdGlvbiI6InJlc3VtZUltcGwkZGVmYXVsdCIsIm1vZHVsZSI6ImtvdGxpbnguY29yb3V0aW5lcy5DYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGwiLCJsaW5lbm8iOjQ5NywibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6IkNhbmNlbGxhYmxlQ29udGludWF0aW9uSW1wbC5rdCIsImZ1bmN0aW9uIjoicmVzdW1lSW1wbCIsIm1vZHVsZSI6ImtvdGxpbnguY29yb3V0aW5lcy5DYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGwiLCJsaW5lbm8iOjUwOCwibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6IkNhbmNlbGxhYmxlQ29udGludWF0aW9uSW1wbC5rdCIsImZ1bmN0aW9uIjoiZGlzcGF0Y2hSZXN1bWUiLCJtb2R1bGUiOiJrb3RsaW54LmNvcm91dGluZXMuQ2FuY2VsbGFibGVDb250aW51YXRpb25JbXBsIiwibGluZW5vIjo0NzQsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJEaXNwYXRjaGVkVGFzay5rdCIsImZ1bmN0aW9uIjoiZGlzcGF0Y2giLCJtb2R1bGUiOiJrb3RsaW54LmNvcm91dGluZXMuRGlzcGF0Y2hlZFRhc2tLdCIsImxpbmVubyI6MTY4LCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiRGlzcGF0Y2hlZFRhc2sua3QiLCJmdW5jdGlvbiI6InJlc3VtZSIsIm1vZHVsZSI6ImtvdGxpbnguY29yb3V0aW5lcy5EaXNwYXRjaGVkVGFza0t0IiwibGluZW5vIjoyMzUsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJDb250aW51YXRpb25JbXBsLmt0IiwiZnVuY3Rpb24iOiJyZXN1bWVXaXRoIiwibW9kdWxlIjoia290bGluLmNvcm91dGluZXMuanZtLmludGVybmFsLkJhc2VDb250aW51YXRpb25JbXBsIiwibGluZW5vIjozMywibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6Ik1haW5BY3Rpdml0eS5rdCIsImZ1bmN0aW9uIjoiaW52b2tlU3VzcGVuZCIsIm1vZHVsZSI6ImNvbS5leGFtcGxlLm15YXBwbGljYXRpb24uTWFpbkFjdGl2aXR5JG9uQ3JlYXRlJDIiLCJsaW5lbm8iOjM4LCJpbl9hcHAiOnRydWUsIm5hdGl2ZSI6ZmFsc2V9XX0sIm1lY2hhbmlzbSI6eyJ0eXBlIjoiY2hhaW5lZCIsImV4Y2VwdGlvbl9pZCI6MH19XX0sImZpbmdlcnByaW50IjpbXSwibW9kdWxlcyI6eyJhbmRyb2lkeC5hcmNoLmNvcmU6Y29yZS1ydW50aW1lIjoiMi4yLjAiLCJhbmRyb2lkeC5jb3JlOmNvcmUta3R4IjoiMS4xMy4xIiwib3JnLmpldGJyYWlucy5rb3RsaW46a290bGluLXN0ZGxpYi1qZGs3IjoiMS45LjI0Iiwib3JnLmpldGJyYWlucy5rb3RsaW46a290bGluLXN0ZGxpYi1qZGs4IjoiMS45LjI0IiwiYW5kcm9pZHguY29uY3VycmVudDpjb25jdXJyZW50LWZ1dHVyZXMiOiIxLjEuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1ydW50aW1lLWFuZHJvaWQiOiIyLjguMyIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdXRpbC1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5jb21wb3NlLnVpOnVpLXRvb2xpbmctYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguY29tcG9zZS51aTp1aS10b29saW5nLWRhdGEtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguc3RhcnR1cDpzdGFydHVwLXJ1bnRpbWUiOiIxLjEuMSIsImFuZHJvaWR4LmxpZmVjeWNsZTpsaWZlY3ljbGUtdmlld21vZGVsLWFuZHJvaWQiOiIyLjguMyIsImFuZHJvaWR4LmxpZmVjeWNsZTpsaWZlY3ljbGUtdmlld21vZGVsLWt0eCI6IjIuOC4zIiwib3JnLmpldGJyYWlucy5rb3RsaW46a290bGluLXN0ZGxpYiI6IjIuMC4yMSIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdGV4dC1hbmRyb2lkIjoiMS43LjAiLCJjb20uZ29vZ2xlLmd1YXZhOmxpc3RlbmFibGVmdXR1cmUiOiIxLjAiLCJhbmRyb2lkeC5saWZlY3ljbGU6bGlmZWN5Y2xlLXByb2Nlc3MiOiIyLjguMyIsImlvLnNlbnRyeTpzZW50cnktY29tcG9zZS1hbmRyb2lkIjoiOC42LjAiLCJhbmRyb2lkeC5hY3Rpdml0eTphY3Rpdml0eS1jb21wb3NlIjoiMS44LjIiLCJhbmRyb2lkeC5jb21wb3NlLnVpOnVpLWdlb21ldHJ5LWFuZHJvaWQiOiIxLjcuMCIsImlvLnNlbnRyeTpzZW50cnktYW5kcm9pZC1yZXBsYXkiOiI4LjYuMCIsImFuZHJvaWR4LmNvbXBvc2UuYW5pbWF0aW9uOmFuaW1hdGlvbi1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5jb21wb3NlLmZvdW5kYXRpb246Zm91bmRhdGlvbi1hbmRyb2lkIjoiMS43LjAiLCJpby5zZW50cnk6c2VudHJ5LW5hdGl2ZS1uZGsiOiIwLjguMyIsImFuZHJvaWR4LmFjdGl2aXR5OmFjdGl2aXR5LWt0eCI6IjEuOC4yIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1ydW50aW1lLWNvbXBvc2UtYW5kcm9pZCI6IjIuOC4zIiwib3JnLmpldGJyYWlucy5rb3RsaW54OmtvdGxpbngtY29yb3V0aW5lcy1jb3JlLWp2bSI6IjEuNy4zIiwiaW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLWNvcmUiOiI4LjYuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktZ3JhcGhpY3MtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguYWN0aXZpdHk6YWN0aXZpdHkiOiIxLjguMiIsImFuZHJvaWR4LmNvbXBvc2UucnVudGltZTpydW50aW1lLWFuZHJvaWQiOiIxLjcuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdGVzdC1tYW5pZmVzdCI6IjEuNy4wIiwiYW5kcm9pZHguZW1vamkyOmVtb2ppMiI6IjEuMy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS12aWV3bW9kZWwtc2F2ZWRzdGF0ZSI6IjIuOC4zIiwiYW5kcm9pZHguZ3JhcGhpY3M6Z3JhcGhpY3MtcGF0aCI6IjEuMC4xIiwiYW5kcm9pZHguY29tcG9zZS5tYXRlcmlhbDM6bWF0ZXJpYWwzLWFuZHJvaWQiOiIxLjMuMCIsImFuZHJvaWR4LmFubm90YXRpb246YW5ub3RhdGlvbi1leHBlcmltZW50YWwiOiIxLjQuMCIsImFuZHJvaWR4LnNhdmVkc3RhdGU6c2F2ZWRzdGF0ZS1rdHgiOiIxLjIuMSIsImFuZHJvaWR4LmNvbGxlY3Rpb246Y29sbGVjdGlvbi1qdm0iOiIxLjQuMCIsImlvLnNlbnRyeTpzZW50cnkta290bGluLWV4dGVuc2lvbnMiOiI4LjYuMCIsIm9yZy5qZXRicmFpbnMua290bGlueDprb3RsaW54LWNvcm91dGluZXMtYW5kcm9pZCI6IjEuNy4zIiwiYW5kcm9pZHguY29tcG9zZS5ydW50aW1lOnJ1bnRpbWUtc2F2ZWFibGUtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguY29tcG9zZS5tYXRlcmlhbDptYXRlcmlhbC1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5zYXZlZHN0YXRlOnNhdmVkc3RhdGUiOiIxLjIuMSIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdW5pdC1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5jb3JlOmNvcmUiOiIxLjEzLjEiLCJhbmRyb2lkeC5jb2xsZWN0aW9uOmNvbGxlY3Rpb24ta3R4IjoiMS40LjAiLCJhbmRyb2lkeC5jb21wb3NlLm1hdGVyaWFsOm1hdGVyaWFsLWljb25zLWNvcmUtYW5kcm9pZCI6IjEuNy4wIiwiaW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkIjoiOC42LjAiLCJhbmRyb2lkeC5saWZlY3ljbGU6bGlmZWN5Y2xlLXJ1bnRpbWUta3R4LWFuZHJvaWQiOiIyLjguMyIsImlvLnNlbnRyeTpzZW50cnktYW5kcm9pZC1uZGsiOiI4LjYuMCIsImFuZHJvaWR4LmFyY2guY29yZTpjb3JlLWNvbW1vbiI6IjIuMi4wIiwiYW5kcm9pZHguY29tcG9zZS5hbmltYXRpb246YW5pbWF0aW9uLWNvcmUtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1jb21tb24tamF2YTgiOiIyLjguMyIsImFuZHJvaWR4LmN1c3RvbXZpZXc6Y3VzdG9tdmlldy1wb29saW5nY29udGFpbmVyIjoiMS4wLjAiLCJvcmcuamV0YnJhaW5zOmFubm90YXRpb25zIjoiMjMuMC4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1jb21tb24tanZtIjoiMi44LjMiLCJpby5zZW50cnk6c2VudHJ5LWFuZHJvaWQtbmF2aWdhdGlvbiI6IjguNi4wIiwiYW5kcm9pZHguY29tcG9zZS5tYXRlcmlhbDptYXRlcmlhbC1yaXBwbGUtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1saXZlZGF0YS1jb3JlIjoiMi44LjMiLCJpby5zZW50cnk6c2VudHJ5IjoiOC42LjAiLCJhbmRyb2lkeC5wcm9maWxlaW5zdGFsbGVyOnByb2ZpbGVpbnN0YWxsZXIiOiIxLjMuMSIsImFuZHJvaWR4LmF1dG9maWxsOmF1dG9maWxsIjoiMS4wLjAiLCJhbmRyb2lkeC5pbnRlcnBvbGF0b3I6aW50ZXJwb2xhdG9yIjoiMS4wLjAiLCJhbmRyb2lkeC50cmFjaW5nOnRyYWNpbmciOiIxLjAuMCIsImFuZHJvaWR4LmFubm90YXRpb246YW5ub3RhdGlvbi1qdm0iOiIxLjguMCIsImFuZHJvaWR4LnZlcnNpb25lZHBhcmNlbGFibGU6dmVyc2lvbmVkcGFyY2VsYWJsZSI6IjEuMS4xIiwiYW5kcm9pZHguY29tcG9zZS5mb3VuZGF0aW9uOmZvdW5kYXRpb24tbGF5b3V0LWFuZHJvaWQiOiIxLjcuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdG9vbGluZy1wcmV2aWV3LWFuZHJvaWQiOiIxLjcuMCJ9LCJldmVudF9pZCI6IjRiNjE0MGZiOTc1MDQ5NDU5MDhmZTUyYzViMGRkMTIzIiwiY29udGV4dHMiOnsiYXBwIjp7ImFwcF9pZGVudGlmaWVyIjoiY29tLmV4YW1wbGUubXlhcHBsaWNhdGlvbiIsImFwcF9uYW1lIjoiTXkgQXBwbGljYXRpb24iLCJhcHBfdmVyc2lvbiI6IjEuMCIsImFwcF9idWlsZCI6IjEiLCJwZXJtaXNzaW9ucyI6eyJEWU5BTUlDX1JFQ0VJVkVSX05PVF9FWFBPUlRFRF9QRVJNSVNTSU9OIjoiZ3JhbnRlZCIsIklOVEVSTkVUIjoiZ3JhbnRlZCJ9LCJpbl9mb3JlZ3JvdW5kIjp0cnVlLCJpc19zcGxpdF9hcGtzIjpmYWxzZX0sImRldmljZSI6eyJtYW51ZmFjdHVyZXIiOiJHb29nbGUiLCJicmFuZCI6Imdvb2dsZSIsImZhbWlseSI6InNka19ncGhvbmU2NF94ODZfNjQiLCJtb2RlbCI6InNka19ncGhvbmU2NF94ODZfNjQiLCJtb2RlbF9pZCI6IkJQMjIuMjUwMjIxLjAxMCIsImFyY2hzIjpbIng4Nl82NCIsImFybTY0LXY4YSJdLCJiYXR0ZXJ5X2xldmVsIjoxMDAuMCwiY2hhcmdpbmciOmZhbHNlLCJvcmllbnRhdGlvbiI6InBvcnRyYWl0Iiwic2ltdWxhdG9yIjp0cnVlLCJtZW1vcnlfc2l6ZSI6MjA2NzI1NTI5NiwiZnJlZV9tZW1vcnkiOjY1MDUxODUyOCwibG93X21lbW9yeSI6ZmFsc2UsInN0b3JhZ2Vfc2l6ZSI6NjIyODExNTQ1NiwiZnJlZV9zdG9yYWdlIjo0NDcyMzczMjQ4LCJleHRlcm5hbF9zdG9yYWdlX3NpemUiOjUzNDc2MTQ3MiwiZXh0ZXJuYWxfZnJlZV9zdG9yYWdlIjo1MzQ3MDQxMjgsInNjcmVlbl93aWR0aF9waXhlbHMiOjcyMCwic2NyZWVuX2hlaWdodF9waXhlbHMiOjEyODAsInNjcmVlbl9kZW5zaXR5IjoyLjAsInNjcmVlbl9kcGkiOjMyMCwiYm9vdF90aW1lIjoiMjAyNS0wNC0wM1QxMjo0NjozMC45NjhaIiwidGltZXpvbmUiOiJHTVQiLCJpZCI6IjYxZmY0NDk4MGQ5NTQxOTViMDhjMmVlZDgxZTE5MTA0IiwiYmF0dGVyeV90ZW1wZXJhdHVyZSI6MjUuMCwibG9jYWxlIjoiZW5fVVMiLCJwcm9jZXNzb3JfY291bnQiOjQsInByb2Nlc3Nvcl9mcmVxdWVuY3kiOjAuMH0sIm9zIjp7Im5hbWUiOiJBbmRyb2lkIiwidmVyc2lvbiI6IjE2IiwiYnVpbGQiOiJCUDIyLjI1MDIyMS4wMTAiLCJrZXJuZWxfdmVyc2lvbiI6IjYuNi42Ni1hbmRyb2lkMTUtOC1nODA3Y2UzYjRmMDJmLWFiMTI5OTY5MDgiLCJyb290ZWQiOmZhbHNlfSwidHJhY2UiOnsidHJhY2VfaWQiOiIzOWIxZmE0NGUxZDU0NTFlOTZhYmExMDYxYTU2NjkyZiIsInNwYW5faWQiOiJkYzhkZmI2NDI1OWQ0YzEzIiwib3AiOiJkZWZhdWx0Iiwib3JpZ2luIjoibWFudWFsIiwiZGF0YSI6eyJ0aHJlYWQubmFtZSI6Im1haW4iLCJ0aHJlYWQuaWQiOiI5NTM2In19fSwic2RrIjp7Im5hbWUiOiJzZW50cnkuamF2YS5hbmRyb2lkIiwidmVyc2lvbiI6IjguNi4wIiwicGFja2FnZXMiOlt7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLWNvcmUiLCJ2ZXJzaW9uIjoiOC42LjAifSx7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5LWFuZHJvaWQtcmVwbGF5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1jb21wb3NlIiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLW5kayIsInZlcnNpb24iOiI4LjYuMCJ9XSwiaW50ZWdyYXRpb25zIjpbIkFwcFN0YXJ0SW5zdHJ1bWVudGF0aW9uIiwiQ29tcG9zZUluc3RydW1lbnRhdGlvbiIsIkRhdGFiYXNlSW5zdHJ1bWVudGF0aW9uIiwiRmlsZUlPSW5zdHJ1bWVudGF0aW9uIiwiTG9nY2F0SW5zdHJ1bWVudGF0aW9uIiwiVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIiwiU2h1dGRvd25Ib29rIiwiU2VuZENhY2hlZEVudmVsb3BlIiwiTmRrIiwiQXBwTGlmZWN5Y2xlIiwiQW5yVjIiLCJBcHBDb21wb25lbnRzQnJlYWRjcnVtYnMiLCJFbnZlbG9wZUZpbGVPYnNlcnZlciIsIlN5c3RlbUV2ZW50c0JyZWFkY3J1bWJzIl19LCJ0YWdzIjp7ImlzU2lkZUxvYWRlZCI6InRydWUifSwicmVsZWFzZSI6ImNvbS5leGFtcGxlLm15YXBwbGljYXRpb25AMS4wKzEiLCJlbnZpcm9ubWVudCI6InByb2R1Y3Rpb24iLCJwbGF0Zm9ybSI6ImphdmEiLCJ1c2VyIjp7ImlkIjoiNjFmZjQ0OTgwZDk1NDE5NWIwOGMyZWVkODFlMTkxMDQifSwiZGlzdCI6IjEiLCJicmVhZGNydW1icyI6W3sidGltZXN0YW1wIjoiMjAyNS0wNC0wM1QxMzoxNjowMi42MDlaIiwidHlwZSI6Im5hdmlnYXRpb24iLCJkYXRhIjp7InN0YXRlIjoiZm9yZWdyb3VuZCJ9LCJjYXRlZ29yeSI6ImFwcC5saWZlY3ljbGUiLCJsZXZlbCI6ImluZm8ifSx7InRpbWVzdGFtcCI6IjIwMjUtMDQtMDNUMTM6MTY6MDQuMzMxWiIsInR5cGUiOiJzeXN0ZW0iLCJkYXRhIjp7ImxldmVsIjoxMDAuMCwiY2hhcmdpbmciOmZhbHNlLCJhY3Rpb24iOiJCQVRURVJZX0NIQU5HRUQifSwiY2F0ZWdvcnkiOiJkZXZpY2UuZXZlbnQiLCJsZXZlbCI6ImluZm8ifV19CnsiY29udGVudF90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsInR5cGUiOiJzZXNzaW9uIiwibGVuZ3RoIjoyODd9Cnsic2lkIjoiNzEzZWQwMzViYjI5NDI2Mzk2MmE4YTAxZGNkZTVjNTIiLCJkaWQiOiI2MWZmNDQ5ODBkOTU0MTk1YjA4YzJlZWQ4MWUxOTEwNCIsInN0YXJ0ZWQiOiIyMDI1LTA0LTAzVDEzOjE2OjAyLjE3N1oiLCJzdGF0dXMiOiJvayIsInNlcSI6MTc0MzY4NjE5ODQ2NywiZXJyb3JzIjoyODcsInRpbWVzdGFtcCI6IjIwMjUtMDQtMDNUMTM6MTY6MzguNDY3WiIsImF0dHJzIjp7InJlbGVhc2UiOiJjb20uZXhhbXBsZS5teWFwcGxpY2F0aW9uQDEuMCsxIiwiZW52aXJvbm1lbnQiOiJwcm9kdWN0aW9uIn19Cg==" + projectId: '67ed371b4196dcbd73537c64', + payload: { + envelope: 'eyJldmVudF9pZCI6IjRiNjE0MGZiOTc1MDQ5NDU5MDhmZTUyYzViMGRkMTIzIiwic2RrIjp7Im5hbWUiOiJzZW50cnkuamF2YS5hbmRyb2lkIiwidmVyc2lvbiI6IjguNi4wIiwicGFja2FnZXMiOlt7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLWNvcmUiLCJ2ZXJzaW9uIjoiOC42LjAifSx7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5LWFuZHJvaWQtcmVwbGF5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1jb21wb3NlIiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLW5kayIsInZlcnNpb24iOiI4LjYuMCJ9XSwiaW50ZWdyYXRpb25zIjpbIkFwcFN0YXJ0SW5zdHJ1bWVudGF0aW9uIiwiQ29tcG9zZUluc3RydW1lbnRhdGlvbiIsIkRhdGFiYXNlSW5zdHJ1bWVudGF0aW9uIiwiRmlsZUlPSW5zdHJ1bWVudGF0aW9uIiwiTG9nY2F0SW5zdHJ1bWVudGF0aW9uIiwiVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIiwiU2h1dGRvd25Ib29rIiwiU2VuZENhY2hlZEVudmVsb3BlIiwiTmRrIiwiQXBwTGlmZWN5Y2xlIiwiQW5yVjIiLCJBcHBDb21wb25lbnRzQnJlYWRjcnVtYnMiLCJFbnZlbG9wZUZpbGVPYnNlcnZlciIsIlN5c3RlbUV2ZW50c0JyZWFkY3J1bWJzIl19LCJ0cmFjZSI6eyJ0cmFjZV9pZCI6IjM5YjFmYTQ0ZTFkNTQ1MWU5NmFiYTEwNjFhNTY2OTJmIiwicHVibGljX2tleSI6Ijc3ZThjYTBkMzllMzQ5NWZhN2UzNjBkOTYwYjc2ZTVmNzg5Mzc3ZjFmYTJiNGZlMmJmZmI2ODY0OTU5M2ExMjMiLCJyZWxlYXNlIjoiY29tLmV4YW1wbGUubXlhcHBsaWNhdGlvbkAxLjArMSIsImVudmlyb25tZW50IjoicHJvZHVjdGlvbiIsInNhbXBsZV9yYW5kIjoiMC4zNTY0MTc5MDcyOTI0NjMifSwic2VudF9hdCI6IjIwMjUtMDQtMDNUMTM6Mjc6MjcuMzQ4WiJ9CnsiY29udGVudF90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsInR5cGUiOiJldmVudCIsImxlbmd0aCI6ODQwM30KeyJ0aW1lc3RhbXAiOiIyMDI1LTA0LTAzVDEzOjE2OjM4LjQzMFoiLCJleGNlcHRpb24iOnsidmFsdWVzIjpbeyJ0eXBlIjoiRXhjZXB0aW9uIiwidmFsdWUiOiLQotC10YHRgtC+0LLQsNGPINC+0YjQuNCx0LrQsCAjMjg3IiwibW9kdWxlIjoiamF2YS5sYW5nIiwidGhyZWFkX2lkIjoyLCJzdGFja3RyYWNlIjp7ImZyYW1lcyI6W3siZmlsZW5hbWUiOiJaeWdvdGVJbml0LmphdmEiLCJmdW5jdGlvbiI6Im1haW4iLCJtb2R1bGUiOiJjb20uYW5kcm9pZC5pbnRlcm5hbC5vcy5aeWdvdGVJbml0IiwibGluZW5vIjo5MzIsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJSdW50aW1lSW5pdC5qYXZhIiwiZnVuY3Rpb24iOiJydW4iLCJtb2R1bGUiOiJjb20uYW5kcm9pZC5pbnRlcm5hbC5vcy5SdW50aW1lSW5pdCRNZXRob2RBbmRBcmdzQ2FsbGVyIiwibGluZW5vIjo1OTMsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJNZXRob2QuamF2YSIsImZ1bmN0aW9uIjoiaW52b2tlIiwibW9kdWxlIjoiamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIiwibmF0aXZlIjp0cnVlfSx7ImZpbGVuYW1lIjoiQWN0aXZpdHlUaHJlYWQuamF2YSIsImZ1bmN0aW9uIjoibWFpbiIsIm1vZHVsZSI6ImFuZHJvaWQuYXBwLkFjdGl2aXR5VGhyZWFkIiwibGluZW5vIjo4OTgyLCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiTG9vcGVyLmphdmEiLCJmdW5jdGlvbiI6Imxvb3AiLCJtb2R1bGUiOiJhbmRyb2lkLm9zLkxvb3BlciIsImxpbmVubyI6MzM4LCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiTG9vcGVyLmphdmEiLCJmdW5jdGlvbiI6Imxvb3BPbmNlIiwibW9kdWxlIjoiYW5kcm9pZC5vcy5Mb29wZXIiLCJsaW5lbm8iOjI0OCwibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6IkhhbmRsZXIuamF2YSIsImZ1bmN0aW9uIjoiZGlzcGF0Y2hNZXNzYWdlIiwibW9kdWxlIjoiYW5kcm9pZC5vcy5IYW5kbGVyIiwibGluZW5vIjoxMDMsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJIYW5kbGVyLmphdmEiLCJmdW5jdGlvbiI6ImhhbmRsZUNhbGxiYWNrIiwibW9kdWxlIjoiYW5kcm9pZC5vcy5IYW5kbGVyIiwibGluZW5vIjo5OTUsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJSdW5uYWJsZS5rdCIsImZ1bmN0aW9uIjoicnVuIiwibW9kdWxlIjoia290bGlueC5jb3JvdXRpbmVzLmFuZHJvaWQuSGFuZGxlckNvbnRleHQkc2NoZWR1bGVSZXN1bWVBZnRlckRlbGF5JCRpbmxpbmVkJFJ1bm5hYmxlJDEiLCJsaW5lbm8iOjE5LCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiQ2FuY2VsbGFibGVDb250aW51YXRpb25JbXBsLmt0IiwiZnVuY3Rpb24iOiJyZXN1bWVVbmRpc3BhdGNoZWQiLCJtb2R1bGUiOiJrb3RsaW54LmNvcm91dGluZXMuQ2FuY2VsbGFibGVDb250aW51YXRpb25JbXBsIiwibGluZW5vIjo1OTUsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJDYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGwua3QiLCJmdW5jdGlvbiI6InJlc3VtZUltcGwkZGVmYXVsdCIsIm1vZHVsZSI6ImtvdGxpbnguY29yb3V0aW5lcy5DYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGwiLCJsaW5lbm8iOjQ5NywibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6IkNhbmNlbGxhYmxlQ29udGludWF0aW9uSW1wbC5rdCIsImZ1bmN0aW9uIjoicmVzdW1lSW1wbCIsIm1vZHVsZSI6ImtvdGxpbnguY29yb3V0aW5lcy5DYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGwiLCJsaW5lbm8iOjUwOCwibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6IkNhbmNlbGxhYmxlQ29udGludWF0aW9uSW1wbC5rdCIsImZ1bmN0aW9uIjoiZGlzcGF0Y2hSZXN1bWUiLCJtb2R1bGUiOiJrb3RsaW54LmNvcm91dGluZXMuQ2FuY2VsbGFibGVDb250aW51YXRpb25JbXBsIiwibGluZW5vIjo0NzQsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJEaXNwYXRjaGVkVGFzay5rdCIsImZ1bmN0aW9uIjoiZGlzcGF0Y2giLCJtb2R1bGUiOiJrb3RsaW54LmNvcm91dGluZXMuRGlzcGF0Y2hlZFRhc2tLdCIsImxpbmVubyI6MTY4LCJuYXRpdmUiOmZhbHNlfSx7ImZpbGVuYW1lIjoiRGlzcGF0Y2hlZFRhc2sua3QiLCJmdW5jdGlvbiI6InJlc3VtZSIsIm1vZHVsZSI6ImtvdGxpbnguY29yb3V0aW5lcy5EaXNwYXRjaGVkVGFza0t0IiwibGluZW5vIjoyMzUsIm5hdGl2ZSI6ZmFsc2V9LHsiZmlsZW5hbWUiOiJDb250aW51YXRpb25JbXBsLmt0IiwiZnVuY3Rpb24iOiJyZXN1bWVXaXRoIiwibW9kdWxlIjoia290bGluLmNvcm91dGluZXMuanZtLmludGVybmFsLkJhc2VDb250aW51YXRpb25JbXBsIiwibGluZW5vIjozMywibmF0aXZlIjpmYWxzZX0seyJmaWxlbmFtZSI6Ik1haW5BY3Rpdml0eS5rdCIsImZ1bmN0aW9uIjoiaW52b2tlU3VzcGVuZCIsIm1vZHVsZSI6ImNvbS5leGFtcGxlLm15YXBwbGljYXRpb24uTWFpbkFjdGl2aXR5JG9uQ3JlYXRlJDIiLCJsaW5lbm8iOjM4LCJpbl9hcHAiOnRydWUsIm5hdGl2ZSI6ZmFsc2V9XX0sIm1lY2hhbmlzbSI6eyJ0eXBlIjoiY2hhaW5lZCIsImV4Y2VwdGlvbl9pZCI6MH19XX0sImZpbmdlcnByaW50IjpbXSwibW9kdWxlcyI6eyJhbmRyb2lkeC5hcmNoLmNvcmU6Y29yZS1ydW50aW1lIjoiMi4yLjAiLCJhbmRyb2lkeC5jb3JlOmNvcmUta3R4IjoiMS4xMy4xIiwib3JnLmpldGJyYWlucy5rb3RsaW46a290bGluLXN0ZGxpYi1qZGs3IjoiMS45LjI0Iiwib3JnLmpldGJyYWlucy5rb3RsaW46a290bGluLXN0ZGxpYi1qZGs4IjoiMS45LjI0IiwiYW5kcm9pZHguY29uY3VycmVudDpjb25jdXJyZW50LWZ1dHVyZXMiOiIxLjEuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1ydW50aW1lLWFuZHJvaWQiOiIyLjguMyIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdXRpbC1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5jb21wb3NlLnVpOnVpLXRvb2xpbmctYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguY29tcG9zZS51aTp1aS10b29saW5nLWRhdGEtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguc3RhcnR1cDpzdGFydHVwLXJ1bnRpbWUiOiIxLjEuMSIsImFuZHJvaWR4LmxpZmVjeWNsZTpsaWZlY3ljbGUtdmlld21vZGVsLWFuZHJvaWQiOiIyLjguMyIsImFuZHJvaWR4LmxpZmVjeWNsZTpsaWZlY3ljbGUtdmlld21vZGVsLWt0eCI6IjIuOC4zIiwib3JnLmpldGJyYWlucy5rb3RsaW46a290bGluLXN0ZGxpYiI6IjIuMC4yMSIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdGV4dC1hbmRyb2lkIjoiMS43LjAiLCJjb20uZ29vZ2xlLmd1YXZhOmxpc3RlbmFibGVmdXR1cmUiOiIxLjAiLCJhbmRyb2lkeC5saWZlY3ljbGU6bGlmZWN5Y2xlLXByb2Nlc3MiOiIyLjguMyIsImlvLnNlbnRyeTpzZW50cnktY29tcG9zZS1hbmRyb2lkIjoiOC42LjAiLCJhbmRyb2lkeC5hY3Rpdml0eTphY3Rpdml0eS1jb21wb3NlIjoiMS44LjIiLCJhbmRyb2lkeC5jb21wb3NlLnVpOnVpLWdlb21ldHJ5LWFuZHJvaWQiOiIxLjcuMCIsImlvLnNlbnRyeTpzZW50cnktYW5kcm9pZC1yZXBsYXkiOiI4LjYuMCIsImFuZHJvaWR4LmNvbXBvc2UuYW5pbWF0aW9uOmFuaW1hdGlvbi1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5jb21wb3NlLmZvdW5kYXRpb246Zm91bmRhdGlvbi1hbmRyb2lkIjoiMS43LjAiLCJpby5zZW50cnk6c2VudHJ5LW5hdGl2ZS1uZGsiOiIwLjguMyIsImFuZHJvaWR4LmFjdGl2aXR5OmFjdGl2aXR5LWt0eCI6IjEuOC4yIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1ydW50aW1lLWNvbXBvc2UtYW5kcm9pZCI6IjIuOC4zIiwib3JnLmpldGJyYWlucy5rb3RsaW54OmtvdGxpbngtY29yb3V0aW5lcy1jb3JlLWp2bSI6IjEuNy4zIiwiaW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLWNvcmUiOiI4LjYuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktZ3JhcGhpY3MtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguYWN0aXZpdHk6YWN0aXZpdHkiOiIxLjguMiIsImFuZHJvaWR4LmNvbXBvc2UucnVudGltZTpydW50aW1lLWFuZHJvaWQiOiIxLjcuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdGVzdC1tYW5pZmVzdCI6IjEuNy4wIiwiYW5kcm9pZHguZW1vamkyOmVtb2ppMiI6IjEuMy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS12aWV3bW9kZWwtc2F2ZWRzdGF0ZSI6IjIuOC4zIiwiYW5kcm9pZHguZ3JhcGhpY3M6Z3JhcGhpY3MtcGF0aCI6IjEuMC4xIiwiYW5kcm9pZHguY29tcG9zZS5tYXRlcmlhbDM6bWF0ZXJpYWwzLWFuZHJvaWQiOiIxLjMuMCIsImFuZHJvaWR4LmFubm90YXRpb246YW5ub3RhdGlvbi1leHBlcmltZW50YWwiOiIxLjQuMCIsImFuZHJvaWR4LnNhdmVkc3RhdGU6c2F2ZWRzdGF0ZS1rdHgiOiIxLjIuMSIsImFuZHJvaWR4LmNvbGxlY3Rpb246Y29sbGVjdGlvbi1qdm0iOiIxLjQuMCIsImlvLnNlbnRyeTpzZW50cnkta290bGluLWV4dGVuc2lvbnMiOiI4LjYuMCIsIm9yZy5qZXRicmFpbnMua290bGlueDprb3RsaW54LWNvcm91dGluZXMtYW5kcm9pZCI6IjEuNy4zIiwiYW5kcm9pZHguY29tcG9zZS5ydW50aW1lOnJ1bnRpbWUtc2F2ZWFibGUtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHguY29tcG9zZS5tYXRlcmlhbDptYXRlcmlhbC1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5zYXZlZHN0YXRlOnNhdmVkc3RhdGUiOiIxLjIuMSIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdW5pdC1hbmRyb2lkIjoiMS43LjAiLCJhbmRyb2lkeC5jb3JlOmNvcmUiOiIxLjEzLjEiLCJhbmRyb2lkeC5jb2xsZWN0aW9uOmNvbGxlY3Rpb24ta3R4IjoiMS40LjAiLCJhbmRyb2lkeC5jb21wb3NlLm1hdGVyaWFsOm1hdGVyaWFsLWljb25zLWNvcmUtYW5kcm9pZCI6IjEuNy4wIiwiaW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkIjoiOC42LjAiLCJhbmRyb2lkeC5saWZlY3ljbGU6bGlmZWN5Y2xlLXJ1bnRpbWUta3R4LWFuZHJvaWQiOiIyLjguMyIsImlvLnNlbnRyeTpzZW50cnktYW5kcm9pZC1uZGsiOiI4LjYuMCIsImFuZHJvaWR4LmFyY2guY29yZTpjb3JlLWNvbW1vbiI6IjIuMi4wIiwiYW5kcm9pZHguY29tcG9zZS5hbmltYXRpb246YW5pbWF0aW9uLWNvcmUtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1jb21tb24tamF2YTgiOiIyLjguMyIsImFuZHJvaWR4LmN1c3RvbXZpZXc6Y3VzdG9tdmlldy1wb29saW5nY29udGFpbmVyIjoiMS4wLjAiLCJvcmcuamV0YnJhaW5zOmFubm90YXRpb25zIjoiMjMuMC4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1jb21tb24tanZtIjoiMi44LjMiLCJpby5zZW50cnk6c2VudHJ5LWFuZHJvaWQtbmF2aWdhdGlvbiI6IjguNi4wIiwiYW5kcm9pZHguY29tcG9zZS5tYXRlcmlhbDptYXRlcmlhbC1yaXBwbGUtYW5kcm9pZCI6IjEuNy4wIiwiYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1saXZlZGF0YS1jb3JlIjoiMi44LjMiLCJpby5zZW50cnk6c2VudHJ5IjoiOC42LjAiLCJhbmRyb2lkeC5wcm9maWxlaW5zdGFsbGVyOnByb2ZpbGVpbnN0YWxsZXIiOiIxLjMuMSIsImFuZHJvaWR4LmF1dG9maWxsOmF1dG9maWxsIjoiMS4wLjAiLCJhbmRyb2lkeC5pbnRlcnBvbGF0b3I6aW50ZXJwb2xhdG9yIjoiMS4wLjAiLCJhbmRyb2lkeC50cmFjaW5nOnRyYWNpbmciOiIxLjAuMCIsImFuZHJvaWR4LmFubm90YXRpb246YW5ub3RhdGlvbi1qdm0iOiIxLjguMCIsImFuZHJvaWR4LnZlcnNpb25lZHBhcmNlbGFibGU6dmVyc2lvbmVkcGFyY2VsYWJsZSI6IjEuMS4xIiwiYW5kcm9pZHguY29tcG9zZS5mb3VuZGF0aW9uOmZvdW5kYXRpb24tbGF5b3V0LWFuZHJvaWQiOiIxLjcuMCIsImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdG9vbGluZy1wcmV2aWV3LWFuZHJvaWQiOiIxLjcuMCJ9LCJldmVudF9pZCI6IjRiNjE0MGZiOTc1MDQ5NDU5MDhmZTUyYzViMGRkMTIzIiwiY29udGV4dHMiOnsiYXBwIjp7ImFwcF9pZGVudGlmaWVyIjoiY29tLmV4YW1wbGUubXlhcHBsaWNhdGlvbiIsImFwcF9uYW1lIjoiTXkgQXBwbGljYXRpb24iLCJhcHBfdmVyc2lvbiI6IjEuMCIsImFwcF9idWlsZCI6IjEiLCJwZXJtaXNzaW9ucyI6eyJEWU5BTUlDX1JFQ0VJVkVSX05PVF9FWFBPUlRFRF9QRVJNSVNTSU9OIjoiZ3JhbnRlZCIsIklOVEVSTkVUIjoiZ3JhbnRlZCJ9LCJpbl9mb3JlZ3JvdW5kIjp0cnVlLCJpc19zcGxpdF9hcGtzIjpmYWxzZX0sImRldmljZSI6eyJtYW51ZmFjdHVyZXIiOiJHb29nbGUiLCJicmFuZCI6Imdvb2dsZSIsImZhbWlseSI6InNka19ncGhvbmU2NF94ODZfNjQiLCJtb2RlbCI6InNka19ncGhvbmU2NF94ODZfNjQiLCJtb2RlbF9pZCI6IkJQMjIuMjUwMjIxLjAxMCIsImFyY2hzIjpbIng4Nl82NCIsImFybTY0LXY4YSJdLCJiYXR0ZXJ5X2xldmVsIjoxMDAuMCwiY2hhcmdpbmciOmZhbHNlLCJvcmllbnRhdGlvbiI6InBvcnRyYWl0Iiwic2ltdWxhdG9yIjp0cnVlLCJtZW1vcnlfc2l6ZSI6MjA2NzI1NTI5NiwiZnJlZV9tZW1vcnkiOjY1MDUxODUyOCwibG93X21lbW9yeSI6ZmFsc2UsInN0b3JhZ2Vfc2l6ZSI6NjIyODExNTQ1NiwiZnJlZV9zdG9yYWdlIjo0NDcyMzczMjQ4LCJleHRlcm5hbF9zdG9yYWdlX3NpemUiOjUzNDc2MTQ3MiwiZXh0ZXJuYWxfZnJlZV9zdG9yYWdlIjo1MzQ3MDQxMjgsInNjcmVlbl93aWR0aF9waXhlbHMiOjcyMCwic2NyZWVuX2hlaWdodF9waXhlbHMiOjEyODAsInNjcmVlbl9kZW5zaXR5IjoyLjAsInNjcmVlbl9kcGkiOjMyMCwiYm9vdF90aW1lIjoiMjAyNS0wNC0wM1QxMjo0NjozMC45NjhaIiwidGltZXpvbmUiOiJHTVQiLCJpZCI6IjYxZmY0NDk4MGQ5NTQxOTViMDhjMmVlZDgxZTE5MTA0IiwiYmF0dGVyeV90ZW1wZXJhdHVyZSI6MjUuMCwibG9jYWxlIjoiZW5fVVMiLCJwcm9jZXNzb3JfY291bnQiOjQsInByb2Nlc3Nvcl9mcmVxdWVuY3kiOjAuMH0sIm9zIjp7Im5hbWUiOiJBbmRyb2lkIiwidmVyc2lvbiI6IjE2IiwiYnVpbGQiOiJCUDIyLjI1MDIyMS4wMTAiLCJrZXJuZWxfdmVyc2lvbiI6IjYuNi42Ni1hbmRyb2lkMTUtOC1nODA3Y2UzYjRmMDJmLWFiMTI5OTY5MDgiLCJyb290ZWQiOmZhbHNlfSwidHJhY2UiOnsidHJhY2VfaWQiOiIzOWIxZmE0NGUxZDU0NTFlOTZhYmExMDYxYTU2NjkyZiIsInNwYW5faWQiOiJkYzhkZmI2NDI1OWQ0YzEzIiwib3AiOiJkZWZhdWx0Iiwib3JpZ2luIjoibWFudWFsIiwiZGF0YSI6eyJ0aHJlYWQubmFtZSI6Im1haW4iLCJ0aHJlYWQuaWQiOiI5NTM2In19fSwic2RrIjp7Im5hbWUiOiJzZW50cnkuamF2YS5hbmRyb2lkIiwidmVyc2lvbiI6IjguNi4wIiwicGFja2FnZXMiOlt7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLWNvcmUiLCJ2ZXJzaW9uIjoiOC42LjAifSx7Im5hbWUiOiJtYXZlbjppby5zZW50cnk6c2VudHJ5LWFuZHJvaWQtcmVwbGF5IiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1jb21wb3NlIiwidmVyc2lvbiI6IjguNi4wIn0seyJuYW1lIjoibWF2ZW46aW8uc2VudHJ5OnNlbnRyeS1hbmRyb2lkLW5kayIsInZlcnNpb24iOiI4LjYuMCJ9XSwiaW50ZWdyYXRpb25zIjpbIkFwcFN0YXJ0SW5zdHJ1bWVudGF0aW9uIiwiQ29tcG9zZUluc3RydW1lbnRhdGlvbiIsIkRhdGFiYXNlSW5zdHJ1bWVudGF0aW9uIiwiRmlsZUlPSW5zdHJ1bWVudGF0aW9uIiwiTG9nY2F0SW5zdHJ1bWVudGF0aW9uIiwiVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIiwiU2h1dGRvd25Ib29rIiwiU2VuZENhY2hlZEVudmVsb3BlIiwiTmRrIiwiQXBwTGlmZWN5Y2xlIiwiQW5yVjIiLCJBcHBDb21wb25lbnRzQnJlYWRjcnVtYnMiLCJFbnZlbG9wZUZpbGVPYnNlcnZlciIsIlN5c3RlbUV2ZW50c0JyZWFkY3J1bWJzIl19LCJ0YWdzIjp7ImlzU2lkZUxvYWRlZCI6InRydWUifSwicmVsZWFzZSI6ImNvbS5leGFtcGxlLm15YXBwbGljYXRpb25AMS4wKzEiLCJlbnZpcm9ubWVudCI6InByb2R1Y3Rpb24iLCJwbGF0Zm9ybSI6ImphdmEiLCJ1c2VyIjp7ImlkIjoiNjFmZjQ0OTgwZDk1NDE5NWIwOGMyZWVkODFlMTkxMDQifSwiZGlzdCI6IjEiLCJicmVhZGNydW1icyI6W3sidGltZXN0YW1wIjoiMjAyNS0wNC0wM1QxMzoxNjowMi42MDlaIiwidHlwZSI6Im5hdmlnYXRpb24iLCJkYXRhIjp7InN0YXRlIjoiZm9yZWdyb3VuZCJ9LCJjYXRlZ29yeSI6ImFwcC5saWZlY3ljbGUiLCJsZXZlbCI6ImluZm8ifSx7InRpbWVzdGFtcCI6IjIwMjUtMDQtMDNUMTM6MTY6MDQuMzMxWiIsInR5cGUiOiJzeXN0ZW0iLCJkYXRhIjp7ImxldmVsIjoxMDAuMCwiY2hhcmdpbmciOmZhbHNlLCJhY3Rpb24iOiJCQVRURVJZX0NIQU5HRUQifSwiY2F0ZWdvcnkiOiJkZXZpY2UuZXZlbnQiLCJsZXZlbCI6ImluZm8ifV19CnsiY29udGVudF90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsInR5cGUiOiJzZXNzaW9uIiwibGVuZ3RoIjoyODd9Cnsic2lkIjoiNzEzZWQwMzViYjI5NDI2Mzk2MmE4YTAxZGNkZTVjNTIiLCJkaWQiOiI2MWZmNDQ5ODBkOTU0MTk1YjA4YzJlZWQ4MWUxOTEwNCIsInN0YXJ0ZWQiOiIyMDI1LTA0LTAzVDEzOjE2OjAyLjE3N1oiLCJzdGF0dXMiOiJvayIsInNlcSI6MTc0MzY4NjE5ODQ2NywiZXJyb3JzIjoyODcsInRpbWVzdGFtcCI6IjIwMjUtMDQtMDNUMTM6MTY6MzguNDY3WiIsImF0dHJzIjp7InJlbGVhc2UiOiJjb20uZXhhbXBsZS5teWFwcGxpY2F0aW9uQDEuMCsxIiwiZW52aXJvbm1lbnQiOiJwcm9kdWN0aW9uIn19Cg==', }, - "catcherType": "external/sentry" + catcherType: 'external/sentry', }; it('should correctly parse string envelope with cyrillic chars in exception title', async () => { @@ -716,7 +716,7 @@ describe('SentryEventWorker', () => { (eventBuffered.payload as { envelope: Buffer - }).envelope = base64toBuffer(event.payload.envelope) + }).envelope = base64toBuffer(event.payload.envelope); await worker.handle(event as SentryEventWorkerTask); diff --git a/yarn.lock b/yarn.lock index a0cb9a4d..c83d5fac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -354,14 +354,6 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@7.26.9", "@babel/types@^7.26.9": - version "7.26.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.9.tgz#08b43dec79ee8e682c2ac631c010bdcac54a21ce" - integrity sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw== - dependencies: - "@babel/helper-string-parser" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - "@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.15.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" @@ -436,10 +428,10 @@ dependencies: "@types/mongodb" "^3.5.34" -"@hawk.so/types@^0.1.28": - version "0.1.28" - resolved "https://registry.yarnpkg.com/@hawk.so/types/-/types-0.1.28.tgz#a479f411a4ae1855a6661084fa4396c7f323b170" - integrity sha512-W8xNlbkQuffwhVn/ja5Bo4EglN0waSM0Rx3R+jGmcrbYi1a4g6kGPQFYkMSd0WadikOH1nd9NrfmyJB9cVOBWA== +"@hawk.so/types@^0.1.29": + version "0.1.29" + resolved "https://registry.yarnpkg.com/@hawk.so/types/-/types-0.1.29.tgz#95b32d2a9ea7771ecceede50e419741f2fc0746a" + integrity sha512-skPS8ypvlR0hAMDxxJ6Yx96EhssLuOSrNm6lZS08FZESA/crldxK4D7OHV/EPxJccmEJLegXq3PEk4zJfC76YA== dependencies: "@types/mongodb" "^3.5.34"