@interfere/nest 0.0.1-canary.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 ADDED
@@ -0,0 +1,30 @@
1
+ # @interfere/nest
2
+
3
+ > **Status: canary.** Pre-1.0 API, expect breaking changes. Pin to a specific `10.0.0-canary.N` in CI.
4
+
5
+ NestJS SDK for [Interfere](https://interfere.com). Wraps [`@interfere/node`](../node) with a global exception filter and OTel auto-instrumentation for controllers, guards, pipes, interceptors, and middleware.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ bun add @interfere/nest
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ // instrument.ts — imported first in main.ts, before any @nestjs/* import
17
+ import { init } from "@interfere/nest";
18
+ await init({ serviceName: "my-api" });
19
+ ```
20
+
21
+ ```ts
22
+ // app.module.ts
23
+ import { Module } from "@nestjs/common";
24
+ import { InterfereModule } from "@interfere/nest";
25
+
26
+ @Module({ imports: [InterfereModule.forRoot()] })
27
+ export class AppModule {}
28
+ ```
29
+
30
+ Set `INTERFERE_API_KEY` in the environment. Full docs at <https://interfere.com/docs>.
@@ -0,0 +1,9 @@
1
+ //#region \0@oxc-project+runtime@0.129.0/helpers/decorate.js
2
+ function __decorate(decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ }
8
+ //#endregion
9
+ export { __decorate };
@@ -0,0 +1,6 @@
1
+ //#region \0@oxc-project+runtime@0.129.0/helpers/decorateMetadata.js
2
+ function __decorateMetadata(k, v) {
3
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4
+ }
5
+ //#endregion
6
+ export { __decorateMetadata };
@@ -0,0 +1,8 @@
1
+ //#region \0@oxc-project+runtime@0.129.0/helpers/decorateParam.js
2
+ function __decorateParam(paramIndex, decorator) {
3
+ return function(target, key) {
4
+ decorator(target, key, paramIndex);
5
+ };
6
+ }
7
+ //#endregion
8
+ export { __decorateParam };
@@ -0,0 +1,18 @@
1
+ import { ArgumentsHost, ExceptionFilter } from "@nestjs/common";
2
+ import { BaseExceptionFilter, HttpAdapterHost } from "@nestjs/core";
3
+
4
+ //#region src/exception-filter.d.ts
5
+ /**
6
+ * Forwards uncaught exceptions to Interfere, then delegates to Nest's
7
+ * default response shaping. Skips `HttpException` with status 4xx —
8
+ * client-fault errors are framework-handled and shouldn't bill against
9
+ * crash dashboards.
10
+ */
11
+ declare class InterfereExceptionFilter extends BaseExceptionFilter implements ExceptionFilter {
12
+ constructor(adapterHost?: HttpAdapterHost);
13
+ catch(exception: unknown, host: ArgumentsHost): void;
14
+ private shouldReport;
15
+ private extractRequest;
16
+ }
17
+ //#endregion
18
+ export { InterfereExceptionFilter };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception-filter.d.mts","names":[],"sources":["../src/exception-filter.ts"],"mappings":";;;;;;AAkBA;;;;cACa,wBAAA,SACH,mBAAA,YACG,eAAA;cAG4B,WAAA,GAAc,eAAA;EAK5C,KAAA,CAAM,SAAA,WAAoB,IAAA,EAAM,aAAA;EAAA,QAOjC,YAAA;EAAA,QAOA,cAAA;AAAA"}
@@ -0,0 +1,33 @@
1
+ import { __decorateMetadata } from "./_virtual/_@oxc-project_runtime@0.129.0/helpers/decorateMetadata.mjs";
2
+ import { __decorateParam } from "./_virtual/_@oxc-project_runtime@0.129.0/helpers/decorateParam.mjs";
3
+ import { __decorate } from "./_virtual/_@oxc-project_runtime@0.129.0/helpers/decorate.mjs";
4
+ import { captureError } from "@interfere/node";
5
+ import { Catch, HttpException, Inject, Optional } from "@nestjs/common";
6
+ import { BaseExceptionFilter, HttpAdapterHost } from "@nestjs/core";
7
+ //#region src/exception-filter.ts
8
+ var _ref;
9
+ let InterfereExceptionFilter = class InterfereExceptionFilter extends BaseExceptionFilter {
10
+ constructor(adapterHost) {
11
+ super(adapterHost?.httpAdapter);
12
+ }
13
+ catch(exception, host) {
14
+ if (this.shouldReport(exception)) captureError(exception, this.extractRequest(host));
15
+ super.catch(exception, host);
16
+ }
17
+ shouldReport(exception) {
18
+ if (exception instanceof HttpException) return exception.getStatus() >= 500;
19
+ return true;
20
+ }
21
+ extractRequest(host) {
22
+ if (host.getType() !== "http") return;
23
+ return host.switchToHttp().getRequest();
24
+ }
25
+ };
26
+ InterfereExceptionFilter = __decorate([
27
+ Catch(),
28
+ __decorateParam(0, Optional()),
29
+ __decorateParam(0, Inject(HttpAdapterHost)),
30
+ __decorateMetadata("design:paramtypes", [typeof (_ref = typeof HttpAdapterHost !== "undefined" && HttpAdapterHost) === "function" ? _ref : Object])
31
+ ], InterfereExceptionFilter);
32
+ //#endregion
33
+ export { InterfereExceptionFilter };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception-filter.mjs","names":[],"sources":["../src/exception-filter.ts"],"sourcesContent":["import { captureError } from \"@interfere/node\";\n\nimport {\n type ArgumentsHost,\n Catch,\n type ExceptionFilter,\n HttpException,\n Inject,\n Optional,\n} from \"@nestjs/common\";\nimport { BaseExceptionFilter, HttpAdapterHost } from \"@nestjs/core\";\n\n/**\n * Forwards uncaught exceptions to Interfere, then delegates to Nest's\n * default response shaping. Skips `HttpException` with status 4xx —\n * client-fault errors are framework-handled and shouldn't bill against\n * crash dashboards.\n */\n@Catch()\nexport class InterfereExceptionFilter\n extends BaseExceptionFilter\n implements ExceptionFilter\n{\n constructor(\n @Optional() @Inject(HttpAdapterHost) adapterHost?: HttpAdapterHost\n ) {\n super(adapterHost?.httpAdapter);\n }\n\n override catch(exception: unknown, host: ArgumentsHost): void {\n if (this.shouldReport(exception)) {\n captureError(exception, this.extractRequest(host));\n }\n super.catch(exception, host);\n }\n\n private shouldReport(exception: unknown): boolean {\n if (exception instanceof HttpException) {\n return exception.getStatus() >= 500;\n }\n return true;\n }\n\n private extractRequest(host: ArgumentsHost): unknown {\n if (host.getType() !== \"http\") {\n return;\n }\n return host.switchToHttp().getRequest();\n }\n}\n"],"mappings":";;;;;;;;AAmBO,IAAA,2BAAA,MAAM,iCACH,oBAEV;CACE,YACE,aACA;EACA,MAAM,aAAa,YAAY;;CAGjC,MAAe,WAAoB,MAA2B;EAC5D,IAAI,KAAK,aAAa,UAAU,EAC9B,aAAa,WAAW,KAAK,eAAe,KAAK,CAAC;EAEpD,MAAM,MAAM,WAAW,KAAK;;CAG9B,aAAqB,WAA6B;EAChD,IAAI,qBAAqB,eACvB,OAAO,UAAU,WAAW,IAAI;EAElC,OAAO;;CAGT,eAAuB,MAA8B;EACnD,IAAI,KAAK,SAAS,KAAK,QACrB;EAEF,OAAO,KAAK,cAAc,CAAC,YAAY;;;;CA7B1C,OAAO;oBAMH,UAAU,CAAA;oBAAE,OAAO,gBAAgB,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { InterfereExceptionFilter } from "./exception-filter.mjs";
2
+ import { InitOptions, init } from "./init.mjs";
3
+ import { InterfereModule } from "./module.mjs";
4
+ import { CaptureErrorContext, captureError, captureMessage, close, flush, withSpan } from "@interfere/node";
5
+ export { type CaptureErrorContext, type InitOptions, InterfereExceptionFilter, InterfereModule, captureError, captureMessage, close, flush, init, withSpan };
package/dist/index.mjs ADDED
@@ -0,0 +1,5 @@
1
+ import { InterfereExceptionFilter } from "./exception-filter.mjs";
2
+ import { init } from "./init.mjs";
3
+ import { InterfereModule } from "./module.mjs";
4
+ import { captureError, captureMessage, close, flush, withSpan } from "@interfere/node";
5
+ export { InterfereExceptionFilter, InterfereModule, captureError, captureMessage, close, flush, init, withSpan };
@@ -0,0 +1,13 @@
1
+ import { InitOptions, InitOptions as InitOptions$1 } from "@interfere/node";
2
+
3
+ //#region src/init.d.ts
4
+ /**
5
+ * Bootstraps `@interfere/node` and registers
6
+ * `@opentelemetry/instrumentation-nestjs-core` for auto-spans across
7
+ * controllers, guards, pipes, interceptors, and middleware. Must run
8
+ * before `@nestjs/core` is imported — see the README for the
9
+ * `instrument.ts` pattern.
10
+ */
11
+ declare function init(options?: InitOptions$1): Promise<void>;
12
+ //#endregion
13
+ export { type InitOptions, init };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.mts","names":[],"sources":["../src/init.ts"],"mappings":";;;;;AAcA;;;;;iBAAsB,IAAA,CAAK,OAAA,GAAS,aAAA,GAAmB,OAAA"}
package/dist/init.mjs ADDED
@@ -0,0 +1,21 @@
1
+ import { init as init$1 } from "@interfere/node";
2
+ import { registerInstrumentations } from "@opentelemetry/instrumentation";
3
+ import { NestInstrumentation } from "@opentelemetry/instrumentation-nestjs-core";
4
+ //#region src/init.ts
5
+ let instrumented = false;
6
+ /**
7
+ * Bootstraps `@interfere/node` and registers
8
+ * `@opentelemetry/instrumentation-nestjs-core` for auto-spans across
9
+ * controllers, guards, pipes, interceptors, and middleware. Must run
10
+ * before `@nestjs/core` is imported — see the README for the
11
+ * `instrument.ts` pattern.
12
+ */
13
+ async function init(options = {}) {
14
+ if (!instrumented) {
15
+ registerInstrumentations({ instrumentations: [new NestInstrumentation()] });
16
+ instrumented = true;
17
+ }
18
+ await init$1(options);
19
+ }
20
+ //#endregion
21
+ export { init };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.mjs","names":["nodeInit"],"sources":["../src/init.ts"],"sourcesContent":["import { type InitOptions, init as nodeInit } from \"@interfere/node\";\n\nimport { registerInstrumentations } from \"@opentelemetry/instrumentation\";\nimport { NestInstrumentation } from \"@opentelemetry/instrumentation-nestjs-core\";\n\nlet instrumented = false;\n\n/**\n * Bootstraps `@interfere/node` and registers\n * `@opentelemetry/instrumentation-nestjs-core` for auto-spans across\n * controllers, guards, pipes, interceptors, and middleware. Must run\n * before `@nestjs/core` is imported — see the README for the\n * `instrument.ts` pattern.\n */\nexport async function init(options: InitOptions = {}): Promise<void> {\n if (!instrumented) {\n registerInstrumentations({\n instrumentations: [new NestInstrumentation()],\n });\n instrumented = true;\n }\n await nodeInit(options);\n}\n\nexport type { InitOptions } from \"@interfere/node\";\n"],"mappings":";;;;AAKA,IAAI,eAAe;;;;;;;;AASnB,eAAsB,KAAK,UAAuB,EAAE,EAAiB;CACnE,IAAI,CAAC,cAAc;EACjB,yBAAyB,EACvB,kBAAkB,CAAC,IAAI,qBAAqB,CAAC,EAC9C,CAAC;EACF,eAAe;;CAEjB,MAAMA,OAAS,QAAQ"}
@@ -0,0 +1,13 @@
1
+ import { DynamicModule } from "@nestjs/common";
2
+
3
+ //#region src/module.d.ts
4
+ /**
5
+ * Registers `InterfereExceptionFilter` as a global filter via
6
+ * `APP_FILTER`. Import once at the app root: `imports:
7
+ * [InterfereModule.forRoot()]`.
8
+ */
9
+ declare class InterfereModule {
10
+ static forRoot(): DynamicModule;
11
+ }
12
+ //#endregion
13
+ export { InterfereModule };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.mts","names":[],"sources":["../src/module.ts"],"mappings":";;;;;AAUA;;;cACa,eAAA;EAAA,OACJ,OAAA,CAAA,GAAW,aAAA;AAAA"}
@@ -0,0 +1,20 @@
1
+ import { __decorate } from "./_virtual/_@oxc-project_runtime@0.129.0/helpers/decorate.mjs";
2
+ import { InterfereExceptionFilter } from "./exception-filter.mjs";
3
+ import { Module } from "@nestjs/common";
4
+ import { APP_FILTER } from "@nestjs/core";
5
+ //#region src/module.ts
6
+ var _InterfereModule;
7
+ let InterfereModule = _InterfereModule = class InterfereModule {
8
+ static forRoot() {
9
+ return {
10
+ module: _InterfereModule,
11
+ providers: [{
12
+ provide: APP_FILTER,
13
+ useClass: InterfereExceptionFilter
14
+ }]
15
+ };
16
+ }
17
+ };
18
+ InterfereModule = _InterfereModule = __decorate([Module({})], InterfereModule);
19
+ //#endregion
20
+ export { InterfereModule };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.mjs","names":[],"sources":["../src/module.ts"],"sourcesContent":["import { type DynamicModule, Module } from \"@nestjs/common\";\nimport { APP_FILTER } from \"@nestjs/core\";\n\nimport { InterfereExceptionFilter } from \"./exception-filter.js\";\n\n/**\n * Registers `InterfereExceptionFilter` as a global filter via\n * `APP_FILTER`. Import once at the app root: `imports:\n * [InterfereModule.forRoot()]`.\n */\n@Module({})\nexport class InterfereModule {\n static forRoot(): DynamicModule {\n return {\n module: InterfereModule,\n providers: [\n {\n provide: APP_FILTER,\n useClass: InterfereExceptionFilter,\n },\n ],\n };\n }\n}\n"],"mappings":";;;;;;AAWO,IAAA,kBAAA,mBAAA,MAAM,gBAAgB;CAC3B,OAAO,UAAyB;EAC9B,OAAO;GACL,QAAA;GACA,WAAW,CACT;IACE,SAAS;IACT,UAAU;IACX,CACF;GACF;;;iDAXJ,OAAO,EAAE,CAAC,CAAA,EAAA,gBAAA"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@interfere/nest",
3
+ "version": "0.0.1-canary.0",
4
+ "license": "MIT",
5
+ "description": "NestJS SDK for Interfere. Auto-captures uncaught exceptions from controllers, providers, and middleware via a global ExceptionFilter, plus re-exports the @interfere/node OTel instrumentation.",
6
+ "keywords": [
7
+ "observability",
8
+ "typescript",
9
+ "nestjs",
10
+ "nest",
11
+ "error-tracking",
12
+ "opentelemetry"
13
+ ],
14
+ "homepage": "https://interfere.com",
15
+ "bugs": {
16
+ "url": "mailto:support@interfere.com"
17
+ },
18
+ "author": "Interfere <support@interfere.com> (https://interfere.com)",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/interfere-inc/interfere.git",
22
+ "directory": "src/packages/public/nest"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "type": "module",
28
+ "exports": {
29
+ ".": {
30
+ "@source": "./src/index.ts",
31
+ "types": "./dist/index.d.mts",
32
+ "default": "./dist/index.mjs"
33
+ }
34
+ },
35
+ "sideEffects": false,
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "tag": "canary"
39
+ },
40
+ "scripts": {
41
+ "build": "tsdown",
42
+ "test": "vitest run --passWithNoTests",
43
+ "typecheck": "tsc --noEmit --incremental"
44
+ },
45
+ "dependencies": {
46
+ "@interfere/node": "^0.0.1-canary.0",
47
+ "@opentelemetry/instrumentation": "^0.217.0",
48
+ "@opentelemetry/instrumentation-nestjs-core": "^0.63.0"
49
+ },
50
+ "peerDependencies": {
51
+ "@nestjs/common": "^10 || ^11",
52
+ "@nestjs/core": "^10 || ^11"
53
+ },
54
+ "devDependencies": {
55
+ "@interfere/test-utils": "^9.0.0",
56
+ "@interfere/typescript-config": "^9.0.0",
57
+ "@nestjs/common": "^11",
58
+ "@nestjs/core": "^11",
59
+ "@types/node": "^24.12.0",
60
+ "@vitest/coverage-v8": "^4.1.6",
61
+ "reflect-metadata": "^0.2",
62
+ "tsdown": "^0.22.0",
63
+ "typescript": "^6.0.3",
64
+ "vitest": "^4.1.6"
65
+ }
66
+ }