@veryfront/ext-observability-sentry 0.1.1173 → 0.1.1174

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 CHANGED
@@ -14,3 +14,15 @@ binaries include the dormant adapter; npm consumers install
14
14
  `@veryfront/ext-observability-sentry` separately. The adapter captures
15
15
  unexpected application failures, tags them by service and boundary, and keeps
16
16
  OpenTelemetry as the owner of traces, metrics, and logs.
17
+
18
+ ## Runtime entrypoints
19
+
20
+ - `@veryfront/ext-observability-sentry` keeps the V1 Deno-compatible root
21
+ reporter export.
22
+ - `@veryfront/ext-observability-sentry/deno` exports the explicit Deno reporter.
23
+ - `@veryfront/ext-observability-sentry/node` exports the explicit Node reporter.
24
+
25
+ The Node and Deno reporters share the same privacy policy, service tags,
26
+ `veryfront.boundary` tagging, Grafana trace correlation, fingerprinting, and
27
+ bounded flush behavior. They only use Sentry for error capture; tracing, logs,
28
+ request bodies, user data, and OpenTelemetry provider setup remain disabled.
package/esm/deno.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import * as Sentry from "@sentry/deno";
2
+ import type { ApplicationErrorReporter, SentryConfig } from "veryfront/observability/sentry";
3
+ import { type SentryPolicySdk } from "./policy.js";
4
+ type DenoSentrySdk = SentryPolicySdk & {
5
+ init(options: Parameters<typeof Sentry.init>[0]): unknown;
6
+ };
7
+ export declare function createDenoSentryApplicationErrorReporter(config: Required<SentryConfig>, sdk?: DenoSentrySdk): ApplicationErrorReporter;
8
+ export {};
9
+ //# sourceMappingURL=deno.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno.d.ts","sourceRoot":"","sources":["../src/deno.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC7F,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AASrB,KAAK,aAAa,GAAG,eAAe,GAAG;IACrC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CAC3D,CAAC;AAEF,wBAAgB,wCAAwC,CACtD,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,GAAG,GAAE,aAAsB,GAC1B,wBAAwB,CA+B1B"}
package/esm/deno.js ADDED
@@ -0,0 +1,36 @@
1
+ import * as Sentry from "@sentry/deno";
2
+ import { captureWithSentryPolicy, flushWithSentryPolicy, prepareSentryEvent, } from "./policy.js";
3
+ const DISABLED_DENO_INTEGRATIONS = new Set([
4
+ "Breadcrumbs",
5
+ "DenoHttp",
6
+ "DenoServe",
7
+ "GlobalHandlers",
8
+ ]);
9
+ export function createDenoSentryApplicationErrorReporter(config, sdk = Sentry) {
10
+ sdk.init({
11
+ dsn: config.dsn,
12
+ ...(config.environment ? { environment: config.environment } : {}),
13
+ ...(config.release ? { release: config.release } : {}),
14
+ beforeSend: (event) => prepareSentryEvent(event, config.serviceName),
15
+ dataCollection: {
16
+ cookies: false,
17
+ databaseQueryData: false,
18
+ frameContextLines: 0,
19
+ genAI: { inputs: false, outputs: false },
20
+ graphQL: { document: false, variables: false },
21
+ httpBodies: [],
22
+ httpHeaders: { request: false, response: false },
23
+ stackFrameVariables: false,
24
+ urlQueryParams: false,
25
+ userInfo: false,
26
+ },
27
+ integrations: (defaultIntegrations) => defaultIntegrations.filter((integration) => !DISABLED_DENO_INTEGRATIONS.has(integration.name)),
28
+ skipOpenTelemetrySetup: true,
29
+ });
30
+ return {
31
+ capture(error, context) {
32
+ return captureWithSentryPolicy(sdk, config.serviceName, error, context);
33
+ },
34
+ flush: (timeoutMs) => flushWithSentryPolicy(sdk, timeoutMs),
35
+ };
36
+ }
package/esm/index.d.ts CHANGED
@@ -1,18 +1,5 @@
1
- import * as Sentry from "@sentry/deno";
2
1
  import type { ExtensionFactory } from "veryfront/extensions";
3
- import type { ApplicationErrorReporter, SentryConfig } from "veryfront/observability/sentry";
4
- type SentryScope = {
5
- setContext(name: string, context: Record<string, unknown>): void;
6
- setFingerprint(fingerprint: string[]): void;
7
- setTag(key: string, value: string): void;
8
- };
9
- type SentrySdk = {
10
- captureException(error: unknown): string;
11
- flush(timeoutMs?: number): Promise<boolean>;
12
- init(options: Parameters<typeof Sentry.init>[0]): unknown;
13
- withScope(callback: (scope: SentryScope) => void): void;
14
- };
15
- export declare function createSentryApplicationErrorReporter(config: Required<SentryConfig>, sdk?: SentrySdk): ApplicationErrorReporter;
2
+ export { createDenoSentryApplicationErrorReporter, createDenoSentryApplicationErrorReporter as createSentryApplicationErrorReporter, } from "./deno.js";
16
3
  declare const extSentry: ExtensionFactory;
17
4
  export default extSentry;
18
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAEV,wBAAwB,EACxB,YAAY,EACb,MAAM,gCAAgC,CAAC;AAgBxC,KAAK,WAAW,GAAG;IACjB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjE,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAC1D,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAAC;CACzD,CAAC;AAEF,wBAAgB,oCAAoC,CAClD,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,GAAG,GAAE,SAAkB,GACtB,wBAAwB,CA6B1B;AA8ED,QAAA,MAAM,SAAS,EAAE,gBAOf,CAAC;AAEH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EACL,wCAAwC,EACxC,wCAAwC,IAAI,oCAAoC,GACjF,MAAM,WAAW,CAAC;AAEnB,QAAA,MAAM,SAAS,EAAE,gBAOf,CAAC;AAEH,eAAe,SAAS,CAAC"}
package/esm/index.js CHANGED
@@ -1,111 +1,4 @@
1
- import * as Sentry from "@sentry/deno";
2
- const DEFAULT_FINGERPRINT = "{{ default }}";
3
- const DISABLED_INTEGRATIONS = new Set([
4
- "Breadcrumbs",
5
- "DenoHttp",
6
- "DenoServe",
7
- "GlobalHandlers",
8
- ]);
9
- const SENTRY_TOKEN_PATTERN = /\bsntrys_[A-Za-z0-9_+/=-]+\b/g;
10
- const BEARER_TOKEN_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+\b/gi;
11
- const JWT_PATTERN = /\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;
12
- const URL_CREDENTIAL_PATTERN = /(https?:\/\/)[^@\s/]+(@[^/\s]+)/gi;
13
- const SENSITIVE_QUERY_PATTERN = /([?&](?:access_token|api_key|auth|authorization|dsn|password|secret|token)=)[^&#\s]+/gi;
14
- export function createSentryApplicationErrorReporter(config, sdk = Sentry) {
15
- sdk.init({
16
- dsn: config.dsn,
17
- ...(config.environment ? { environment: config.environment } : {}),
18
- ...(config.release ? { release: config.release } : {}),
19
- beforeSend: (event) => prepareSentryEvent(event, config.serviceName),
20
- dataCollection: {
21
- cookies: false,
22
- databaseQueryData: false,
23
- frameContextLines: 0,
24
- genAI: { inputs: false, outputs: false },
25
- graphQL: { document: false, variables: false },
26
- httpBodies: [],
27
- httpHeaders: { request: false, response: false },
28
- stackFrameVariables: false,
29
- urlQueryParams: false,
30
- userInfo: false,
31
- },
32
- integrations: (defaultIntegrations) => defaultIntegrations.filter((integration) => !DISABLED_INTEGRATIONS.has(integration.name)),
33
- skipOpenTelemetrySetup: true,
34
- });
35
- return {
36
- capture(error, context) {
37
- return captureWithSentry(sdk, config.serviceName, error, context);
38
- },
39
- flush: (timeoutMs) => sdk.flush(timeoutMs),
40
- };
41
- }
42
- function captureWithSentry(sdk, serviceName, error, context) {
43
- let eventId;
44
- sdk.withScope((scope) => {
45
- scope.setFingerprint([serviceName, DEFAULT_FINGERPRINT]);
46
- scope.setTag("service.name", serviceName);
47
- scope.setTag("veryfront.boundary", context.boundary);
48
- if (context.method)
49
- scope.setTag("http.request.method", context.method);
50
- if (context.requestId)
51
- scope.setTag("veryfront.request_id", context.requestId);
52
- if (context.traceId) {
53
- scope.setTag("grafana.trace_id", context.traceId);
54
- scope.setContext("grafana_trace", {
55
- trace_id: context.traceId,
56
- ...(context.spanId ? { span_id: context.spanId } : {}),
57
- });
58
- }
59
- eventId = sdk.captureException(error);
60
- });
61
- return eventId;
62
- }
63
- function prepareSentryEvent(event, serviceName) {
64
- event.tags = {
65
- ...event.tags,
66
- "service.name": serviceName,
67
- };
68
- event.fingerprint = [serviceName, ...(event.fingerprint ?? [DEFAULT_FINGERPRINT])];
69
- delete event.breadcrumbs;
70
- delete event.request;
71
- delete event.user;
72
- if (event.message)
73
- event.message = redactSensitiveText(event.message);
74
- if (event.logentry?.message) {
75
- event.logentry.message = redactSensitiveText(event.logentry.message);
76
- }
77
- for (const value of event.exception?.values ?? []) {
78
- if (value.value)
79
- value.value = redactSensitiveText(value.value);
80
- for (const frame of value.stacktrace?.frames ?? []) {
81
- if (frame.filename)
82
- frame.filename = sanitizeStackFramePath(frame.filename);
83
- if (frame.abs_path)
84
- frame.abs_path = sanitizeStackFramePath(frame.abs_path);
85
- }
86
- }
87
- return event;
88
- }
89
- function redactSensitiveText(value) {
90
- return value
91
- .replace(SENTRY_TOKEN_PATTERN, "[REDACTED]")
92
- .replace(BEARER_TOKEN_PATTERN, "[REDACTED]")
93
- .replace(JWT_PATTERN, "[REDACTED]")
94
- .replace(URL_CREDENTIAL_PATTERN, "$1[REDACTED]$2")
95
- .replace(SENSITIVE_QUERY_PATTERN, "$1[REDACTED]");
96
- }
97
- function sanitizeStackFramePath(value) {
98
- const redacted = redactSensitiveText(value);
99
- const path = redacted.startsWith("file://") ? redacted.slice("file://".length) : redacted;
100
- if (!path.startsWith("/") && !/^[A-Za-z]:[\\/]/.test(path))
101
- return redacted;
102
- const normalized = path.replaceAll("\\", "/");
103
- const sourcePath = normalized.match(/(?:^|\/)((?:src|extensions|cli|dist)\/.+)$/)?.[1];
104
- if (sourcePath)
105
- return sourcePath;
106
- const basename = normalized.split("/").filter(Boolean).at(-1);
107
- return basename ? `[REDACTED]/${basename}` : "[REDACTED]";
108
- }
1
+ export { createDenoSentryApplicationErrorReporter, createDenoSentryApplicationErrorReporter as createSentryApplicationErrorReporter, } from "./deno.js";
109
2
  const extSentry = () => ({
110
3
  name: "ext-observability-sentry",
111
4
  version: "0.1.0",
package/esm/node.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import * as Sentry from "@sentry/node";
2
+ import type { ApplicationErrorReporter, SentryConfig } from "veryfront/observability/sentry";
3
+ import { type SentryPolicySdk } from "./policy.js";
4
+ type NodeSentrySdk = SentryPolicySdk & {
5
+ init(options: Parameters<typeof Sentry.init>[0]): unknown;
6
+ };
7
+ export declare function createNodeSentryApplicationErrorReporter(config: Required<SentryConfig>, sdk?: NodeSentrySdk): ApplicationErrorReporter;
8
+ export {};
9
+ //# 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,CAAC;AACvC,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC7F,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,KAAK,aAAa,GAAG,eAAe,GAAG;IACrC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CAC3D,CAAC;AAEF,wBAAgB,wCAAwC,CACtD,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,GAAG,GAAE,aAAsB,GAC1B,wBAAwB,CA8B1B"}
package/esm/node.js ADDED
@@ -0,0 +1,32 @@
1
+ import * as Sentry from "@sentry/node";
2
+ import { captureWithSentryPolicy, flushWithSentryPolicy, prepareSentryEvent, } from "./policy.js";
3
+ export function createNodeSentryApplicationErrorReporter(config, sdk = Sentry) {
4
+ sdk.init({
5
+ dsn: config.dsn,
6
+ ...(config.environment ? { environment: config.environment } : {}),
7
+ ...(config.release ? { release: config.release } : {}),
8
+ beforeSend: (event) => prepareSentryEvent(event, config.serviceName),
9
+ dataCollection: {
10
+ cookies: false,
11
+ databaseQueryData: false,
12
+ frameContextLines: 0,
13
+ genAI: { inputs: false, outputs: false },
14
+ graphQL: { document: false, variables: false },
15
+ httpBodies: [],
16
+ httpHeaders: { request: false, response: false },
17
+ stackFrameVariables: false,
18
+ urlQueryParams: false,
19
+ userInfo: false,
20
+ },
21
+ defaultIntegrations: false,
22
+ enableLogs: false,
23
+ sendDefaultPii: false,
24
+ skipOpenTelemetrySetup: true,
25
+ });
26
+ return {
27
+ capture(error, context) {
28
+ return captureWithSentryPolicy(sdk, config.serviceName, error, context);
29
+ },
30
+ flush: (timeoutMs) => flushWithSentryPolicy(sdk, timeoutMs),
31
+ };
32
+ }
@@ -0,0 +1,42 @@
1
+ import type { ApplicationErrorContext } from "veryfront/observability/sentry";
2
+ export declare const DEFAULT_FINGERPRINT = "{{ default }}";
3
+ export type SentryPolicyScope = {
4
+ setContext(name: string, context: Record<string, unknown>): void;
5
+ setFingerprint(fingerprint: string[]): void;
6
+ setTag(key: string, value: string): void;
7
+ };
8
+ export type SentryPolicySdk = {
9
+ captureException(error: unknown): string;
10
+ flush(timeoutMs?: number): Promise<boolean>;
11
+ withScope(callback: (scope: SentryPolicyScope) => void): void;
12
+ };
13
+ export type SentryPolicyEvent = {
14
+ breadcrumbs?: unknown;
15
+ exception?: {
16
+ values?: Array<{
17
+ value?: string;
18
+ stacktrace?: {
19
+ frames?: Array<{
20
+ abs_path?: string;
21
+ filename?: string;
22
+ }>;
23
+ };
24
+ }>;
25
+ };
26
+ fingerprint?: string[];
27
+ logentry?: {
28
+ message?: string;
29
+ };
30
+ message?: string;
31
+ request?: unknown;
32
+ tags?: Record<string, unknown>;
33
+ type?: undefined;
34
+ user?: unknown;
35
+ };
36
+ export declare function captureWithSentryPolicy(sdk: SentryPolicySdk, serviceName: string, error: unknown, context: ApplicationErrorContext): string | undefined;
37
+ export declare function flushWithSentryPolicy(sdk: Pick<SentryPolicySdk, "flush">, timeoutMs?: number): Promise<boolean>;
38
+ export declare function applySentryScopePolicy(scope: SentryPolicyScope, serviceName: string, context: ApplicationErrorContext): void;
39
+ export declare function prepareSentryEvent<TEvent extends SentryPolicyEvent>(event: TEvent, serviceName: string): TEvent & SentryPolicyEvent;
40
+ export declare function redactSensitiveText(value: string): string;
41
+ export declare function sanitizeStackFramePath(value: string): string;
42
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE9E,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AASnD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjE,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,KAAK,CAAC;YACb,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,UAAU,CAAC,EAAE;gBACX,MAAM,CAAC,EAAE,KAAK,CAAC;oBACb,QAAQ,CAAC,EAAE,MAAM,CAAC;oBAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;iBACnB,CAAC,CAAC;aACJ,CAAC;SACH,CAAC,CAAC;KACJ,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,uBAAuB,GAC/B,MAAM,GAAG,SAAS,CAWpB;AAED,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EACnC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,uBAAuB,GAC/B,IAAI,CAaN;AAED,wBAAgB,kBAAkB,CAAC,MAAM,SAAS,iBAAiB,EACjE,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,iBAAiB,CAwB5B;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW5D"}
package/esm/policy.js ADDED
@@ -0,0 +1,89 @@
1
+ export const DEFAULT_FINGERPRINT = "{{ default }}";
2
+ const SENTRY_TOKEN_PATTERN = /\bsntrys_[A-Za-z0-9_+/=-]+\b/g;
3
+ const BEARER_TOKEN_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+\b/gi;
4
+ const JWT_PATTERN = /\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;
5
+ const URL_CREDENTIAL_PATTERN = /(https?:\/\/)[^@\s/]+(@[^/\s]+)/gi;
6
+ const SENSITIVE_QUERY_PATTERN = /([?&](?:access_token|api_key|auth|authorization|dsn|password|secret|token)=)[^&#\s]+/gi;
7
+ export function captureWithSentryPolicy(sdk, serviceName, error, context) {
8
+ try {
9
+ let eventId;
10
+ sdk.withScope((scope) => {
11
+ applySentryScopePolicy(scope, serviceName, context);
12
+ eventId = sdk.captureException(error);
13
+ });
14
+ return eventId;
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
19
+ }
20
+ export async function flushWithSentryPolicy(sdk, timeoutMs) {
21
+ try {
22
+ return await sdk.flush(timeoutMs);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ export function applySentryScopePolicy(scope, serviceName, context) {
29
+ scope.setFingerprint([serviceName, DEFAULT_FINGERPRINT]);
30
+ scope.setTag("service.name", serviceName);
31
+ scope.setTag("veryfront.boundary", context.boundary);
32
+ if (context.method)
33
+ scope.setTag("http.request.method", context.method);
34
+ if (context.requestId)
35
+ scope.setTag("veryfront.request_id", context.requestId);
36
+ if (context.traceId) {
37
+ scope.setTag("grafana.trace_id", context.traceId);
38
+ scope.setContext("grafana_trace", {
39
+ trace_id: context.traceId,
40
+ ...(context.spanId ? { span_id: context.spanId } : {}),
41
+ });
42
+ }
43
+ }
44
+ export function prepareSentryEvent(event, serviceName) {
45
+ event.tags = {
46
+ ...event.tags,
47
+ "service.name": serviceName,
48
+ };
49
+ event.fingerprint = [serviceName, ...(event.fingerprint ?? [DEFAULT_FINGERPRINT])];
50
+ delete event.breadcrumbs;
51
+ delete event.request;
52
+ delete event.user;
53
+ if (event.message)
54
+ event.message = redactSensitiveText(event.message);
55
+ if (event.logentry?.message) {
56
+ event.logentry.message = redactSensitiveText(event.logentry.message);
57
+ }
58
+ for (const value of event.exception?.values ?? []) {
59
+ if (value.value)
60
+ value.value = redactSensitiveText(value.value);
61
+ for (const frame of value.stacktrace?.frames ?? []) {
62
+ if (frame.filename)
63
+ frame.filename = sanitizeStackFramePath(frame.filename);
64
+ if (frame.abs_path)
65
+ frame.abs_path = sanitizeStackFramePath(frame.abs_path);
66
+ }
67
+ }
68
+ return event;
69
+ }
70
+ export function redactSensitiveText(value) {
71
+ return value
72
+ .replace(SENTRY_TOKEN_PATTERN, "[REDACTED]")
73
+ .replace(BEARER_TOKEN_PATTERN, "[REDACTED]")
74
+ .replace(JWT_PATTERN, "[REDACTED]")
75
+ .replace(URL_CREDENTIAL_PATTERN, "$1[REDACTED]$2")
76
+ .replace(SENSITIVE_QUERY_PATTERN, "$1[REDACTED]");
77
+ }
78
+ export function sanitizeStackFramePath(value) {
79
+ const redacted = redactSensitiveText(value);
80
+ const path = redacted.startsWith("file://") ? redacted.slice("file://".length) : redacted;
81
+ if (!path.startsWith("/") && !/^[A-Za-z]:[\\/]/.test(path))
82
+ return redacted;
83
+ const normalized = path.replaceAll("\\", "/");
84
+ const sourcePath = normalized.match(/(?:^|\/)((?:src|extensions|cli|dist)\/.+)$/)?.[1];
85
+ if (sourcePath)
86
+ return sourcePath;
87
+ const basename = normalized.split("/").filter(Boolean).at(-1);
88
+ return basename ? `[REDACTED]/${basename}` : "[REDACTED]";
89
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veryfront/ext-observability-sentry",
3
- "version": "0.1.1173",
3
+ "version": "0.1.1174",
4
4
  "description": "Veryfront first-party extension package for ext-observability-sentry",
5
5
  "keywords": [
6
6
  "veryfront",
@@ -23,6 +23,14 @@
23
23
  ".": {
24
24
  "import": "./esm/index.js",
25
25
  "types": "./esm/index.d.ts"
26
+ },
27
+ "./deno": {
28
+ "import": "./esm/deno.js",
29
+ "types": "./esm/deno.d.ts"
30
+ },
31
+ "./node": {
32
+ "import": "./esm/node.js",
33
+ "types": "./esm/node.d.ts"
26
34
  }
27
35
  },
28
36
  "scripts": {},
@@ -44,10 +52,11 @@
44
52
  ]
45
53
  },
46
54
  "dependencies": {
47
- "@sentry/deno": "10.68.0"
55
+ "@sentry/deno": "10.68.0",
56
+ "@sentry/node": "10.68.0"
48
57
  },
49
58
  "peerDependencies": {
50
- "veryfront": "^0.1.1173"
59
+ "veryfront": "^0.1.1174"
51
60
  },
52
61
  "type": "module",
53
62
  "types": "./esm/index.d.ts",