Skip to content

Commit d18c7ec

Browse files
github-actions[bot]talygurynCopilotneSpecce11sy
authored
Update prod (#493)
* Fix: Improve quota notification and blocking logic (#489) * Improve quota notification and blocking logic Refactored the quota check to ensure workspaces are blocked and notified only when appropriate. Added logging for both blocking and approaching quota limits, and clarified notification task handling. * Suppress magic number lint warning in logger Added an ESLint directive to ignore the magic number warning for the percentage calculation in the workspace events limit log message. * Fix: save workspace blocked date (#491) * pull new hawk types * Track blocked date for workspaces in LimiterWorker Adds a 'blockedDate' property to workspaces when blocking and unblocking them. This allows tracking when a workspace was blocked or cleared, improving auditability and state management. * Add and populate blockedDate for blocked workspaces Introduces the blockedDate field to workspace updates in dbHelper and ensures it is set for all blocked workspaces, including a temporary fix for existing records missing this field. This change supports better tracking of when a workspace was blocked and prepares for future removal of the migration code. * Add tests for blockedDate handling in workspaces Extended tests to cover setting and clearing the blockedDate field when blocking and unblocking workspaces. Added scenarios for updating blockedDate when missing and verifying correct behavior during workspace state transitions. * Update index.ts * Refactor blocked workspace reminder to use days after block Renamed variables and template placeholders from 'daysAfterPayday' to 'daysAfterBlock' to more accurately reflect the time since a workspace was blocked. Updated related logic, types, and templates to use the new naming and calculation. Added a utility function to compute days after block in payday.ts. * Update yarn.lock to deduplicate and reorder entries This commit cleans up the yarn.lock file by removing duplicate entries, consolidating package references, and reordering dependencies for consistency. No package versions were changed; this improves maintainability and reduces lockfile bloat. * Rename daysAfterPayday to daysAfterBlock in payload Updated variable and property names from daysAfterPayday to daysAfterBlock in SenderWorker to reflect the correct payload structure and improve clarity. * Handle undefined daysAfterBlock in reminders logic Updated countDaysAfterBlock to return undefined instead of null when blockedDate is missing. Adjusted paymaster worker logic to check for undefined, ensuring reminders are sent only when daysAfterBlock is valid. * Adjust blockedDate calculation in PaymasterWorker test Updates the blockedDate assignment to subtract days based on expectedDaysAfterBlock in the PaymasterWorker test, improving test accuracy for blocked subscriptions. * Update workers/paymaster/tests/index.test.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update workers/paymaster/src/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update lib/utils/payday.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dbHelper.test.ts * Remove obsolete test and update blocked workspace logic Deleted a test for setting blockedDate on already blocked workspaces in limiter tests, as the scenario is no longer relevant. Updated workspace mock to include blockedDate as undefined. Simplified reminder logic in PaymasterWorker by removing unnecessary undefined check for daysAfterBlock. * Refactor blockedDate handling in workspace mocks Removed redundant logic for setting blockedDate when workspace is already blocked in LimiterWorker. Standardized blockedDate type to Date (not Date | null/undefined) in test mocks and updated test cases to use null instead of undefined where appropriate. * Update index.test.ts * Update dbHelper.test.ts * Update index.test.ts * Update index.test.ts * Update workers/paymaster/tests/index.test.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update index.test.ts * Update workers/paymaster/src/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update lib/utils/payday.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update workers/paymaster/src/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update emailOverview.ts * Update workers/limiter/src/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update lib/utils/payday.ts Co-authored-by: Peter <specc.dev@gmail.com> * Update index.test.ts * Update index.test.ts * Update index.ts --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Peter <specc.dev@gmail.com> * feat(js): arrange babel plugins respectfully to vue and svetle frameworks (#492) * feat(): arrange babel plugins respectfully to vue and svetle frameworks * chore(): add context to hawk errors and cover utils with tests * chore(): clean up * Update workers/javascript/src/utils.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore(): fix tests description * imp(): move getFunctionContext to utils * chore(): lint fix * chore(): improve jsdoc --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Taly <vitalik7tv@yandex.ru> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Peter <specc.dev@gmail.com> Co-authored-by: e11sy <130844513+e11sy@users.noreply.github.com>
1 parent 7f8782b commit d18c7ec

File tree

4 files changed

+619
-267
lines changed

4 files changed

+619
-267
lines changed

workers/javascript/src/index.ts

Lines changed: 6 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@ import { JavaScriptEventWorkerTask } from '../types/javascript-event-worker-task
1010
import { BeautifyBacktracePayload } from '../types/beautify-backtrace-payload';
1111
import HawkCatcher from '@hawk.so/nodejs';
1212
import { BacktraceFrame, CatcherMessagePayload, CatcherMessageType, ErrorsCatcherType, SourceCodeLine, SourceMapDataExtended } from '@hawk.so/types';
13-
import { beautifyUserAgent } from './utils';
13+
import { beautifyUserAgent, getFunctionContext } from './utils';
1414
import { Collection } from 'mongodb';
15-
import { parse } from '@babel/parser';
16-
import traverse from '@babel/traverse';
17-
import { extname } from 'path';
1815
/* eslint-disable-next-line no-unused-vars */
1916
import { memoize } from '../../../lib/memoize';
2017

@@ -135,6 +132,9 @@ export default class JavascriptEventWorker extends EventWorker {
135132
*/
136133
HawkCatcher.send(error, {
137134
payload: backtrace as unknown as Record<string, never>,
135+
releaseRecord: JSON.stringify(releaseRecord),
136+
backtrace: JSON.stringify(backtrace),
137+
projectId,
138138
});
139139

140140
return backtrace[index];
@@ -232,13 +232,13 @@ export default class JavascriptEventWorker extends EventWorker {
232232

233233
const originalContent = consumer.sourceContentFor(originalLocation.source);
234234

235-
functionContext = await this.getFunctionContext(
235+
functionContext = await getFunctionContext(
236236
originalContent,
237237
originalLocation.line,
238238
originalLocation.source
239239
) ?? originalLocation.name;
240240
} catch (e) {
241-
HawkCatcher.send(e);
241+
HawkCatcher.send(e, { stackFrame: JSON.stringify(stackFrame) });
242242
this.logger.error('Can\'t get function context');
243243
this.logger.error(e);
244244
}
@@ -253,103 +253,6 @@ export default class JavascriptEventWorker extends EventWorker {
253253
}) as BacktraceFrame;
254254
}
255255

256-
/**
257-
* Method that is used to parse full function context of the code position
258-
*
259-
* @param sourceCode - content of the source file
260-
* @param line - number of the line from the stack trace
261-
* @param sourcePath - original source path from the source map (used to pick parser plugins)
262-
* @returns {string | null} - string of the function context or null if it could not be parsed
263-
*/
264-
private getFunctionContext(sourceCode: string, line: number, sourcePath?: string): string | null {
265-
let functionName: string | null = null;
266-
let className: string | null = null;
267-
let isAsync = false;
268-
269-
try {
270-
const parserPlugins = this.getBabelParserPluginsForFile(sourcePath);
271-
272-
const ast = parse(sourceCode, {
273-
sourceType: 'module',
274-
plugins: parserPlugins,
275-
});
276-
277-
traverse(ast as any, {
278-
/**
279-
* It is used to get class decorator of the position, it will save class that is related to original position
280-
*
281-
* @param path
282-
*/
283-
ClassDeclaration(path) {
284-
if (path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line) {
285-
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}`);
286-
287-
className = path.node.id.name || null;
288-
}
289-
},
290-
/**
291-
* It is used to get class and its method decorator of the position
292-
* It will save class and method, that are related to original position
293-
*
294-
* @param path
295-
*/
296-
ClassMethod(path) {
297-
if (path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line) {
298-
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}`);
299-
300-
// Handle different key types
301-
if (path.node.key.type === 'Identifier') {
302-
functionName = path.node.key.name;
303-
}
304-
isAsync = path.node.async;
305-
}
306-
},
307-
/**
308-
* It is used to get function name that is declared out of class
309-
*
310-
* @param path
311-
*/
312-
FunctionDeclaration(path) {
313-
if (path.node.loc && path.node.loc.start.line <= line && path.node.loc.end.line >= line) {
314-
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}`);
315-
316-
functionName = path.node.id.name || null;
317-
isAsync = path.node.async;
318-
}
319-
},
320-
/**
321-
* It is used to get anonimous function names in function expressions or arrow function expressions
322-
*
323-
* @param path
324-
*/
325-
VariableDeclarator(path) {
326-
if (
327-
path.node.init &&
328-
(path.node.init.type === 'FunctionExpression' || path.node.init.type === 'ArrowFunctionExpression') &&
329-
path.node.loc &&
330-
path.node.loc.start.line <= line &&
331-
path.node.loc.end.line >= line
332-
) {
333-
console.log(`variable declaration: node.type: ${path.node.init.type}, line: ${line}, `);
334-
335-
// Handle different id types
336-
if (path.node.id.type === 'Identifier') {
337-
functionName = path.node.id.name;
338-
}
339-
isAsync = (path.node.init as any).async;
340-
}
341-
},
342-
});
343-
} catch (traverseError) {
344-
console.error(`Failed to parse source code:`);
345-
console.error(traverseError);
346-
347-
HawkCatcher.send(traverseError);
348-
}
349-
350-
return functionName ? `${isAsync ? 'async ' : ''}${className ? `${className}.` : ''}${functionName}` : null;
351-
}
352-
353256
/**
354257
* Downloads source map file from Grid FS
355258
*
@@ -451,55 +354,4 @@ export default class JavascriptEventWorker extends EventWorker {
451354
this.logger.error(`Error on source-map consumer initialization: ${e}`);
452355
}
453356
}
454-
455-
/**
456-
* Choose babel parser plugins based on source file extension
457-
*
458-
* @param sourcePath - original file path from source map (e.g. "src/App.tsx")
459-
*/
460-
private getBabelParserPluginsForFile(sourcePath?: string): any[] {
461-
const basePlugins: string[] = [
462-
'classProperties',
463-
'decorators',
464-
'optionalChaining',
465-
'nullishCoalescingOperator',
466-
'dynamicImport',
467-
'bigInt',
468-
'topLevelAwait',
469-
];
470-
471-
/**
472-
* Default - use only typescript plugin because it's more stable and less likely will produce errors
473-
*/
474-
let enableTypeScript = true;
475-
let enableJSX = false;
476-
477-
if (sourcePath) {
478-
// remove query/hash if there is any
479-
const cleanPath = sourcePath.split('?')[0].split('#')[0];
480-
const ext = extname(cleanPath).toLowerCase();
481-
482-
const isTs = ext === '.ts' || ext === '.d.ts';
483-
const isTsx = ext === '.tsx';
484-
const isJs = ext === '.js' || ext === '.mjs' || ext === '.cjs';
485-
const isJsx = ext === '.jsx';
486-
487-
enableTypeScript = isTs || isTsx;
488-
// JSX:
489-
// - for .ts/.d.ts — DISABLE
490-
// - for .tsx/.jsx — ENABLE
491-
// - for .js — keep enabled, to not break App.js with JSX
492-
enableJSX = isTsx || isJsx || isJs;
493-
}
494-
495-
if (enableTypeScript) {
496-
basePlugins.push('typescript');
497-
}
498-
499-
if (enableJSX) {
500-
basePlugins.push('jsx');
501-
}
502-
503-
return basePlugins;
504-
}
505357
}

0 commit comments

Comments
 (0)