@vigilly/core 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/dist/dsn.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Vigilly DSN parsing.
3
+ *
4
+ * A Vigilly DSN is a standard Sentry-shaped DSN:
5
+ *
6
+ * https://<publicKey>@<host>/<projectId>
7
+ *
8
+ * e.g. `https://<publicKey>@vigilly.dev/<projectId>`. The host is the Vigilly
9
+ * Observe ingest host (`vigilly.dev` in prod, `staging.vigilly.dev` /
10
+ * `local.vigilly.dev` for other envs) and is used AS-IS. The public key
11
+ * identifies the service to Vigilly ingest; the projectId is the DSN path
12
+ * segment (present for Sentry-DSN-format compatibility, not used for auth).
13
+ *
14
+ * Vigilly's ingest route is `<host>/api/observe/<projectId>/envelope/`, which is
15
+ * NOT the path a stock Sentry DSN derives (`<host>/api/<projectId>/envelope/`).
16
+ * The wrapper bridges that gap with the SDK's `tunnel` option — see `options.ts`.
17
+ */
18
+ export interface VigillyDsnComponents {
19
+ /** DSN public key — identifies the service to Vigilly ingest (auth). */
20
+ publicKey: string;
21
+ /** URL protocol, e.g. `https`. */
22
+ protocol: string;
23
+ /** Ingest host, used as-is, e.g. `vigilly.dev`. */
24
+ host: string;
25
+ /** Project identifier from the DSN path; used in the ingest path. */
26
+ projectId: string;
27
+ }
28
+ export declare class InvalidVigillyDsnError extends Error {
29
+ constructor(dsn: string, reason: string);
30
+ }
31
+ /**
32
+ * Parse a Vigilly DSN into its components.
33
+ *
34
+ * @throws {InvalidVigillyDsnError} when the DSN is missing, malformed, or lacks a
35
+ * public key / host.
36
+ */
37
+ export declare function parseVigillyDsn(dsn: string): VigillyDsnComponents;
38
+ /**
39
+ * The Vigilly envelope ingest URL for a parsed DSN. Used as the Sentry SDK's
40
+ * `tunnel` so envelopes land on Vigilly's route shape rather than the path a
41
+ * stock Sentry DSN would derive.
42
+ */
43
+ export declare function envelopeTunnelUrl(c: VigillyDsnComponents): string;
44
+ /**
45
+ * A Sentry-valid DSN (`<protocol>://<publicKey>@<host>/0`) synthesised from a
46
+ * Vigilly DSN. The underlying Sentry SDK requires a (numeric) project id in the
47
+ * DSN path even when a `tunnel` overrides the transport URL; this DSN also seeds
48
+ * the `dsn` field of the envelope header that Vigilly ingest reads for the public
49
+ * key. The real Vigilly project id lives in the tunnel path, not here.
50
+ */
51
+ export declare function toSentryDsn(c: VigillyDsnComponents): string;
52
+ //# sourceMappingURL=dsn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsn.d.ts","sourceRoot":"","sources":["../src/dsn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIxC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAyCjE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAEjE;AAYD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAE3D"}
package/dist/dsn.js ADDED
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * Vigilly DSN parsing.
4
+ *
5
+ * A Vigilly DSN is a standard Sentry-shaped DSN:
6
+ *
7
+ * https://<publicKey>@<host>/<projectId>
8
+ *
9
+ * e.g. `https://<publicKey>@vigilly.dev/<projectId>`. The host is the Vigilly
10
+ * Observe ingest host (`vigilly.dev` in prod, `staging.vigilly.dev` /
11
+ * `local.vigilly.dev` for other envs) and is used AS-IS. The public key
12
+ * identifies the service to Vigilly ingest; the projectId is the DSN path
13
+ * segment (present for Sentry-DSN-format compatibility, not used for auth).
14
+ *
15
+ * Vigilly's ingest route is `<host>/api/observe/<projectId>/envelope/`, which is
16
+ * NOT the path a stock Sentry DSN derives (`<host>/api/<projectId>/envelope/`).
17
+ * The wrapper bridges that gap with the SDK's `tunnel` option — see `options.ts`.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.InvalidVigillyDsnError = void 0;
21
+ exports.parseVigillyDsn = parseVigillyDsn;
22
+ exports.envelopeTunnelUrl = envelopeTunnelUrl;
23
+ exports.toSentryDsn = toSentryDsn;
24
+ class InvalidVigillyDsnError extends Error {
25
+ constructor(dsn, reason) {
26
+ super(`Invalid Vigilly DSN "${dsn}": ${reason}`);
27
+ this.name = "InvalidVigillyDsnError";
28
+ }
29
+ }
30
+ exports.InvalidVigillyDsnError = InvalidVigillyDsnError;
31
+ /**
32
+ * Parse a Vigilly DSN into its components.
33
+ *
34
+ * @throws {InvalidVigillyDsnError} when the DSN is missing, malformed, or lacks a
35
+ * public key / host.
36
+ */
37
+ function parseVigillyDsn(dsn) {
38
+ if (!dsn || typeof dsn !== "string") {
39
+ throw new InvalidVigillyDsnError(String(dsn), "a non-empty DSN string is required");
40
+ }
41
+ let url;
42
+ try {
43
+ url = new URL(dsn);
44
+ }
45
+ catch {
46
+ throw new InvalidVigillyDsnError(dsn, "not a valid URL");
47
+ }
48
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
49
+ throw new InvalidVigillyDsnError(dsn, "protocol must be http or https");
50
+ }
51
+ const publicKey = url.username;
52
+ if (!publicKey) {
53
+ throw new InvalidVigillyDsnError(dsn, "missing public key (expected https://<publicKey>@<host>)");
54
+ }
55
+ if (url.password) {
56
+ throw new InvalidVigillyDsnError(dsn, "DSN must not contain a secret — only the public key");
57
+ }
58
+ const host = url.host; // used as-is; includes port if present
59
+ if (!host) {
60
+ throw new InvalidVigillyDsnError(dsn, "missing host");
61
+ }
62
+ const protocol = url.protocol.replace(":", "");
63
+ // Project id is the DSN path segment.
64
+ const projectId = url.pathname.split("/").filter(Boolean).pop() || "";
65
+ if (!projectId) {
66
+ throw new InvalidVigillyDsnError(dsn, "missing project id (expected https://<publicKey>@<host>/<projectId>)");
67
+ }
68
+ return { publicKey, protocol, host, projectId };
69
+ }
70
+ /**
71
+ * The Vigilly envelope ingest URL for a parsed DSN. Used as the Sentry SDK's
72
+ * `tunnel` so envelopes land on Vigilly's route shape rather than the path a
73
+ * stock Sentry DSN would derive.
74
+ */
75
+ function envelopeTunnelUrl(c) {
76
+ return `${c.protocol}://${c.host}/api/observe/${c.projectId}/envelope/`;
77
+ }
78
+ /**
79
+ * Placeholder project id used in the synthesised Sentry DSN. The Sentry SDK
80
+ * validates that a DSN's project id is purely numeric, while a Vigilly project
81
+ * id may be a non-numeric slug. The synthesised DSN's project id is irrelevant
82
+ * to Vigilly — the transport URL is overridden by the `tunnel` and ingest auth
83
+ * uses only the public key — so a constant numeric value is always safe. The
84
+ * real project id is carried in the tunnel path (see `envelopeTunnelUrl`).
85
+ */
86
+ const SENTRY_DSN_PROJECT_ID = "0";
87
+ /**
88
+ * A Sentry-valid DSN (`<protocol>://<publicKey>@<host>/0`) synthesised from a
89
+ * Vigilly DSN. The underlying Sentry SDK requires a (numeric) project id in the
90
+ * DSN path even when a `tunnel` overrides the transport URL; this DSN also seeds
91
+ * the `dsn` field of the envelope header that Vigilly ingest reads for the public
92
+ * key. The real Vigilly project id lives in the tunnel path, not here.
93
+ */
94
+ function toSentryDsn(c) {
95
+ return `${c.protocol}://${c.publicKey}@${c.host}/${SENTRY_DSN_PROJECT_ID}`;
96
+ }
97
+ //# sourceMappingURL=dsn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsn.js","sourceRoot":"","sources":["../src/dsn.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AA0BH,0CAyCC;AAOD,8CAEC;AAmBD,kCAEC;AApFD,MAAa,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,GAAW,EAAE,MAAc;QACrC,KAAK,CAAC,wBAAwB,GAAG,MAAM,MAAM,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AALD,wDAKC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,oCAAoC,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,sBAAsB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1D,MAAM,IAAI,sBAAsB,CAAC,GAAG,EAAE,gCAAgC,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,sBAAsB,CAAC,GAAG,EAAE,0DAA0D,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,IAAI,sBAAsB,CAAC,GAAG,EAAE,qDAAqD,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,uCAAuC;IAC9D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,sBAAsB,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAE/C,sCAAsC;IACtC,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACtE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,sBAAsB,CAC9B,GAAG,EACH,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,CAAuB;IACvD,OAAO,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,SAAS,YAAY,CAAC;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAElC;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,CAAuB;IACjD,OAAO,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,IAAI,qBAAqB,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { parseVigillyDsn, envelopeTunnelUrl, toSentryDsn, InvalidVigillyDsnError, } from "./dsn";
2
+ export type { VigillyDsnComponents } from "./dsn";
3
+ export { resolveVigillyOptions } from "./options";
4
+ export type { VigillyOptions, ResolvedVigillyOptions, VigillyBreadcrumb, VigillyEvent, VigillyEventHint, } from "./options";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,sBAAsB,GACvB,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,GACjB,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveVigillyOptions = exports.InvalidVigillyDsnError = exports.toSentryDsn = exports.envelopeTunnelUrl = exports.parseVigillyDsn = void 0;
4
+ var dsn_1 = require("./dsn");
5
+ Object.defineProperty(exports, "parseVigillyDsn", { enumerable: true, get: function () { return dsn_1.parseVigillyDsn; } });
6
+ Object.defineProperty(exports, "envelopeTunnelUrl", { enumerable: true, get: function () { return dsn_1.envelopeTunnelUrl; } });
7
+ Object.defineProperty(exports, "toSentryDsn", { enumerable: true, get: function () { return dsn_1.toSentryDsn; } });
8
+ Object.defineProperty(exports, "InvalidVigillyDsnError", { enumerable: true, get: function () { return dsn_1.InvalidVigillyDsnError; } });
9
+ var options_1 = require("./options");
10
+ Object.defineProperty(exports, "resolveVigillyOptions", { enumerable: true, get: function () { return options_1.resolveVigillyOptions; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,6BAKe;AAJb,sGAAA,eAAe,OAAA;AACf,wGAAA,iBAAiB,OAAA;AACjB,kGAAA,WAAW,OAAA;AACX,6GAAA,sBAAsB,OAAA;AAIxB,qCAAkD;AAAzC,gHAAA,qBAAqB,OAAA"}
@@ -0,0 +1,69 @@
1
+ /** Curated, transport-agnostic shape of a captured breadcrumb. */
2
+ export interface VigillyBreadcrumb {
3
+ type?: string;
4
+ level?: "fatal" | "error" | "warning" | "log" | "info" | "debug";
5
+ category?: string;
6
+ message?: string;
7
+ data?: Record<string, unknown>;
8
+ timestamp?: number;
9
+ }
10
+ /** Minimal event/hint typing — kept loose to stay SDK-version agnostic. */
11
+ export type VigillyEvent = Record<string, any>;
12
+ export type VigillyEventHint = Record<string, any>;
13
+ /**
14
+ * The options accepted by `Vigilly.init`. A curated subset of the Sentry init
15
+ * options plus the Vigilly DSN. Unsupported Sentry options (tracing, replay,
16
+ * integrations, …) are deliberately absent.
17
+ */
18
+ export interface VigillyOptions {
19
+ /** Vigilly DSN: `https://<publicKey>@<host>/<projectId>`, e.g. `https://<publicKey>@vigilly.dev/<projectId>`. */
20
+ dsn: string;
21
+ /** Release identifier (e.g. a version or git SHA). */
22
+ release?: string;
23
+ /** Deployment environment, e.g. `production`, `staging`. */
24
+ environment?: string;
25
+ /** Turn on SDK debug logging. */
26
+ debug?: boolean;
27
+ /** Master switch; when `false` the SDK is inert. Defaults to `true`. */
28
+ enabled?: boolean;
29
+ /** Error sampling rate in [0, 1]. Defaults to `1.0`. */
30
+ sampleRate?: number;
31
+ /** Max breadcrumbs retained per event. */
32
+ maxBreadcrumbs?: number;
33
+ /** Attach a synthetic stack trace to captured messages. */
34
+ attachStacktrace?: boolean;
35
+ /** Depth to which structured context is normalized. */
36
+ normalizeDepth?: number;
37
+ /** Patterns of error messages to drop before sending. */
38
+ ignoreErrors?: Array<string | RegExp>;
39
+ /** Server name reported with events (Node). */
40
+ serverName?: string;
41
+ /** Hook to mutate/drop an event before it is sent. Return `null` to drop. */
42
+ beforeSend?: (event: VigillyEvent, hint: VigillyEventHint) => VigillyEvent | null | PromiseLike<VigillyEvent | null>;
43
+ /** Hook to mutate/drop a breadcrumb before it is recorded. */
44
+ beforeBreadcrumb?: (breadcrumb: VigillyBreadcrumb, hint?: any) => VigillyBreadcrumb | null;
45
+ /** Initial scope (tags, user, extra, …) applied at init. */
46
+ initialScope?: Record<string, any> | ((scope: any) => any);
47
+ /**
48
+ * Advanced / testing escape hatch: a custom Sentry transport factory. Most
49
+ * users never set this — Vigilly presets the transport via `tunnel`.
50
+ */
51
+ transport?: (transportOptions: any) => any;
52
+ }
53
+ /**
54
+ * The resolved option object handed to `Sentry.init`. Includes the synthesised
55
+ * Sentry DSN and the `tunnel` pointing at Vigilly's `/api/observe/:projectId/`
56
+ * `envelope/` route. Typed loosely so each wrapper can cast to its SDK's exact
57
+ * option type.
58
+ */
59
+ export type ResolvedVigillyOptions = Record<string, unknown> & {
60
+ dsn: string;
61
+ tunnel: string;
62
+ };
63
+ /**
64
+ * Translate `VigillyOptions` into the option object for the underlying Sentry
65
+ * SDK: parse the Vigilly DSN, synthesise a Sentry-valid DSN, and preset
66
+ * `tunnel` to Vigilly's ingest URL. Only curated, defined fields are forwarded.
67
+ */
68
+ export declare function resolveVigillyOptions(options: VigillyOptions): ResolvedVigillyOptions;
69
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAYA,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC/C,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEnD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,iHAAiH;IACjH,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACtC,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,KAAK,YAAY,GAAG,IAAI,GAAG,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACrH,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,iBAAiB,GAAG,IAAI,CAAC;IAC3F,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;IAC3D;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,gBAAgB,EAAE,GAAG,KAAK,GAAG,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,sBAAsB,CAoCrF"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveVigillyOptions = resolveVigillyOptions;
4
+ /**
5
+ * Mapping from the curated `VigillyOptions` surface to the option object the
6
+ * underlying Sentry SDK consumes.
7
+ *
8
+ * The surface is intentionally small: it exposes the exception-reporting
9
+ * features Vigilly supports today and omits everything else (performance
10
+ * tracing, profiling, session replay, cron monitoring, custom integrations,
11
+ * …). Those are neither forwarded nor enabled, so a Vigilly client only ever
12
+ * sends error/message envelopes.
13
+ */
14
+ const dsn_1 = require("./dsn");
15
+ /**
16
+ * Translate `VigillyOptions` into the option object for the underlying Sentry
17
+ * SDK: parse the Vigilly DSN, synthesise a Sentry-valid DSN, and preset
18
+ * `tunnel` to Vigilly's ingest URL. Only curated, defined fields are forwarded.
19
+ */
20
+ function resolveVigillyOptions(options) {
21
+ const components = (0, dsn_1.parseVigillyDsn)(options.dsn);
22
+ const resolved = {
23
+ dsn: (0, dsn_1.toSentryDsn)(components),
24
+ tunnel: (0, dsn_1.envelopeTunnelUrl)(components),
25
+ // Vigilly handles exceptions only — never opt the SDK into tracing.
26
+ tracesSampleRate: 0,
27
+ sampleRate: options.sampleRate ?? 1.0,
28
+ };
29
+ // Forward only the curated options that were actually provided.
30
+ const passthrough = [
31
+ "release",
32
+ "environment",
33
+ "debug",
34
+ "enabled",
35
+ "maxBreadcrumbs",
36
+ "attachStacktrace",
37
+ "normalizeDepth",
38
+ "ignoreErrors",
39
+ "serverName",
40
+ "beforeSend",
41
+ "beforeBreadcrumb",
42
+ "initialScope",
43
+ "transport",
44
+ ];
45
+ const sink = resolved;
46
+ for (const key of passthrough) {
47
+ const value = options[key];
48
+ if (value !== undefined) {
49
+ sink[key] = value;
50
+ }
51
+ }
52
+ return resolved;
53
+ }
54
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";;AAmFA,sDAoCC;AAvHD;;;;;;;;;GASG;AACH,+BAAwE;AAoExE;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,OAAuB;IAC3D,MAAM,UAAU,GAAG,IAAA,qBAAe,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAA2B;QACvC,GAAG,EAAE,IAAA,iBAAW,EAAC,UAAU,CAAC;QAC5B,MAAM,EAAE,IAAA,uBAAiB,EAAC,UAAU,CAAC;QACrC,oEAAoE;QACpE,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,GAAG;KACtC,CAAC;IAEF,gEAAgE;IAChE,MAAM,WAAW,GAAgC;QAC/C,SAAS;QACT,aAAa;QACb,OAAO;QACP,SAAS;QACT,gBAAgB;QAChB,kBAAkB;QAClB,gBAAgB;QAChB,cAAc;QACd,YAAY;QACZ,YAAY;QACZ,kBAAkB;QAClB,cAAc;QACd,WAAW;KACZ,CAAC;IACF,MAAM,IAAI,GAAG,QAAmC,CAAC;IACjD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@vigilly/core",
3
+ "version": "0.1.0",
4
+ "description": "Shared internals for the Vigilly exceptions clients: DSN parsing and Sentry option mapping.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/vigilly/exceptions-js.git",
9
+ "directory": "packages/core"
10
+ },
11
+ "main": "dist/index.js",
12
+ "types": "dist/index.d.ts",
13
+ "files": ["dist", "src", "!**/*.test.*"],
14
+ "scripts": {
15
+ "build": "tsc -b"
16
+ }
17
+ }
package/src/dsn.ts ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Vigilly DSN parsing.
3
+ *
4
+ * A Vigilly DSN is a standard Sentry-shaped DSN:
5
+ *
6
+ * https://<publicKey>@<host>/<projectId>
7
+ *
8
+ * e.g. `https://<publicKey>@vigilly.dev/<projectId>`. The host is the Vigilly
9
+ * Observe ingest host (`vigilly.dev` in prod, `staging.vigilly.dev` /
10
+ * `local.vigilly.dev` for other envs) and is used AS-IS. The public key
11
+ * identifies the service to Vigilly ingest; the projectId is the DSN path
12
+ * segment (present for Sentry-DSN-format compatibility, not used for auth).
13
+ *
14
+ * Vigilly's ingest route is `<host>/api/observe/<projectId>/envelope/`, which is
15
+ * NOT the path a stock Sentry DSN derives (`<host>/api/<projectId>/envelope/`).
16
+ * The wrapper bridges that gap with the SDK's `tunnel` option — see `options.ts`.
17
+ */
18
+
19
+ export interface VigillyDsnComponents {
20
+ /** DSN public key — identifies the service to Vigilly ingest (auth). */
21
+ publicKey: string;
22
+ /** URL protocol, e.g. `https`. */
23
+ protocol: string;
24
+ /** Ingest host, used as-is, e.g. `vigilly.dev`. */
25
+ host: string;
26
+ /** Project identifier from the DSN path; used in the ingest path. */
27
+ projectId: string;
28
+ }
29
+
30
+ export class InvalidVigillyDsnError extends Error {
31
+ constructor(dsn: string, reason: string) {
32
+ super(`Invalid Vigilly DSN "${dsn}": ${reason}`);
33
+ this.name = "InvalidVigillyDsnError";
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Parse a Vigilly DSN into its components.
39
+ *
40
+ * @throws {InvalidVigillyDsnError} when the DSN is missing, malformed, or lacks a
41
+ * public key / host.
42
+ */
43
+ export function parseVigillyDsn(dsn: string): VigillyDsnComponents {
44
+ if (!dsn || typeof dsn !== "string") {
45
+ throw new InvalidVigillyDsnError(String(dsn), "a non-empty DSN string is required");
46
+ }
47
+
48
+ let url: URL;
49
+ try {
50
+ url = new URL(dsn);
51
+ } catch {
52
+ throw new InvalidVigillyDsnError(dsn, "not a valid URL");
53
+ }
54
+
55
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
56
+ throw new InvalidVigillyDsnError(dsn, "protocol must be http or https");
57
+ }
58
+
59
+ const publicKey = url.username;
60
+ if (!publicKey) {
61
+ throw new InvalidVigillyDsnError(dsn, "missing public key (expected https://<publicKey>@<host>)");
62
+ }
63
+ if (url.password) {
64
+ throw new InvalidVigillyDsnError(dsn, "DSN must not contain a secret — only the public key");
65
+ }
66
+
67
+ const host = url.host; // used as-is; includes port if present
68
+ if (!host) {
69
+ throw new InvalidVigillyDsnError(dsn, "missing host");
70
+ }
71
+
72
+ const protocol = url.protocol.replace(":", "");
73
+
74
+ // Project id is the DSN path segment.
75
+ const projectId = url.pathname.split("/").filter(Boolean).pop() || "";
76
+ if (!projectId) {
77
+ throw new InvalidVigillyDsnError(
78
+ dsn,
79
+ "missing project id (expected https://<publicKey>@<host>/<projectId>)",
80
+ );
81
+ }
82
+
83
+ return { publicKey, protocol, host, projectId };
84
+ }
85
+
86
+ /**
87
+ * The Vigilly envelope ingest URL for a parsed DSN. Used as the Sentry SDK's
88
+ * `tunnel` so envelopes land on Vigilly's route shape rather than the path a
89
+ * stock Sentry DSN would derive.
90
+ */
91
+ export function envelopeTunnelUrl(c: VigillyDsnComponents): string {
92
+ return `${c.protocol}://${c.host}/api/observe/${c.projectId}/envelope/`;
93
+ }
94
+
95
+ /**
96
+ * Placeholder project id used in the synthesised Sentry DSN. The Sentry SDK
97
+ * validates that a DSN's project id is purely numeric, while a Vigilly project
98
+ * id may be a non-numeric slug. The synthesised DSN's project id is irrelevant
99
+ * to Vigilly — the transport URL is overridden by the `tunnel` and ingest auth
100
+ * uses only the public key — so a constant numeric value is always safe. The
101
+ * real project id is carried in the tunnel path (see `envelopeTunnelUrl`).
102
+ */
103
+ const SENTRY_DSN_PROJECT_ID = "0";
104
+
105
+ /**
106
+ * A Sentry-valid DSN (`<protocol>://<publicKey>@<host>/0`) synthesised from a
107
+ * Vigilly DSN. The underlying Sentry SDK requires a (numeric) project id in the
108
+ * DSN path even when a `tunnel` overrides the transport URL; this DSN also seeds
109
+ * the `dsn` field of the envelope header that Vigilly ingest reads for the public
110
+ * key. The real Vigilly project id lives in the tunnel path, not here.
111
+ */
112
+ export function toSentryDsn(c: VigillyDsnComponents): string {
113
+ return `${c.protocol}://${c.publicKey}@${c.host}/${SENTRY_DSN_PROJECT_ID}`;
114
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ export {
2
+ parseVigillyDsn,
3
+ envelopeTunnelUrl,
4
+ toSentryDsn,
5
+ InvalidVigillyDsnError,
6
+ } from "./dsn";
7
+ export type { VigillyDsnComponents } from "./dsn";
8
+
9
+ export { resolveVigillyOptions } from "./options";
10
+ export type {
11
+ VigillyOptions,
12
+ ResolvedVigillyOptions,
13
+ VigillyBreadcrumb,
14
+ VigillyEvent,
15
+ VigillyEventHint,
16
+ } from "./options";
package/src/options.ts ADDED
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Mapping from the curated `VigillyOptions` surface to the option object the
3
+ * underlying Sentry SDK consumes.
4
+ *
5
+ * The surface is intentionally small: it exposes the exception-reporting
6
+ * features Vigilly supports today and omits everything else (performance
7
+ * tracing, profiling, session replay, cron monitoring, custom integrations,
8
+ * …). Those are neither forwarded nor enabled, so a Vigilly client only ever
9
+ * sends error/message envelopes.
10
+ */
11
+ import { envelopeTunnelUrl, parseVigillyDsn, toSentryDsn } from "./dsn";
12
+
13
+ /** Curated, transport-agnostic shape of a captured breadcrumb. */
14
+ export interface VigillyBreadcrumb {
15
+ type?: string;
16
+ level?: "fatal" | "error" | "warning" | "log" | "info" | "debug";
17
+ category?: string;
18
+ message?: string;
19
+ data?: Record<string, unknown>;
20
+ timestamp?: number;
21
+ }
22
+
23
+ /** Minimal event/hint typing — kept loose to stay SDK-version agnostic. */
24
+ export type VigillyEvent = Record<string, any>;
25
+ export type VigillyEventHint = Record<string, any>;
26
+
27
+ /**
28
+ * The options accepted by `Vigilly.init`. A curated subset of the Sentry init
29
+ * options plus the Vigilly DSN. Unsupported Sentry options (tracing, replay,
30
+ * integrations, …) are deliberately absent.
31
+ */
32
+ export interface VigillyOptions {
33
+ /** Vigilly DSN: `https://<publicKey>@<host>/<projectId>`, e.g. `https://<publicKey>@vigilly.dev/<projectId>`. */
34
+ dsn: string;
35
+ /** Release identifier (e.g. a version or git SHA). */
36
+ release?: string;
37
+ /** Deployment environment, e.g. `production`, `staging`. */
38
+ environment?: string;
39
+ /** Turn on SDK debug logging. */
40
+ debug?: boolean;
41
+ /** Master switch; when `false` the SDK is inert. Defaults to `true`. */
42
+ enabled?: boolean;
43
+ /** Error sampling rate in [0, 1]. Defaults to `1.0`. */
44
+ sampleRate?: number;
45
+ /** Max breadcrumbs retained per event. */
46
+ maxBreadcrumbs?: number;
47
+ /** Attach a synthetic stack trace to captured messages. */
48
+ attachStacktrace?: boolean;
49
+ /** Depth to which structured context is normalized. */
50
+ normalizeDepth?: number;
51
+ /** Patterns of error messages to drop before sending. */
52
+ ignoreErrors?: Array<string | RegExp>;
53
+ /** Server name reported with events (Node). */
54
+ serverName?: string;
55
+ /** Hook to mutate/drop an event before it is sent. Return `null` to drop. */
56
+ beforeSend?: (event: VigillyEvent, hint: VigillyEventHint) => VigillyEvent | null | PromiseLike<VigillyEvent | null>;
57
+ /** Hook to mutate/drop a breadcrumb before it is recorded. */
58
+ beforeBreadcrumb?: (breadcrumb: VigillyBreadcrumb, hint?: any) => VigillyBreadcrumb | null;
59
+ /** Initial scope (tags, user, extra, …) applied at init. */
60
+ initialScope?: Record<string, any> | ((scope: any) => any);
61
+ /**
62
+ * Advanced / testing escape hatch: a custom Sentry transport factory. Most
63
+ * users never set this — Vigilly presets the transport via `tunnel`.
64
+ */
65
+ transport?: (transportOptions: any) => any;
66
+ }
67
+
68
+ /**
69
+ * The resolved option object handed to `Sentry.init`. Includes the synthesised
70
+ * Sentry DSN and the `tunnel` pointing at Vigilly's `/api/observe/:projectId/`
71
+ * `envelope/` route. Typed loosely so each wrapper can cast to its SDK's exact
72
+ * option type.
73
+ */
74
+ export type ResolvedVigillyOptions = Record<string, unknown> & {
75
+ dsn: string;
76
+ tunnel: string;
77
+ };
78
+
79
+ /**
80
+ * Translate `VigillyOptions` into the option object for the underlying Sentry
81
+ * SDK: parse the Vigilly DSN, synthesise a Sentry-valid DSN, and preset
82
+ * `tunnel` to Vigilly's ingest URL. Only curated, defined fields are forwarded.
83
+ */
84
+ export function resolveVigillyOptions(options: VigillyOptions): ResolvedVigillyOptions {
85
+ const components = parseVigillyDsn(options.dsn);
86
+
87
+ const resolved: ResolvedVigillyOptions = {
88
+ dsn: toSentryDsn(components),
89
+ tunnel: envelopeTunnelUrl(components),
90
+ // Vigilly handles exceptions only — never opt the SDK into tracing.
91
+ tracesSampleRate: 0,
92
+ sampleRate: options.sampleRate ?? 1.0,
93
+ };
94
+
95
+ // Forward only the curated options that were actually provided.
96
+ const passthrough: Array<keyof VigillyOptions> = [
97
+ "release",
98
+ "environment",
99
+ "debug",
100
+ "enabled",
101
+ "maxBreadcrumbs",
102
+ "attachStacktrace",
103
+ "normalizeDepth",
104
+ "ignoreErrors",
105
+ "serverName",
106
+ "beforeSend",
107
+ "beforeBreadcrumb",
108
+ "initialScope",
109
+ "transport",
110
+ ];
111
+ const sink = resolved as Record<string, unknown>;
112
+ for (const key of passthrough) {
113
+ const value = options[key];
114
+ if (value !== undefined) {
115
+ sink[key] = value;
116
+ }
117
+ }
118
+
119
+ return resolved;
120
+ }