@interfere/next 0.2.0-alpha.5 → 0.2.0-alpha.8
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 +119 -0
- package/dist/config.d.mts +2 -2
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +4 -2
- package/dist/config.mjs.map +1 -1
- package/dist/instrument-client.d.mts +3 -2
- package/dist/instrument-client.mjs +2 -2
- package/dist/internal/build/configure-build.d.mts +5 -2
- package/dist/internal/build/configure-build.d.mts.map +1 -1
- package/dist/internal/build/configure-build.mjs.map +1 -1
- package/dist/internal/build/release/index.d.mts.map +1 -1
- package/dist/internal/build/release/index.mjs.map +1 -1
- package/dist/internal/build/value-injection-loader.d.mts +1 -1
- package/dist/internal/build/value-injection-loader.mjs.map +1 -1
- package/dist/internal/server/capture.d.mts +3 -3
- package/dist/internal/server/capture.d.mts.map +1 -1
- package/dist/internal/server/capture.mjs +9 -5
- package/dist/internal/server/capture.mjs.map +1 -1
- package/dist/internal/server/envelope.d.mts.map +1 -1
- package/dist/internal/server/envelope.mjs +16 -2
- package/dist/internal/server/envelope.mjs.map +1 -1
- package/dist/provider.d.mts +2 -1
- package/dist/route-handler.d.mts.map +1 -1
- package/dist/route-handler.mjs +10 -2
- package/dist/route-handler.mjs.map +1 -1
- package/dist/server.d.mts +1 -6
- package/dist/server.mjs +1 -5
- package/package.json +8 -8
- package/dist/internal/build/injected.d.mts +0 -12
- package/dist/internal/build/injected.d.mts.map +0 -1
- package/dist/internal/build/injected.mjs +0 -9
- package/dist/internal/build/injected.mjs.map +0 -1
- package/dist/internal/build/release/types.d.mts +0 -11
- package/dist/internal/build/release/types.d.mts.map +0 -1
- package/dist/internal/build/release/types.mjs +0 -1
- package/dist/internal/route/cors.d.mts +0 -4
- package/dist/internal/route/cors.d.mts.map +0 -1
- package/dist/internal/route/cors.mjs +0 -15
- package/dist/internal/route/cors.mjs.map +0 -1
- package/dist/internal/server/mechanisms.d.mts +0 -7
- package/dist/internal/server/mechanisms.d.mts.map +0 -1
- package/dist/internal/server/mechanisms.mjs +0 -12
- package/dist/internal/server/mechanisms.mjs.map +0 -1
- package/dist/internal/server/session.d.mts +0 -11
- package/dist/internal/server/session.d.mts.map +0 -1
- package/dist/internal/server/session.mjs +0 -15
- package/dist/internal/server/session.mjs.map +0 -1
- package/dist/server.d.mts.map +0 -1
- package/dist/server.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -97,6 +97,125 @@ export default function RootLayout({
|
|
|
97
97
|
| --- | --- | --- |
|
|
98
98
|
| `INTERFERE_API_KEY` | Yes | Your project API key |
|
|
99
99
|
|
|
100
|
+
## Identity Management
|
|
101
|
+
|
|
102
|
+
Link sessions to your authenticated users with `identity.set()`:
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { useInterfere } from "@interfere/next/provider";
|
|
106
|
+
|
|
107
|
+
function OnLogin({ user }: { user: { id: string; name: string; email: string } }) {
|
|
108
|
+
const { identity } = useInterfere();
|
|
109
|
+
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
identity.set({
|
|
112
|
+
identifier: user.id,
|
|
113
|
+
name: user.name,
|
|
114
|
+
email: user.email,
|
|
115
|
+
});
|
|
116
|
+
}, [user.id]);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Parameters
|
|
121
|
+
|
|
122
|
+
| Field | Required | Description |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| `identifier` | Yes | Unique user ID (your internal ID, not email) |
|
|
125
|
+
| `name` | No | Display name |
|
|
126
|
+
| `email` | No | Email address |
|
|
127
|
+
| `avatar` | No | Avatar URL |
|
|
128
|
+
| `traits` | No | Arbitrary key-value metadata (`Record<string, unknown>`) |
|
|
129
|
+
|
|
130
|
+
### API
|
|
131
|
+
|
|
132
|
+
| Method | Description |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| `identity.set(params)` | Link the current session to a user. Deduplicated per session — only the first call sends a request. |
|
|
135
|
+
| `identity.get()` | Returns the current `IdentifyParams`, or `null` if no identity has been set. |
|
|
136
|
+
|
|
137
|
+
Identity is automatically cleared when the SDK is closed or the session rotates.
|
|
138
|
+
|
|
139
|
+
## Consent Management
|
|
140
|
+
|
|
141
|
+
By default, all SDK features are active. To gate features behind user consent, pass a `consent` prop to the provider:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
// app/layout.tsx
|
|
145
|
+
import { InterfereProvider } from "@interfere/next/provider";
|
|
146
|
+
|
|
147
|
+
export default function RootLayout({
|
|
148
|
+
children,
|
|
149
|
+
}: {
|
|
150
|
+
children: React.ReactNode;
|
|
151
|
+
}) {
|
|
152
|
+
return (
|
|
153
|
+
<html lang="en">
|
|
154
|
+
<body>
|
|
155
|
+
<InterfereProvider consent={{ analytics: true, replay: false }}>
|
|
156
|
+
{children}
|
|
157
|
+
</InterfereProvider>
|
|
158
|
+
</body>
|
|
159
|
+
</html>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Consent categories
|
|
165
|
+
|
|
166
|
+
| Category | Plugins | Gated? |
|
|
167
|
+
| --- | --- | --- |
|
|
168
|
+
| `necessary` | Error tracking | Always on |
|
|
169
|
+
| `analytics` | Page events, rage clicks, fingerprint | Yes |
|
|
170
|
+
| `replay` | Session replay | Yes |
|
|
171
|
+
|
|
172
|
+
Omitting the `consent` prop disables gating entirely (all features load). Passing it enables gating — only `necessary` plugins plus explicitly consented categories will activate.
|
|
173
|
+
|
|
174
|
+
### Imperative API
|
|
175
|
+
|
|
176
|
+
Use `consent.set()` and `consent.get()` from the `useInterfere` hook:
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
const { consent } = useInterfere();
|
|
180
|
+
|
|
181
|
+
consent.set({ analytics: true, replay: true }); // selective
|
|
182
|
+
consent.set(); // grant all
|
|
183
|
+
consent.get(); // current state, or null if no gating
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Integration with consent libraries
|
|
187
|
+
|
|
188
|
+
Works with any consent management platform — c15t, CookieYes, OneTrust, etc.:
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
import { InterfereProvider } from "@interfere/next/provider";
|
|
192
|
+
|
|
193
|
+
function Layout({ children }: { children: React.ReactNode }) {
|
|
194
|
+
const { has } = useConsentManager(); // from your CMP
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<InterfereProvider
|
|
198
|
+
consent={{ analytics: has("measurement"), replay: has("experience") }}
|
|
199
|
+
>
|
|
200
|
+
{children}
|
|
201
|
+
</InterfereProvider>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Initial consent via bootstrap
|
|
207
|
+
|
|
208
|
+
To set consent before React renders (avoiding any window where non-consented plugins might load), pass it to `init()`:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
// instrumentation-client.ts
|
|
212
|
+
import { init } from "@interfere/next/instrument-client";
|
|
213
|
+
|
|
214
|
+
init({ consent: { analytics: false, replay: false } });
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The provider's `consent` prop will then keep it in sync as the user updates their preferences.
|
|
218
|
+
|
|
100
219
|
## What's Included
|
|
101
220
|
|
|
102
221
|
- **Error tracking** — automatic capture of server and client errors with rich stack traces
|
package/dist/config.d.mts
CHANGED
|
@@ -3,9 +3,9 @@ import { NextConfig } from "next";
|
|
|
3
3
|
|
|
4
4
|
//#region src/config.d.ts
|
|
5
5
|
interface InterfereConfig extends Partial<Pick<Envelope, "buildId" | "releaseId">> {}
|
|
6
|
-
|
|
6
|
+
interface NextConfigWithInterfere extends NextConfig {
|
|
7
7
|
interfere?: InterfereConfig;
|
|
8
|
-
}
|
|
8
|
+
}
|
|
9
9
|
declare function withInterfere(nextConfig?: NextConfigWithInterfere): NextConfig;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { InterfereConfig, NextConfigWithInterfere, withInterfere };
|
package/dist/config.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;UAciB,eAAA,SACP,OAAA,CAAQ,IAAA,CAAK,QAAA;AAAA,UAEN,uBAAA,SAAgC,UAAA;EAC/C,SAAA,GAAY,eAAA;AAAA;AAAA,iBAUE,aAAA,CACd,UAAA,GAAY,uBAAA,GACX,UAAA"}
|
package/dist/config.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { configureBuild } from "./internal/build/configure-build.mjs";
|
|
2
|
-
import { buildInjectedValues } from "./internal/build/injected.mjs";
|
|
3
2
|
import { log } from "./internal/logger.mjs";
|
|
4
3
|
import { runGitCommand } from "./internal/build/release/git.mjs";
|
|
5
4
|
import { readInterfereEnv } from "./internal/env.mjs";
|
|
@@ -13,7 +12,10 @@ function withInterfere(nextConfig = {}) {
|
|
|
13
12
|
existingWebpack: webpack,
|
|
14
13
|
existingTurbopack: turbopack,
|
|
15
14
|
projectDir: process.cwd(),
|
|
16
|
-
values:
|
|
15
|
+
values: {
|
|
16
|
+
__INTERFERE_BUILD_ID__: config.buildId,
|
|
17
|
+
__INTERFERE_RELEASE_ID__: config.releaseId
|
|
18
|
+
}
|
|
17
19
|
});
|
|
18
20
|
if (config.apiKey !== null && !build.webpack && !build.turbopack) throw new Error("[Interfere] INTERFERE_API_KEY is set but no instrumentation-client file was found. Create an instrumentation-client.ts file in your project root or src/ directory. See: https://interfere.com/docs/nextjs/setup");
|
|
19
21
|
const existingHook = compiler?.runAfterProductionCompile;
|
package/dist/config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import {\n releaseDestinationIdEnvKeys,\n releaseSourceIdEnvKeys,\n} from \"@interfere/types/integrations\";\nimport { parseEnvValue, readFirstEnvValue } from \"@interfere/types/sdk/env\";\nimport type { Envelope } from \"@interfere/types/sdk/envelope\";\n\nimport type { NextConfig } from \"next\";\n\nimport { configureBuild } from \"./internal/build/configure-build.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import {\n releaseDestinationIdEnvKeys,\n releaseSourceIdEnvKeys,\n} from \"@interfere/types/integrations\";\nimport { parseEnvValue, readFirstEnvValue } from \"@interfere/types/sdk/env\";\nimport type { Envelope } from \"@interfere/types/sdk/envelope\";\n\nimport type { NextConfig } from \"next\";\n\nimport { configureBuild } from \"./internal/build/configure-build.js\";\nimport { runGitCommand } from \"./internal/build/release/git.js\";\nimport { readInterfereEnv } from \"./internal/env.js\";\nimport { log } from \"./internal/logger.js\";\n\nexport interface InterfereConfig\n extends Partial<Pick<Envelope, \"buildId\" | \"releaseId\">> {}\n\nexport interface NextConfigWithInterfere extends NextConfig {\n interfere?: InterfereConfig;\n}\n\ninterface ResolvedBuildConfig {\n readonly apiKey: string | null;\n readonly apiUrl: string;\n readonly buildId: string | null;\n readonly releaseId: string | null;\n}\n\nexport function withInterfere(\n nextConfig: NextConfigWithInterfere = {}\n): NextConfig {\n const {\n interfere,\n env: userEnv,\n webpack,\n turbopack,\n compiler,\n productionBrowserSourceMaps,\n ...rest\n } = nextConfig;\n\n const config = resolveBuildConfig(interfere);\n const build = configureBuild({\n existingWebpack: webpack,\n existingTurbopack: turbopack,\n projectDir: process.cwd(),\n values: {\n __INTERFERE_BUILD_ID__: config.buildId,\n __INTERFERE_RELEASE_ID__: config.releaseId,\n },\n });\n\n if (config.apiKey !== null && !build.webpack && !build.turbopack) {\n throw new Error(\n \"[Interfere] INTERFERE_API_KEY is set but no instrumentation-client file was found. \" +\n \"Create an instrumentation-client.ts file in your project root or src/ directory. \" +\n \"See: https://interfere.com/docs/nextjs/setup\"\n );\n }\n\n const existingHook = (compiler as NextCompilerWithProductionHook | undefined)\n ?.runAfterProductionCompile;\n\n return {\n ...rest,\n env: mergeEnvConfig(userEnv, config),\n compiler: {\n ...(compiler ?? {}),\n async runAfterProductionCompile(context: ProductionCompileContext) {\n if (existingHook) {\n await existingHook(context);\n }\n\n await runBuildReleasePipeline(context, config);\n },\n } as NextConfig[\"compiler\"],\n webpack: build.webpack,\n turbopack: build.turbopack,\n productionBrowserSourceMaps:\n config.apiKey !== null ? true : productionBrowserSourceMaps,\n };\n}\n\nfunction resolveBuildConfig(interfere?: InterfereConfig): ResolvedBuildConfig {\n const { apiKey, apiUrl } = readInterfereEnv();\n\n const buildId =\n parseEnvValue(interfere?.buildId) ??\n readFirstEnvValue(process.env, releaseSourceIdEnvKeys) ??\n runGitCommand(\"git rev-parse HEAD\");\n const releaseId =\n parseEnvValue(interfere?.releaseId) ??\n readFirstEnvValue(process.env, releaseDestinationIdEnvKeys) ??\n buildId;\n\n return { apiKey, apiUrl, buildId, releaseId };\n}\n\nfunction mergeEnvConfig(\n userEnv: NextConfig[\"env\"] | undefined,\n config: ResolvedBuildConfig\n): NextConfig[\"env\"] {\n const merged: Record<string, string> = {};\n\n if (config.buildId !== null) {\n merged.NEXT_PUBLIC_INTERFERE_BUILD_ID = config.buildId;\n }\n\n if (config.releaseId !== null) {\n merged.NEXT_PUBLIC_INTERFERE_RELEASE_ID = config.releaseId;\n }\n\n return { ...merged, ...userEnv };\n}\n\ninterface ProductionCompileContext {\n readonly distDir: string;\n readonly projectDir: string;\n}\n\ntype NextCompilerWithProductionHook = NonNullable<NextConfig[\"compiler\"]> & {\n runAfterProductionCompile?: (\n context: ProductionCompileContext\n ) => void | Promise<void>;\n};\n\nasync function runBuildReleasePipeline(\n context: ProductionCompileContext,\n config: ResolvedBuildConfig\n): Promise<void> {\n const { apiKey, apiUrl, buildId } = config;\n\n if (apiKey === null) {\n throw new Error(\n \"[Interfere] INTERFERE_API_KEY is not set. \" +\n \"withInterfere() requires an API key to upload source maps during production builds. \" +\n \"Set the INTERFERE_API_KEY environment variable, or remove withInterfere() from your Next.js config. \" +\n \"See: https://interfere.com/docs/nextjs/setup\"\n );\n }\n\n if (buildId === null) {\n log.error(\"Build ID missing\", [\n \"Could not resolve a build ID from config, environment variables, or git.\",\n \"Source maps will not be uploaded and errors will have unresolved stack traces.\",\n \"Set INTERFERE_BUILD_ID, or ensure git is available in your build environment.\",\n ]);\n return;\n }\n\n const { createRelease } = await import(\"./internal/build/release/index.js\");\n const { runSourceMapPipeline } = await import(\n \"./internal/build/source-maps/index.js\"\n );\n\n const client: import(\"./internal/build/source-maps/index.js\").BuildClient = {\n async createRelease() {\n const release = await createRelease(apiKey, apiUrl, buildId);\n return {\n slug: release.destination.slug,\n orgSlug: release.org.slug,\n buildId: release.build.hash ?? buildId,\n };\n },\n async uploadSourceMaps(releaseSlug, body) {\n const url = `${apiUrl}/v1/releases/${releaseSlug}/source-maps`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"x-api-key\": apiKey },\n body,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(\n `Source map upload failed: ${response.status} ${response.statusText} ${text}`\n );\n }\n },\n };\n\n try {\n const result = await runSourceMapPipeline(\n context.projectDir,\n context.distDir,\n client\n );\n\n if (!result.ready) {\n log.warn(\"Skipping\", [\"No source maps found\"]);\n return;\n }\n\n log.info(\"Completed\", [\n `https://interfere.com/~/${result.orgSlug}`,\n `Release: ${result.releaseSlug}`,\n `Build: ${result.buildId}`,\n `Artifacts: ${result.fileCount} source maps`,\n ]);\n } catch (error) {\n log.error(\"Error\", [\n error instanceof Error ? error.message : String(error),\n ]);\n throw error;\n }\n}\n"],"mappings":";;;;;;;AA4BA,SAAgB,cACd,aAAsC,EAAE,EAC5B;CACZ,MAAM,EACJ,WACA,KAAK,SACL,SACA,WACA,UACA,6BACA,GAAG,SACD;CAEJ,MAAM,SAAS,mBAAmB,UAAU;CAC5C,MAAM,QAAQ,eAAe;EAC3B,iBAAiB;EACjB,mBAAmB;EACnB,YAAY,QAAQ,KAAK;EACzB,QAAQ;GACN,wBAAwB,OAAO;GAC/B,0BAA0B,OAAO;GAClC;EACF,CAAC;AAEF,KAAI,OAAO,WAAW,QAAQ,CAAC,MAAM,WAAW,CAAC,MAAM,UACrD,OAAM,IAAI,MACR,mNAGD;CAGH,MAAM,eAAgB,UAClB;AAEJ,QAAO;EACL,GAAG;EACH,KAAK,eAAe,SAAS,OAAO;EACpC,UAAU;GACR,GAAI,YAAY,EAAE;GAClB,MAAM,0BAA0B,SAAmC;AACjE,QAAI,aACF,OAAM,aAAa,QAAQ;AAG7B,UAAM,wBAAwB,SAAS,OAAO;;GAEjD;EACD,SAAS,MAAM;EACf,WAAW,MAAM;EACjB,6BACE,OAAO,WAAW,OAAO,OAAO;EACnC;;AAGH,SAAS,mBAAmB,WAAkD;CAC5E,MAAM,EAAE,QAAQ,WAAW,kBAAkB;CAE7C,MAAM,UACJ,cAAc,WAAW,QAAQ,IACjC,kBAAkB,QAAQ,KAAK,uBAAuB,IACtD,cAAc,qBAAqB;AAMrC,QAAO;EAAE;EAAQ;EAAQ;EAAS,WAJhC,cAAc,WAAW,UAAU,IACnC,kBAAkB,QAAQ,KAAK,4BAA4B,IAC3D;EAE2C;;AAG/C,SAAS,eACP,SACA,QACmB;CACnB,MAAM,SAAiC,EAAE;AAEzC,KAAI,OAAO,YAAY,KACrB,QAAO,iCAAiC,OAAO;AAGjD,KAAI,OAAO,cAAc,KACvB,QAAO,mCAAmC,OAAO;AAGnD,QAAO;EAAE,GAAG;EAAQ,GAAG;EAAS;;AAclC,eAAe,wBACb,SACA,QACe;CACf,MAAM,EAAE,QAAQ,QAAQ,YAAY;AAEpC,KAAI,WAAW,KACb,OAAM,IAAI,MACR,iRAID;AAGH,KAAI,YAAY,MAAM;AACpB,MAAI,MAAM,oBAAoB;GAC5B;GACA;GACA;GACD,CAAC;AACF;;CAGF,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,MAAM,EAAE,yBAAyB,MAAM,OACrC;CAGF,MAAM,SAAsE;EAC1E,MAAM,gBAAgB;GACpB,MAAM,UAAU,MAAM,cAAc,QAAQ,QAAQ,QAAQ;AAC5D,UAAO;IACL,MAAM,QAAQ,YAAY;IAC1B,SAAS,QAAQ,IAAI;IACrB,SAAS,QAAQ,MAAM,QAAQ;IAChC;;EAEH,MAAM,iBAAiB,aAAa,MAAM;GACxC,MAAM,MAAM,GAAG,OAAO,eAAe,YAAY;GACjD,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,QAAQ;IACR,SAAS,EAAE,aAAa,QAAQ;IAChC;IACD,CAAC;AAEF,OAAI,CAAC,SAAS,IAAI;IAChB,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,YAAY,GAAG;AAClD,UAAM,IAAI,MACR,6BAA6B,SAAS,OAAO,GAAG,SAAS,WAAW,GAAG,OACxE;;;EAGN;AAED,KAAI;EACF,MAAM,SAAS,MAAM,qBACnB,QAAQ,YACR,QAAQ,SACR,OACD;AAED,MAAI,CAAC,OAAO,OAAO;AACjB,OAAI,KAAK,YAAY,CAAC,uBAAuB,CAAC;AAC9C;;AAGF,MAAI,KAAK,aAAa;GACpB,2BAA2B,OAAO;GAClC,YAAY,OAAO;GACnB,UAAU,OAAO;GACjB,cAAc,OAAO,UAAU;GAChC,CAAC;UACK,OAAO;AACd,MAAI,MAAM,SAAS,CACjB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD,CAAC;AACF,QAAM"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { init } from "@interfere/react/internal/client";
|
|
2
|
-
|
|
1
|
+
import { consent, init } from "@interfere/react/internal/client";
|
|
2
|
+
import { ConsentCategory, ConsentState, GateableCategory } from "@interfere/types/sdk/plugins/manifest";
|
|
3
|
+
export { type ConsentCategory, type ConsentState, type GateableCategory, consent, init };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { init } from "@interfere/react/internal/client";
|
|
2
|
-
export { init };
|
|
1
|
+
import { consent, init } from "@interfere/react/internal/client";
|
|
2
|
+
export { consent, init };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { InterfereInjectedValues } from "./injected.mjs";
|
|
2
1
|
import { NextConfig } from "next";
|
|
3
2
|
|
|
4
3
|
//#region src/internal/build/configure-build.d.ts
|
|
4
|
+
interface InterfereInjectedValues {
|
|
5
|
+
readonly __INTERFERE_BUILD_ID__: string | null;
|
|
6
|
+
readonly __INTERFERE_RELEASE_ID__: string | null;
|
|
7
|
+
}
|
|
5
8
|
interface ConfigureBuildInput {
|
|
6
9
|
readonly existingWebpack: NextConfig["webpack"] | undefined;
|
|
7
10
|
readonly existingTurbopack: NextConfig["turbopack"] | undefined;
|
|
@@ -19,4 +22,4 @@ declare function configureBuild({
|
|
|
19
22
|
values
|
|
20
23
|
}: ConfigureBuildInput): ConfigureBuildOutput;
|
|
21
24
|
//#endregion
|
|
22
|
-
export { configureBuild };
|
|
25
|
+
export { InterfereInjectedValues, configureBuild };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure-build.d.mts","names":[],"sources":["../../../src/internal/build/configure-build.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"configure-build.d.mts","names":[],"sources":["../../../src/internal/build/configure-build.ts"],"mappings":";;;UAKiB,uBAAA;EAAA,SACN,sBAAA;EAAA,SACA,wBAAA;AAAA;AAAA,UAqBD,mBAAA;EAAA,SACC,eAAA,EAAiB,UAAA;EAAA,SACjB,iBAAA,EAAmB,UAAA;EAAA,SACnB,UAAA;EAAA,SACA,MAAA,EAAQ,uBAAA;AAAA;AAAA,UAGT,oBAAA;EAAA,SACC,OAAA,EAAS,UAAA;EAAA,SACT,SAAA,EAAW,UAAA;AAAA;AAAA,iBAGN,cAAA,CAAA;EACd,eAAA;EACA,iBAAA;EACA,UAAA;EACA;AAAA,GACC,mBAAA,GAAsB,oBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure-build.mjs","names":[],"sources":["../../../src/internal/build/configure-build.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { basename, dirname, join, normalize, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NextConfig } from \"next\";\n\
|
|
1
|
+
{"version":3,"file":"configure-build.mjs","names":[],"sources":["../../../src/internal/build/configure-build.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { basename, dirname, join, normalize, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NextConfig } from \"next\";\n\nexport interface InterfereInjectedValues {\n readonly __INTERFERE_BUILD_ID__: string | null;\n readonly __INTERFERE_RELEASE_ID__: string | null;\n}\n\nconst INSTRUMENTATION_CLIENT_FILES = [\n \"instrumentation-client.ts\",\n \"instrumentation-client.tsx\",\n \"instrumentation-client.js\",\n \"instrumentation-client.jsx\",\n \"src/instrumentation-client.ts\",\n \"src/instrumentation-client.tsx\",\n \"src/instrumentation-client.js\",\n \"src/instrumentation-client.jsx\",\n] as const;\n\nconst LOADER_FILE_CANDIDATES = [\n \"value-injection-loader.ts\",\n \"value-injection-loader.js\",\n \"value-injection-loader.mjs\",\n \"value-injection-loader.cjs\",\n] as const;\n\ninterface ConfigureBuildInput {\n readonly existingWebpack: NextConfig[\"webpack\"] | undefined;\n readonly existingTurbopack: NextConfig[\"turbopack\"] | undefined;\n readonly projectDir: string;\n readonly values: InterfereInjectedValues;\n}\n\ninterface ConfigureBuildOutput {\n readonly webpack: NextConfig[\"webpack\"] | undefined;\n readonly turbopack: NextConfig[\"turbopack\"] | undefined;\n}\n\nexport function configureBuild({\n existingWebpack,\n existingTurbopack,\n projectDir,\n values,\n}: ConfigureBuildInput): ConfigureBuildOutput {\n const instrumentationClientPath = resolveInstrumentationClientPath(projectDir);\n\n return {\n webpack: buildWebpackHook(existingWebpack, instrumentationClientPath, values),\n turbopack: buildTurbopackConfig(\n existingTurbopack,\n instrumentationClientPath,\n values\n ),\n };\n}\n\nfunction hasInjectedMetadata(metadata: InterfereInjectedValues): boolean {\n return (\n metadata.__INTERFERE_BUILD_ID__ !== null ||\n metadata.__INTERFERE_RELEASE_ID__ !== null\n );\n}\n\nfunction buildWebpackHook(\n existingWebpack: NextConfig[\"webpack\"] | undefined,\n instrumentationClientPath: string | null,\n values: InterfereInjectedValues\n): NextConfig[\"webpack\"] | undefined {\n if (!(instrumentationClientPath && hasInjectedMetadata(values))) {\n return existingWebpack;\n }\n\n const normalizedPath = normalize(instrumentationClientPath);\n const loaderPath = resolveLoaderPath();\n\n return (webpackConfig, options) => {\n const outputConfig = existingWebpack\n ? existingWebpack(webpackConfig, options)\n : webpackConfig;\n const mutableConfig = outputConfig as {\n module?: { rules?: unknown[] };\n };\n\n const injectionRule = {\n test: (resource: string): boolean =>\n Boolean(resource) && normalize(resource) === normalizedPath,\n use: [\n {\n loader: loaderPath,\n options: { values },\n },\n ],\n };\n\n mutableConfig.module ??= {};\n mutableConfig.module.rules ??= [];\n mutableConfig.module.rules.push(injectionRule);\n\n return outputConfig;\n };\n}\n\nfunction buildTurbopackConfig(\n existingTurbopack: NextConfig[\"turbopack\"] | undefined,\n instrumentationClientPath: string | null,\n values: InterfereInjectedValues\n): NextConfig[\"turbopack\"] | undefined {\n if (!(instrumentationClientPath && hasInjectedMetadata(values))) {\n return existingTurbopack;\n }\n\n const baseConfig = (existingTurbopack ?? {}) as {\n rules?: Record<string, unknown>;\n };\n const ruleKey = `**/${basename(instrumentationClientPath)}`;\n const existingRule = (baseConfig.rules?.[ruleKey] ?? {}) as {\n loaders?: unknown[];\n };\n const existingLoaders = Array.isArray(existingRule.loaders)\n ? existingRule.loaders\n : [];\n\n return {\n ...baseConfig,\n rules: {\n ...baseConfig.rules,\n [ruleKey]: {\n ...existingRule,\n loaders: [\n ...existingLoaders,\n {\n loader: resolveLoaderPath(),\n options: {\n serializedValues: JSON.stringify(values),\n },\n },\n ],\n },\n },\n } as NextConfig[\"turbopack\"];\n}\n\nfunction resolveInstrumentationClientPath(projectDir: string): string | null {\n for (const candidate of INSTRUMENTATION_CLIENT_FILES) {\n const filePath = resolve(projectDir, candidate);\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n}\n\nfunction resolveLoaderPath(): string {\n const directory = resolve(dirname(fileURLToPath(import.meta.url)));\n\n for (const candidate of LOADER_FILE_CANDIDATES) {\n const filePath = join(directory, candidate);\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return join(directory, \"value-injection-loader.js\");\n}\n"],"mappings":";;;;AAUA,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACD;AAcD,SAAgB,eAAe,EAC7B,iBACA,mBACA,YACA,UAC4C;CAC5C,MAAM,4BAA4B,iCAAiC,WAAW;AAE9E,QAAO;EACL,SAAS,iBAAiB,iBAAiB,2BAA2B,OAAO;EAC7E,WAAW,qBACT,mBACA,2BACA,OACD;EACF;;AAGH,SAAS,oBAAoB,UAA4C;AACvE,QACE,SAAS,2BAA2B,QACpC,SAAS,6BAA6B;;AAI1C,SAAS,iBACP,iBACA,2BACA,QACmC;AACnC,KAAI,EAAE,6BAA6B,oBAAoB,OAAO,EAC5D,QAAO;CAGT,MAAM,iBAAiB,UAAU,0BAA0B;CAC3D,MAAM,aAAa,mBAAmB;AAEtC,SAAQ,eAAe,YAAY;EACjC,MAAM,eAAe,kBACjB,gBAAgB,eAAe,QAAQ,GACvC;EACJ,MAAM,gBAAgB;EAItB,MAAM,gBAAgB;GACpB,OAAO,aACL,QAAQ,SAAS,IAAI,UAAU,SAAS,KAAK;GAC/C,KAAK,CACH;IACE,QAAQ;IACR,SAAS,EAAE,QAAQ;IACpB,CACF;GACF;AAED,gBAAc,WAAW,EAAE;AAC3B,gBAAc,OAAO,UAAU,EAAE;AACjC,gBAAc,OAAO,MAAM,KAAK,cAAc;AAE9C,SAAO;;;AAIX,SAAS,qBACP,mBACA,2BACA,QACqC;AACrC,KAAI,EAAE,6BAA6B,oBAAoB,OAAO,EAC5D,QAAO;CAGT,MAAM,aAAc,qBAAqB,EAAE;CAG3C,MAAM,UAAU,MAAM,SAAS,0BAA0B;CACzD,MAAM,eAAgB,WAAW,QAAQ,YAAY,EAAE;CAGvD,MAAM,kBAAkB,MAAM,QAAQ,aAAa,QAAQ,GACvD,aAAa,UACb,EAAE;AAEN,QAAO;EACL,GAAG;EACH,OAAO;GACL,GAAG,WAAW;IACb,UAAU;IACT,GAAG;IACH,SAAS,CACP,GAAG,iBACH;KACE,QAAQ,mBAAmB;KAC3B,SAAS,EACP,kBAAkB,KAAK,UAAU,OAAO,EACzC;KACF,CACF;IACF;GACF;EACF;;AAGH,SAAS,iCAAiC,YAAmC;AAC3E,MAAK,MAAM,aAAa,8BAA8B;EACpD,MAAM,WAAW,QAAQ,YAAY,UAAU;AAC/C,MAAI,WAAW,SAAS,CACtB,QAAO;;AAIX,QAAO;;AAGT,SAAS,oBAA4B;CACnC,MAAM,YAAY,QAAQ,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,CAAC;AAElE,MAAK,MAAM,aAAa,wBAAwB;EAC9C,MAAM,WAAW,KAAK,WAAW,UAAU;AAC3C,MAAI,WAAW,SAAS,CACtB,QAAO;;AAIX,QAAO,KAAK,WAAW,4BAA4B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../../src/internal/build/release/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../../src/internal/build/release/index.ts"],"mappings":";;;;iBAgCsB,aAAA,CACpB,MAAA,UACA,MAAA,UACA,OAAA,WACC,OAAA,CAAQ,qBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/internal/build/release/index.ts"],"sourcesContent":["import type {\n DestinationProvider,\n SourceProvider,\n} from \"@interfere/types/integrations\";\nimport type { CreateReleaseResponse } from \"@interfere/types/releases/definition\";\n\nimport { Interfere } from \"@interfere/sdk\";\nimport { InterfereHTTPError } from \"@interfere/sdk/models/errors/interfere-http-error.js\";\n\nimport * as vercel from \"./destinations/vercel.js\";\nimport * as github from \"./sources/github.js\";\
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/internal/build/release/index.ts"],"sourcesContent":["import type {\n DestinationProvider,\n ReleaseDestinationMetadata,\n ReleaseSourceMetadata,\n SourceProvider,\n} from \"@interfere/types/integrations\";\nimport type { CreateReleaseResponse } from \"@interfere/types/releases/definition\";\n\nimport { Interfere } from \"@interfere/sdk\";\nimport { InterfereHTTPError } from \"@interfere/sdk/models/errors/interfere-http-error.js\";\n\nimport * as vercel from \"./destinations/vercel.js\";\nimport * as github from \"./sources/github.js\";\n\ninterface SourceResolver {\n resolve(): ReleaseSourceMetadata;\n}\n\ninterface DestinationResolver {\n resolve(): ReleaseDestinationMetadata | null;\n}\n\nexport { runGitCommand } from \"./git.js\";\n\nconst sources: Record<SourceProvider, SourceResolver> = {\n github,\n};\n\nconst destinations: Record<DestinationProvider, DestinationResolver> = {\n vercel,\n};\n\nexport async function createRelease(\n apiKey: string,\n apiUrl: string,\n buildId: string,\n): Promise<CreateReleaseResponse> {\n const sdk = new Interfere({ serverURL: apiUrl });\n\n const request = {\n source: sources.github.resolve(),\n destination: destinations.vercel.resolve(),\n buildId,\n };\n\n try {\n return await sdk.releases.createRelease(request, {\n headers: { \"x-api-key\": apiKey },\n });\n } catch (error) {\n if (error instanceof InterfereHTTPError && error.statusCode === 404) {\n throw new Error(\n `Interfere release API returned 404 at '${error.rawResponse.url}'. Is INTERFERE_API_URL incorrectly set?`,\n );\n }\n\n throw error;\n }\n}\n"],"mappings":";;;;;;AAwBA,MAAM,UAAkD,EACtD,QAAA,gBACD;AAED,MAAM,eAAiE,EACrE,QAAA,gBACD;AAED,eAAsB,cACpB,QACA,QACA,SACgC;CAChC,MAAM,MAAM,IAAI,UAAU,EAAE,WAAW,QAAQ,CAAC;CAEhD,MAAM,UAAU;EACd,QAAQ,QAAQ,OAAO,SAAS;EAChC,aAAa,aAAa,OAAO,SAAS;EAC1C;EACD;AAED,KAAI;AACF,SAAO,MAAM,IAAI,SAAS,cAAc,SAAS,EAC/C,SAAS,EAAE,aAAa,QAAQ,EACjC,CAAC;UACK,OAAO;AACd,MAAI,iBAAiB,sBAAsB,MAAM,eAAe,IAC9D,OAAM,IAAI,MACR,0CAA0C,MAAM,YAAY,IAAI,0CACjE;AAGH,QAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-injection-loader.mjs","names":[],"sources":["../../../src/internal/build/value-injection-loader.ts"],"sourcesContent":["import type { LoaderContext } from \"webpack\";\n\nimport type { InterfereInjectedValues } from \"./
|
|
1
|
+
{"version":3,"file":"value-injection-loader.mjs","names":[],"sources":["../../../src/internal/build/value-injection-loader.ts"],"sourcesContent":["import type { LoaderContext } from \"webpack\";\n\nimport type { InterfereInjectedValues } from \"./configure-build.js\";\n\nexport interface ValueInjectionLoaderOptions {\n readonly values?: Partial<InterfereInjectedValues>;\n readonly serializedValues?: string;\n}\n\nexport default function valueInjectionLoader(\n this: LoaderContext<ValueInjectionLoaderOptions>,\n userCode: string\n): string {\n const values = resolveValues(this.getOptions());\n const lines = Object.entries(values)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => {\n const escapedKey = key.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n return `globalThis[\"${escapedKey}\"] = ${JSON.stringify(value)};`;\n });\n\n if (lines.length === 0) {\n return userCode;\n }\n\n return `${lines.join(\"\\n\")}\\n${userCode}`;\n}\n\nfunction resolveValues(options: ValueInjectionLoaderOptions): Record<string, unknown> {\n if (typeof options.serializedValues === \"string\") {\n try {\n const parsed = JSON.parse(options.serializedValues);\n if (isRecord(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n }\n\n return options.values ?? {};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";AASA,SAAwB,qBAEtB,UACQ;CACR,MAAM,SAAS,cAAc,KAAK,YAAY,CAAC;CAC/C,MAAM,QAAQ,OAAO,QAAQ,OAAO,CACjC,QAAQ,GAAG,WAAW,UAAU,KAAA,EAAU,CAC1C,KAAK,CAAC,KAAK,WAAW;AAErB,SAAO,eADY,IAAI,QAAQ,OAAO,OAAO,CAAC,QAAQ,MAAM,OAAM,CACjC,OAAO,KAAK,UAAU,MAAM,CAAC;GAC9D;AAEJ,KAAI,MAAM,WAAW,EACnB,QAAO;AAGT,QAAO,GAAG,MAAM,KAAK,KAAK,CAAC,IAAI;;AAGjC,SAAS,cAAc,SAA+D;AACpF,KAAI,OAAO,QAAQ,qBAAqB,SACtC,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,QAAQ,iBAAiB;AACnD,MAAI,SAAS,OAAO,CAClB,QAAO;AAET,SAAO,EAAE;SACH;AACN,SAAO,EAAE;;AAIb,QAAO,QAAQ,UAAU,EAAE;;AAG7B,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CaptureErrorContext, OnRequestErrorContext } from "./types.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/internal/server/capture.d.ts
|
|
4
|
-
declare function
|
|
5
|
-
declare function
|
|
4
|
+
declare function captureError(error: unknown, request?: unknown, context?: CaptureErrorContext): Promise<void>;
|
|
5
|
+
declare function onRequestError(error: Error & {
|
|
6
6
|
digest?: string;
|
|
7
7
|
}, request: unknown, context: OnRequestErrorContext): Promise<void>;
|
|
8
8
|
//#endregion
|
|
9
|
-
export {
|
|
9
|
+
export { captureError, onRequestError };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.mts","names":[],"sources":["../../../src/internal/server/capture.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"capture.d.mts","names":[],"sources":["../../../src/internal/server/capture.ts"],"mappings":";;;iBAqBsB,YAAA,CACpB,KAAA,WACA,OAAA,YACA,OAAA,GAAU,mBAAA,GACT,OAAA;AAAA,iBA4BmB,cAAA,CACpB,KAAA,EAAO,KAAA;EAAU,MAAA;AAAA,GACjB,OAAA,WACA,OAAA,EAAS,qBAAA,GACR,OAAA"}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { isErrorCaptured, markErrorCaptured } from "./dedupe.mjs";
|
|
2
|
-
import { ON_REQUEST_ERROR_MECHANISM } from "./mechanisms.mjs";
|
|
3
2
|
import { buildErrorEnvelope } from "./envelope.mjs";
|
|
4
3
|
import { normalizeRequest } from "./normalize-request.mjs";
|
|
5
4
|
import { resolveServerCaptureRuntime } from "./runtime.mjs";
|
|
6
5
|
import { sendEnvelope } from "./transport.mjs";
|
|
7
6
|
//#region src/internal/server/capture.ts
|
|
7
|
+
const ON_REQUEST_ERROR_MECHANISM = {
|
|
8
|
+
type: "onRequestError",
|
|
9
|
+
handled: false,
|
|
10
|
+
synthetic: false
|
|
11
|
+
};
|
|
8
12
|
const DEFAULT_REQUEST = {
|
|
9
13
|
method: "GET",
|
|
10
14
|
path: "/",
|
|
11
15
|
headers: new Headers()
|
|
12
16
|
};
|
|
13
|
-
async function
|
|
17
|
+
async function captureError(error, request, context) {
|
|
14
18
|
const runtime = resolveServerCaptureRuntime();
|
|
15
19
|
if (runtime.apiKey === null) return;
|
|
16
20
|
const normalizedRequest = normalizeRequest(request);
|
|
@@ -28,11 +32,11 @@ async function captureServerError(error, request, context) {
|
|
|
28
32
|
});
|
|
29
33
|
} catch {}
|
|
30
34
|
}
|
|
31
|
-
async function
|
|
35
|
+
async function onRequestError(error, request, context) {
|
|
32
36
|
if (isErrorCaptured(error)) return;
|
|
33
37
|
markErrorCaptured(error);
|
|
34
38
|
const normalizedRequest = normalizeRequest(request) ?? DEFAULT_REQUEST;
|
|
35
|
-
await
|
|
39
|
+
await captureError(error, normalizedRequest, {
|
|
36
40
|
mechanism: ON_REQUEST_ERROR_MECHANISM,
|
|
37
41
|
nextjs: {
|
|
38
42
|
...context,
|
|
@@ -43,4 +47,4 @@ async function captureOnRequestError(error, request, context) {
|
|
|
43
47
|
});
|
|
44
48
|
}
|
|
45
49
|
//#endregion
|
|
46
|
-
export {
|
|
50
|
+
export { captureError, onRequestError };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.mjs","names":[],"sources":["../../../src/internal/server/capture.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"capture.mjs","names":[],"sources":["../../../src/internal/server/capture.ts"],"sourcesContent":["import type { ErrorMechanism } from \"@interfere/types/sdk/plugins/payload/errors\";\n\nimport { isErrorCaptured, markErrorCaptured } from \"./dedupe.js\";\nimport { buildErrorEnvelope } from \"./envelope.js\";\nimport { normalizeRequest, TRACEPARENT_HEADER } from \"./normalize-request.js\";\nimport { resolveServerCaptureRuntime } from \"./runtime.js\";\nimport { sendEnvelope } from \"./transport.js\";\nimport type { CaptureErrorContext, OnRequestErrorContext } from \"./types.js\";\n\nconst ON_REQUEST_ERROR_MECHANISM: ErrorMechanism = {\n type: \"onRequestError\",\n handled: false,\n synthetic: false,\n};\n\nconst DEFAULT_REQUEST = {\n method: \"GET\",\n path: \"/\",\n headers: new Headers(),\n};\n\nexport async function captureError(\n error: unknown,\n request?: unknown,\n context?: CaptureErrorContext\n): Promise<void> {\n const runtime = resolveServerCaptureRuntime();\n if (runtime.apiKey === null) {\n return;\n }\n\n const normalizedRequest = normalizeRequest(request);\n const envelope = buildErrorEnvelope({\n error,\n request: normalizedRequest,\n context,\n runtime,\n });\n\n try {\n await sendEnvelope({\n envelope,\n runtime,\n traceparent:\n context?.traceparent ??\n normalizedRequest?.headers.get(TRACEPARENT_HEADER) ??\n undefined,\n });\n } catch {\n /* best-effort */\n }\n}\n\nexport async function onRequestError(\n error: Error & { digest?: string },\n request: unknown,\n context: OnRequestErrorContext\n): Promise<void> {\n if (isErrorCaptured(error)) {\n return;\n }\n markErrorCaptured(error);\n\n const normalizedRequest = normalizeRequest(request) ?? DEFAULT_REQUEST;\n\n await captureError(error, normalizedRequest, {\n mechanism: ON_REQUEST_ERROR_MECHANISM,\n nextjs: {\n ...context,\n requestMethod: normalizedRequest.method,\n requestPath: normalizedRequest.path,\n ...(error.digest ? { errorDigest: error.digest } : {}),\n },\n });\n}\n"],"mappings":";;;;;;AASA,MAAM,6BAA6C;CACjD,MAAM;CACN,SAAS;CACT,WAAW;CACZ;AAED,MAAM,kBAAkB;CACtB,QAAQ;CACR,MAAM;CACN,SAAS,IAAI,SAAS;CACvB;AAED,eAAsB,aACpB,OACA,SACA,SACe;CACf,MAAM,UAAU,6BAA6B;AAC7C,KAAI,QAAQ,WAAW,KACrB;CAGF,MAAM,oBAAoB,iBAAiB,QAAQ;CACnD,MAAM,WAAW,mBAAmB;EAClC;EACA,SAAS;EACT;EACA;EACD,CAAC;AAEF,KAAI;AACF,QAAM,aAAa;GACjB;GACA;GACA,aACE,SAAS,eACT,mBAAmB,QAAQ,IAAA,cAAuB,IAClD,KAAA;GACH,CAAC;SACI;;AAKV,eAAsB,eACpB,OACA,SACA,SACe;AACf,KAAI,gBAAgB,MAAM,CACxB;AAEF,mBAAkB,MAAM;CAExB,MAAM,oBAAoB,iBAAiB,QAAQ,IAAI;AAEvD,OAAM,aAAa,OAAO,mBAAmB;EAC3C,WAAW;EACX,QAAQ;GACN,GAAG;GACH,eAAe,kBAAkB;GACjC,aAAa,kBAAkB;GAC/B,GAAI,MAAM,SAAS,EAAE,aAAa,MAAM,QAAQ,GAAG,EAAE;GACtD;EACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.d.mts","names":[],"sources":["../../../src/internal/server/envelope.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"envelope.d.mts","names":[],"sources":["../../../src/internal/server/envelope.ts"],"mappings":";;;;;UAmBU,wBAAA;EAAA,SACC,OAAA,GAAU,mBAAA;EAAA,SACV,KAAA;EAAA,SACA,OAAA,EAAS,iBAAA;EAAA,SACT,OAAA,EAAS,oBAAA;AAAA;AAAA,iBAGJ,kBAAA,CACd,MAAA,EAAQ,wBAAA,GACP,QAAA"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { resolveSession } from "./session.mjs";
|
|
1
|
+
import { sessionIdSchema } from "@interfere/types/data/session";
|
|
3
2
|
import { toError, toExceptions } from "@interfere/types/sdk/errors";
|
|
4
3
|
import { v7 } from "uuid";
|
|
5
4
|
//#region src/internal/server/envelope.ts
|
|
5
|
+
const SESSION_HEADER = "x-interfere-session";
|
|
6
|
+
const DEFAULT_ERROR_MECHANISM = {
|
|
7
|
+
type: "captureError",
|
|
8
|
+
handled: true
|
|
9
|
+
};
|
|
6
10
|
function buildErrorEnvelope(params) {
|
|
7
11
|
const { error, request, context, runtime } = params;
|
|
8
12
|
const session = resolveSession(request?.headers ?? new Headers());
|
|
@@ -37,5 +41,15 @@ function toNextjsContext(context) {
|
|
|
37
41
|
...context
|
|
38
42
|
};
|
|
39
43
|
}
|
|
44
|
+
function resolveSession(headers) {
|
|
45
|
+
const sessionId = headers.get(SESSION_HEADER);
|
|
46
|
+
if (sessionId === null) return { id: null };
|
|
47
|
+
const parsed = sessionIdSchema.safeParse(sessionId);
|
|
48
|
+
if (!parsed.success) return { id: null };
|
|
49
|
+
return {
|
|
50
|
+
id: parsed.data,
|
|
51
|
+
source: "header"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
40
54
|
//#endregion
|
|
41
55
|
export { buildErrorEnvelope };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.mjs","names":["uuidv7"],"sources":["../../../src/internal/server/envelope.ts"],"sourcesContent":["import type { Envelope } from \"@interfere/types/sdk/envelope\";\nimport { toError, toExceptions } from \"@interfere/types/sdk/errors\";\nimport type { NextjsContext } from \"@interfere/types/sdk/plugins/context/next\";\
|
|
1
|
+
{"version":3,"file":"envelope.mjs","names":["uuidv7"],"sources":["../../../src/internal/server/envelope.ts"],"sourcesContent":["import type { SessionId } from \"@interfere/types/data/session\";\nimport { sessionIdSchema } from \"@interfere/types/data/session\";\nimport type { Envelope, SessionSource } from \"@interfere/types/sdk/envelope\";\nimport { toError, toExceptions } from \"@interfere/types/sdk/errors\";\nimport type { NextjsContext } from \"@interfere/types/sdk/plugins/context/next\";\nimport type { ErrorMechanism } from \"@interfere/types/sdk/plugins/payload/errors\";\n\nimport { v7 as uuidv7 } from \"uuid\";\n\nimport type { ServerCaptureRuntime } from \"./runtime.js\";\nimport type { CaptureErrorContext, NormalizedRequest } from \"./types.js\";\n\nconst SESSION_HEADER = \"x-interfere-session\";\n\nconst DEFAULT_ERROR_MECHANISM: ErrorMechanism = {\n type: \"captureError\",\n handled: true,\n};\n\ninterface BuildErrorEnvelopeParams {\n readonly context?: CaptureErrorContext;\n readonly error: unknown;\n readonly request: NormalizedRequest | null;\n readonly runtime: ServerCaptureRuntime;\n}\n\nexport function buildErrorEnvelope(\n params: BuildErrorEnvelopeParams\n): Envelope<\"error\"> {\n const { error, request, context, runtime } = params;\n const session = resolveSession(request?.headers ?? new Headers());\n\n let nextjsContext: NextjsContext | undefined;\n if (context?.nextjs) {\n nextjsContext = toNextjsContext(context.nextjs);\n } else if (request) {\n nextjsContext = toNextjsRequestContext(request);\n }\n\n return {\n uuid: uuidv7(),\n v: 0,\n type: \"error\",\n payload: {\n exceptions: toExceptions(\n toError(error),\n context?.mechanism ?? DEFAULT_ERROR_MECHANISM\n ),\n },\n clientTs: Date.now(),\n runtime: runtime.runtime,\n environment: runtime.environment,\n buildId: runtime.buildId,\n releaseId: runtime.releaseId,\n sessionId: session.id,\n ...(session.source ? { sessionSource: session.source } : {}),\n ...(nextjsContext ? { context: nextjsContext } : {}),\n };\n}\n\nfunction toNextjsRequestContext(request: NormalizedRequest): NextjsContext {\n return {\n runtime: \"nextjs\",\n requestMethod: request.method,\n requestPath: request.path,\n };\n}\n\nfunction toNextjsContext(\n context: Omit<NextjsContext, \"runtime\">\n): NextjsContext {\n return {\n runtime: \"nextjs\",\n ...context,\n };\n}\n\nfunction resolveSession(headers: Headers): {\n readonly id: SessionId | null;\n readonly source?: SessionSource;\n} {\n const sessionId = headers.get(SESSION_HEADER);\n if (sessionId === null) {\n return { id: null };\n }\n\n const parsed = sessionIdSchema.safeParse(sessionId);\n if (!parsed.success) {\n return { id: null };\n }\n\n return {\n id: parsed.data,\n source: \"header\",\n };\n}\n"],"mappings":";;;;AAYA,MAAM,iBAAiB;AAEvB,MAAM,0BAA0C;CAC9C,MAAM;CACN,SAAS;CACV;AASD,SAAgB,mBACd,QACmB;CACnB,MAAM,EAAE,OAAO,SAAS,SAAS,YAAY;CAC7C,MAAM,UAAU,eAAe,SAAS,WAAW,IAAI,SAAS,CAAC;CAEjE,IAAI;AACJ,KAAI,SAAS,OACX,iBAAgB,gBAAgB,QAAQ,OAAO;UACtC,QACT,iBAAgB,uBAAuB,QAAQ;AAGjD,QAAO;EACL,MAAMA,IAAQ;EACd,GAAG;EACH,MAAM;EACN,SAAS,EACP,YAAY,aACV,QAAQ,MAAM,EACd,SAAS,aAAa,wBACvB,EACF;EACD,UAAU,KAAK,KAAK;EACpB,SAAS,QAAQ;EACjB,aAAa,QAAQ;EACrB,SAAS,QAAQ;EACjB,WAAW,QAAQ;EACnB,WAAW,QAAQ;EACnB,GAAI,QAAQ,SAAS,EAAE,eAAe,QAAQ,QAAQ,GAAG,EAAE;EAC3D,GAAI,gBAAgB,EAAE,SAAS,eAAe,GAAG,EAAE;EACpD;;AAGH,SAAS,uBAAuB,SAA2C;AACzE,QAAO;EACL,SAAS;EACT,eAAe,QAAQ;EACvB,aAAa,QAAQ;EACtB;;AAGH,SAAS,gBACP,SACe;AACf,QAAO;EACL,SAAS;EACT,GAAG;EACJ;;AAGH,SAAS,eAAe,SAGtB;CACA,MAAM,YAAY,QAAQ,IAAI,eAAe;AAC7C,KAAI,cAAc,KAChB,QAAO,EAAE,IAAI,MAAM;CAGrB,MAAM,SAAS,gBAAgB,UAAU,UAAU;AACnD,KAAI,CAAC,OAAO,QACV,QAAO,EAAE,IAAI,MAAM;AAGrB,QAAO;EACL,IAAI,OAAO;EACX,QAAQ;EACT"}
|
package/dist/provider.d.mts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { InterfereProvider, useInterfere, useSession } from "@interfere/react/provider";
|
|
2
|
-
|
|
2
|
+
import { ConsentCategory, ConsentState, GateableCategory } from "@interfere/types/sdk/plugins/manifest";
|
|
3
|
+
export { type ConsentCategory, type ConsentState, type GateableCategory, InterfereProvider, useInterfere, useSession };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-handler.d.mts","names":[],"sources":["../src/route-handler.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"route-handler.d.mts","names":[],"sources":["../src/route-handler.ts"],"mappings":";iBAGgB,GAAA,CAAI,OAAA,EAAS,OAAA,GAAU,QAAA;AAAA,iBAIvB,IAAA,CAAK,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA;AAAA,iBAIhC,GAAA,CAAI,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA;AAAA,iBAW/B,OAAA,CAAA,GAAW,QAAA"}
|
package/dist/route-handler.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { handleOptions } from "./internal/route/cors.mjs";
|
|
2
1
|
import { handleGet } from "./internal/route/handle-get.mjs";
|
|
3
2
|
import { handlePost } from "./internal/route/handle-post.mjs";
|
|
4
3
|
//#region src/route-handler.ts
|
|
@@ -11,8 +10,17 @@ function POST(request) {
|
|
|
11
10
|
function PUT(request) {
|
|
12
11
|
return handlePost(request);
|
|
13
12
|
}
|
|
13
|
+
const CORS_HEADERS = {
|
|
14
|
+
"Access-Control-Allow-Origin": "*",
|
|
15
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, OPTIONS",
|
|
16
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
17
|
+
"Access-Control-Max-Age": "86400"
|
|
18
|
+
};
|
|
14
19
|
function OPTIONS() {
|
|
15
|
-
return
|
|
20
|
+
return new Response(null, {
|
|
21
|
+
status: 200,
|
|
22
|
+
headers: CORS_HEADERS
|
|
23
|
+
});
|
|
16
24
|
}
|
|
17
25
|
//#endregion
|
|
18
26
|
export { GET, OPTIONS, POST, PUT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-handler.mjs","names":[],"sources":["../src/route-handler.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"route-handler.mjs","names":[],"sources":["../src/route-handler.ts"],"sourcesContent":["import { handleGet } from \"./internal/route/handle-get.js\";\nimport { handlePost } from \"./internal/route/handle-post.js\";\n\nexport function GET(request: Request): Response {\n return handleGet(request);\n}\n\nexport function POST(request: Request): Promise<Response> {\n return handlePost(request);\n}\n\nexport function PUT(request: Request): Promise<Response> {\n return handlePost(request);\n}\n\nconst CORS_HEADERS = {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n \"Access-Control-Max-Age\": \"86400\",\n};\n\nexport function OPTIONS(): Response {\n return new Response(null, { status: 200, headers: CORS_HEADERS });\n}\n"],"mappings":";;;AAGA,SAAgB,IAAI,SAA4B;AAC9C,QAAO,UAAU,QAAQ;;AAG3B,SAAgB,KAAK,SAAqC;AACxD,QAAO,WAAW,QAAQ;;AAG5B,SAAgB,IAAI,SAAqC;AACvD,QAAO,WAAW,QAAQ;;AAG5B,MAAM,eAAe;CACnB,+BAA+B;CAC/B,gCAAgC;CAChC,gCAAgC;CAChC,0BAA0B;CAC3B;AAED,SAAgB,UAAoB;AAClC,QAAO,IAAI,SAAS,MAAM;EAAE,QAAQ;EAAK,SAAS;EAAc,CAAC"}
|
package/dist/server.d.mts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
import { CaptureErrorContext, OnRequestErrorContext } from "./internal/server/types.mjs";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
//#region src/server.d.ts
|
|
5
|
-
declare const captureError: typeof captureServerError;
|
|
6
|
-
declare const onRequestError: typeof captureOnRequestError;
|
|
7
|
-
//#endregion
|
|
2
|
+
import { captureError, onRequestError } from "./internal/server/capture.mjs";
|
|
8
3
|
export { type CaptureErrorContext, type OnRequestErrorContext, captureError, onRequestError };
|
package/dist/server.mjs
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/server.ts
|
|
3
|
-
const captureError = captureServerError;
|
|
4
|
-
const onRequestError = captureOnRequestError;
|
|
5
|
-
//#endregion
|
|
1
|
+
import { captureError, onRequestError } from "./internal/server/capture.mjs";
|
|
6
2
|
export { captureError, onRequestError };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interfere/next",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.8",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Build software that never breaks.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"observability",
|
|
8
8
|
"typescript",
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"test": "bun run test:unit && bun run test:browser"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@interfere/constants": "0.2.0-alpha.
|
|
68
|
-
"@interfere/react": "0.2.0-alpha.
|
|
69
|
-
"@interfere/sdk": "0.2.0-alpha.
|
|
70
|
-
"@interfere/types": "0.2.0-alpha.
|
|
67
|
+
"@interfere/constants": "0.2.0-alpha.4",
|
|
68
|
+
"@interfere/react": "0.2.0-alpha.5",
|
|
69
|
+
"@interfere/sdk": "0.2.0-alpha.5",
|
|
70
|
+
"@interfere/types": "0.2.0-alpha.5",
|
|
71
71
|
"chalk": "^5.6.2",
|
|
72
72
|
"glob": "^13.0.6",
|
|
73
73
|
"uuid": "^13.0.0"
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"react-dom": ">=19"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@interfere/typescript-config": "1.1.0-alpha.
|
|
83
|
-
"@interfere/vitest-config": "1.1.0-alpha.
|
|
82
|
+
"@interfere/typescript-config": "1.1.0-alpha.6",
|
|
83
|
+
"@interfere/vitest-config": "1.1.0-alpha.6",
|
|
84
84
|
"@testing-library/react": "^16.3.2",
|
|
85
85
|
"@types/node": "^24.12.0",
|
|
86
86
|
"@types/react": "19.2.14",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
//#region src/internal/build/injected.d.ts
|
|
2
|
-
interface InterfereBuildMetadata {
|
|
3
|
-
readonly buildId: string | null;
|
|
4
|
-
readonly releaseId: string | null;
|
|
5
|
-
}
|
|
6
|
-
interface InterfereInjectedValues {
|
|
7
|
-
readonly __INTERFERE_BUILD_ID__: string | null;
|
|
8
|
-
readonly __INTERFERE_RELEASE_ID__: string | null;
|
|
9
|
-
}
|
|
10
|
-
declare function buildInjectedValues(metadata: InterfereBuildMetadata): InterfereInjectedValues;
|
|
11
|
-
//#endregion
|
|
12
|
-
export { InterfereBuildMetadata, InterfereInjectedValues, buildInjectedValues };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injected.d.mts","names":[],"sources":["../../../src/internal/build/injected.ts"],"mappings":";UAAiB,sBAAA;EAAA,SACN,OAAA;EAAA,SACA,SAAA;AAAA;AAAA,UAGM,uBAAA;EAAA,SACN,sBAAA;EAAA,SACA,wBAAA;AAAA;AAAA,iBAGK,mBAAA,CACd,QAAA,EAAU,sBAAA,GACT,uBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"injected.mjs","names":[],"sources":["../../../src/internal/build/injected.ts"],"sourcesContent":["export interface InterfereBuildMetadata {\n readonly buildId: string | null;\n readonly releaseId: string | null;\n}\n\nexport interface InterfereInjectedValues {\n readonly __INTERFERE_BUILD_ID__: string | null;\n readonly __INTERFERE_RELEASE_ID__: string | null;\n}\n\nexport function buildInjectedValues(\n metadata: InterfereBuildMetadata\n): InterfereInjectedValues {\n return {\n __INTERFERE_BUILD_ID__: metadata.buildId,\n __INTERFERE_RELEASE_ID__: metadata.releaseId,\n };\n}\n"],"mappings":";AAUA,SAAgB,oBACd,UACyB;AACzB,QAAO;EACL,wBAAwB,SAAS;EACjC,0BAA0B,SAAS;EACpC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ReleaseDestinationMetadata, ReleaseSourceMetadata } from "@interfere/types/integrations";
|
|
2
|
-
|
|
3
|
-
//#region src/internal/build/release/types.d.ts
|
|
4
|
-
interface SourceResolver {
|
|
5
|
-
resolve(): ReleaseSourceMetadata;
|
|
6
|
-
}
|
|
7
|
-
interface DestinationResolver {
|
|
8
|
-
resolve(): ReleaseDestinationMetadata | null;
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { DestinationResolver, SourceResolver };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../src/internal/build/release/types.ts"],"mappings":";;;UAKiB,cAAA;EACf,OAAA,IAAW,qBAAA;AAAA;AAAA,UAGI,mBAAA;EACf,OAAA,IAAW,0BAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.mts","names":[],"sources":["../../../src/internal/route/cors.ts"],"mappings":";iBAOgB,aAAA,CAAA,GAAiB,QAAA"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
//#region src/internal/route/cors.ts
|
|
2
|
-
const CORS_HEADERS = {
|
|
3
|
-
"Access-Control-Allow-Origin": "*",
|
|
4
|
-
"Access-Control-Allow-Methods": "GET, POST, PUT, OPTIONS",
|
|
5
|
-
"Access-Control-Allow-Headers": "Content-Type",
|
|
6
|
-
"Access-Control-Max-Age": "86400"
|
|
7
|
-
};
|
|
8
|
-
function handleOptions() {
|
|
9
|
-
return new Response(null, {
|
|
10
|
-
status: 200,
|
|
11
|
-
headers: CORS_HEADERS
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
export { handleOptions };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cors.mjs","names":[],"sources":["../../../src/internal/route/cors.ts"],"sourcesContent":["const CORS_HEADERS = {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n \"Access-Control-Max-Age\": \"86400\",\n};\n\nexport function handleOptions(): Response {\n return new Response(null, {\n status: 200,\n headers: CORS_HEADERS,\n });\n}\n"],"mappings":";AAAA,MAAM,eAAe;CACnB,+BAA+B;CAC/B,gCAAgC;CAChC,gCAAgC;CAChC,0BAA0B;CAC3B;AAED,SAAgB,gBAA0B;AACxC,QAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,SAAS;EACV,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { ErrorMechanism } from "@interfere/types/sdk/plugins/payload/errors";
|
|
2
|
-
|
|
3
|
-
//#region src/internal/server/mechanisms.d.ts
|
|
4
|
-
declare const DEFAULT_ERROR_MECHANISM: ErrorMechanism;
|
|
5
|
-
declare const ON_REQUEST_ERROR_MECHANISM: ErrorMechanism;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { DEFAULT_ERROR_MECHANISM, ON_REQUEST_ERROR_MECHANISM };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mechanisms.d.mts","names":[],"sources":["../../../src/internal/server/mechanisms.ts"],"mappings":";;;cAEa,uBAAA,EAAyB,cAAA;AAAA,cAKzB,0BAAA,EAA4B,cAAA"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
//#region src/internal/server/mechanisms.ts
|
|
2
|
-
const DEFAULT_ERROR_MECHANISM = {
|
|
3
|
-
type: "captureError",
|
|
4
|
-
handled: true
|
|
5
|
-
};
|
|
6
|
-
const ON_REQUEST_ERROR_MECHANISM = {
|
|
7
|
-
type: "onRequestError",
|
|
8
|
-
handled: false,
|
|
9
|
-
synthetic: false
|
|
10
|
-
};
|
|
11
|
-
//#endregion
|
|
12
|
-
export { DEFAULT_ERROR_MECHANISM, ON_REQUEST_ERROR_MECHANISM };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mechanisms.mjs","names":[],"sources":["../../../src/internal/server/mechanisms.ts"],"sourcesContent":["import type { ErrorMechanism } from \"@interfere/types/sdk/plugins/payload/errors\";\n\nexport const DEFAULT_ERROR_MECHANISM: ErrorMechanism = {\n type: \"captureError\",\n handled: true,\n};\n\nexport const ON_REQUEST_ERROR_MECHANISM: ErrorMechanism = {\n type: \"onRequestError\",\n handled: false,\n synthetic: false,\n};\n"],"mappings":";AAEA,MAAa,0BAA0C;CACrD,MAAM;CACN,SAAS;CACV;AAED,MAAa,6BAA6C;CACxD,MAAM;CACN,SAAS;CACT,WAAW;CACZ"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { SessionId } from "@interfere/types/data/session";
|
|
2
|
-
import { SessionSource } from "@interfere/types/sdk/envelope";
|
|
3
|
-
|
|
4
|
-
//#region src/internal/server/session.d.ts
|
|
5
|
-
declare const SESSION_HEADER = "x-interfere-session";
|
|
6
|
-
declare function resolveSession(headers: Headers): {
|
|
7
|
-
readonly id: SessionId | null;
|
|
8
|
-
readonly source?: SessionSource;
|
|
9
|
-
};
|
|
10
|
-
//#endregion
|
|
11
|
-
export { SESSION_HEADER, resolveSession };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.mts","names":[],"sources":["../../../src/internal/server/session.ts"],"mappings":";;;;cAIa,cAAA;AAAA,iBAEG,cAAA,CAAe,OAAA,EAAS,OAAA;EAAA,SAC7B,EAAA,EAAI,SAAA;EAAA,SACJ,MAAA,GAAS,aAAA;AAAA"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { sessionIdSchema } from "@interfere/types/data/session";
|
|
2
|
-
//#region src/internal/server/session.ts
|
|
3
|
-
const SESSION_HEADER = "x-interfere-session";
|
|
4
|
-
function resolveSession(headers) {
|
|
5
|
-
const sessionId = headers.get(SESSION_HEADER);
|
|
6
|
-
if (sessionId === null) return { id: null };
|
|
7
|
-
const parsed = sessionIdSchema.safeParse(sessionId);
|
|
8
|
-
if (!parsed.success) return { id: null };
|
|
9
|
-
return {
|
|
10
|
-
id: parsed.data,
|
|
11
|
-
source: "header"
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
export { SESSION_HEADER, resolveSession };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.mjs","names":[],"sources":["../../../src/internal/server/session.ts"],"sourcesContent":["import type { SessionId } from \"@interfere/types/data/session\";\nimport { sessionIdSchema } from \"@interfere/types/data/session\";\nimport type { SessionSource } from \"@interfere/types/sdk/envelope\";\n\nexport const SESSION_HEADER = \"x-interfere-session\";\n\nexport function resolveSession(headers: Headers): {\n readonly id: SessionId | null;\n readonly source?: SessionSource;\n} {\n const sessionId = headers.get(SESSION_HEADER);\n if (sessionId === null) {\n return { id: null };\n }\n\n const parsed = sessionIdSchema.safeParse(sessionId);\n if (!parsed.success) {\n return { id: null };\n }\n\n return {\n id: parsed.data,\n source: \"header\",\n };\n}\n"],"mappings":";;AAIA,MAAa,iBAAiB;AAE9B,SAAgB,eAAe,SAG7B;CACA,MAAM,YAAY,QAAQ,IAAI,eAAe;AAC7C,KAAI,cAAc,KAChB,QAAO,EAAE,IAAI,MAAM;CAGrB,MAAM,SAAS,gBAAgB,UAAU,UAAU;AACnD,KAAI,CAAC,OAAO,QACV,QAAO,EAAE,IAAI,MAAM;AAGrB,QAAO;EACL,IAAI,OAAO;EACX,QAAQ;EACT"}
|
package/dist/server.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.mts","names":[],"sources":["../src/server.ts"],"mappings":";;;;cAUa,YAAA,SAAY,kBAAA;AAAA,cACZ,cAAA,SAAc,qBAAA"}
|
package/dist/server.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["import {\n captureOnRequestError,\n captureServerError,\n} from \"./internal/server/capture.js\";\n\nexport type {\n CaptureErrorContext,\n OnRequestErrorContext,\n} from \"./internal/server/types.js\";\n\nexport const captureError = captureServerError;\nexport const onRequestError = captureOnRequestError;\n"],"mappings":";;AAUA,MAAa,eAAe;AAC5B,MAAa,iBAAiB"}
|