@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.
Files changed (54) hide show
  1. package/README.md +77 -0
  2. package/dist/cjs/browser.d.ts +29 -0
  3. package/dist/cjs/browser.d.ts.map +1 -0
  4. package/dist/cjs/browser.js +57 -0
  5. package/dist/cjs/config.d.ts +8 -0
  6. package/dist/cjs/config.d.ts.map +1 -0
  7. package/dist/cjs/config.js +16 -0
  8. package/dist/cjs/index.d.ts +4 -0
  9. package/dist/cjs/index.d.ts.map +1 -0
  10. package/dist/cjs/index.js +13 -0
  11. package/dist/cjs/nextjs.d.ts +29 -0
  12. package/dist/cjs/nextjs.d.ts.map +1 -0
  13. package/dist/cjs/nextjs.js +52 -0
  14. package/dist/cjs/node.d.ts +39 -0
  15. package/dist/cjs/node.d.ts.map +1 -0
  16. package/dist/cjs/node.js +84 -0
  17. package/dist/cjs/package.json +3 -0
  18. package/dist/cjs/scrub.d.ts +36 -0
  19. package/dist/cjs/scrub.d.ts.map +1 -0
  20. package/dist/cjs/scrub.js +70 -0
  21. package/dist/cjs/scrubbers.d.ts +27 -0
  22. package/dist/cjs/scrubbers.d.ts.map +1 -0
  23. package/dist/cjs/scrubbers.js +51 -0
  24. package/dist/esm/browser.d.ts +29 -0
  25. package/dist/esm/browser.d.ts.map +1 -0
  26. package/dist/esm/browser.js +31 -0
  27. package/dist/esm/config.d.ts +8 -0
  28. package/dist/esm/config.d.ts.map +1 -0
  29. package/dist/esm/config.js +12 -0
  30. package/dist/esm/index.d.ts +4 -0
  31. package/dist/esm/index.d.ts.map +1 -0
  32. package/dist/esm/index.js +5 -0
  33. package/dist/esm/nextjs.d.ts +29 -0
  34. package/dist/esm/nextjs.d.ts.map +1 -0
  35. package/dist/esm/nextjs.js +26 -0
  36. package/dist/esm/node.d.ts +39 -0
  37. package/dist/esm/node.d.ts.map +1 -0
  38. package/dist/esm/node.js +57 -0
  39. package/dist/esm/package.json +3 -0
  40. package/dist/esm/scrub.d.ts +36 -0
  41. package/dist/esm/scrub.d.ts.map +1 -0
  42. package/dist/esm/scrub.js +66 -0
  43. package/dist/esm/scrubbers.d.ts +27 -0
  44. package/dist/esm/scrubbers.d.ts.map +1 -0
  45. package/dist/esm/scrubbers.js +47 -0
  46. package/package.json +86 -0
  47. package/src/browser.ts +50 -0
  48. package/src/config.ts +11 -0
  49. package/src/index.ts +10 -0
  50. package/src/nextjs.ts +48 -0
  51. package/src/node.ts +81 -0
  52. package/src/scrub.test.ts +93 -0
  53. package/src/scrub.ts +85 -0
  54. package/src/scrubbers.ts +68 -0
@@ -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,31 @@
1
+ import * as Sentry from '@sentry/react';
2
+ import { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config';
3
+ import { createSentryScrubbers } from './scrubbers';
4
+ /** Re-exported SDK, for the rare escape hatch. Prefer the helpers below. */
5
+ export { Sentry };
6
+ /** Sentry's React error boundary, re-exported so apps don't import `@sentry/react` directly. */
7
+ export const ErrorBoundary = Sentry.ErrorBoundary;
8
+ export const captureException = Sentry.captureException;
9
+ let initialised = false;
10
+ /**
11
+ * Initialises `@sentry/react` for a Vyro frontend with secret-scrubbing already wired
12
+ * in. Idempotent and a no-op when no DSN is provided.
13
+ */
14
+ export function initSentry(options = {}) {
15
+ var _a, _b;
16
+ if (initialised)
17
+ return;
18
+ const dsn = options.dsn;
19
+ if (!dsn) {
20
+ initialised = true;
21
+ return;
22
+ }
23
+ Sentry.init({
24
+ ...createSentryScrubbers(options.scrub),
25
+ dsn,
26
+ environment: (_a = options.environment) !== null && _a !== void 0 ? _a : resolveEnvironment(),
27
+ tracesSampleRate: (_b = options.tracesSampleRate) !== null && _b !== void 0 ? _b : DEFAULT_TRACES_SAMPLE_RATE,
28
+ ...options.init,
29
+ });
30
+ initialised = true;
31
+ }
@@ -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,12 @@
1
+ /** Default performance tracing sample rate used across Vyro services. */
2
+ export 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 const resolveEnvironment = () => {
8
+ var _a, _b;
9
+ if (typeof process === 'undefined' || !process.env)
10
+ return undefined;
11
+ return (_b = (_a = process.env.SENTRY_ENVIRONMENT) !== null && _a !== void 0 ? _a : process.env.NODE_ENV) !== null && _b !== void 0 ? _b : undefined;
12
+ };
@@ -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,5 @@
1
+ // SDK-agnostic surface. Import from `@vyro-x/sentry/node`, `/browser` or `/nextjs`
2
+ // for an SDK-wired `initSentry`. This root entry has no `@sentry/*` dependency.
3
+ export { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config';
4
+ export { DEFAULT_SENSITIVE_KEY_PATTERN, scrubSentrySensitiveData, } from './scrub';
5
+ export { createSentryScrubbers } from './scrubbers';
@@ -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,26 @@
1
+ import * as Sentry from '@sentry/nextjs';
2
+ import { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config';
3
+ import { createSentryScrubbers } from './scrubbers';
4
+ /** Re-exported SDK, for the rare escape hatch. Prefer the helper below. */
5
+ export { Sentry };
6
+ export const captureException = Sentry.captureException;
7
+ /**
8
+ * Initialises `@sentry/nextjs` (server, client or edge) for the Vyro website with
9
+ * secret-scrubbing already wired in. Idempotent and a no-op when no DSN is configured.
10
+ */
11
+ export function initSentry(options = {}) {
12
+ var _a, _b, _c, _d;
13
+ const dsn = (_a = options.dsn) !== null && _a !== void 0 ? _a : (typeof process !== 'undefined'
14
+ ? ((_b = process.env.NEXT_PUBLIC_SENTRY_DSN) !== null && _b !== void 0 ? _b : process.env.SENTRY_DSN)
15
+ : undefined);
16
+ if (!dsn)
17
+ return;
18
+ Sentry.init({
19
+ ...createSentryScrubbers(options.scrub),
20
+ dsn,
21
+ serverName: options.serverName,
22
+ environment: (_c = options.environment) !== null && _c !== void 0 ? _c : resolveEnvironment(),
23
+ tracesSampleRate: (_d = options.tracesSampleRate) !== null && _d !== void 0 ? _d : DEFAULT_TRACES_SAMPLE_RATE,
24
+ ...options.init,
25
+ });
26
+ }
@@ -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"}
@@ -0,0 +1,57 @@
1
+ import * as Sentry from '@sentry/node';
2
+ import { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config';
3
+ import { createSentryScrubbers } from './scrubbers';
4
+ /** Re-exported SDK, for the rare escape hatch. Prefer the helpers below. */
5
+ export { Sentry };
6
+ /**
7
+ * Express error handler (Sentry v8+). Call after your routes are registered so
8
+ * errors bubbling out of the app are reported. Replaces the removed
9
+ * `Sentry.Handlers.errorHandler()`.
10
+ */
11
+ export const setupExpressErrorHandler = Sentry.setupExpressErrorHandler;
12
+ let initialised = false;
13
+ /**
14
+ * Initialises `@sentry/node` for a Vyro service with secret-scrubbing already wired
15
+ * in. Idempotent and a no-op when no DSN is configured.
16
+ */
17
+ export function initSentry(options) {
18
+ var _a, _b, _c;
19
+ if (initialised)
20
+ return;
21
+ const dsn = (_a = options.dsn) !== null && _a !== void 0 ? _a : process.env.SENTRY_DSN;
22
+ if (!dsn) {
23
+ initialised = true;
24
+ return;
25
+ }
26
+ Sentry.init({
27
+ ...createSentryScrubbers(options.scrub),
28
+ dsn,
29
+ serverName: options.serverName,
30
+ environment: (_b = options.environment) !== null && _b !== void 0 ? _b : resolveEnvironment(),
31
+ tracesSampleRate: (_c = options.tracesSampleRate) !== null && _c !== void 0 ? _c : DEFAULT_TRACES_SAMPLE_RATE,
32
+ ...options.init,
33
+ });
34
+ initialised = true;
35
+ }
36
+ /**
37
+ * Reports an exception with optional tags/extra. No-op until `initSentry` has run
38
+ * with a DSN. Consolidates the helper previously copied into individual services.
39
+ */
40
+ export function captureException(error, context) {
41
+ if (!initialised)
42
+ return;
43
+ if (!context) {
44
+ Sentry.captureException(error);
45
+ return;
46
+ }
47
+ Sentry.withScope((scope) => {
48
+ if (context.tags) {
49
+ for (const [key, value] of Object.entries(context.tags)) {
50
+ scope.setTag(key, value);
51
+ }
52
+ }
53
+ if (context.extra)
54
+ scope.setExtras(context.extra);
55
+ Sentry.captureException(error);
56
+ });
57
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -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,66 @@
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 const DEFAULT_SENSITIVE_KEY_PATTERN = /authorization|api[-_ ]?key|x-hasura-admin-secret|access[-_ ]?token|refresh[-_ ]?token|token|secret|cookie|password|credential/i;
18
+ const buildMatcher = (options) => {
19
+ var _a, _b, _c;
20
+ const patterns = [
21
+ (_a = options.pattern) !== null && _a !== void 0 ? _a : DEFAULT_SENSITIVE_KEY_PATTERN,
22
+ ...((_b = options.extraPatterns) !== null && _b !== void 0 ? _b : []),
23
+ ];
24
+ const keys = ((_c = options.extraKeys) !== null && _c !== void 0 ? _c : []).map((key) => key.toLowerCase());
25
+ return (key) => {
26
+ if (patterns.some((pattern) => pattern.test(key)))
27
+ return true;
28
+ if (keys.length === 0)
29
+ return false;
30
+ const lower = key.toLowerCase();
31
+ return keys.some((needle) => lower.includes(needle));
32
+ };
33
+ };
34
+ /**
35
+ * Recursively redacts sensitive keys of `value` **in place**. Safe on any input:
36
+ * primitives and `null`/`undefined` are ignored, arrays are walked, and circular
37
+ * references are handled. Sensitive values are replaced with the placeholder.
38
+ */
39
+ export const scrubSentrySensitiveData = (value, options = {}) => {
40
+ var _a, _b;
41
+ const placeholder = (_a = options.placeholder) !== null && _a !== void 0 ? _a : '[Filtered]';
42
+ const maxDepth = (_b = options.maxDepth) !== null && _b !== void 0 ? _b : 6;
43
+ const isSensitive = buildMatcher(options);
44
+ const seen = new WeakSet();
45
+ const walk = (node, depth) => {
46
+ if (!node || typeof node !== 'object' || depth > maxDepth)
47
+ return;
48
+ if (seen.has(node))
49
+ return;
50
+ seen.add(node);
51
+ if (Array.isArray(node)) {
52
+ for (const item of node)
53
+ walk(item, depth + 1);
54
+ return;
55
+ }
56
+ const record = node;
57
+ for (const key of Object.keys(record)) {
58
+ if (isSensitive(key)) {
59
+ record[key] = placeholder;
60
+ continue;
61
+ }
62
+ walk(record[key], depth + 1);
63
+ }
64
+ };
65
+ walk(value, 0);
66
+ };
@@ -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,47 @@
1
+ import { scrubSentrySensitiveData } from './scrub';
2
+ const scrubEvent = (event, options) => {
3
+ if (!event || typeof event !== 'object')
4
+ return;
5
+ const record = event;
6
+ const request = record.request;
7
+ if (request) {
8
+ scrubSentrySensitiveData(request.headers, options);
9
+ scrubSentrySensitiveData(request.cookies, options);
10
+ scrubSentrySensitiveData(request.data, options);
11
+ }
12
+ scrubSentrySensitiveData(record.contexts, options);
13
+ scrubSentrySensitiveData(record.extra, options);
14
+ scrubSentrySensitiveData(record.tags, options);
15
+ };
16
+ const scrubBreadcrumb = (breadcrumb, options) => {
17
+ if (!breadcrumb || typeof breadcrumb !== 'object')
18
+ return;
19
+ scrubSentrySensitiveData(breadcrumb.data, options);
20
+ };
21
+ /**
22
+ * Builds `beforeSend` / `beforeBreadcrumb` hooks that redact authorization headers,
23
+ * API keys, tokens and other secrets from outgoing Sentry events and breadcrumbs.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import * as Sentry from "@sentry/node"
28
+ * import { createSentryScrubbers } from "@vyro-x/sentry"
29
+ *
30
+ * Sentry.init({
31
+ * ...createSentryScrubbers(),
32
+ * dsn: process.env.SENTRY_DSN,
33
+ * })
34
+ * ```
35
+ */
36
+ export function createSentryScrubbers(options = {}) {
37
+ return {
38
+ beforeSend: (event) => {
39
+ scrubEvent(event, options);
40
+ return event;
41
+ },
42
+ beforeBreadcrumb: (breadcrumb) => {
43
+ scrubBreadcrumb(breadcrumb, options);
44
+ return breadcrumb;
45
+ },
46
+ };
47
+ }
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@vyro-x/sentry",
3
+ "version": "0.1.0",
4
+ "description": "Vyro's shared Sentry setup: environment-specific init wrappers with built-in secret scrubbing (authorization headers, API keys, tokens).",
5
+ "license": "UNLICENSED",
6
+ "main": "./dist/cjs/index.js",
7
+ "module": "./dist/esm/index.js",
8
+ "types": "./dist/cjs/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/esm/index.d.ts",
13
+ "default": "./dist/esm/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/cjs/index.d.ts",
17
+ "default": "./dist/cjs/index.js"
18
+ }
19
+ },
20
+ "./node": {
21
+ "import": {
22
+ "types": "./dist/esm/node.d.ts",
23
+ "default": "./dist/esm/node.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/cjs/node.d.ts",
27
+ "default": "./dist/cjs/node.js"
28
+ }
29
+ },
30
+ "./browser": {
31
+ "import": {
32
+ "types": "./dist/esm/browser.d.ts",
33
+ "default": "./dist/esm/browser.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/cjs/browser.d.ts",
37
+ "default": "./dist/cjs/browser.js"
38
+ }
39
+ },
40
+ "./nextjs": {
41
+ "import": {
42
+ "types": "./dist/esm/nextjs.d.ts",
43
+ "default": "./dist/esm/nextjs.js"
44
+ },
45
+ "require": {
46
+ "types": "./dist/cjs/nextjs.d.ts",
47
+ "default": "./dist/cjs/nextjs.js"
48
+ }
49
+ }
50
+ },
51
+ "typesVersions": {
52
+ "*": {
53
+ "node": ["dist/cjs/node.d.ts"],
54
+ "browser": ["dist/cjs/browser.d.ts"],
55
+ "nextjs": ["dist/cjs/nextjs.d.ts"]
56
+ }
57
+ },
58
+ "files": ["dist", "src"],
59
+ "keywords": ["sentry", "scrub", "redact", "pii", "security", "api-key"],
60
+ "scripts": {
61
+ "build": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && node scripts/finalize-dist.mjs",
62
+ "build:clean": "rm -rf dist",
63
+ "dev": "tsc -p tsconfig.esm.json --watch",
64
+ "test": "jest"
65
+ },
66
+ "peerDependencies": {
67
+ "@sentry/nextjs": "^9.9.0",
68
+ "@sentry/node": "^9.9.0",
69
+ "@sentry/react": "^9.9.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "@sentry/nextjs": { "optional": true },
73
+ "@sentry/node": { "optional": true },
74
+ "@sentry/react": { "optional": true }
75
+ },
76
+ "devDependencies": {
77
+ "@sentry/nextjs": "9.9.0",
78
+ "@sentry/node": "9.9.0",
79
+ "@sentry/react": "9.9.0",
80
+ "@types/jest": "^29.5.12",
81
+ "@types/node": "^24.0.0",
82
+ "jest": "^29.7.0",
83
+ "ts-jest": "^29.2.5",
84
+ "typescript": "5.4.3"
85
+ }
86
+ }
package/src/browser.ts ADDED
@@ -0,0 +1,50 @@
1
+ import * as Sentry from '@sentry/react'
2
+ import { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config'
3
+ import type { SentryScrubOptions } from './scrub'
4
+ import { createSentryScrubbers } from './scrubbers'
5
+
6
+ /** Re-exported SDK, for the rare escape hatch. Prefer the helpers below. */
7
+ export { Sentry }
8
+ /** Sentry's React error boundary, re-exported so apps don't import `@sentry/react` directly. */
9
+ export const ErrorBoundary = Sentry.ErrorBoundary
10
+ export const captureException = Sentry.captureException
11
+
12
+ let initialised = false
13
+
14
+ export interface BrowserSentryInitOptions {
15
+ /**
16
+ * DSN. Browsers read it from a build-time env (e.g. `import.meta.env.VITE_SENTRY_DSN`
17
+ * or `process.env.NEXT_PUBLIC_SENTRY_DSN`), so pass it in explicitly. When absent,
18
+ * init is skipped.
19
+ */
20
+ dsn?: string
21
+ /** Performance tracing sample rate. Defaults to `0.2`. */
22
+ tracesSampleRate?: number
23
+ /** Overrides the resolved `environment`. */
24
+ environment?: string
25
+ /** Scrubber options (extra keys/patterns, placeholder, …). */
26
+ scrub?: SentryScrubOptions
27
+ /** Extra `@sentry/react` init options, merged last so they can override defaults. */
28
+ init?: Parameters<typeof Sentry.init>[0]
29
+ }
30
+
31
+ /**
32
+ * Initialises `@sentry/react` for a Vyro frontend with secret-scrubbing already wired
33
+ * in. Idempotent and a no-op when no DSN is provided.
34
+ */
35
+ export function initSentry(options: BrowserSentryInitOptions = {}): void {
36
+ if (initialised) return
37
+ const dsn = options.dsn
38
+ if (!dsn) {
39
+ initialised = true
40
+ return
41
+ }
42
+ Sentry.init({
43
+ ...createSentryScrubbers(options.scrub),
44
+ dsn,
45
+ environment: options.environment ?? resolveEnvironment(),
46
+ tracesSampleRate: options.tracesSampleRate ?? DEFAULT_TRACES_SAMPLE_RATE,
47
+ ...options.init,
48
+ })
49
+ initialised = true
50
+ }
package/src/config.ts ADDED
@@ -0,0 +1,11 @@
1
+ /** Default performance tracing sample rate used across Vyro services. */
2
+ export const DEFAULT_TRACES_SAMPLE_RATE = 0.2
3
+
4
+ /**
5
+ * Resolves the Sentry `environment` from the runtime env, falling back to
6
+ * `NODE_ENV`. Returns `undefined` in environments without `process` (some browsers).
7
+ */
8
+ export const resolveEnvironment = (): string | undefined => {
9
+ if (typeof process === 'undefined' || !process.env) return undefined
10
+ return process.env.SENTRY_ENVIRONMENT ?? process.env.NODE_ENV ?? undefined
11
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ // SDK-agnostic surface. Import from `@vyro-x/sentry/node`, `/browser` or `/nextjs`
2
+ // for an SDK-wired `initSentry`. This root entry has no `@sentry/*` dependency.
3
+
4
+ export { DEFAULT_TRACES_SAMPLE_RATE, resolveEnvironment } from './config'
5
+ export {
6
+ DEFAULT_SENSITIVE_KEY_PATTERN,
7
+ type SentryScrubOptions,
8
+ scrubSentrySensitiveData,
9
+ } from './scrub'
10
+ export { createSentryScrubbers, type SentryScrubbers } from './scrubbers'