feat(core): add honeybadger support (#21574)
* feat(core): add honeybadger support * feat(honeybadger): configure Honeybadger to disable uncaught error tracking * feat(tests): add info logger mock to app-bootstrap tests * test: fix mock value * test: mock honeybadger as well
This commit is contained in:
parent
222322befc
commit
1fe4e8a4ae
|
|
@ -8,6 +8,14 @@ vi.mock('@/utils/logger', () => ({
|
|||
},
|
||||
}));
|
||||
|
||||
vi.mock('@honeybadger-io/js', () => ({
|
||||
default: {
|
||||
configure: vi.fn(),
|
||||
notify: vi.fn(),
|
||||
setContext: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('app-bootstrap', () => {
|
||||
it('logs uncaught exceptions', async () => {
|
||||
const before = new Set(process.listeners('uncaughtException'));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import antiHotlink from '@/middleware/anti-hotlink';
|
|||
import cache from '@/middleware/cache';
|
||||
import debug from '@/middleware/debug';
|
||||
import header from '@/middleware/header';
|
||||
import honeybadger from '@/middleware/honeybadger';
|
||||
import mLogger from '@/middleware/logger';
|
||||
import parameter from '@/middleware/parameter';
|
||||
import sentry from '@/middleware/sentry';
|
||||
|
|
@ -35,6 +36,7 @@ app.use(
|
|||
);
|
||||
app.use(mLogger);
|
||||
app.use(trace);
|
||||
app.use(honeybadger);
|
||||
app.use(sentry);
|
||||
app.use(accessControl);
|
||||
app.use(debug);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ app.use(mLogger);
|
|||
app.use(trace);
|
||||
|
||||
// Heavy middleware excluded in Worker build:
|
||||
// - honeybadger: @honeybadger-io/js
|
||||
// - sentry: @sentry/node
|
||||
// - antiHotlink: cheerio
|
||||
// - parameter: cheerio, sanitize-html, @jocmp/mercury-parser
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ type ConfigEnvKeys =
|
|||
| 'OTEL_SECONDS_BUCKET'
|
||||
| 'OTEL_MILLISECONDS_BUCKET'
|
||||
| 'SHOW_LOGGER_TIMESTAMP'
|
||||
| 'HONEYBADGER_API_KEY'
|
||||
| 'ERROR_TRACKING_ROUTE_TIMEOUT'
|
||||
| 'SENTRY'
|
||||
| 'SENTRY_ROUTE_TIMEOUT'
|
||||
| 'ENABLE_REMOTE_DEBUGGING'
|
||||
|
|
@ -306,10 +308,13 @@ export type Config = {
|
|||
milliseconds_bucket?: string;
|
||||
};
|
||||
showLoggerTimestamp?: boolean;
|
||||
honeybadger: {
|
||||
apiKey?: string;
|
||||
};
|
||||
sentry: {
|
||||
dsn?: string;
|
||||
routeTimeout: number;
|
||||
};
|
||||
errorTrackingRouteTimeout: number;
|
||||
enableRemoteDebugging?: boolean;
|
||||
// feed config
|
||||
hotlink: {
|
||||
|
|
@ -798,10 +803,13 @@ const calculateValue = () => {
|
|||
milliseconds_bucket: envs.OTEL_MILLISECONDS_BUCKET || '10,20,50,100,250,500,1000,5000,15000',
|
||||
},
|
||||
showLoggerTimestamp: toBoolean(envs.SHOW_LOGGER_TIMESTAMP, false),
|
||||
honeybadger: {
|
||||
apiKey: envs.HONEYBADGER_API_KEY,
|
||||
},
|
||||
sentry: {
|
||||
dsn: envs.SENTRY,
|
||||
routeTimeout: toInt(envs.SENTRY_ROUTE_TIMEOUT, 30000),
|
||||
},
|
||||
errorTrackingRouteTimeout: toInt(envs.ERROR_TRACKING_ROUTE_TIMEOUT || envs.SENTRY_ROUTE_TIMEOUT, 30000),
|
||||
enableRemoteDebugging: toBoolean(envs.ENABLE_REMOTE_DEBUGGING, false),
|
||||
// feed config
|
||||
hotlink: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const notify = vi.fn();
|
||||
|
||||
vi.mock('@honeybadger-io/js', () => ({
|
||||
default: { notify },
|
||||
}));
|
||||
|
||||
vi.mock('@sentry/node', () => ({
|
||||
withScope: vi.fn(),
|
||||
captureException: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('hono/route', () => ({
|
||||
routePath: () => '/test/path',
|
||||
}));
|
||||
|
||||
vi.mock('@/utils/logger', () => ({
|
||||
default: {
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/utils/otel', () => ({
|
||||
requestMetric: {
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('error handler honeybadger', () => {
|
||||
it('sends errors to honeybadger when enabled', async () => {
|
||||
process.env.HONEYBADGER_API_KEY = 'hbp_test_key';
|
||||
vi.resetModules();
|
||||
|
||||
// Re-mock after resetModules
|
||||
vi.doMock('@honeybadger-io/js', () => ({
|
||||
default: { notify },
|
||||
}));
|
||||
vi.doMock('@sentry/node', () => ({
|
||||
withScope: vi.fn(),
|
||||
captureException: vi.fn(),
|
||||
}));
|
||||
vi.doMock('hono/route', () => ({
|
||||
routePath: () => '/test/path',
|
||||
}));
|
||||
vi.doMock('@/utils/logger', () => ({
|
||||
default: { error: vi.fn() },
|
||||
}));
|
||||
vi.doMock('@/utils/otel', () => ({
|
||||
requestMetric: { error: vi.fn() },
|
||||
}));
|
||||
|
||||
const { errorHandler } = await import('@/errors');
|
||||
|
||||
const ctx = {
|
||||
req: {
|
||||
path: '/test/path',
|
||||
method: 'GET',
|
||||
query: () => 'json',
|
||||
},
|
||||
res: {
|
||||
status: 500,
|
||||
headers: new Headers(),
|
||||
},
|
||||
status: vi.fn(),
|
||||
header: vi.fn(),
|
||||
json: (payload: unknown) => payload,
|
||||
html: (payload: unknown) => payload,
|
||||
};
|
||||
|
||||
errorHandler(new Error('boom'), ctx as any);
|
||||
|
||||
expect(notify).toHaveBeenCalledWith(expect.any(Error), {
|
||||
context: { name: 'test' },
|
||||
});
|
||||
|
||||
delete process.env.HONEYBADGER_API_KEY;
|
||||
});
|
||||
});
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import Honeybadger from '@honeybadger-io/js';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import type { ErrorHandler, NotFoundHandler } from 'hono';
|
||||
import { routePath } from 'hono/route';
|
||||
|
|
@ -36,6 +37,12 @@ export const errorHandler: ErrorHandler = (error, ctx) => {
|
|||
hasMatchedRoute && debug.errorRoutes[matchedRoute]++;
|
||||
setDebugInfo(debug);
|
||||
|
||||
if (config.honeybadger.apiKey) {
|
||||
Honeybadger.notify(error, {
|
||||
context: { name: requestPath.split('/')[1] },
|
||||
});
|
||||
}
|
||||
|
||||
if (config.sentry.dsn) {
|
||||
Sentry.withScope((scope) => {
|
||||
scope.setTag('name', requestPath.split('/')[1]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetModules();
|
||||
vi.restoreAllMocks();
|
||||
vi.unmock('@/config');
|
||||
vi.unmock('@/utils/helpers');
|
||||
vi.unmock('@/utils/logger');
|
||||
vi.unmock('@honeybadger-io/js');
|
||||
});
|
||||
|
||||
describe('honeybadger middleware', () => {
|
||||
const loadMiddleware = async () => {
|
||||
const honeybadger = {
|
||||
configure: vi.fn(),
|
||||
setContext: vi.fn(),
|
||||
notify: vi.fn(),
|
||||
};
|
||||
const logger = {
|
||||
info: vi.fn(),
|
||||
};
|
||||
const getRouteNameFromPath = vi.fn((path: string) => `route:${path}`);
|
||||
|
||||
vi.doMock('@honeybadger-io/js', () => ({
|
||||
default: honeybadger,
|
||||
}));
|
||||
vi.doMock('@/utils/logger', () => ({
|
||||
default: logger,
|
||||
}));
|
||||
vi.doMock('@/utils/helpers', () => ({
|
||||
getRouteNameFromPath,
|
||||
}));
|
||||
vi.doMock('@/config', () => ({
|
||||
config: {
|
||||
honeybadger: {
|
||||
apiKey: 'hbp_test_key',
|
||||
},
|
||||
errorTrackingRouteTimeout: 50,
|
||||
nodeName: 'node-a',
|
||||
},
|
||||
}));
|
||||
|
||||
const { default: middleware } = await import('@/middleware/honeybadger');
|
||||
|
||||
return { middleware, honeybadger, logger, getRouteNameFromPath };
|
||||
};
|
||||
|
||||
it('initializes honeybadger and captures slow routes', async () => {
|
||||
const { middleware, honeybadger, logger, getRouteNameFromPath } = await loadMiddleware();
|
||||
|
||||
expect(honeybadger.configure).toHaveBeenCalledWith({
|
||||
apiKey: 'hbp_test_key',
|
||||
enableUncaught: false,
|
||||
});
|
||||
expect(honeybadger.setContext).toHaveBeenCalledWith({ node_name: 'node-a' });
|
||||
expect(logger.info).toHaveBeenCalledWith('Honeybadger inited.');
|
||||
|
||||
const nowSpy = vi.spyOn(Date, 'now');
|
||||
nowSpy.mockReturnValueOnce(0).mockReturnValueOnce(100);
|
||||
|
||||
await middleware({ req: { path: '/test/slow' } } as any, async () => {});
|
||||
|
||||
expect(getRouteNameFromPath).toHaveBeenCalledWith('/test/slow');
|
||||
expect(honeybadger.notify).toHaveBeenCalledTimes(1);
|
||||
expect(honeybadger.notify).toHaveBeenCalledWith(expect.any(Error), {
|
||||
context: { name: 'route:/test/slow' },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import Honeybadger from '@honeybadger-io/js';
|
||||
import type { MiddlewareHandler } from 'hono';
|
||||
|
||||
import { config } from '@/config';
|
||||
import { getRouteNameFromPath } from '@/utils/helpers';
|
||||
import logger from '@/utils/logger';
|
||||
|
||||
if (config.honeybadger.apiKey) {
|
||||
Honeybadger.configure({
|
||||
apiKey: config.honeybadger.apiKey,
|
||||
enableUncaught: false,
|
||||
});
|
||||
Honeybadger.setContext({ node_name: config.nodeName });
|
||||
|
||||
logger.info('Honeybadger inited.');
|
||||
}
|
||||
|
||||
const middleware: MiddlewareHandler = async (ctx, next) => {
|
||||
const time = Date.now();
|
||||
await next();
|
||||
if (config.honeybadger.apiKey && Date.now() - time >= config.errorTrackingRouteTimeout) {
|
||||
Honeybadger.notify(new Error('Route Timeout'), {
|
||||
context: { name: getRouteNameFromPath(ctx.req.path) },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default middleware;
|
||||
|
|
@ -36,8 +36,8 @@ describe('sentry middleware', () => {
|
|||
config: {
|
||||
sentry: {
|
||||
dsn: 'https://sentry.example/123',
|
||||
routeTimeout: 50,
|
||||
},
|
||||
errorTrackingRouteTimeout: 50,
|
||||
nodeName: 'node-a',
|
||||
},
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ if (config.sentry.dsn) {
|
|||
const middleware: MiddlewareHandler = async (ctx, next) => {
|
||||
const time = Date.now();
|
||||
await next();
|
||||
if (config.sentry.dsn && Date.now() - time >= config.sentry.routeTimeout) {
|
||||
if (config.sentry.dsn && Date.now() - time >= config.errorTrackingRouteTimeout) {
|
||||
Sentry.withScope((scope) => {
|
||||
scope.setTag('name', getRouteNameFromPath(ctx.req.path));
|
||||
Sentry.captureException(new Error('Route Timeout'));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
// No-op shim for @honeybadger-io/js in Cloudflare Workers
|
||||
export default {
|
||||
configure: () => {},
|
||||
notify: () => {},
|
||||
setContext: () => {},
|
||||
};
|
||||
|
|
@ -59,6 +59,7 @@
|
|||
"@bbob/html": "4.3.1",
|
||||
"@bbob/plugin-helper": "4.3.1",
|
||||
"@bbob/preset-html5": "4.3.1",
|
||||
"@honeybadger-io/js": "6.12.3",
|
||||
"@hono/node-server": "1.19.12",
|
||||
"@hono/zod-openapi": "1.2.4",
|
||||
"@jocmp/mercury-parser": "3.0.7",
|
||||
|
|
|
|||
104
pnpm-lock.yaml
104
pnpm-lock.yaml
|
|
@ -40,6 +40,9 @@ importers:
|
|||
'@bbob/preset-html5':
|
||||
specifier: 4.3.1
|
||||
version: 4.3.1
|
||||
'@honeybadger-io/js':
|
||||
specifier: 6.12.3
|
||||
version: 6.12.3
|
||||
'@hono/node-server':
|
||||
specifier: 1.19.12
|
||||
version: 1.19.12(hono@4.12.8)
|
||||
|
|
@ -1074,6 +1077,15 @@ packages:
|
|||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.9.0
|
||||
|
||||
'@honeybadger-io/core@6.7.2':
|
||||
resolution: {integrity: sha512-4+hyrFI0S/Eni2cBgO40Lqyft5hyNXjgnuh1EbeH457kty8g4YatJYuHBffmrjwLiZHgFbWXRGv7SlG+NehC5Q==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@honeybadger-io/js@6.12.3':
|
||||
resolution: {integrity: sha512-CL+9A8tGpjawsJEKE74P94hmimHRsq+B90i5N/pXNgnJbgZG40bs9yZpfn2z3w0+3z9wtH12D2RqBjxsGm9DBg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
'@hono/node-server@1.19.12':
|
||||
resolution: {integrity: sha512-txsUW4SQ1iilgE0l9/e9VQWmELXifEFvmdA1j6WFh/aFPj99hIntrSsq/if0UWyGVkmrRPKA1wCeP+UCr1B9Uw==}
|
||||
engines: {node: '>=18.14.1'}
|
||||
|
|
@ -2472,6 +2484,9 @@ packages:
|
|||
'@types/aes-js@3.1.4':
|
||||
resolution: {integrity: sha512-v3D66IptpUqh+pHKVNRxY8yvp2ESSZXe0rTzsGdzUhEwag7ljVfgCllkWv2YgiYXDhWFBrEywll4A5JToyTNFA==}
|
||||
|
||||
'@types/aws-lambda@8.10.161':
|
||||
resolution: {integrity: sha512-rUYdp+MQwSFocxIOcSsYSF3YYYC/uUpMbCY/mbO21vGqfrEYvNSoPyKYDj6RhXXpPfS0KstW9RwG3qXh9sL7FQ==}
|
||||
|
||||
'@types/babel__preset-env@7.10.0':
|
||||
resolution: {integrity: sha512-LS8hRb/8TQir2f8W9/s5enDtrRS2F/6fsdkVw5ePHp6Q8SrSJHOGtWnP93ryaYMmg2du03vOsiGrl5mllz4uDA==}
|
||||
|
||||
|
|
@ -2481,6 +2496,9 @@ packages:
|
|||
'@types/bluebird@3.5.42':
|
||||
resolution: {integrity: sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==}
|
||||
|
||||
'@types/body-parser@1.19.6':
|
||||
resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==}
|
||||
|
||||
'@types/caseless@0.12.5':
|
||||
resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==}
|
||||
|
||||
|
|
@ -2514,6 +2532,12 @@ packages:
|
|||
'@types/etag@1.8.4':
|
||||
resolution: {integrity: sha512-f1z/UMth8gQ6636NBqhFmJ3zES7EuDcUnV6K1gl1osHp+85KPKX+VixYWUpqLkw1fftCagyHJjJOZjZkEi2rHw==}
|
||||
|
||||
'@types/express-serve-static-core@5.1.1':
|
||||
resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==}
|
||||
|
||||
'@types/express@5.0.6':
|
||||
resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==}
|
||||
|
||||
'@types/fs-extra@11.0.4':
|
||||
resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==}
|
||||
|
||||
|
|
@ -2523,6 +2547,9 @@ packages:
|
|||
'@types/http-cache-semantics@4.2.0':
|
||||
resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==}
|
||||
|
||||
'@types/http-errors@2.0.5':
|
||||
resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==}
|
||||
|
||||
'@types/js-beautify@1.14.3':
|
||||
resolution: {integrity: sha512-FMbQHz+qd9DoGvgLHxeqqVPaNRffpIu5ZjozwV8hf9JAGpIOzuAf4wGbRSo8LNITHqGjmmVjaMggTT5P4v4IHg==}
|
||||
|
||||
|
|
@ -2577,6 +2604,12 @@ packages:
|
|||
'@types/pg@8.15.6':
|
||||
resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==}
|
||||
|
||||
'@types/qs@6.15.0':
|
||||
resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==}
|
||||
|
||||
'@types/range-parser@1.2.7':
|
||||
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
|
||||
|
||||
'@types/request-promise@4.1.51':
|
||||
resolution: {integrity: sha512-qVcP9Fuzh9oaAh8oPxiSoWMFGnWKkJDknnij66vi09Yiy62bsSDqtd+fG5kIM9wLLgZsRP3Y6acqj9O/v2ZtRw==}
|
||||
|
||||
|
|
@ -2586,6 +2619,12 @@ packages:
|
|||
'@types/sanitize-html@2.16.1':
|
||||
resolution: {integrity: sha512-n9wjs8bCOTyN/ynwD8s/nTcTreIHB1vf31vhLMGqUPNHaweKC4/fAl4Dj+hUlCTKYgm4P3k83fmiFfzkZ6sgMA==}
|
||||
|
||||
'@types/send@1.2.1':
|
||||
resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==}
|
||||
|
||||
'@types/serve-static@2.2.0':
|
||||
resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==}
|
||||
|
||||
'@types/statuses@2.0.6':
|
||||
resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==}
|
||||
|
||||
|
|
@ -4355,6 +4394,9 @@ packages:
|
|||
json-buffer@3.0.1:
|
||||
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
|
||||
|
||||
json-nd@1.0.0:
|
||||
resolution: {integrity: sha512-8TIp0HZAY0VVrwRQJJPb4+nOTSPoOWZeEKBTLizUfQO4oym5Fc/MKqN8vEbLCxcyxDf2vwNxOQ1q84O49GWPyQ==}
|
||||
|
||||
json-parse-even-better-errors@2.3.1:
|
||||
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
|
||||
|
||||
|
|
@ -5419,6 +5461,10 @@ packages:
|
|||
stackback@0.0.2:
|
||||
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||
|
||||
stacktrace-parser@0.1.11:
|
||||
resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
standard-as-callback@2.1.0:
|
||||
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
|
||||
|
||||
|
|
@ -5732,6 +5778,10 @@ packages:
|
|||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
type-fest@0.7.1:
|
||||
resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
type-fest@3.13.1:
|
||||
resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
|
@ -6664,6 +6714,17 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@honeybadger-io/core@6.7.2':
|
||||
dependencies:
|
||||
json-nd: 1.0.0
|
||||
stacktrace-parser: 0.1.11
|
||||
|
||||
'@honeybadger-io/js@6.12.3':
|
||||
dependencies:
|
||||
'@honeybadger-io/core': 6.7.2
|
||||
'@types/aws-lambda': 8.10.161
|
||||
'@types/express': 5.0.6
|
||||
|
||||
'@hono/node-server@1.19.12(hono@4.12.8)':
|
||||
dependencies:
|
||||
hono: 4.12.8
|
||||
|
|
@ -7895,12 +7956,19 @@ snapshots:
|
|||
|
||||
'@types/aes-js@3.1.4': {}
|
||||
|
||||
'@types/aws-lambda@8.10.161': {}
|
||||
|
||||
'@types/babel__preset-env@7.10.0': {}
|
||||
|
||||
'@types/bezier-js@4.1.3': {}
|
||||
|
||||
'@types/bluebird@3.5.42': {}
|
||||
|
||||
'@types/body-parser@1.19.6':
|
||||
dependencies:
|
||||
'@types/connect': 3.4.38
|
||||
'@types/node': 25.5.0
|
||||
|
||||
'@types/caseless@0.12.5': {}
|
||||
|
||||
'@types/chai@5.2.3':
|
||||
|
|
@ -7935,6 +8003,19 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/node': 25.5.0
|
||||
|
||||
'@types/express-serve-static-core@5.1.1':
|
||||
dependencies:
|
||||
'@types/node': 25.5.0
|
||||
'@types/qs': 6.15.0
|
||||
'@types/range-parser': 1.2.7
|
||||
'@types/send': 1.2.1
|
||||
|
||||
'@types/express@5.0.6':
|
||||
dependencies:
|
||||
'@types/body-parser': 1.19.6
|
||||
'@types/express-serve-static-core': 5.1.1
|
||||
'@types/serve-static': 2.2.0
|
||||
|
||||
'@types/fs-extra@11.0.4':
|
||||
dependencies:
|
||||
'@types/jsonfile': 6.1.4
|
||||
|
|
@ -7944,6 +8025,8 @@ snapshots:
|
|||
|
||||
'@types/http-cache-semantics@4.2.0': {}
|
||||
|
||||
'@types/http-errors@2.0.5': {}
|
||||
|
||||
'@types/js-beautify@1.14.3': {}
|
||||
|
||||
'@types/jsdom@28.0.1':
|
||||
|
|
@ -8005,6 +8088,10 @@ snapshots:
|
|||
pg-protocol: 1.13.0
|
||||
pg-types: 2.2.0
|
||||
|
||||
'@types/qs@6.15.0': {}
|
||||
|
||||
'@types/range-parser@1.2.7': {}
|
||||
|
||||
'@types/request-promise@4.1.51':
|
||||
dependencies:
|
||||
'@types/bluebird': 3.5.42
|
||||
|
|
@ -8021,6 +8108,15 @@ snapshots:
|
|||
dependencies:
|
||||
htmlparser2: 10.1.0
|
||||
|
||||
'@types/send@1.2.1':
|
||||
dependencies:
|
||||
'@types/node': 25.5.0
|
||||
|
||||
'@types/serve-static@2.2.0':
|
||||
dependencies:
|
||||
'@types/http-errors': 2.0.5
|
||||
'@types/node': 25.5.0
|
||||
|
||||
'@types/statuses@2.0.6': {}
|
||||
|
||||
'@types/tedious@4.0.14':
|
||||
|
|
@ -9920,6 +10016,8 @@ snapshots:
|
|||
|
||||
json-buffer@3.0.1: {}
|
||||
|
||||
json-nd@1.0.0: {}
|
||||
|
||||
json-parse-even-better-errors@2.3.1: {}
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
|
|
@ -11302,6 +11400,10 @@ snapshots:
|
|||
|
||||
stackback@0.0.2: {}
|
||||
|
||||
stacktrace-parser@0.1.11:
|
||||
dependencies:
|
||||
type-fest: 0.7.1
|
||||
|
||||
standard-as-callback@2.1.0: {}
|
||||
|
||||
statuses@2.0.2: {}
|
||||
|
|
@ -11618,6 +11720,8 @@ snapshots:
|
|||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
||||
type-fest@0.7.1: {}
|
||||
|
||||
type-fest@3.13.1: {}
|
||||
|
||||
type-fest@4.41.0: {}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ export default defineConfig({
|
|||
'node:child_process': path.resolve('./lib/shims/node-child-process.ts'),
|
||||
'dotenv/config': path.resolve('./lib/shims/dotenv-config.ts'),
|
||||
'@sentry/node': path.resolve('./lib/shims/sentry-node.ts'),
|
||||
'@honeybadger-io/js': path.resolve('./lib/shims/honeybadger.ts'),
|
||||
'xxhash-wasm': path.resolve('./lib/shims/xxhash-wasm.ts'),
|
||||
// Routes file with Worker-specific build (match relative import from lib/)
|
||||
'../assets/build/routes.js': path.resolve('./assets/build/routes-worker.js'),
|
||||
|
|
|
|||
Loading…
Reference in New Issue