@vyro-x/sentry 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -0
- package/dist/cjs/browser.d.ts +29 -0
- package/dist/cjs/browser.d.ts.map +1 -0
- package/dist/cjs/browser.js +57 -0
- package/dist/cjs/config.d.ts +8 -0
- package/dist/cjs/config.d.ts.map +1 -0
- package/dist/cjs/config.js +16 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +13 -0
- package/dist/cjs/nextjs.d.ts +29 -0
- package/dist/cjs/nextjs.d.ts.map +1 -0
- package/dist/cjs/nextjs.js +52 -0
- package/dist/cjs/node.d.ts +39 -0
- package/dist/cjs/node.d.ts.map +1 -0
- package/dist/cjs/node.js +84 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/scrub.d.ts +36 -0
- package/dist/cjs/scrub.d.ts.map +1 -0
- package/dist/cjs/scrub.js +70 -0
- package/dist/cjs/scrubbers.d.ts +27 -0
- package/dist/cjs/scrubbers.d.ts.map +1 -0
- package/dist/cjs/scrubbers.js +51 -0
- package/dist/esm/browser.d.ts +29 -0
- package/dist/esm/browser.d.ts.map +1 -0
- package/dist/esm/browser.js +31 -0
- package/dist/esm/config.d.ts +8 -0
- package/dist/esm/config.d.ts.map +1 -0
- package/dist/esm/config.js +12 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/nextjs.d.ts +29 -0
- package/dist/esm/nextjs.d.ts.map +1 -0
- package/dist/esm/nextjs.js +26 -0
- package/dist/esm/node.d.ts +39 -0
- package/dist/esm/node.d.ts.map +1 -0
- package/dist/esm/node.js +57 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/scrub.d.ts +36 -0
- package/dist/esm/scrub.d.ts.map +1 -0
- package/dist/esm/scrub.js +66 -0
- package/dist/esm/scrubbers.d.ts +27 -0
- package/dist/esm/scrubbers.d.ts.map +1 -0
- package/dist/esm/scrubbers.js +47 -0
- package/package.json +86 -0
- package/src/browser.ts +50 -0
- package/src/config.ts +11 -0
- package/src/index.ts +10 -0
- package/src/nextjs.ts +48 -0
- package/src/node.ts +81 -0
- package/src/scrub.test.ts +93 -0
- package/src/scrub.ts +85 -0
- package/src/scrubbers.ts +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @vyro-x/sentry
|
|
2
|
+
|
|
3
|
+
Vyro's shared Sentry setup. One package that owns the Sentry version and gives every
|
|
4
|
+
service and frontend a ready-to-use `initSentry(...)` with secret scrubbing already
|
|
5
|
+
wired in — so `Authorization` headers, API keys, tokens and other secrets never reach
|
|
6
|
+
Sentry.
|
|
7
|
+
|
|
8
|
+
## Why
|
|
9
|
+
|
|
10
|
+
Previously every project called `Sentry.init(...)` itself, on a different SDK version
|
|
11
|
+
(`@sentry/node` alone spanned five v7 ranges plus v8), each re-implementing config and
|
|
12
|
+
scrubbing. This package centralises all of it:
|
|
13
|
+
|
|
14
|
+
- **One pinned Sentry version**, declared here as a peer dependency.
|
|
15
|
+
- **Scrubbing on by default** — no way to forget it.
|
|
16
|
+
- **Per-environment entry points**, because backends, SPAs and Next.js each need a
|
|
17
|
+
different SDK and config.
|
|
18
|
+
|
|
19
|
+
## Entry points
|
|
20
|
+
|
|
21
|
+
| Import | SDK (peer) | Use in |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `@vyro-x/sentry` | none | shared scrubbing / config helpers |
|
|
24
|
+
| `@vyro-x/sentry/node` | `@sentry/node` | Express / Lambda services |
|
|
25
|
+
| `@vyro-x/sentry/browser` | `@sentry/react` | Vite + React SPAs |
|
|
26
|
+
| `@vyro-x/sentry/nextjs` | `@sentry/nextjs` | `modern-website` |
|
|
27
|
+
|
|
28
|
+
The SDK peers are **optional** — installing `@vyro-x/sentry` in a backend pulls only
|
|
29
|
+
`@sentry/node`.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Backend (`@sentry/node`)
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// src/shared/sentry.ts (or inline)
|
|
37
|
+
import { initSentry } from "@vyro-x/sentry/node"
|
|
38
|
+
|
|
39
|
+
initSentry({ serverName: "users-api" }) // DSN read from process.env.SENTRY_DSN
|
|
40
|
+
|
|
41
|
+
export { captureException, setupExpressErrorHandler } from "@vyro-x/sentry/node"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`Sentry.Handlers.requestHandler()` is gone in v8+. If a service needs Express error
|
|
45
|
+
reporting, call `setupExpressErrorHandler(app)` after your routes.
|
|
46
|
+
|
|
47
|
+
### Frontend SPA (`@sentry/react`)
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { initSentry, ErrorBoundary } from "@vyro-x/sentry/browser"
|
|
51
|
+
|
|
52
|
+
initSentry({ dsn: import.meta.env.VITE_SENTRY_DSN, tracesSampleRate: 0.2 })
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Next.js (`@sentry/nextjs`)
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// sentry.server.config.ts / sentry.client.config.ts / sentry.edge.config.ts
|
|
59
|
+
import { initSentry } from "@vyro-x/sentry/nextjs"
|
|
60
|
+
|
|
61
|
+
initSentry({ serverName: "modern-website-frontend" })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## What gets scrubbed
|
|
65
|
+
|
|
66
|
+
`request.headers`, `request.cookies`, `request.data`, `contexts`, `extra`, `tags` on
|
|
67
|
+
every event, and breadcrumb `data`. Default keys (case-insensitive): `authorization`,
|
|
68
|
+
`api-key` / `apikey` / `api_key` / `x-api-key`, `x-hasura-admin-secret`, `access-token`,
|
|
69
|
+
`refresh-token`, `token`, `secret`, `cookie`, `password`, `credential`. Extend via the
|
|
70
|
+
`scrub` option (`extraKeys`, `extraPatterns`, `pattern`, `placeholder`, `maxDepth`), or
|
|
71
|
+
use the low-level `scrubSentrySensitiveData` from the root entry.
|
|
72
|
+
|
|
73
|
+
## Test
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pnpm --filter @vyro-x/sentry test
|
|
77
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/react';
|
|
2
|
+
import type { SentryScrubOptions } from './scrub';
|
|
3
|
+
/** Re-exported SDK, for the rare escape hatch. Prefer the helpers below. */
|
|
4
|
+
export { Sentry };
|
|
5
|
+
/** Sentry's React error boundary, re-exported so apps don't import `@sentry/react` directly. */
|
|
6
|
+
export declare const ErrorBoundary: typeof Sentry.ErrorBoundary;
|
|
7
|
+
export declare const captureException: typeof Sentry.captureException;
|
|
8
|
+
export interface BrowserSentryInitOptions {
|
|
9
|
+
/**
|
|
10
|
+
* DSN. Browsers read it from a build-time env (e.g. `import.meta.env.VITE_SENTRY_DSN`
|
|
11
|
+
* or `process.env.NEXT_PUBLIC_SENTRY_DSN`), so pass it in explicitly. When absent,
|
|
12
|
+
* init is skipped.
|
|
13
|
+
*/
|
|
14
|
+
dsn?: string;
|
|
15
|
+
/** Performance tracing sample rate. Defaults to `0.2`. */
|
|
16
|
+
tracesSampleRate?: number;
|
|
17
|
+
/** Overrides the resolved `environment`. */
|
|
18
|
+
environment?: string;
|
|
19
|
+
/** Scrubber options (extra keys/patterns, placeholder, …). */
|
|
20
|
+
scrub?: SentryScrubOptions;
|
|
21
|
+
/** Extra `@sentry/react` init options, merged last so they can override defaults. */
|
|
22
|
+
init?: Parameters<typeof Sentry.init>[0];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialises `@sentry/react` for a Vyro frontend with secret-scrubbing already wired
|
|
26
|
+
* in. Idempotent and a no-op when no DSN is provided.
|
|
27
|
+
*/
|
|
28
|
+
export declare function initSentry(options?: BrowserSentryInitOptions): void;
|
|
29
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGjD,4EAA4E;AAC5E,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,gGAAgG;AAChG,eAAO,MAAM,aAAa,6BAAuB,CAAA;AACjD,eAAO,MAAM,gBAAgB,gCAA0B,CAAA;AAIvD,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,qFAAqF;IACrF,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;CACzC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,wBAA6B,GAAG,IAAI,CAevE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.initSentry = exports.captureException = exports.ErrorBoundary = exports.Sentry = void 0;
|
|
27
|
+
const Sentry = __importStar(require("@sentry/react"));
|
|
28
|
+
exports.Sentry = Sentry;
|
|
29
|
+
const config_1 = require("./config");
|
|
30
|
+
const scrubbers_1 = require("./scrubbers");
|
|
31
|
+
/** Sentry's React error boundary, re-exported so apps don't import `@sentry/react` directly. */
|
|
32
|
+
exports.ErrorBoundary = Sentry.ErrorBoundary;
|
|
33
|
+
exports.captureException = Sentry.captureException;
|
|
34
|
+
let initialised = false;
|
|
35
|
+
/**
|
|
36
|
+
* Initialises `@sentry/react` for a Vyro frontend with secret-scrubbing already wired
|
|
37
|
+
* in. Idempotent and a no-op when no DSN is provided.
|
|
38
|
+
*/
|
|
39
|
+
function initSentry(options = {}) {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
if (initialised)
|
|
42
|
+
return;
|
|
43
|
+
const dsn = options.dsn;
|
|
44
|
+
if (!dsn) {
|
|
45
|
+
initialised = true;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
Sentry.init({
|
|
49
|
+
...(0, scrubbers_1.createSentryScrubbers)(options.scrub),
|
|
50
|
+
dsn,
|
|
51
|
+
environment: (_a = options.environment) !== null && _a !== void 0 ? _a : (0, config_1.resolveEnvironment)(),
|
|
52
|
+
tracesSampleRate: (_b = options.tracesSampleRate) !== null && _b !== void 0 ? _b : config_1.DEFAULT_TRACES_SAMPLE_RATE,
|
|
53
|
+
...options.init,
|
|
54
|
+
});
|
|
55
|
+
initialised = true;
|
|
56
|
+
}
|
|
57
|
+
exports.initSentry = initSentry;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Default performance tracing sample rate used across Vyro services. */
|
|
2
|
+
export declare const DEFAULT_TRACES_SAMPLE_RATE = 0.2;
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the Sentry `environment` from the runtime env, falling back to
|
|
5
|
+
* `NODE_ENV`. Returns `undefined` in environments without `process` (some browsers).
|
|
6
|
+
*/
|
|
7
|
+
export declare const resolveEnvironment: () => string | undefined;
|
|
8
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,eAAO,MAAM,0BAA0B,MAAM,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAM,GAAG,SAG9C,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveEnvironment = exports.DEFAULT_TRACES_SAMPLE_RATE = void 0;
|
|
4
|
+
/** Default performance tracing sample rate used across Vyro services. */
|
|
5
|
+
exports.DEFAULT_TRACES_SAMPLE_RATE = 0.2;
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the Sentry `environment` from the runtime env, falling back to
|
|
8
|
+
* `NODE_ENV`. Returns `undefined` in environments without `process` (some browsers).
|
|
9
|
+
*/
|
|
10
|
+
const resolveEnvironment = () => {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
if (typeof process === 'undefined' || !process.env)
|
|
13
|
+
return undefined;
|
|
14
|
+
return (_b = (_a = process.env.SENTRY_ENVIRONMENT) !== null && _a !== void 0 ? _a : process.env.NODE_ENV) !== null && _b !== void 0 ? _b : undefined;
|
|
15
|
+
};
|
|
16
|
+
exports.resolveEnvironment = resolveEnvironment;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config';
|
|
2
|
+
export { DEFAULT_SENSITIVE_KEY_PATTERN, type SentryScrubOptions, scrubSentrySensitiveData, } from './scrub';
|
|
3
|
+
export { createSentryScrubbers, type SentryScrubbers } from './scrubbers';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACzE,OAAO,EACL,6BAA6B,EAC7B,KAAK,kBAAkB,EACvB,wBAAwB,GACzB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SDK-agnostic surface. Import from `@vyro-x/sentry/node`, `/browser` or `/nextjs`
|
|
3
|
+
// for an SDK-wired `initSentry`. This root entry has no `@sentry/*` dependency.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.createSentryScrubbers = exports.scrubSentrySensitiveData = exports.DEFAULT_SENSITIVE_KEY_PATTERN = exports.resolveEnvironment = exports.DEFAULT_TRACES_SAMPLE_RATE = void 0;
|
|
6
|
+
var config_1 = require("./config");
|
|
7
|
+
Object.defineProperty(exports, "DEFAULT_TRACES_SAMPLE_RATE", { enumerable: true, get: function () { return config_1.DEFAULT_TRACES_SAMPLE_RATE; } });
|
|
8
|
+
Object.defineProperty(exports, "resolveEnvironment", { enumerable: true, get: function () { return config_1.resolveEnvironment; } });
|
|
9
|
+
var scrub_1 = require("./scrub");
|
|
10
|
+
Object.defineProperty(exports, "DEFAULT_SENSITIVE_KEY_PATTERN", { enumerable: true, get: function () { return scrub_1.DEFAULT_SENSITIVE_KEY_PATTERN; } });
|
|
11
|
+
Object.defineProperty(exports, "scrubSentrySensitiveData", { enumerable: true, get: function () { return scrub_1.scrubSentrySensitiveData; } });
|
|
12
|
+
var scrubbers_1 = require("./scrubbers");
|
|
13
|
+
Object.defineProperty(exports, "createSentryScrubbers", { enumerable: true, get: function () { return scrubbers_1.createSentryScrubbers; } });
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/nextjs';
|
|
2
|
+
import type { SentryScrubOptions } from './scrub';
|
|
3
|
+
/** Re-exported SDK, for the rare escape hatch. Prefer the helper below. */
|
|
4
|
+
export { Sentry };
|
|
5
|
+
export declare const captureException: typeof Sentry.captureException;
|
|
6
|
+
/**
|
|
7
|
+
* Options for `initSentry`. Used by all three Next.js runtimes
|
|
8
|
+
* (`sentry.server.config.ts`, `sentry.client.config.ts`, `sentry.edge.config.ts`).
|
|
9
|
+
*/
|
|
10
|
+
export interface NextSentryInitOptions {
|
|
11
|
+
/** DSN; defaults to `process.env.NEXT_PUBLIC_SENTRY_DSN` then `process.env.SENTRY_DSN`. */
|
|
12
|
+
dsn?: string;
|
|
13
|
+
/** Logical name shown as `server_name` (server/edge runtimes). */
|
|
14
|
+
serverName?: string;
|
|
15
|
+
/** Performance tracing sample rate. Defaults to `0.2`. */
|
|
16
|
+
tracesSampleRate?: number;
|
|
17
|
+
/** Overrides the resolved `environment`. */
|
|
18
|
+
environment?: string;
|
|
19
|
+
/** Scrubber options (extra keys/patterns, placeholder, …). */
|
|
20
|
+
scrub?: SentryScrubOptions;
|
|
21
|
+
/** Extra `@sentry/nextjs` init options, merged last so they can override defaults. */
|
|
22
|
+
init?: Parameters<typeof Sentry.init>[0];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialises `@sentry/nextjs` (server, client or edge) for the Vyro website with
|
|
26
|
+
* secret-scrubbing already wired in. Idempotent and a no-op when no DSN is configured.
|
|
27
|
+
*/
|
|
28
|
+
export declare function initSentry(options?: NextSentryInitOptions): void;
|
|
29
|
+
//# sourceMappingURL=nextjs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/nextjs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAA;AAExC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGjD,2EAA2E;AAC3E,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,eAAO,MAAM,gBAAgB,gCAA0B,CAAA;AAEvD;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,sFAAsF;IACtF,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;CACzC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,qBAA0B,GAAG,IAAI,CAepE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.initSentry = exports.captureException = exports.Sentry = void 0;
|
|
27
|
+
const Sentry = __importStar(require("@sentry/nextjs"));
|
|
28
|
+
exports.Sentry = Sentry;
|
|
29
|
+
const config_1 = require("./config");
|
|
30
|
+
const scrubbers_1 = require("./scrubbers");
|
|
31
|
+
exports.captureException = Sentry.captureException;
|
|
32
|
+
/**
|
|
33
|
+
* Initialises `@sentry/nextjs` (server, client or edge) for the Vyro website with
|
|
34
|
+
* secret-scrubbing already wired in. Idempotent and a no-op when no DSN is configured.
|
|
35
|
+
*/
|
|
36
|
+
function initSentry(options = {}) {
|
|
37
|
+
var _a, _b, _c, _d;
|
|
38
|
+
const dsn = (_a = options.dsn) !== null && _a !== void 0 ? _a : (typeof process !== 'undefined'
|
|
39
|
+
? ((_b = process.env.NEXT_PUBLIC_SENTRY_DSN) !== null && _b !== void 0 ? _b : process.env.SENTRY_DSN)
|
|
40
|
+
: undefined);
|
|
41
|
+
if (!dsn)
|
|
42
|
+
return;
|
|
43
|
+
Sentry.init({
|
|
44
|
+
...(0, scrubbers_1.createSentryScrubbers)(options.scrub),
|
|
45
|
+
dsn,
|
|
46
|
+
serverName: options.serverName,
|
|
47
|
+
environment: (_c = options.environment) !== null && _c !== void 0 ? _c : (0, config_1.resolveEnvironment)(),
|
|
48
|
+
tracesSampleRate: (_d = options.tracesSampleRate) !== null && _d !== void 0 ? _d : config_1.DEFAULT_TRACES_SAMPLE_RATE,
|
|
49
|
+
...options.init,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
exports.initSentry = initSentry;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/node';
|
|
2
|
+
import type { SentryScrubOptions } from './scrub';
|
|
3
|
+
/** Re-exported SDK, for the rare escape hatch. Prefer the helpers below. */
|
|
4
|
+
export { Sentry };
|
|
5
|
+
/**
|
|
6
|
+
* Express error handler (Sentry v8+). Call after your routes are registered so
|
|
7
|
+
* errors bubbling out of the app are reported. Replaces the removed
|
|
8
|
+
* `Sentry.Handlers.errorHandler()`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const setupExpressErrorHandler: typeof Sentry.setupExpressErrorHandler;
|
|
11
|
+
export interface NodeSentryInitOptions {
|
|
12
|
+
/** Logical service name — shown in Sentry as `server_name`. */
|
|
13
|
+
serverName: string;
|
|
14
|
+
/** DSN; defaults to `process.env.SENTRY_DSN`. When absent, init is skipped. */
|
|
15
|
+
dsn?: string;
|
|
16
|
+
/** Performance tracing sample rate. Defaults to `0.2`. */
|
|
17
|
+
tracesSampleRate?: number;
|
|
18
|
+
/** Overrides the resolved `environment`. */
|
|
19
|
+
environment?: string;
|
|
20
|
+
/** Scrubber options (extra keys/patterns, placeholder, …). */
|
|
21
|
+
scrub?: SentryScrubOptions;
|
|
22
|
+
/** Extra `@sentry/node` init options, merged last so they can override defaults. */
|
|
23
|
+
init?: Parameters<typeof Sentry.init>[0];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialises `@sentry/node` for a Vyro service with secret-scrubbing already wired
|
|
27
|
+
* in. Idempotent and a no-op when no DSN is configured.
|
|
28
|
+
*/
|
|
29
|
+
export declare function initSentry(options: NodeSentryInitOptions): void;
|
|
30
|
+
export interface CaptureContext {
|
|
31
|
+
tags?: Record<string, string>;
|
|
32
|
+
extra?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Reports an exception with optional tags/extra. No-op until `initSentry` has run
|
|
36
|
+
* with a DSN. Consolidates the helper previously copied into individual services.
|
|
37
|
+
*/
|
|
38
|
+
export declare function captureException(error: unknown, context?: CaptureContext): void;
|
|
39
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGjD,4EAA4E;AAC5E,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,wCAAkC,CAAA;AAIvE,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,oFAAoF;IACpF,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;CACzC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAgB/D;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,IAAI,CAeN"}
|
package/dist/cjs/node.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.captureException = exports.initSentry = exports.setupExpressErrorHandler = exports.Sentry = void 0;
|
|
27
|
+
const Sentry = __importStar(require("@sentry/node"));
|
|
28
|
+
exports.Sentry = Sentry;
|
|
29
|
+
const config_1 = require("./config");
|
|
30
|
+
const scrubbers_1 = require("./scrubbers");
|
|
31
|
+
/**
|
|
32
|
+
* Express error handler (Sentry v8+). Call after your routes are registered so
|
|
33
|
+
* errors bubbling out of the app are reported. Replaces the removed
|
|
34
|
+
* `Sentry.Handlers.errorHandler()`.
|
|
35
|
+
*/
|
|
36
|
+
exports.setupExpressErrorHandler = Sentry.setupExpressErrorHandler;
|
|
37
|
+
let initialised = false;
|
|
38
|
+
/**
|
|
39
|
+
* Initialises `@sentry/node` for a Vyro service with secret-scrubbing already wired
|
|
40
|
+
* in. Idempotent and a no-op when no DSN is configured.
|
|
41
|
+
*/
|
|
42
|
+
function initSentry(options) {
|
|
43
|
+
var _a, _b, _c;
|
|
44
|
+
if (initialised)
|
|
45
|
+
return;
|
|
46
|
+
const dsn = (_a = options.dsn) !== null && _a !== void 0 ? _a : process.env.SENTRY_DSN;
|
|
47
|
+
if (!dsn) {
|
|
48
|
+
initialised = true;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
Sentry.init({
|
|
52
|
+
...(0, scrubbers_1.createSentryScrubbers)(options.scrub),
|
|
53
|
+
dsn,
|
|
54
|
+
serverName: options.serverName,
|
|
55
|
+
environment: (_b = options.environment) !== null && _b !== void 0 ? _b : (0, config_1.resolveEnvironment)(),
|
|
56
|
+
tracesSampleRate: (_c = options.tracesSampleRate) !== null && _c !== void 0 ? _c : config_1.DEFAULT_TRACES_SAMPLE_RATE,
|
|
57
|
+
...options.init,
|
|
58
|
+
});
|
|
59
|
+
initialised = true;
|
|
60
|
+
}
|
|
61
|
+
exports.initSentry = initSentry;
|
|
62
|
+
/**
|
|
63
|
+
* Reports an exception with optional tags/extra. No-op until `initSentry` has run
|
|
64
|
+
* with a DSN. Consolidates the helper previously copied into individual services.
|
|
65
|
+
*/
|
|
66
|
+
function captureException(error, context) {
|
|
67
|
+
if (!initialised)
|
|
68
|
+
return;
|
|
69
|
+
if (!context) {
|
|
70
|
+
Sentry.captureException(error);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
Sentry.withScope((scope) => {
|
|
74
|
+
if (context.tags) {
|
|
75
|
+
for (const [key, value] of Object.entries(context.tags)) {
|
|
76
|
+
scope.setTag(key, value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (context.extra)
|
|
80
|
+
scope.setExtras(context.extra);
|
|
81
|
+
Sentry.captureException(error);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
exports.captureException = captureException;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-agnostic Sentry scrubbing helpers.
|
|
3
|
+
*
|
|
4
|
+
* This package intentionally does NOT depend on any `@sentry/*` package so it can
|
|
5
|
+
* be dropped into services and frontends running different Sentry SDK versions
|
|
6
|
+
* (`@sentry/node`, `@sentry/react`, `@sentry/nextjs`, …). The public `beforeSend` /
|
|
7
|
+
* `beforeBreadcrumb` helpers use a generic identity signature (`<T>(x: T) => T`) so
|
|
8
|
+
* they satisfy every SDK's `beforeSend` / `beforeBreadcrumb` option type while
|
|
9
|
+
* operating on the event purely at runtime.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Default set of key/header-name fragments that get redacted (case-insensitive).
|
|
13
|
+
* Matches `authorization`, `x-api-key` and every `api-key` / `apikey` / `api_key`
|
|
14
|
+
* variant, `x-hasura-admin-secret`, `access-token` / `refresh-token` / `token`,
|
|
15
|
+
* `secret`, `cookie`, `password` and `credential`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_SENSITIVE_KEY_PATTERN: RegExp;
|
|
18
|
+
export interface SentryScrubOptions {
|
|
19
|
+
/** Extra regexes matched against key/header names (case-insensitive recommended). */
|
|
20
|
+
extraPatterns?: RegExp[];
|
|
21
|
+
/** Extra literal substrings matched against key/header names (case-insensitive). */
|
|
22
|
+
extraKeys?: string[];
|
|
23
|
+
/** Replace the whole default pattern instead of extending it. */
|
|
24
|
+
pattern?: RegExp;
|
|
25
|
+
/** Value written in place of a redacted entry. Defaults to `"[Filtered]"`. */
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
/** Maximum object depth to walk. Defaults to `6`. */
|
|
28
|
+
maxDepth?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Recursively redacts sensitive keys of `value` **in place**. Safe on any input:
|
|
32
|
+
* primitives and `null`/`undefined` are ignored, arrays are walked, and circular
|
|
33
|
+
* references are handled. Sensitive values are replaced with the placeholder.
|
|
34
|
+
*/
|
|
35
|
+
export declare const scrubSentrySensitiveData: (value: unknown, options?: SentryScrubOptions) => void;
|
|
36
|
+
//# sourceMappingURL=scrub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrub.d.ts","sourceRoot":"","sources":["../../src/scrub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,QACwF,CAAA;AAElI,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAkBD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,UAC5B,OAAO,YACL,kBAAkB,KAC1B,IA2BF,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SDK-agnostic Sentry scrubbing helpers.
|
|
4
|
+
*
|
|
5
|
+
* This package intentionally does NOT depend on any `@sentry/*` package so it can
|
|
6
|
+
* be dropped into services and frontends running different Sentry SDK versions
|
|
7
|
+
* (`@sentry/node`, `@sentry/react`, `@sentry/nextjs`, …). The public `beforeSend` /
|
|
8
|
+
* `beforeBreadcrumb` helpers use a generic identity signature (`<T>(x: T) => T`) so
|
|
9
|
+
* they satisfy every SDK's `beforeSend` / `beforeBreadcrumb` option type while
|
|
10
|
+
* operating on the event purely at runtime.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.scrubSentrySensitiveData = exports.DEFAULT_SENSITIVE_KEY_PATTERN = void 0;
|
|
14
|
+
/**
|
|
15
|
+
* Default set of key/header-name fragments that get redacted (case-insensitive).
|
|
16
|
+
* Matches `authorization`, `x-api-key` and every `api-key` / `apikey` / `api_key`
|
|
17
|
+
* variant, `x-hasura-admin-secret`, `access-token` / `refresh-token` / `token`,
|
|
18
|
+
* `secret`, `cookie`, `password` and `credential`.
|
|
19
|
+
*/
|
|
20
|
+
exports.DEFAULT_SENSITIVE_KEY_PATTERN = /authorization|api[-_ ]?key|x-hasura-admin-secret|access[-_ ]?token|refresh[-_ ]?token|token|secret|cookie|password|credential/i;
|
|
21
|
+
const buildMatcher = (options) => {
|
|
22
|
+
var _a, _b, _c;
|
|
23
|
+
const patterns = [
|
|
24
|
+
(_a = options.pattern) !== null && _a !== void 0 ? _a : exports.DEFAULT_SENSITIVE_KEY_PATTERN,
|
|
25
|
+
...((_b = options.extraPatterns) !== null && _b !== void 0 ? _b : []),
|
|
26
|
+
];
|
|
27
|
+
const keys = ((_c = options.extraKeys) !== null && _c !== void 0 ? _c : []).map((key) => key.toLowerCase());
|
|
28
|
+
return (key) => {
|
|
29
|
+
if (patterns.some((pattern) => pattern.test(key)))
|
|
30
|
+
return true;
|
|
31
|
+
if (keys.length === 0)
|
|
32
|
+
return false;
|
|
33
|
+
const lower = key.toLowerCase();
|
|
34
|
+
return keys.some((needle) => lower.includes(needle));
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Recursively redacts sensitive keys of `value` **in place**. Safe on any input:
|
|
39
|
+
* primitives and `null`/`undefined` are ignored, arrays are walked, and circular
|
|
40
|
+
* references are handled. Sensitive values are replaced with the placeholder.
|
|
41
|
+
*/
|
|
42
|
+
const scrubSentrySensitiveData = (value, options = {}) => {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
const placeholder = (_a = options.placeholder) !== null && _a !== void 0 ? _a : '[Filtered]';
|
|
45
|
+
const maxDepth = (_b = options.maxDepth) !== null && _b !== void 0 ? _b : 6;
|
|
46
|
+
const isSensitive = buildMatcher(options);
|
|
47
|
+
const seen = new WeakSet();
|
|
48
|
+
const walk = (node, depth) => {
|
|
49
|
+
if (!node || typeof node !== 'object' || depth > maxDepth)
|
|
50
|
+
return;
|
|
51
|
+
if (seen.has(node))
|
|
52
|
+
return;
|
|
53
|
+
seen.add(node);
|
|
54
|
+
if (Array.isArray(node)) {
|
|
55
|
+
for (const item of node)
|
|
56
|
+
walk(item, depth + 1);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const record = node;
|
|
60
|
+
for (const key of Object.keys(record)) {
|
|
61
|
+
if (isSensitive(key)) {
|
|
62
|
+
record[key] = placeholder;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
walk(record[key], depth + 1);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
walk(value, 0);
|
|
69
|
+
};
|
|
70
|
+
exports.scrubSentrySensitiveData = scrubSentrySensitiveData;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type SentryScrubOptions } from './scrub';
|
|
2
|
+
/**
|
|
3
|
+
* A pair of scrubbing hooks. The signatures are generic identity functions so the
|
|
4
|
+
* object can be spread straight into any SDK's `Sentry.init({ ... })` regardless of
|
|
5
|
+
* its `Event` / `Breadcrumb` types.
|
|
6
|
+
*/
|
|
7
|
+
export interface SentryScrubbers {
|
|
8
|
+
beforeSend: <T>(event: T) => T;
|
|
9
|
+
beforeBreadcrumb: <T>(breadcrumb: T) => T;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Builds `beforeSend` / `beforeBreadcrumb` hooks that redact authorization headers,
|
|
13
|
+
* API keys, tokens and other secrets from outgoing Sentry events and breadcrumbs.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import * as Sentry from "@sentry/node"
|
|
18
|
+
* import { createSentryScrubbers } from "@vyro-x/sentry"
|
|
19
|
+
*
|
|
20
|
+
* Sentry.init({
|
|
21
|
+
* ...createSentryScrubbers(),
|
|
22
|
+
* dsn: process.env.SENTRY_DSN,
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function createSentryScrubbers(options?: SentryScrubOptions): SentryScrubbers;
|
|
27
|
+
//# sourceMappingURL=scrubbers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrubbers.d.ts","sourceRoot":"","sources":["../../src/scrubbers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAA4B,MAAM,SAAS,CAAA;AAE3E;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;IAC9B,gBAAgB,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,CAAA;CAC1C;AA6BD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,kBAAuB,GAC/B,eAAe,CAWjB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSentryScrubbers = void 0;
|
|
4
|
+
const scrub_1 = require("./scrub");
|
|
5
|
+
const scrubEvent = (event, options) => {
|
|
6
|
+
if (!event || typeof event !== 'object')
|
|
7
|
+
return;
|
|
8
|
+
const record = event;
|
|
9
|
+
const request = record.request;
|
|
10
|
+
if (request) {
|
|
11
|
+
(0, scrub_1.scrubSentrySensitiveData)(request.headers, options);
|
|
12
|
+
(0, scrub_1.scrubSentrySensitiveData)(request.cookies, options);
|
|
13
|
+
(0, scrub_1.scrubSentrySensitiveData)(request.data, options);
|
|
14
|
+
}
|
|
15
|
+
(0, scrub_1.scrubSentrySensitiveData)(record.contexts, options);
|
|
16
|
+
(0, scrub_1.scrubSentrySensitiveData)(record.extra, options);
|
|
17
|
+
(0, scrub_1.scrubSentrySensitiveData)(record.tags, options);
|
|
18
|
+
};
|
|
19
|
+
const scrubBreadcrumb = (breadcrumb, options) => {
|
|
20
|
+
if (!breadcrumb || typeof breadcrumb !== 'object')
|
|
21
|
+
return;
|
|
22
|
+
(0, scrub_1.scrubSentrySensitiveData)(breadcrumb.data, options);
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Builds `beforeSend` / `beforeBreadcrumb` hooks that redact authorization headers,
|
|
26
|
+
* API keys, tokens and other secrets from outgoing Sentry events and breadcrumbs.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import * as Sentry from "@sentry/node"
|
|
31
|
+
* import { createSentryScrubbers } from "@vyro-x/sentry"
|
|
32
|
+
*
|
|
33
|
+
* Sentry.init({
|
|
34
|
+
* ...createSentryScrubbers(),
|
|
35
|
+
* dsn: process.env.SENTRY_DSN,
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function createSentryScrubbers(options = {}) {
|
|
40
|
+
return {
|
|
41
|
+
beforeSend: (event) => {
|
|
42
|
+
scrubEvent(event, options);
|
|
43
|
+
return event;
|
|
44
|
+
},
|
|
45
|
+
beforeBreadcrumb: (breadcrumb) => {
|
|
46
|
+
scrubBreadcrumb(breadcrumb, options);
|
|
47
|
+
return breadcrumb;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exports.createSentryScrubbers = createSentryScrubbers;
|