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"