@interfere/elysia 0.1.0-canary.1

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,92 @@
1
+ # @interfere/elysia
2
+
3
+ Elysia plugin for [Interfere](https://interfere.com). Creates a span for every request and reports server-fault errors (5xx and uncaught throws) with request context.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ bun add @interfere/elysia
9
+ # or
10
+ npm install @interfere/elysia
11
+ # or
12
+ pnpm add @interfere/elysia
13
+ ```
14
+
15
+ `elysia` and `@elysia/opentelemetry` are peer dependencies:
16
+
17
+ ```sh
18
+ bun add elysia @elysia/opentelemetry
19
+ ```
20
+
21
+ ## Setup
22
+
23
+ Register the plugin once at the root of your app:
24
+
25
+ ```ts
26
+ import { Elysia } from "elysia";
27
+ import { interfere } from "@interfere/elysia";
28
+
29
+ new Elysia()
30
+ .use(interfere({ serviceName: "checkout-api" }))
31
+ .get("/", () => "ok")
32
+ .listen(3000);
33
+ ```
34
+
35
+ That's it. The plugin exports per-request spans to Interfere, reports 5xx and uncaught errors with request context, and installs process-level handlers for uncaught exceptions and unhandled rejections. Client faults (validation, not-found) still produce spans but are not reported as errors.
36
+
37
+ When `INTERFERE_PUBLIC_KEY` is unset the plugin is inert, so local runs without the SDK configured don't crash.
38
+
39
+ ## Manual instrumentation
40
+
41
+ ```ts
42
+ import { record, captureError, withSpan } from "@interfere/elysia";
43
+
44
+ app.get("/users", () =>
45
+ record("db.query", () => db.query("SELECT * FROM users"))
46
+ );
47
+ ```
48
+
49
+ - `record(name, fn)` — wrap work in a child span that auto-closes and captures exceptions.
50
+ - `withSpan(name, fn)` — same, framework-agnostic.
51
+ - `captureError(error, request?)` / `captureMessage(message, request?)` — report an error from anywhere.
52
+ - `getCurrentSpan()` / `setAttributes(attrs)` — annotate the active span.
53
+
54
+ ## Build & Deploy
55
+
56
+ Install [`@interfere/cli`](../cli) as a dev dependency and add a `postbuild` script so source maps are uploaded and the release is registered. Without this step, the collector rejects spans from production deployments.
57
+
58
+ ```json
59
+ {
60
+ "scripts": {
61
+ "build": "tsc",
62
+ "postbuild": "interfere sourcemaps upload ./dist"
63
+ }
64
+ }
65
+ ```
66
+
67
+ The CLI derives the release slug from the same commit SHA the SDK uses at runtime (`INTERFERE_SOURCE_ID`, `GITHUB_SHA`, `VERCEL_GIT_COMMIT_SHA`, or `git rev-parse HEAD`). Both must see the same SHA for the slugs to match.
68
+
69
+ ## Environment Variables
70
+
71
+ | Variable | Where | Purpose |
72
+ |---|---|---|
73
+ | `INTERFERE_PUBLIC_KEY` | Runtime | Routes spans to your surface (`interfere_pub_us_*` or `interfere_pub_eu_*`) |
74
+ | `INTERFERE_API_KEY` | CI / Build | Authenticates source map uploads and release registration (`interfere_secret_us_*` or `interfere_secret_eu_*`) |
75
+ | `INTERFERE_SOURCE_ID` | Both | Override the commit SHA used to derive the release slug. |
76
+ | `INTERFERE_DEBUG` | Runtime | Set to `1` to log lifecycle events and exporter results. Equivalent to `debug: true`. |
77
+
78
+ ## Options
79
+
80
+ | Option | Default | Purpose |
81
+ |---|---|---|
82
+ | `serviceName` | `OTEL_SERVICE_NAME` ?? `"elysia-app"` | The identity spans are grouped by. |
83
+ | `serviceNamespace` | — | Groups several services under one product surface. |
84
+ | `environment` | `INTERFERE_ENVIRONMENT` ?? `VERCEL_ENV` ?? `NODE_ENV` ?? `development` | Deployment environment label. |
85
+ | `captureUncaughtException` | `true` | Report and exit on `uncaughtException`. |
86
+ | `captureUnhandledRejection` | `true` | Report on `unhandledRejection`. |
87
+ | `debug` | `false` | Log lifecycle and exporter results to stdout. |
88
+
89
+ ## Compatibility
90
+
91
+ - Elysia 1.4+
92
+ - Bun and Node.js
package/dist/cors.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const require_trace_headers=require("./trace-headers.cjs");let _elysia_cors=require("@elysia/cors");function interfereCors(config={}){let{allowedHeaders}=config;return typeof allowedHeaders==`string`||Array.isArray(allowedHeaders)?(0,_elysia_cors.cors)({...config,allowedHeaders:withTraceHeaders(allowedHeaders)}):(0,_elysia_cors.cors)(config)}function withTraceHeaders(allowedHeaders){let existing=Array.isArray(allowedHeaders)?allowedHeaders:allowedHeaders.split(`,`).map(header=>header.trim()).filter(Boolean),seen=new Set(existing.map(header=>header.toLowerCase()));return[...existing,...require_trace_headers.INTERFERE_TRACE_HEADERS.filter(header=>!seen.has(header))]}exports.interfereCors=interfereCors;
@@ -0,0 +1,23 @@
1
+ import { CORSConfig, cors } from "@elysia/cors";
2
+
3
+ //#region src/cors.d.ts
4
+ /**
5
+ * Drop-in for `@elysia/cors`'s `cors()` that also permits the W3C
6
+ * `traceparent` / `tracestate` / `baggage` request headers, so a
7
+ * different-origin frontend's traces link to this server. Pass your normal
8
+ * CORS options — origins, methods, credentials — exactly as you would to
9
+ * `cors()`.
10
+ *
11
+ * ```ts
12
+ * import { interfereCors } from "@interfere/elysia/cors";
13
+ *
14
+ * new Elysia().use(interfereCors({ origin: "https://app.example.com" }));
15
+ * ```
16
+ *
17
+ * Only an *explicit* `allowedHeaders` allowlist (string or array) is extended;
18
+ * the permissive default (`true`) already reflects the trace headers, so it's
19
+ * passed through untouched — this never tightens your CORS policy.
20
+ */
21
+ declare function interfereCors(config?: CORSConfig): ReturnType<typeof cors>;
22
+ //#endregion
23
+ export { interfereCors };
@@ -0,0 +1,23 @@
1
+ import { CORSConfig, cors } from "@elysia/cors";
2
+
3
+ //#region src/cors.d.ts
4
+ /**
5
+ * Drop-in for `@elysia/cors`'s `cors()` that also permits the W3C
6
+ * `traceparent` / `tracestate` / `baggage` request headers, so a
7
+ * different-origin frontend's traces link to this server. Pass your normal
8
+ * CORS options — origins, methods, credentials — exactly as you would to
9
+ * `cors()`.
10
+ *
11
+ * ```ts
12
+ * import { interfereCors } from "@interfere/elysia/cors";
13
+ *
14
+ * new Elysia().use(interfereCors({ origin: "https://app.example.com" }));
15
+ * ```
16
+ *
17
+ * Only an *explicit* `allowedHeaders` allowlist (string or array) is extended;
18
+ * the permissive default (`true`) already reflects the trace headers, so it's
19
+ * passed through untouched — this never tightens your CORS policy.
20
+ */
21
+ declare function interfereCors(config?: CORSConfig): ReturnType<typeof cors>;
22
+ //#endregion
23
+ export { interfereCors };
package/dist/cors.mjs ADDED
@@ -0,0 +1 @@
1
+ import{INTERFERE_TRACE_HEADERS}from"./trace-headers.mjs";import{cors}from"@elysia/cors";function interfereCors(config={}){let{allowedHeaders}=config;return cors(typeof allowedHeaders==`string`||Array.isArray(allowedHeaders)?{...config,allowedHeaders:withTraceHeaders(allowedHeaders)}:config)}function withTraceHeaders(allowedHeaders){let existing=Array.isArray(allowedHeaders)?allowedHeaders:allowedHeaders.split(`,`).map(header=>header.trim()).filter(Boolean),seen=new Set(existing.map(header=>header.toLowerCase()));return[...existing,...INTERFERE_TRACE_HEADERS.filter(header=>!seen.has(header))]}export{interfereCors};
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const require_trace_headers=require("./trace-headers.cjs"),require_internal_server_fault=require("./internal/server-fault.cjs"),require_version=require("./version.cjs");let _interfere_node=require("@interfere/node"),_interfere_node_otel_config=require("@interfere/node/otel-config"),_elysia_opentelemetry=require("@elysia/opentelemetry"),_opentelemetry_api=require("@opentelemetry/api"),elysia=require("elysia");const PLUGIN_NAME=`@interfere/elysia`;function interfere(options={}){let debug=options.debug??process.env.INTERFERE_DEBUG===`1`,serviceName=options.serviceName??process.env.OTEL_SERVICE_NAME??`elysia-app`,config=(0,_interfere_node_otel_config.resolveOtelConfig)({serviceName,serviceNamespace:options.serviceNamespace,environment:options.environment,sdkName:PLUGIN_NAME,producerVersion:require_version.PRODUCER_VERSION,debug});if(!config)return console.warn(`[interfere] INTERFERE_PUBLIC_KEY not set; SDK disabled`),new elysia.Elysia({name:PLUGIN_NAME});config.releaseSlug||console.warn(`[interfere] No release slug resolved — the collector will reject spans. Add a postbuild script to your package.json:
2
+ "postbuild": "interfere sourcemaps upload ./dist"
3
+ and set INTERFERE_API_KEY in your CI environment. See https://interfere.com/docs/elysia#releases`);let flush=async()=>{await Promise.all(config.spanProcessors.map(p=>p.forceFlush()))};return(0,_interfere_node_otel_config.installGlobalHandlers)({captureUncaughtException:options.captureUncaughtException??!0,captureUnhandledRejection:options.captureUnhandledRejection??!0,flush}),debug&&(console.log(`[interfere] init: service=${serviceName}, env=${config.environment}, endpoint=${config.endpoint}`),config.releaseSlug&&console.log(`[interfere] release.slug=${config.releaseSlug}`)),new elysia.Elysia({name:PLUGIN_NAME,seed:options}).use((0,_elysia_opentelemetry.opentelemetry)({resource:config.resource,spanProcessors:config.spanProcessors})).onError({as:`global`},function({error,code,request,set}){require_internal_server_fault.isServerFault(code,set.status)&&(_opentelemetry_api.trace.getActiveSpan()?.setStatus({code:_opentelemetry_api.SpanStatusCode.ERROR}),(0,_interfere_node.captureError)(error,request))}).onStop(async function(){(0,_interfere_node_otel_config.uninstallGlobalHandlers)(),await flush()})}exports.INTERFERE_TRACE_HEADERS=require_trace_headers.INTERFERE_TRACE_HEADERS,Object.defineProperty(exports,"captureError",{enumerable:!0,get:function(){return _interfere_node.captureError}}),Object.defineProperty(exports,"captureMessage",{enumerable:!0,get:function(){return _interfere_node.captureMessage}}),Object.defineProperty(exports,"getCurrentSpan",{enumerable:!0,get:function(){return _elysia_opentelemetry.getCurrentSpan}}),exports.interfere=interfere,Object.defineProperty(exports,"record",{enumerable:!0,get:function(){return _elysia_opentelemetry.record}}),Object.defineProperty(exports,"setAttributes",{enumerable:!0,get:function(){return _elysia_opentelemetry.setAttributes}}),Object.defineProperty(exports,"withSpan",{enumerable:!0,get:function(){return _interfere_node.withSpan}});
@@ -0,0 +1,88 @@
1
+ import { INTERFERE_TRACE_HEADERS } from "./trace-headers.cjs";
2
+ import { Elysia } from "elysia";
3
+ import { CaptureErrorContext, captureError, captureMessage, withSpan } from "@interfere/node";
4
+ import { getCurrentSpan, record, setAttributes } from "@elysia/opentelemetry";
5
+
6
+ //#region src/index.d.ts
7
+ interface InterfereOptions {
8
+ /**
9
+ * Install a `process.on("uncaughtException")` listener that captures the
10
+ * error, flushes spans, and exits the process. Default `true`. Disable to
11
+ * use your own handler.
12
+ */
13
+ readonly captureUncaughtException?: boolean;
14
+ /**
15
+ * Install a `process.on("unhandledRejection")` listener that captures the
16
+ * rejection and flushes spans. Default `true`. Disable to use your own
17
+ * handler.
18
+ */
19
+ readonly captureUnhandledRejection?: boolean;
20
+ /**
21
+ * Log lifecycle events and exporter results to `stdout`. Also activatable
22
+ * via `INTERFERE_DEBUG=1`. Default `false`.
23
+ */
24
+ readonly debug?: boolean;
25
+ /**
26
+ * Deployment environment label (e.g. `production`, `staging`, `preview`).
27
+ * Falls back to `INTERFERE_ENVIRONMENT`, then `VERCEL_ENV`, then `NODE_ENV`,
28
+ * then `development`.
29
+ */
30
+ readonly environment?: string;
31
+ /**
32
+ * Sets the OTel `service.name` resource attribute — the identity spans are
33
+ * grouped by in the dashboard. Defaults to `OTEL_SERVICE_NAME`, then
34
+ * `"elysia-app"`.
35
+ */
36
+ readonly serviceName?: string;
37
+ /**
38
+ * Sets the OTel `service.namespace` resource attribute. Optional; groups
39
+ * several services under one logical product surface.
40
+ */
41
+ readonly serviceNamespace?: string;
42
+ }
43
+ /**
44
+ * Elysia plugin that instruments your server for Interfere: it stands up an
45
+ * OpenTelemetry tracer that exports per-request spans to the Interfere
46
+ * collector, and reports server-fault errors (5xx and uncaught throws) with
47
+ * request context. Client faults (validation, not-found) still produce spans
48
+ * but are not reported as errors.
49
+ *
50
+ * Register once at the root of your app:
51
+ *
52
+ * ```ts
53
+ * new Elysia().use(interfere({ serviceName: "checkout-api" })).listen(3000);
54
+ * ```
55
+ *
56
+ * No-ops when `INTERFERE_PUBLIC_KEY` is unset so local runs without the SDK
57
+ * configured don't crash.
58
+ */
59
+ declare function interfere(options?: InterfereOptions): Elysia<"", {
60
+ decorator: {};
61
+ store: {};
62
+ derive: {};
63
+ resolve: {};
64
+ }, {
65
+ typebox: {};
66
+ error: {};
67
+ }, {
68
+ schema: {};
69
+ standaloneSchema: {};
70
+ macro: {};
71
+ macroFn: {};
72
+ parser: {};
73
+ response: {};
74
+ }, {}, {
75
+ derive: {};
76
+ resolve: {};
77
+ schema: {};
78
+ standaloneSchema: {};
79
+ response: {};
80
+ }, {
81
+ derive: {};
82
+ resolve: {};
83
+ schema: {};
84
+ standaloneSchema: {};
85
+ response: {};
86
+ }>;
87
+ //#endregion
88
+ export { type CaptureErrorContext, INTERFERE_TRACE_HEADERS, InterfereOptions, captureError, captureMessage, getCurrentSpan, interfere, record, setAttributes, withSpan };
@@ -0,0 +1,88 @@
1
+ import { INTERFERE_TRACE_HEADERS } from "./trace-headers.mjs";
2
+ import { CaptureErrorContext, captureError, captureMessage, withSpan } from "@interfere/node";
3
+ import { getCurrentSpan, record, setAttributes } from "@elysia/opentelemetry";
4
+ import { Elysia } from "elysia";
5
+
6
+ //#region src/index.d.ts
7
+ interface InterfereOptions {
8
+ /**
9
+ * Install a `process.on("uncaughtException")` listener that captures the
10
+ * error, flushes spans, and exits the process. Default `true`. Disable to
11
+ * use your own handler.
12
+ */
13
+ readonly captureUncaughtException?: boolean;
14
+ /**
15
+ * Install a `process.on("unhandledRejection")` listener that captures the
16
+ * rejection and flushes spans. Default `true`. Disable to use your own
17
+ * handler.
18
+ */
19
+ readonly captureUnhandledRejection?: boolean;
20
+ /**
21
+ * Log lifecycle events and exporter results to `stdout`. Also activatable
22
+ * via `INTERFERE_DEBUG=1`. Default `false`.
23
+ */
24
+ readonly debug?: boolean;
25
+ /**
26
+ * Deployment environment label (e.g. `production`, `staging`, `preview`).
27
+ * Falls back to `INTERFERE_ENVIRONMENT`, then `VERCEL_ENV`, then `NODE_ENV`,
28
+ * then `development`.
29
+ */
30
+ readonly environment?: string;
31
+ /**
32
+ * Sets the OTel `service.name` resource attribute — the identity spans are
33
+ * grouped by in the dashboard. Defaults to `OTEL_SERVICE_NAME`, then
34
+ * `"elysia-app"`.
35
+ */
36
+ readonly serviceName?: string;
37
+ /**
38
+ * Sets the OTel `service.namespace` resource attribute. Optional; groups
39
+ * several services under one logical product surface.
40
+ */
41
+ readonly serviceNamespace?: string;
42
+ }
43
+ /**
44
+ * Elysia plugin that instruments your server for Interfere: it stands up an
45
+ * OpenTelemetry tracer that exports per-request spans to the Interfere
46
+ * collector, and reports server-fault errors (5xx and uncaught throws) with
47
+ * request context. Client faults (validation, not-found) still produce spans
48
+ * but are not reported as errors.
49
+ *
50
+ * Register once at the root of your app:
51
+ *
52
+ * ```ts
53
+ * new Elysia().use(interfere({ serviceName: "checkout-api" })).listen(3000);
54
+ * ```
55
+ *
56
+ * No-ops when `INTERFERE_PUBLIC_KEY` is unset so local runs without the SDK
57
+ * configured don't crash.
58
+ */
59
+ declare function interfere(options?: InterfereOptions): Elysia<"", {
60
+ decorator: {};
61
+ store: {};
62
+ derive: {};
63
+ resolve: {};
64
+ }, {
65
+ typebox: {};
66
+ error: {};
67
+ }, {
68
+ schema: {};
69
+ standaloneSchema: {};
70
+ macro: {};
71
+ macroFn: {};
72
+ parser: {};
73
+ response: {};
74
+ }, {}, {
75
+ derive: {};
76
+ resolve: {};
77
+ schema: {};
78
+ standaloneSchema: {};
79
+ response: {};
80
+ }, {
81
+ derive: {};
82
+ resolve: {};
83
+ schema: {};
84
+ standaloneSchema: {};
85
+ response: {};
86
+ }>;
87
+ //#endregion
88
+ export { type CaptureErrorContext, INTERFERE_TRACE_HEADERS, InterfereOptions, captureError, captureMessage, getCurrentSpan, interfere, record, setAttributes, withSpan };
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import{INTERFERE_TRACE_HEADERS}from"./trace-headers.mjs";import{isServerFault}from"./internal/server-fault.mjs";import{PRODUCER_VERSION}from"./version.mjs";import{captureError,captureError as captureError$1,captureMessage,withSpan}from"@interfere/node";import{installGlobalHandlers,resolveOtelConfig,uninstallGlobalHandlers}from"@interfere/node/otel-config";import{getCurrentSpan,opentelemetry,record,setAttributes}from"@elysia/opentelemetry";import{SpanStatusCode,trace}from"@opentelemetry/api";import{Elysia}from"elysia";const PLUGIN_NAME=`@interfere/elysia`;function interfere(options={}){let debug=options.debug??process.env.INTERFERE_DEBUG===`1`,serviceName=options.serviceName??process.env.OTEL_SERVICE_NAME??`elysia-app`,config=resolveOtelConfig({serviceName,serviceNamespace:options.serviceNamespace,environment:options.environment,sdkName:PLUGIN_NAME,producerVersion:PRODUCER_VERSION,debug});if(!config)return console.warn(`[interfere] INTERFERE_PUBLIC_KEY not set; SDK disabled`),new Elysia({name:PLUGIN_NAME});config.releaseSlug||console.warn(`[interfere] No release slug resolved — the collector will reject spans. Add a postbuild script to your package.json:
2
+ "postbuild": "interfere sourcemaps upload ./dist"
3
+ and set INTERFERE_API_KEY in your CI environment. See https://interfere.com/docs/elysia#releases`);let flush=async()=>{await Promise.all(config.spanProcessors.map(p=>p.forceFlush()))};return installGlobalHandlers({captureUncaughtException:options.captureUncaughtException??!0,captureUnhandledRejection:options.captureUnhandledRejection??!0,flush}),debug&&(console.log(`[interfere] init: service=${serviceName}, env=${config.environment}, endpoint=${config.endpoint}`),config.releaseSlug&&console.log(`[interfere] release.slug=${config.releaseSlug}`)),new Elysia({name:PLUGIN_NAME,seed:options}).use(opentelemetry({resource:config.resource,spanProcessors:config.spanProcessors})).onError({as:`global`},function({error,code,request,set}){isServerFault(code,set.status)&&(trace.getActiveSpan()?.setStatus({code:SpanStatusCode.ERROR}),captureError$1(error,request))}).onStop(async function(){uninstallGlobalHandlers(),await flush()})}export{INTERFERE_TRACE_HEADERS,captureError,captureMessage,getCurrentSpan,interfere,record,setAttributes,withSpan};
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const CLIENT_FAULT_CODES=new Set([`VALIDATION`,`NOT_FOUND`,`PARSE`,`INVALID_COOKIE_SIGNATURE`,`INVALID_FILE_TYPE`]);function isServerFault(code,status){if(typeof code==`string`&&CLIENT_FAULT_CODES.has(code))return!1;let resolved=resolveStatus(code,status);return typeof resolved==`number`?resolved>=500:!0}function resolveStatus(code,status){if(typeof status==`number`)return status;if(typeof code==`number`)return code}exports.isServerFault=isServerFault;
@@ -0,0 +1,9 @@
1
+ //#region src/internal/server-fault.d.ts
2
+ /**
3
+ * Decides whether an Elysia error represents a server fault worth reporting.
4
+ * Skips the framework's client-fault codes and any error whose response
5
+ * status is a 4xx; unknown throws with no status default to reportable.
6
+ */
7
+ declare function isServerFault(code: string | number, status: number | string | undefined): boolean;
8
+ //#endregion
9
+ export { isServerFault };
@@ -0,0 +1,9 @@
1
+ //#region src/internal/server-fault.d.ts
2
+ /**
3
+ * Decides whether an Elysia error represents a server fault worth reporting.
4
+ * Skips the framework's client-fault codes and any error whose response
5
+ * status is a 4xx; unknown throws with no status default to reportable.
6
+ */
7
+ declare function isServerFault(code: string | number, status: number | string | undefined): boolean;
8
+ //#endregion
9
+ export { isServerFault };
@@ -0,0 +1 @@
1
+ const CLIENT_FAULT_CODES=new Set([`VALIDATION`,`NOT_FOUND`,`PARSE`,`INVALID_COOKIE_SIGNATURE`,`INVALID_FILE_TYPE`]);function isServerFault(code,status){if(typeof code==`string`&&CLIENT_FAULT_CODES.has(code))return!1;let resolved=resolveStatus(code,status);return typeof resolved==`number`?resolved>=500:!0}function resolveStatus(code,status){if(typeof status==`number`)return status;if(typeof code==`number`)return code}export{isServerFault};
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"name",{enumerable:!0,get:function(){return`@interfere/elysia`}}),Object.defineProperty(exports,"version",{enumerable:!0,get:function(){return`0.1.0-canary.1`}});
@@ -0,0 +1 @@
1
+ var name=`@interfere/elysia`,version=`0.1.0-canary.1`;export{name,version};
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const INTERFERE_TRACE_HEADERS=[`traceparent`,`tracestate`,`baggage`];exports.INTERFERE_TRACE_HEADERS=INTERFERE_TRACE_HEADERS;
@@ -0,0 +1,17 @@
1
+ //#region src/trace-headers.d.ts
2
+ /**
3
+ * W3C trace-context and baggage request headers the browser SDK injects on
4
+ * cross-origin requests. Spread these into your CORS `allowedHeaders` allowlist
5
+ * so preflight requests from a different-origin frontend are accepted and
6
+ * front-to-back traces stay linked:
7
+ *
8
+ * ```ts
9
+ * cors({ allowedHeaders: ["content-type", ...INTERFERE_TRACE_HEADERS] })
10
+ * ```
11
+ *
12
+ * Unnecessary when the frontend is same-origin, or when your CORS layer
13
+ * reflects requested headers (the `@elysia/cors` default).
14
+ */
15
+ declare const INTERFERE_TRACE_HEADERS: readonly ["traceparent", "tracestate", "baggage"];
16
+ //#endregion
17
+ export { INTERFERE_TRACE_HEADERS };
@@ -0,0 +1,17 @@
1
+ //#region src/trace-headers.d.ts
2
+ /**
3
+ * W3C trace-context and baggage request headers the browser SDK injects on
4
+ * cross-origin requests. Spread these into your CORS `allowedHeaders` allowlist
5
+ * so preflight requests from a different-origin frontend are accepted and
6
+ * front-to-back traces stay linked:
7
+ *
8
+ * ```ts
9
+ * cors({ allowedHeaders: ["content-type", ...INTERFERE_TRACE_HEADERS] })
10
+ * ```
11
+ *
12
+ * Unnecessary when the frontend is same-origin, or when your CORS layer
13
+ * reflects requested headers (the `@elysia/cors` default).
14
+ */
15
+ declare const INTERFERE_TRACE_HEADERS: readonly ["traceparent", "tracestate", "baggage"];
16
+ //#endregion
17
+ export { INTERFERE_TRACE_HEADERS };
@@ -0,0 +1 @@
1
+ const INTERFERE_TRACE_HEADERS=[`traceparent`,`tracestate`,`baggage`];export{INTERFERE_TRACE_HEADERS};
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const require_package=require("./package.cjs"),PRODUCER_VERSION=`${require_package.name}@${require_package.version}`;exports.PRODUCER_VERSION=PRODUCER_VERSION;
@@ -0,0 +1,4 @@
1
+ //#region src/version.d.ts
2
+ declare const PRODUCER_VERSION: string;
3
+ //#endregion
4
+ export { PRODUCER_VERSION };
@@ -0,0 +1,4 @@
1
+ //#region src/version.d.ts
2
+ declare const PRODUCER_VERSION: string;
3
+ //#endregion
4
+ export { PRODUCER_VERSION };
@@ -0,0 +1 @@
1
+ import{name,version}from"./package.mjs";const PRODUCER_VERSION=`${name}@${version}`;export{PRODUCER_VERSION};
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@interfere/elysia",
3
+ "version": "0.1.0-canary.1",
4
+ "license": "MIT",
5
+ "description": "Elysia plugin for Interfere. Per-request OTel spans and error capture for any Elysia server.",
6
+ "keywords": [
7
+ "observability",
8
+ "typescript",
9
+ "elysia",
10
+ "bun",
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://interfere.ghe.com/interfere/interfere.git",
22
+ "directory": "src/packages/public/elysia"
23
+ },
24
+ "files": [
25
+ "dist/**/*.cjs",
26
+ "dist/**/*.mjs",
27
+ "dist/**/*.d.cts",
28
+ "dist/**/*.d.mts",
29
+ "README.md"
30
+ ],
31
+ "type": "module",
32
+ "main": "./dist/index.cjs",
33
+ "module": "./dist/index.mjs",
34
+ "types": "./dist/index.d.cts",
35
+ "exports": {
36
+ ".": {
37
+ "monorepo": "./src/index.ts",
38
+ "import": {
39
+ "types": "./dist/index.d.mts",
40
+ "default": "./dist/index.mjs"
41
+ },
42
+ "require": {
43
+ "types": "./dist/index.d.cts",
44
+ "default": "./dist/index.cjs"
45
+ }
46
+ },
47
+ "./cors": {
48
+ "monorepo": "./src/cors.ts",
49
+ "import": {
50
+ "types": "./dist/cors.d.mts",
51
+ "default": "./dist/cors.mjs"
52
+ },
53
+ "require": {
54
+ "types": "./dist/cors.d.cts",
55
+ "default": "./dist/cors.cjs"
56
+ }
57
+ }
58
+ },
59
+ "sideEffects": false,
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "scripts": {
64
+ "build": "tsdown",
65
+ "test": "vitest run --passWithNoTests",
66
+ "typecheck": "tsc --noEmit"
67
+ },
68
+ "dependencies": {
69
+ "@interfere/node": "^0.1.0-canary.10",
70
+ "@opentelemetry/api": "^1.9.1"
71
+ },
72
+ "peerDependencies": {
73
+ "@elysia/cors": "^1.4.1",
74
+ "@elysia/opentelemetry": "^1.4.11",
75
+ "elysia": "^1.4.29"
76
+ },
77
+ "peerDependenciesMeta": {
78
+ "@elysia/cors": {
79
+ "optional": true
80
+ }
81
+ },
82
+ "devDependencies": {
83
+ "@elysia/cors": "^1.4.1",
84
+ "@elysia/opentelemetry": "^1.4.11",
85
+ "@interfere/test-utils": "^9.0.1-canary.1",
86
+ "@interfere/typescript-config": "^9.0.1-canary.1",
87
+ "@types/node": "^26.1.0",
88
+ "@vitest/coverage-v8": "4.1.9",
89
+ "elysia": "^1.4.29",
90
+ "tsdown": "^0.22.2",
91
+ "typescript": "^6.0.3",
92
+ "vitest": "4.1.9"
93
+ }
94
+ }