Skip to content

Commit 6fbf221

Browse files
committed
chore: upgrade Node.js version to 24.12.0 and update CI workflows to use .nvmrc; reintroduce @hawk.so/types in package.json
1 parent 57feedf commit 6fbf221

10 files changed

Lines changed: 50 additions & 37 deletions

File tree

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ jobs:
88
CI_JOB_NUMBER: 1
99
steps:
1010
- uses: actions/checkout@v1
11-
- name: Use Node.js 24.x
11+
- name: Use Node.js from .nvmrc
1212
uses: actions/setup-node@v1
1313
with:
14-
node-version: 24.x
14+
node-version-file: '.nvmrc'
1515
- run: yarn install
1616
- run: yarn lint-test
1717

@@ -21,9 +21,9 @@ jobs:
2121
CI_JOB_NUMBER: 2
2222
steps:
2323
- uses: actions/checkout@v1
24-
- name: Use Node.js 24.x
24+
- name: Use Node.js from .nvmrc
2525
uses: actions/setup-node@v1
2626
with:
27-
node-version: 24.x
27+
node-version-file: '.nvmrc'
2828
- run: yarn install
2929
- run: yarn build

.github/workflows/npm-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@v2
1313
- uses: actions/setup-node@v1
1414
with:
15-
node-version: 24.x
15+
node-version-file: '.nvmrc'
1616
registry-url: https://registry.npmjs.org/
1717
- run: yarn
1818
- run: yarn lint-test

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v20.18.0
1+
24.12.0

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"url": "git+https://github.com/codex-team/hawk.javascript.git"
1919
},
2020
"devDependencies": {
21-
"@hawk.so/types": "0.5.2",
2221
"@size-limit/preset-small-lib": "^11.1.6",
2322
"eslint": "^7.24.0",
2423
"eslint-config-codex": "^1.6.1",

packages/javascript/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"error-stack-parser": "^2.1.4"
4040
},
4141
"devDependencies": {
42+
"@hawk.so/types": "0.5.2",
4243
"vue": "^2",
4344
"vite-plugin-dts": "^4.2.4"
4445
}

packages/javascript/src/addons/breadcrumbs.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import type { Breadcrumb, BreadcrumbLevel, BreadcrumbType, Json, JsonNode } from '@hawk.so/types';
55
import Sanitizer from '../modules/sanitizer';
66
import { buildElementSelector } from '../utils/selector';
7+
import log from '../utils/log';
78

89
/**
910
* Default maximum number of breadcrumbs to store
@@ -194,7 +195,7 @@ export class BreadcrumbManager {
194195
*/
195196
public init(options: BreadcrumbsOptions = {}): void {
196197
if (this.isInitialized) {
197-
console.warn('[BreadcrumbManager] init has already been called; breadcrumb configuration is global and subsequent init options are ignored.');
198+
log('[BreadcrumbManager] init has already been called; breadcrumb configuration is global and subsequent init options are ignored.', 'warn');
198199

199200
return;
200201
}
@@ -231,7 +232,8 @@ export class BreadcrumbManager {
231232
* Add a breadcrumb to the buffer
232233
*
233234
* @param breadcrumb - The breadcrumb data to add
234-
* @param hint - Optional hint object with original event data
235+
* @param hint - Optional hint object with original event data (Event, Response, XMLHttpRequest, etc.)
236+
* Used by beforeBreadcrumb callback to access original event context
235237
*/
236238
public addBreadcrumb(breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint): void {
237239
/**
@@ -353,20 +355,13 @@ export class BreadcrumbManager {
353355
}
354356

355357
/**
356-
* Sanitize and trim breadcrumb data object
358+
* Sanitize breadcrumb data object
359+
* Sanitizer already trims strings, so no additional trimming needed
357360
*
358361
* @param data - The data object to sanitize
359362
*/
360363
private sanitizeData(data: Record<string, unknown>): Record<string, JsonNode> {
361-
const sanitized = Sanitizer.sanitize(data) as Record<string, unknown>;
362-
363-
for (const key in sanitized) {
364-
if (typeof sanitized[key] === 'string') {
365-
sanitized[key] = this.trimString(sanitized[key] as string, this.options.maxValueLength);
366-
}
367-
}
368-
369-
return sanitized as Record<string, JsonNode>;
364+
return Sanitizer.sanitize(data) as Record<string, JsonNode>;
370365
}
371366

372367
/**
@@ -441,7 +436,7 @@ export class BreadcrumbManager {
441436
manager.addBreadcrumb({
442437
type: 'request',
443438
category: 'fetch',
444-
message: `${method} ${url} failed`,
439+
message: `[FAIL] ${method} ${url}`,
445440
level: 'error',
446441
data: {
447442
url,

packages/javascript/src/catcher.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Socket from './modules/socket';
22
import Sanitizer from './modules/sanitizer';
33
import log from './utils/log';
44
import StackParser from './modules/stackParser';
5-
import type { CatcherMessage, HawkInitialSettings } from './types';
5+
import type { CatcherMessage, HawkInitialSettings, BreadcrumbsAPI } from './types';
66
import { VueIntegration } from './integrations/vue';
77
import { id } from './utils/id';
88
import type {
@@ -18,18 +18,9 @@ import { EventRejectedError } from './errors';
1818
import type { HawkJavaScriptEvent } from './types';
1919
import { isErrorProcessed, markErrorAsProcessed } from './utils/event';
2020
import { ConsoleCatcher } from './addons/consoleCatcher';
21-
import { BreadcrumbManager, type BreadcrumbHint, type BreadcrumbInput } from './addons/breadcrumbs';
21+
import { BreadcrumbManager } from './addons/breadcrumbs';
2222
import { validateUser, validateContext } from './utils/validation';
2323

24-
/**
25-
* Breadcrumbs API interface
26-
*/
27-
interface BreadcrumbsAPI {
28-
add: (breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint) => void;
29-
get: () => Breadcrumb[];
30-
clear: () => void;
31-
}
32-
3324
/**
3425
* Allow to use global VERSION, that will be overwritten by Webpack
3526
*/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { Breadcrumb } from '@hawk.so/types';
2+
import type { BreadcrumbInput, BreadcrumbHint } from '../addons/breadcrumbs';
3+
4+
/**
5+
* Breadcrumbs API interface
6+
*/
7+
export interface BreadcrumbsAPI {
8+
add: (breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint) => void;
9+
get: () => Breadcrumb[];
10+
clear: () => void;
11+
}

packages/javascript/src/types/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { CatcherMessage } from './catcher-message';
22
import type { HawkInitialSettings } from './hawk-initial-settings';
33
import type { HawkJavaScriptEvent } from './event';
44
import type { VueIntegrationData, NuxtIntegrationData, NuxtIntegrationAddons, JavaScriptCatcherIntegrations } from './integrations';
5+
import type { BreadcrumbsAPI } from './breadcrumbs-api';
56

67
export type {
78
CatcherMessage,
@@ -10,5 +11,6 @@ export type {
1011
VueIntegrationData,
1112
NuxtIntegrationData,
1213
NuxtIntegrationAddons,
13-
JavaScriptCatcherIntegrations
14+
JavaScriptCatcherIntegrations,
15+
BreadcrumbsAPI
1416
};

packages/javascript/src/utils/selector.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
/**
22
* Build a simple CSS selector from an HTML element
3+
* If element has no id or class, recursively builds selector from parent
34
*
45
* @param element - HTML element to build selector from
5-
* @returns CSS selector string (e.g., "div#myId.class1.class2")
6+
* @param maxDepth - Maximum recursion depth (default: 3)
7+
* @returns CSS selector string (e.g., "div#myId.class1.class2" or ".some-parent button")
68
*/
7-
export function buildElementSelector(element: HTMLElement): string {
9+
export function buildElementSelector(element: HTMLElement, maxDepth: number = 3): string {
810
let selector = element.tagName.toLowerCase();
911

1012
if (element.id) {
1113
selector += `#${element.id}`;
12-
} else if (element.className && typeof element.className === 'string') {
13-
selector += `.${element.className.split(' ').filter(Boolean)
14-
.join('.')}`;
14+
return selector;
15+
}
16+
17+
if (element.className) {
18+
selector += `.${element.className.split(' ').filter(Boolean).join('.')}`;
19+
return selector;
20+
}
21+
22+
/**
23+
* If element has no id or class, try to build selector from parent
24+
*/
25+
if (maxDepth > 0 && element.parentElement) {
26+
const parentSelector = buildElementSelector(element.parentElement as HTMLElement, maxDepth - 1);
27+
28+
return `${parentSelector} ${selector}`;
1529
}
1630

1731
return selector;

0 commit comments

Comments
 (0)