Skip to content

Commit 5505090

Browse files
committed
fix: lint
1 parent c1a81f2 commit 5505090

6 files changed

Lines changed: 47 additions & 158 deletions

File tree

packages/javascript/src/addons/consoleCatcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export class ConsoleCatcher {
150150
* This ensures DevTools will navigate to the user's code, not the interceptor's code.
151151
*
152152
* @param errorStack - Full stack trace string from Error.stack
153-
* @returns Object with userStack (full stack from user code) and fileLine (first frame for DevTools link)
153+
* @returns {object} Object with userStack (full stack from user code) and fileLine (first frame for DevTools link)
154154
*/
155155
private extractUserStack(errorStack: string | undefined): {
156156
userStack: string;
@@ -250,7 +250,7 @@ export class ConsoleCatcher {
250250
* 4. Store it in the buffer
251251
* 5. Forward the call to the native console (so output still appears in DevTools)
252252
*
253-
* @param {...any} args
253+
* @param args - console method arguments
254254
*/
255255
window.console[method] = (...args: unknown[]): void => {
256256
// Capture full stack trace and extract user code stack

packages/javascript/src/catcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {
1010
EventContext,
1111
JavaScriptAddons,
1212
VueIntegrationAddons,
13-
Json, EncodedIntegrationToken, DecodedIntegrationToken,
13+
Json, EncodedIntegrationToken, DecodedIntegrationToken
1414
} from '@hawk.so/types';
1515
import type { JavaScriptCatcherIntegrations } from './types/integrations';
1616
import { EventRejectedError } from './errors';

packages/javascript/src/utils/selector.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
*
55
* @param element - HTML element to build selector from
66
* @param maxDepth - Maximum recursion depth (default: 3)
7-
* @returns CSS selector string (e.g., "div#myId.class1.class2" or ".some-parent button")
7+
* @returns {string} CSS selector string (e.g., "div#myId.class1.class2" or ".some-parent button")
88
*/
99
export function buildElementSelector(element: HTMLElement, maxDepth: number = 3): string {
1010
let selector = element.tagName.toLowerCase();
1111

1212
if (element.id) {
1313
selector += `#${element.id}`;
14+
1415
return selector;
1516
}
1617

@@ -23,7 +24,9 @@ export function buildElementSelector(element: HTMLElement, maxDepth: number = 3)
2324
const classNameStr = String(element.className);
2425

2526
if (classNameStr) {
26-
selector += `.${classNameStr.split(' ').filter(Boolean).join('.')}`;
27+
selector += `.${classNameStr.split(' ').filter(Boolean)
28+
.join('.')}`;
29+
2730
return selector;
2831
}
2932
}

packages/javascript/src/utils/validation.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Sanitizer from '../modules/sanitizer';
55
/**
66
* Validates user data - basic security checks
77
*
8-
* @param user
8+
* @param user - user data to validate
99
*/
1010
export function validateUser(user: AffectedUser): boolean {
1111
if (!user || !Sanitizer.isObject(user)) {
@@ -27,7 +27,7 @@ export function validateUser(user: AffectedUser): boolean {
2727
/**
2828
* Validates context data - basic security checks
2929
*
30-
* @param context
30+
* @param context - context data to validate
3131
*/
3232
export function validateContext(context: EventContext | undefined): boolean {
3333
if (context && !Sanitizer.isObject(context)) {
@@ -41,6 +41,7 @@ export function validateContext(context: EventContext | undefined): boolean {
4141

4242
/**
4343
* Checks if value is a plain object (not array, Date, etc.)
44+
*
4445
* @param value - value to check
4546
*/
4647
function isPlainObject(value: unknown): value is Record<string, unknown> {
@@ -51,6 +52,7 @@ function isPlainObject(value: unknown): value is Record<string, unknown> {
5152
* Runtime check for required EventData fields.
5253
* Per @hawk.so/types EventData, `title` is the only non-optional field.
5354
* Additionally validates `backtrace` shape if present (must be an array).
55+
*
5456
* @param payload - value to validate
5557
*/
5658
export function isValidEventPayload(payload: unknown): payload is EventData<JavaScriptAddons> {
@@ -72,6 +74,7 @@ export function isValidEventPayload(payload: unknown): payload is EventData<Java
7274
/**
7375
* Runtime check that value is a valid Breadcrumb-like object.
7476
* Must be a plain object with a numeric timestamp.
77+
*
7578
* @param breadcrumb - value to validate
7679
*/
7780
export function isValidBreadcrumb(breadcrumb: unknown): breadcrumb is Breadcrumb {

packages/javascript/tests/before-send.test.ts

Lines changed: 14 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,11 @@ function getSentPayload(): HawkJavaScriptEvent | null {
3737
/**
3838
* Single Catcher instance. beforeSend routes by event.title:
3939
*
40-
* "pass-through" → return event as-is
41-
* "modify" → mutate context, return event
42-
* "drop" → return false
43-
* "void" → no return (undefined)
44-
* "null" → return null
45-
* "invalid" → return true
46-
* "empty-obj" → return {}
47-
* "optional" → delete release, return event
40+
* "modify" → mutate context, return event
41+
* "drop" → return false
42+
* "invalid" → return undefined (no return)
43+
* "optional"→ delete release, return event
44+
* default → return event as-is
4845
*/
4946
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5047
const hawk = new Catcher({
@@ -60,17 +57,8 @@ const hawk = new Catcher({
6057

6158
return event;
6259

63-
case 'void':
64-
return;
65-
66-
case 'null':
67-
return null as any;
68-
6960
case 'invalid':
70-
return true as any;
71-
72-
case 'empty-obj':
73-
return {} as any;
61+
return;
7462

7563
case 'optional':
7664
delete event.release;
@@ -95,98 +83,47 @@ describe('beforeSend', () => {
9583
warnSpy.mockRestore();
9684
});
9785

98-
it('return event → event sent', async () => {
86+
it('should send event as-is when returned unchanged', async () => {
9987
hawk.send(new Error('pass-through'));
10088
await flush();
10189

10290
expect(socketSendSpy).toHaveBeenCalledOnce();
103-
104-
const payload = getSentPayload()!;
105-
106-
expect(payload.title).toBe('pass-through');
107-
expect(payload.backtrace).toBeInstanceOf(Array);
91+
expect(getSentPayload()!.title).toBe('pass-through');
10892
});
10993

110-
it('return modified event → sent event with changes', async () => {
94+
it('should send modified event when hook mutates and returns it', async () => {
11195
hawk.send(new Error('modify'));
11296
await flush();
11397

11498
expect(socketSendSpy).toHaveBeenCalledOnce();
115-
116-
const payload = getSentPayload()!;
117-
118-
expect(payload.title).toBe('modify');
119-
expect(payload.context).toEqual({ sanitized: true });
99+
expect(getSentPayload()!.context).toEqual({ sanitized: true });
120100
});
121101

122-
it('return false → event not sent', async () => {
102+
it('should drop event when hook returns false', async () => {
123103
hawk.send(new Error('drop'));
124104
await flush();
125105

126106
expect(socketSendSpy).not.toHaveBeenCalled();
127107
});
128108

129-
it('return undefined → sent original event + warn', async () => {
130-
hawk.send(new Error('void'));
131-
await flush();
132-
133-
expect(socketSendSpy).toHaveBeenCalledOnce();
134-
expect(warnSpy).toHaveBeenCalledWith(
135-
expect.stringContaining('Invalid beforeSend value: (undefined)'),
136-
expect.anything(),
137-
expect.anything()
138-
);
139-
expect(getSentPayload()!.title).toBe('void');
140-
});
141-
142-
it('return null → sent original event + warn', async () => {
143-
hawk.send(new Error('null'));
144-
await flush();
145-
146-
expect(socketSendSpy).toHaveBeenCalledOnce();
147-
expect(warnSpy).toHaveBeenCalledWith(
148-
expect.stringContaining('Invalid beforeSend value: (null)'),
149-
expect.anything(),
150-
expect.anything()
151-
);
152-
expect(getSentPayload()!.title).toBe('null');
153-
});
154-
155-
it('return true → sent original event + warn', async () => {
109+
it('should send original event and warn when hook returns invalid value', async () => {
156110
hawk.send(new Error('invalid'));
157111
await flush();
158112

159113
expect(socketSendSpy).toHaveBeenCalledOnce();
160-
expect(warnSpy).toHaveBeenCalledWith(
161-
expect.stringContaining('Invalid beforeSend value:'),
162-
expect.anything(),
163-
expect.anything()
164-
);
165114
expect(getSentPayload()!.title).toBe('invalid');
166-
});
167-
168-
it('return {} → sent original event + warn', async () => {
169-
hawk.send(new Error('empty-obj'));
170-
await flush();
171-
172-
expect(socketSendSpy).toHaveBeenCalledOnce();
173115
expect(warnSpy).toHaveBeenCalledWith(
174116
expect.stringContaining('Invalid beforeSend value:'),
175117
expect.anything(),
176118
expect.anything()
177119
);
178-
expect(getSentPayload()!.title).toBe('empty-obj');
179120
});
180121

181-
it('delete optional fields → sent event without them', async () => {
122+
it('should send event without deleted optional fields', async () => {
182123
hawk.send(new Error('optional'));
183124
await flush();
184125

185126
expect(socketSendSpy).toHaveBeenCalledOnce();
186-
187-
const payload = getSentPayload()!;
188-
189-
expect(payload.title).toBe('optional');
190-
expect(payload.release).toBeUndefined();
127+
expect(getSentPayload()!.release).toBeUndefined();
191128
});
192129
});

0 commit comments

Comments
 (0)