@interfere/next 0.1.0-alpha.11 → 0.1.0-alpha.2
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 +70 -305
- package/dist/_virtual/_rolldown/runtime.mjs +11 -5
- package/dist/config.d.mts +11 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +116 -0
- package/dist/config.mjs.map +1 -0
- package/dist/instrument-client.d.mts +2 -0
- package/dist/instrument-client.mjs +2 -0
- package/dist/internal/build/configure-build.d.mts +22 -0
- package/dist/internal/build/configure-build.d.mts.map +1 -0
- package/dist/internal/build/configure-build.mjs +87 -0
- package/dist/internal/build/configure-build.mjs.map +1 -0
- package/dist/internal/build/injected.d.mts +12 -0
- package/dist/internal/build/injected.d.mts.map +1 -0
- package/dist/internal/build/injected.mjs +9 -0
- package/dist/internal/build/injected.mjs.map +1 -0
- package/dist/internal/build/logger.d.mts +8 -0
- package/dist/internal/build/logger.d.mts.map +1 -0
- package/dist/internal/build/logger.mjs +44 -0
- package/dist/internal/build/logger.mjs.map +1 -0
- package/dist/internal/build/release/destinations/vercel.d.mts +6 -0
- package/dist/internal/build/release/destinations/vercel.d.mts.map +1 -0
- package/dist/internal/build/release/destinations/vercel.mjs +25 -0
- package/dist/internal/build/release/destinations/vercel.mjs.map +1 -0
- package/dist/internal/build/release/git.d.mts +4 -0
- package/dist/internal/build/release/git.d.mts.map +1 -0
- package/dist/internal/build/release/git.mjs +21 -0
- package/dist/internal/build/release/git.mjs.map +1 -0
- package/dist/internal/build/release/index.d.mts +7 -0
- package/dist/internal/build/release/index.d.mts.map +1 -0
- package/dist/internal/build/release/index.mjs +26 -0
- package/dist/internal/build/release/index.mjs.map +1 -0
- package/dist/internal/build/release/sources/github.d.mts +6 -0
- package/dist/internal/build/release/sources/github.d.mts.map +1 -0
- package/dist/internal/build/release/sources/github.mjs +15 -0
- package/dist/internal/build/release/sources/github.mjs.map +1 -0
- package/dist/internal/build/release/types.d.mts +11 -0
- package/dist/internal/build/release/types.d.mts.map +1 -0
- package/dist/internal/build/release/types.mjs +1 -0
- package/dist/internal/build/source-maps/discover.d.mts +14 -0
- package/dist/internal/build/source-maps/discover.d.mts.map +1 -0
- package/dist/internal/build/source-maps/discover.mjs +61 -0
- package/dist/internal/build/source-maps/discover.mjs.map +1 -0
- package/dist/internal/build/source-maps/index.d.mts +23 -0
- package/dist/internal/build/source-maps/index.d.mts.map +1 -0
- package/dist/internal/build/source-maps/index.mjs +33 -0
- package/dist/internal/build/source-maps/index.mjs.map +1 -0
- package/dist/internal/build/value-injection-loader.d.mts +10 -0
- package/dist/internal/build/value-injection-loader.d.mts.map +1 -0
- package/dist/internal/build/value-injection-loader.mjs +24 -0
- package/dist/internal/build/value-injection-loader.mjs.map +1 -0
- package/dist/internal/env.d.mts +15 -0
- package/dist/internal/env.d.mts.map +1 -0
- package/dist/internal/env.mjs +18 -0
- package/dist/internal/env.mjs.map +1 -0
- package/dist/internal/route/cors.d.mts +4 -0
- package/dist/internal/route/cors.d.mts.map +1 -0
- package/dist/internal/route/cors.mjs +15 -0
- package/dist/internal/route/cors.mjs.map +1 -0
- package/dist/internal/route/handle-get.d.mts +4 -0
- package/dist/internal/route/handle-get.d.mts.map +1 -0
- package/dist/internal/route/handle-get.mjs +15 -0
- package/dist/internal/route/handle-get.mjs.map +1 -0
- package/dist/internal/route/handle-post.d.mts +4 -0
- package/dist/internal/route/handle-post.d.mts.map +1 -0
- package/dist/internal/route/handle-post.mjs +105 -0
- package/dist/internal/route/handle-post.mjs.map +1 -0
- package/dist/internal/route/sw-script.d.mts +4 -0
- package/dist/internal/route/sw-script.d.mts.map +1 -0
- package/dist/internal/route/sw-script.mjs +32 -0
- package/dist/internal/route/sw-script.mjs.map +1 -0
- package/dist/internal/server/capture.d.mts +9 -0
- package/dist/internal/server/capture.d.mts.map +1 -0
- package/dist/internal/server/capture.mjs +46 -0
- package/dist/internal/server/capture.mjs.map +1 -0
- package/dist/internal/server/dedupe.d.mts +5 -0
- package/dist/internal/server/dedupe.d.mts.map +1 -0
- package/dist/internal/server/dedupe.mjs +11 -0
- package/dist/internal/server/dedupe.mjs.map +1 -0
- package/dist/internal/server/envelope.d.mts +14 -0
- package/dist/internal/server/envelope.d.mts.map +1 -0
- package/dist/internal/server/envelope.mjs +41 -0
- package/dist/internal/server/envelope.mjs.map +1 -0
- package/dist/internal/server/mechanisms.d.mts +7 -0
- package/dist/internal/server/mechanisms.d.mts.map +1 -0
- package/dist/internal/server/mechanisms.mjs +12 -0
- package/dist/internal/server/mechanisms.mjs.map +1 -0
- package/dist/internal/server/normalize-request.d.mts +7 -0
- package/dist/internal/server/normalize-request.d.mts.map +1 -0
- package/dist/internal/server/normalize-request.mjs +50 -0
- package/dist/internal/server/normalize-request.mjs.map +1 -0
- package/dist/internal/server/runtime.d.mts +14 -0
- package/dist/internal/server/runtime.d.mts.map +1 -0
- package/dist/internal/server/runtime.mjs +18 -0
- package/dist/internal/server/runtime.mjs.map +1 -0
- package/dist/internal/server/session.d.mts +11 -0
- package/dist/internal/server/session.d.mts.map +1 -0
- package/dist/internal/server/session.mjs +15 -0
- package/dist/internal/server/session.mjs.map +1 -0
- package/dist/internal/server/transport.d.mts +12 -0
- package/dist/internal/server/transport.d.mts.map +1 -0
- package/dist/internal/server/transport.mjs +17 -0
- package/dist/internal/server/transport.mjs.map +1 -0
- package/dist/internal/server/types.d.mts +17 -0
- package/dist/internal/server/types.d.mts.map +1 -0
- package/dist/internal/server/types.mjs +1 -0
- package/dist/provider.d.mts +2 -0
- package/dist/provider.mjs +3 -0
- package/dist/route-handler.d.mts +7 -0
- package/dist/route-handler.d.mts.map +1 -0
- package/dist/route-handler.mjs +18 -0
- package/dist/route-handler.mjs.map +1 -0
- package/dist/server.d.mts +8 -0
- package/dist/server.d.mts.map +1 -0
- package/dist/server.mjs +6 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +52 -84
- package/LICENSE +0 -21
- package/dist/build/env-config.d.mts +0 -9
- package/dist/build/env-config.d.mts.map +0 -1
- package/dist/build/env-config.mjs +0 -25
- package/dist/build/env-config.mjs.map +0 -1
- package/dist/build/exchange-surface.d.mts +0 -9
- package/dist/build/exchange-surface.d.mts.map +0 -1
- package/dist/build/exchange-surface.mjs +0 -36
- package/dist/build/exchange-surface.mjs.map +0 -1
- package/dist/build/loaders/value-injection-loader.d.mts +0 -22
- package/dist/build/loaders/value-injection-loader.d.mts.map +0 -1
- package/dist/build/loaders/value-injection-loader.mjs +0 -35
- package/dist/build/loaders/value-injection-loader.mjs.map +0 -1
- package/dist/build/logger.d.mts +0 -11
- package/dist/build/logger.d.mts.map +0 -1
- package/dist/build/logger.mjs +0 -153
- package/dist/build/logger.mjs.map +0 -1
- package/dist/build/nextjs-version.d.mts +0 -40
- package/dist/build/nextjs-version.d.mts.map +0 -1
- package/dist/build/nextjs-version.mjs +0 -66
- package/dist/build/nextjs-version.mjs.map +0 -1
- package/dist/build/release-program.d.mts +0 -21
- package/dist/build/release-program.d.mts.map +0 -1
- package/dist/build/release-program.mjs +0 -91
- package/dist/build/release-program.mjs.map +0 -1
- package/dist/build/services/config.service.d.mts +0 -9
- package/dist/build/services/config.service.d.mts.map +0 -1
- package/dist/build/services/config.service.mjs +0 -8
- package/dist/build/services/config.service.mjs.map +0 -1
- package/dist/build/services/instrumentation-detection.service.d.mts +0 -19
- package/dist/build/services/instrumentation-detection.service.d.mts.map +0 -1
- package/dist/build/services/instrumentation-detection.service.mjs +0 -77
- package/dist/build/services/instrumentation-detection.service.mjs.map +0 -1
- package/dist/build/services/preflight.service.d.mts +0 -18
- package/dist/build/services/preflight.service.d.mts.map +0 -1
- package/dist/build/services/preflight.service.mjs +0 -67
- package/dist/build/services/preflight.service.mjs.map +0 -1
- package/dist/build/services/release-api.service.d.mts +0 -11
- package/dist/build/services/release-api.service.d.mts.map +0 -1
- package/dist/build/services/release-api.service.mjs +0 -9
- package/dist/build/services/release-api.service.mjs.map +0 -1
- package/dist/build/services/release-identity.service.d.mts +0 -23
- package/dist/build/services/release-identity.service.d.mts.map +0 -1
- package/dist/build/services/release-identity.service.mjs +0 -61
- package/dist/build/services/release-identity.service.mjs.map +0 -1
- package/dist/build/services/source-map-failure-cleanup.service.d.mts +0 -11
- package/dist/build/services/source-map-failure-cleanup.service.d.mts.map +0 -1
- package/dist/build/services/source-map-failure-cleanup.service.mjs +0 -9
- package/dist/build/services/source-map-failure-cleanup.service.mjs.map +0 -1
- package/dist/build/services/source-map.service.d.mts +0 -20
- package/dist/build/services/source-map.service.d.mts.map +0 -1
- package/dist/build/services/source-map.service.mjs +0 -56
- package/dist/build/services/source-map.service.mjs.map +0 -1
- package/dist/build/source-maps/api.d.mts +0 -44
- package/dist/build/source-maps/api.d.mts.map +0 -1
- package/dist/build/source-maps/api.mjs +0 -64
- package/dist/build/source-maps/api.mjs.map +0 -1
- package/dist/build/source-maps/client.d.mts +0 -82
- package/dist/build/source-maps/client.d.mts.map +0 -1
- package/dist/build/source-maps/client.mjs +0 -239
- package/dist/build/source-maps/client.mjs.map +0 -1
- package/dist/build/source-maps/errors.d.mts +0 -121
- package/dist/build/source-maps/errors.d.mts.map +0 -1
- package/dist/build/source-maps/errors.mjs +0 -46
- package/dist/build/source-maps/errors.mjs.map +0 -1
- package/dist/build/source-maps/files.d.mts +0 -35
- package/dist/build/source-maps/files.d.mts.map +0 -1
- package/dist/build/source-maps/files.mjs +0 -220
- package/dist/build/source-maps/files.mjs.map +0 -1
- package/dist/build/source-maps/providers/deployment/detector.d.mts +0 -17
- package/dist/build/source-maps/providers/deployment/detector.d.mts.map +0 -1
- package/dist/build/source-maps/providers/deployment/detector.mjs +0 -20
- package/dist/build/source-maps/providers/deployment/detector.mjs.map +0 -1
- package/dist/build/source-maps/providers/deployment/types.d.mts +0 -12
- package/dist/build/source-maps/providers/deployment/types.d.mts.map +0 -1
- package/dist/build/source-maps/providers/deployment/types.mjs +0 -3
- package/dist/build/source-maps/providers/deployment/vercel.d.mts +0 -6
- package/dist/build/source-maps/providers/deployment/vercel.d.mts.map +0 -1
- package/dist/build/source-maps/providers/deployment/vercel.mjs +0 -33
- package/dist/build/source-maps/providers/deployment/vercel.mjs.map +0 -1
- package/dist/build/source-maps/providers/source-control/detector.d.mts +0 -16
- package/dist/build/source-maps/providers/source-control/detector.d.mts.map +0 -1
- package/dist/build/source-maps/providers/source-control/detector.mjs +0 -20
- package/dist/build/source-maps/providers/source-control/detector.mjs.map +0 -1
- package/dist/build/source-maps/providers/source-control/git.d.mts +0 -6
- package/dist/build/source-maps/providers/source-control/git.d.mts.map +0 -1
- package/dist/build/source-maps/providers/source-control/git.mjs +0 -47
- package/dist/build/source-maps/providers/source-control/git.mjs.map +0 -1
- package/dist/build/source-maps/providers/source-control/types.d.mts +0 -14
- package/dist/build/source-maps/providers/source-control/types.d.mts.map +0 -1
- package/dist/build/source-maps/providers/source-control/types.mjs +0 -3
- package/dist/build/with-interfere.d.mts +0 -70
- package/dist/build/with-interfere.d.mts.map +0 -1
- package/dist/build/with-interfere.mjs +0 -182
- package/dist/build/with-interfere.mjs.map +0 -1
- package/dist/client/auto-init.d.mts +0 -91
- package/dist/client/auto-init.d.mts.map +0 -1
- package/dist/client/auto-init.mjs +0 -121
- package/dist/client/auto-init.mjs.map +0 -1
- package/dist/client/client.d.mts +0 -3
- package/dist/client/client.mjs +0 -5
- package/dist/client/provider.d.mts +0 -22
- package/dist/client/provider.d.mts.map +0 -1
- package/dist/client/provider.mjs +0 -50
- package/dist/client/provider.mjs.map +0 -1
- package/dist/lib/env.d.mts +0 -12
- package/dist/lib/env.d.mts.map +0 -1
- package/dist/lib/env.mjs +0 -17
- package/dist/lib/env.mjs.map +0 -1
- package/dist/lib/types.d.mts +0 -22
- package/dist/lib/types.d.mts.map +0 -1
- package/dist/lib/types.mjs +0 -7
- package/dist/lib/types.mjs.map +0 -1
- package/dist/server/auto-init.d.mts +0 -88
- package/dist/server/auto-init.d.mts.map +0 -1
- package/dist/server/auto-init.mjs +0 -101
- package/dist/server/auto-init.mjs.map +0 -1
- package/dist/server/middleware.d.mts +0 -11
- package/dist/server/middleware.d.mts.map +0 -1
- package/dist/server/middleware.mjs +0 -92
- package/dist/server/middleware.mjs.map +0 -1
- package/dist/server/on-request-error.d.mts +0 -27
- package/dist/server/on-request-error.d.mts.map +0 -1
- package/dist/server/on-request-error.mjs +0 -74
- package/dist/server/on-request-error.mjs.map +0 -1
- package/dist/server/proxy.d.mts +0 -6
- package/dist/server/proxy.d.mts.map +0 -1
- package/dist/server/proxy.mjs +0 -29
- package/dist/server/proxy.mjs.map +0 -1
- package/dist/server/route-handler.d.mts +0 -39
- package/dist/server/route-handler.d.mts.map +0 -1
- package/dist/server/route-handler.mjs +0 -171
- package/dist/server/route-handler.mjs.map +0 -1
- package/dist/server/sdk.d.mts +0 -96
- package/dist/server/sdk.d.mts.map +0 -1
- package/dist/server/sdk.mjs +0 -152
- package/dist/server/sdk.mjs.map +0 -1
- package/dist/server/services/config.service.d.mts +0 -48
- package/dist/server/services/config.service.d.mts.map +0 -1
- package/dist/server/services/config.service.mjs +0 -67
- package/dist/server/services/config.service.mjs.map +0 -1
- package/dist/server/services/error-tracking.service.d.mts +0 -19
- package/dist/server/services/error-tracking.service.d.mts.map +0 -1
- package/dist/server/services/error-tracking.service.mjs +0 -33
- package/dist/server/services/error-tracking.service.mjs.map +0 -1
- package/dist/server/session-context.d.mts +0 -60
- package/dist/server/session-context.d.mts.map +0 -1
- package/dist/server/session-context.mjs +0 -62
- package/dist/server/session-context.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,84 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://interfere.com">
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://qyzkf4cgb8ydxtq1.public.blob.vercel-storage.com/v2/header/logo-dark.png">
|
|
5
|
+
<img src="https://qyzkf4cgb8ydxtq1.public.blob.vercel-storage.com/v2/header/logo-light.png" height="64">
|
|
6
|
+
</picture>
|
|
7
|
+
</a>
|
|
8
|
+
<h1 align="center">@interfere/next</h1>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/@interfere/next"><img src="https://img.shields.io/npm/v/@interfere/next.svg" /></a>
|
|
13
|
+
<a href="https://github.com/interfere-inc/interfere/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@interfere/next.svg" /></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@interfere/next"><img src="https://img.shields.io/npm/dm/@interfere/next.svg" /></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
Next.js SDK for <a href="https://interfere.com">Interfere</a> — error tracking, session replay, and analytics for modern product teams.
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<a href="https://interfere.com/docs">Documentation</a>
|
|
23
|
+
·
|
|
24
|
+
<a href="https://github.com/interfere-inc/interfere/issues/new">Report a Bug</a>
|
|
25
|
+
·
|
|
26
|
+
<a href="mailto:support@interfere.com">Get Help</a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Getting Started
|
|
32
|
+
|
|
33
|
+
### Prerequisites
|
|
34
|
+
|
|
35
|
+
- Next.js `>=16`
|
|
36
|
+
- React `>=19`
|
|
37
|
+
- Node.js `>=20`
|
|
38
|
+
|
|
39
|
+
### Installation
|
|
6
40
|
|
|
7
41
|
```bash
|
|
8
42
|
npm install @interfere/next
|
|
9
|
-
# or
|
|
10
|
-
yarn add @interfere/next
|
|
11
|
-
# or
|
|
12
|
-
bun add @interfere/next
|
|
13
43
|
```
|
|
14
44
|
|
|
15
|
-
|
|
45
|
+
### Quick Start
|
|
16
46
|
|
|
17
|
-
|
|
47
|
+
**1. Wrap your Next.js config**
|
|
18
48
|
|
|
19
|
-
|
|
49
|
+
```ts
|
|
50
|
+
// next.config.ts
|
|
51
|
+
import { withInterfere } from "@interfere/next/config";
|
|
52
|
+
import type { NextConfig } from "next";
|
|
20
53
|
|
|
21
|
-
|
|
54
|
+
const config: NextConfig = {};
|
|
22
55
|
|
|
23
|
-
|
|
24
|
-
import { captureRequestError } from '@interfere/next/server/on-request-error';
|
|
25
|
-
|
|
26
|
-
export async function register() {
|
|
27
|
-
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
28
|
-
const { autoInitServer } = await import('@interfere/next/server/auto-init');
|
|
29
|
-
autoInitServer();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function onRequestError(error, request, context) {
|
|
34
|
-
await captureRequestError({ error, request, context });
|
|
35
|
-
}
|
|
56
|
+
export default withInterfere(config);
|
|
36
57
|
```
|
|
37
58
|
|
|
38
|
-
|
|
39
|
-
- **routerKind**: "App Router" or "Pages Router"
|
|
40
|
-
- **routePath**: The route file path (e.g., `/app/api/users/route`)
|
|
41
|
-
- **routeType**: "render", "route", "action", "middleware", or "proxy"
|
|
42
|
-
- **renderSource**: For render errors - "react-server-components", "server-rendering", etc.
|
|
43
|
-
- **error.digest**: Unique error identifier for deduplication
|
|
44
|
-
|
|
45
|
-
### 2. Initialize the Client SDK
|
|
59
|
+
**2. Wire instrumentation**
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
import { init } from '@interfere/next';
|
|
51
|
-
|
|
52
|
-
export const interfere = init({
|
|
53
|
-
project: process.env.NEXT_PUBLIC_INTERFERE_PROJECT_ID!,
|
|
54
|
-
options: {
|
|
55
|
-
env: process.env.NODE_ENV as 'development' | 'preview' | 'production',
|
|
56
|
-
debug: process.env.NODE_ENV === 'development',
|
|
57
|
-
},
|
|
58
|
-
});
|
|
61
|
+
```ts
|
|
62
|
+
// instrumentation.ts
|
|
63
|
+
export { onRequestError } from "@interfere/next/server";
|
|
59
64
|
```
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
The SDK sends events through a server-side proxy route to keep your API credentials secure. Create `app/api/interfere/[[...path]]/route.ts`:
|
|
66
|
+
**3. Mount the ingest route**
|
|
64
67
|
|
|
65
|
-
```
|
|
66
|
-
|
|
68
|
+
```ts
|
|
69
|
+
// app/api/interfere/[[...path]]/route.ts
|
|
70
|
+
export { GET, POST, OPTIONS } from "@interfere/next/route-handler";
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
INTERFERE_API_KEY=ak_xxx
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### 4. Add Error Boundary (App Directory)
|
|
76
|
-
|
|
77
|
-
In your root layout (`app/layout.tsx`):
|
|
73
|
+
**4. Add the provider**
|
|
78
74
|
|
|
79
75
|
```tsx
|
|
80
|
-
|
|
81
|
-
import {
|
|
76
|
+
// app/layout.tsx
|
|
77
|
+
import { InterfereProvider } from "@interfere/next/provider";
|
|
82
78
|
|
|
83
79
|
export default function RootLayout({
|
|
84
80
|
children,
|
|
@@ -88,258 +84,27 @@ export default function RootLayout({
|
|
|
88
84
|
return (
|
|
89
85
|
<html lang="en">
|
|
90
86
|
<body>
|
|
91
|
-
<InterfereProvider>
|
|
92
|
-
<InterfereErrorBoundary>
|
|
93
|
-
{children}
|
|
94
|
-
</InterfereErrorBoundary>
|
|
95
|
-
</InterfereProvider>
|
|
87
|
+
<InterfereProvider>{children}</InterfereProvider>
|
|
96
88
|
</body>
|
|
97
89
|
</html>
|
|
98
90
|
);
|
|
99
91
|
}
|
|
100
92
|
```
|
|
101
93
|
|
|
102
|
-
###
|
|
103
|
-
|
|
104
|
-
Create `app/error.tsx`:
|
|
105
|
-
|
|
106
|
-
```tsx
|
|
107
|
-
'use client';
|
|
108
|
-
|
|
109
|
-
import { useEffect } from 'react';
|
|
110
|
-
import { captureErrorBoundaryError } from '@interfere/next';
|
|
111
|
-
|
|
112
|
-
export default function Error({
|
|
113
|
-
error,
|
|
114
|
-
reset,
|
|
115
|
-
}: {
|
|
116
|
-
error: Error & { digest?: string };
|
|
117
|
-
reset: () => void;
|
|
118
|
-
}) {
|
|
119
|
-
useEffect(() => {
|
|
120
|
-
captureErrorBoundaryError(error, {
|
|
121
|
-
componentStack: error.stack || '',
|
|
122
|
-
});
|
|
123
|
-
}, [error]);
|
|
124
|
-
|
|
125
|
-
return (
|
|
126
|
-
<div>
|
|
127
|
-
<h2>Something went wrong!</h2>
|
|
128
|
-
<button onClick={() => reset()}>Try again</button>
|
|
129
|
-
</div>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 6. Add Global Error Handler
|
|
135
|
-
|
|
136
|
-
Create `app/global-error.tsx`:
|
|
137
|
-
|
|
138
|
-
```tsx
|
|
139
|
-
'use client';
|
|
140
|
-
|
|
141
|
-
import { createInterfereErrorHandler } from '@interfere/next';
|
|
142
|
-
|
|
143
|
-
const errorHandler = createInterfereErrorHandler();
|
|
144
|
-
|
|
145
|
-
export default function GlobalError({
|
|
146
|
-
error,
|
|
147
|
-
reset,
|
|
148
|
-
}: {
|
|
149
|
-
error: Error & { digest?: string };
|
|
150
|
-
reset: () => void;
|
|
151
|
-
}) {
|
|
152
|
-
errorHandler(error, { digest: error.digest });
|
|
153
|
-
|
|
154
|
-
return (
|
|
155
|
-
<html>
|
|
156
|
-
<body>
|
|
157
|
-
<h2>Something went wrong!</h2>
|
|
158
|
-
<button onClick={() => reset()}>Try again</button>
|
|
159
|
-
</body>
|
|
160
|
-
</html>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## API Routes
|
|
166
|
-
|
|
167
|
-
### Automatic Error Capture
|
|
168
|
-
|
|
169
|
-
Wrap your API route handlers:
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// app/api/users/route.ts
|
|
173
|
-
import { withInterfereApiRoute } from '@interfere/next';
|
|
174
|
-
|
|
175
|
-
export const GET = withInterfereApiRoute(async (request) => {
|
|
176
|
-
// Your API logic here
|
|
177
|
-
const users = await fetchUsers();
|
|
178
|
-
return Response.json(users);
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Manual Error Capture
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
// app/api/webhook/route.ts
|
|
186
|
-
import { captureServerError } from '@interfere/next';
|
|
187
|
-
|
|
188
|
-
export async function POST(request: Request) {
|
|
189
|
-
try {
|
|
190
|
-
const body = await request.json();
|
|
191
|
-
// Process webhook
|
|
192
|
-
} catch (error) {
|
|
193
|
-
captureServerError(error, request, {
|
|
194
|
-
pathname: '/api/webhook',
|
|
195
|
-
type: 'webhook_error',
|
|
196
|
-
});
|
|
197
|
-
return Response.json({ error: 'Webhook failed' }, { status: 500 });
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## Middleware
|
|
203
|
-
|
|
204
|
-
Wrap your middleware to capture errors:
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
// middleware.ts
|
|
208
|
-
import { withInterfereMiddleware } from '@interfere/next';
|
|
209
|
-
import { NextResponse } from 'next/server';
|
|
210
|
-
|
|
211
|
-
export default withInterfereMiddleware(async (request) => {
|
|
212
|
-
// Your middleware logic
|
|
213
|
-
return NextResponse.next();
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
export const config = {
|
|
217
|
-
matcher: '/api/:path*',
|
|
218
|
-
};
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## Server Components
|
|
94
|
+
### Environment Variables
|
|
222
95
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// app/dashboard/page.tsx
|
|
227
|
-
import { withInterfereServerComponent } from '@interfere/next';
|
|
228
|
-
|
|
229
|
-
async function DashboardPage() {
|
|
230
|
-
const data = await fetchDashboardData();
|
|
231
|
-
return <Dashboard data={data} />;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export default withInterfereServerComponent(DashboardPage, 'DashboardPage');
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
## Custom Event Capture
|
|
238
|
-
|
|
239
|
-
Capture custom events and errors:
|
|
240
|
-
|
|
241
|
-
```typescript
|
|
242
|
-
import { capture, captureServerError } from '@interfere/next';
|
|
243
|
-
|
|
244
|
-
// Capture custom events
|
|
245
|
-
capture('custom', {
|
|
246
|
-
action: 'user_signup',
|
|
247
|
-
userId: user.id,
|
|
248
|
-
plan: 'premium',
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Capture handled errors
|
|
252
|
-
try {
|
|
253
|
-
await riskyOperation();
|
|
254
|
-
} catch (error) {
|
|
255
|
-
captureServerError(error, undefined, {
|
|
256
|
-
operation: 'risky_operation',
|
|
257
|
-
context: { userId: user.id },
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
```
|
|
96
|
+
| Variable | Required | Description |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| `INTERFERE_API_KEY` | Yes | Your project API key |
|
|
261
99
|
|
|
262
|
-
##
|
|
100
|
+
## What's Included
|
|
263
101
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
import { useInterfere } from '@interfere/next';
|
|
270
|
-
|
|
271
|
-
export function Button() {
|
|
272
|
-
const { capture } = useInterfere();
|
|
273
|
-
|
|
274
|
-
const handleClick = () => {
|
|
275
|
-
capture('ui_event', {
|
|
276
|
-
action: 'button_click',
|
|
277
|
-
label: 'cta_button',
|
|
278
|
-
});
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
return <button onClick={handleClick}>Click me</button>;
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
## Configuration Options
|
|
286
|
-
|
|
287
|
-
```typescript
|
|
288
|
-
init({
|
|
289
|
-
project: 'if_proj_xxx', // Your project ID
|
|
290
|
-
options: {
|
|
291
|
-
env: 'production', // 'development' | 'preview' | 'production'
|
|
292
|
-
flushInterval: 5000, // Flush interval in ms (client-side only)
|
|
293
|
-
debug: false, // Enable debug logging
|
|
294
|
-
sessionId: 'custom-session-id', // Optional custom session ID
|
|
295
|
-
},
|
|
296
|
-
});
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Event Types
|
|
300
|
-
|
|
301
|
-
The SDK automatically captures these event types:
|
|
302
|
-
|
|
303
|
-
- `error` - Runtime errors (client, server, and edge); origin is indicated by `errorSource` in the payload (`client` | `server` | `edge`).
|
|
304
|
-
- `ui_event` - User interface events
|
|
305
|
-
- `custom` - Custom application events
|
|
306
|
-
- `rage_click` - rage clicks
|
|
307
|
-
|
|
308
|
-
## Best Practices
|
|
309
|
-
|
|
310
|
-
1. **Initialize Early**: Initialize Interfere as early as possible in your application lifecycle.
|
|
311
|
-
|
|
312
|
-
2. **Use Error Boundaries**: Always wrap your app with `InterfereErrorBoundary` to catch React errors.
|
|
313
|
-
|
|
314
|
-
3. **Wrap Async Functions**: Use `withErrorCapture` or specific wrappers for automatic error tracking.
|
|
315
|
-
|
|
316
|
-
4. **Add Context**: Include relevant context when capturing errors manually:
|
|
317
|
-
```typescript
|
|
318
|
-
captureServerError(error, request, {
|
|
319
|
-
userId: session.userId,
|
|
320
|
-
action: 'update_profile',
|
|
321
|
-
metadata: { ... },
|
|
322
|
-
});
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
5. **Environment Variables**: Store your project ID in environment variables:
|
|
326
|
-
```bash
|
|
327
|
-
NEXT_PUBLIC_INTERFERE_PROJECT_ID=if_proj_xxx
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## TypeScript
|
|
331
|
-
|
|
332
|
-
The SDK is fully typed. Import types as needed:
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
import type {
|
|
336
|
-
Config,
|
|
337
|
-
InitConfig,
|
|
338
|
-
EventType,
|
|
339
|
-
Envelope,
|
|
340
|
-
} from '@interfere/next';
|
|
341
|
-
```
|
|
102
|
+
- **Error tracking** — automatic capture of server and client errors with rich stack traces
|
|
103
|
+
- **Session replay** — full visual playback of user sessions
|
|
104
|
+
- **Source maps** — automatic upload during production builds
|
|
105
|
+
- **Release tracking** — links builds to Git commits and deployments
|
|
106
|
+
- **Server capture** — `captureError()` for manual server-side error reporting
|
|
342
107
|
|
|
343
108
|
## License
|
|
344
109
|
|
|
345
|
-
MIT
|
|
110
|
+
MIT
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
|
|
3
1
|
//#region \0rolldown/runtime.js
|
|
4
|
-
var
|
|
5
|
-
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
6
12
|
//#endregion
|
|
7
|
-
export {
|
|
13
|
+
export { __exportAll };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Envelope } from "@interfere/types/sdk/envelope";
|
|
2
|
+
import { NextConfig } from "next";
|
|
3
|
+
|
|
4
|
+
//#region src/config.d.ts
|
|
5
|
+
interface InterfereConfig extends Partial<Pick<Envelope, "buildId" | "releaseId">> {}
|
|
6
|
+
type NextConfigWithInterfere = NextConfig & {
|
|
7
|
+
interfere?: InterfereConfig;
|
|
8
|
+
};
|
|
9
|
+
declare function withInterfere(nextConfig?: NextConfigWithInterfere): NextConfig;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { InterfereConfig, NextConfigWithInterfere, withInterfere };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;UAkBiB,eAAA,SACP,OAAA,CAAQ,IAAA,CAAK,QAAA;AAAA,KAEX,uBAAA,GAA0B,UAAA;EACpC,SAAA,GAAY,eAAA;AAAA;AAAA,iBAGE,aAAA,CACd,UAAA,GAAY,uBAAA,GACX,UAAA"}
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { configureBuild } from "./internal/build/configure-build.mjs";
|
|
2
|
+
import { buildInjectedValues } from "./internal/build/injected.mjs";
|
|
3
|
+
import { buildLog } from "./internal/build/logger.mjs";
|
|
4
|
+
import { runGitCommand } from "./internal/build/release/git.mjs";
|
|
5
|
+
import { readInterfereEnv } from "./internal/env.mjs";
|
|
6
|
+
import { releaseDestinationIdEnvKeys, releaseSourceIdEnvKeys } from "@interfere/types/integrations";
|
|
7
|
+
import { parseEnvValue, readFirstEnvValue } from "@interfere/types/sdk/env";
|
|
8
|
+
//#region src/config.ts
|
|
9
|
+
function withInterfere(nextConfig = {}) {
|
|
10
|
+
const { interfere, env: userEnv, webpack, turbopack, compiler, productionBrowserSourceMaps, ...rest } = nextConfig;
|
|
11
|
+
const metadata = resolveBuildMetadata(interfere);
|
|
12
|
+
const injectedValues = buildInjectedValues(metadata);
|
|
13
|
+
const hasApiKey = readInterfereEnv().apiKey !== null;
|
|
14
|
+
const build = configureBuild({
|
|
15
|
+
existingWebpack: webpack,
|
|
16
|
+
existingTurbopack: turbopack,
|
|
17
|
+
projectDir: process.cwd(),
|
|
18
|
+
values: injectedValues
|
|
19
|
+
});
|
|
20
|
+
if (hasApiKey && !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");
|
|
21
|
+
return {
|
|
22
|
+
...rest,
|
|
23
|
+
env: mergeEnvConfig(userEnv, metadata),
|
|
24
|
+
compiler: buildCompilerConfig(compiler, hasApiKey),
|
|
25
|
+
webpack: build.webpack,
|
|
26
|
+
turbopack: build.turbopack,
|
|
27
|
+
productionBrowserSourceMaps: hasApiKey ? true : productionBrowserSourceMaps
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function resolveBuildMetadata(config) {
|
|
31
|
+
const buildId = parseEnvValue(config?.buildId) ?? readFirstEnvValue(process.env, releaseSourceIdEnvKeys) ?? runGitCommand("git rev-parse HEAD");
|
|
32
|
+
return {
|
|
33
|
+
buildId,
|
|
34
|
+
releaseId: parseEnvValue(config?.releaseId) ?? readFirstEnvValue(process.env, releaseDestinationIdEnvKeys) ?? buildId
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function mergeEnvConfig(userEnv, metadata) {
|
|
38
|
+
const merged = {};
|
|
39
|
+
if (metadata.buildId !== null) merged.NEXT_PUBLIC_INTERFERE_BUILD_ID = metadata.buildId;
|
|
40
|
+
if (metadata.releaseId !== null) merged.NEXT_PUBLIC_INTERFERE_RELEASE_ID = metadata.releaseId;
|
|
41
|
+
return {
|
|
42
|
+
...merged,
|
|
43
|
+
...userEnv
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function buildCompilerConfig(existingCompiler, enabled) {
|
|
47
|
+
const compiler = existingCompiler;
|
|
48
|
+
const existingHook = compiler?.runAfterProductionCompile;
|
|
49
|
+
if (!(existingHook || enabled)) return existingCompiler;
|
|
50
|
+
return {
|
|
51
|
+
...compiler ?? {},
|
|
52
|
+
async runAfterProductionCompile(context) {
|
|
53
|
+
if (existingHook) await existingHook(context);
|
|
54
|
+
if (enabled) await runBuildReleasePipeline(context);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async function runBuildReleasePipeline(context) {
|
|
59
|
+
const env = readInterfereEnv();
|
|
60
|
+
const { apiKey, apiUrl } = env;
|
|
61
|
+
if (apiKey === null) {
|
|
62
|
+
buildLog.warn("Skipping", ["Missing INTERFERE_API_KEY."]);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const buildId = env.release.sourceId;
|
|
66
|
+
if (buildId === null) {
|
|
67
|
+
buildLog.error("Build ID missing", [
|
|
68
|
+
"Could not resolve a build ID from config, environment variables, or git.",
|
|
69
|
+
"Source maps will not be uploaded and errors will have unresolved stack traces.",
|
|
70
|
+
"Set INTERFERE_BUILD_ID, or ensure git is available in your build environment."
|
|
71
|
+
]);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const { createRelease } = await import("./internal/build/release/index.mjs");
|
|
75
|
+
const { runSourceMapPipeline } = await import("./internal/build/source-maps/index.mjs");
|
|
76
|
+
const client = {
|
|
77
|
+
async createRelease() {
|
|
78
|
+
const release = await createRelease(apiKey, buildId);
|
|
79
|
+
return {
|
|
80
|
+
slug: release.destination.slug,
|
|
81
|
+
orgSlug: release.org.slug,
|
|
82
|
+
buildId: release.build.hash ?? buildId
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
async uploadSourceMaps(releaseSlug, body) {
|
|
86
|
+
const url = `${apiUrl}/v1/releases/${releaseSlug}/source-maps`;
|
|
87
|
+
const response = await fetch(url, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: { "x-api-key": apiKey },
|
|
90
|
+
body
|
|
91
|
+
});
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
const text = await response.text().catch(() => "");
|
|
94
|
+
throw new Error(`Source map upload failed: ${response.status} ${response.statusText} ${text}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
try {
|
|
99
|
+
const result = await runSourceMapPipeline(context.projectDir, context.distDir, client);
|
|
100
|
+
if (!result.ready) {
|
|
101
|
+
buildLog.warn("Skipping", ["No source maps found"]);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
buildLog.info("Completed", [
|
|
105
|
+
`https://interfere.com/~/${result.orgSlug}`,
|
|
106
|
+
`Release: ${result.releaseSlug}`,
|
|
107
|
+
`Build: ${result.buildId}`,
|
|
108
|
+
`Artifacts: ${result.fileCount} source maps`
|
|
109
|
+
]);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
buildLog.error("Error", [error instanceof Error ? error.message : String(error)]);
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { withInterfere };
|
|
@@ -0,0 +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 {\n buildInjectedValues,\n type InterfereBuildMetadata,\n} from \"./internal/build/injected.js\";\nimport { buildLog } from \"./internal/build/logger.js\";\nimport { runGitCommand } from \"./internal/build/release/git.js\";\nimport { readInterfereEnv } from \"./internal/env.js\";\n\nexport interface InterfereConfig\n extends Partial<Pick<Envelope, \"buildId\" | \"releaseId\">> {}\n\nexport type NextConfigWithInterfere = NextConfig & {\n interfere?: InterfereConfig;\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 const metadata = resolveBuildMetadata(interfere);\n const injectedValues = buildInjectedValues(metadata);\n const hasApiKey = readInterfereEnv().apiKey !== null;\n const build = configureBuild({\n existingWebpack: webpack,\n existingTurbopack: turbopack,\n projectDir: process.cwd(),\n values: injectedValues,\n });\n\n if (hasApiKey && !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 return {\n ...rest,\n env: mergeEnvConfig(userEnv, metadata),\n compiler: buildCompilerConfig(compiler, hasApiKey),\n webpack: build.webpack,\n turbopack: build.turbopack,\n productionBrowserSourceMaps: hasApiKey ? true : productionBrowserSourceMaps,\n };\n}\n\nfunction resolveBuildMetadata(\n config?: InterfereConfig\n): InterfereBuildMetadata {\n const buildId =\n parseEnvValue(config?.buildId) ??\n readFirstEnvValue(process.env, releaseSourceIdEnvKeys) ??\n runGitCommand(\"git rev-parse HEAD\");\n const releaseId =\n parseEnvValue(config?.releaseId) ??\n readFirstEnvValue(process.env, releaseDestinationIdEnvKeys) ??\n buildId;\n\n return { buildId, releaseId };\n}\n\nfunction mergeEnvConfig(\n userEnv: NextConfig[\"env\"] | undefined,\n metadata: InterfereBuildMetadata\n): NextConfig[\"env\"] {\n const merged: Record<string, string> = {};\n\n if (metadata.buildId !== null) {\n merged.NEXT_PUBLIC_INTERFERE_BUILD_ID = metadata.buildId;\n }\n\n if (metadata.releaseId !== null) {\n merged.NEXT_PUBLIC_INTERFERE_RELEASE_ID = metadata.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\nfunction buildCompilerConfig(\n existingCompiler: NextConfig[\"compiler\"] | undefined,\n enabled: boolean\n): NextConfig[\"compiler\"] | undefined {\n const compiler = existingCompiler as\n | NextCompilerWithProductionHook\n | undefined;\n const existingHook = compiler?.runAfterProductionCompile;\n\n if (!(existingHook || enabled)) {\n return existingCompiler;\n }\n\n return {\n ...(compiler ?? {}),\n async runAfterProductionCompile(context: ProductionCompileContext) {\n if (existingHook) {\n await existingHook(context);\n }\n\n if (enabled) {\n await runBuildReleasePipeline(context);\n }\n },\n } as NextConfig[\"compiler\"];\n}\n\nasync function runBuildReleasePipeline(\n context: ProductionCompileContext\n): Promise<void> {\n const env = readInterfereEnv();\n\n const { apiKey, apiUrl } = env;\n\n if (apiKey === null) {\n buildLog.warn(\"Skipping\", [\"Missing INTERFERE_API_KEY.\"]);\n return;\n }\n\n const buildId = env.release.sourceId;\n\n if (buildId === null) {\n buildLog.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, 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 buildLog.warn(\"Skipping\", [\"No source maps found\"]);\n return;\n }\n\n buildLog.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 buildLog.error(\"Error\", [\n error instanceof Error ? error.message : String(error),\n ]);\n throw error;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InterfereInjectedValues } from "./injected.mjs";
|
|
2
|
+
import { NextConfig } from "next";
|
|
3
|
+
|
|
4
|
+
//#region src/internal/build/configure-build.d.ts
|
|
5
|
+
interface ConfigureBuildInput {
|
|
6
|
+
readonly existingWebpack: NextConfig["webpack"] | undefined;
|
|
7
|
+
readonly existingTurbopack: NextConfig["turbopack"] | undefined;
|
|
8
|
+
readonly projectDir: string;
|
|
9
|
+
readonly values: InterfereInjectedValues;
|
|
10
|
+
}
|
|
11
|
+
interface ConfigureBuildOutput {
|
|
12
|
+
readonly webpack: NextConfig["webpack"] | undefined;
|
|
13
|
+
readonly turbopack: NextConfig["turbopack"] | undefined;
|
|
14
|
+
}
|
|
15
|
+
declare function configureBuild({
|
|
16
|
+
existingWebpack,
|
|
17
|
+
existingTurbopack,
|
|
18
|
+
projectDir,
|
|
19
|
+
values
|
|
20
|
+
}: ConfigureBuildInput): ConfigureBuildOutput;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { configureBuild };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-build.d.mts","names":[],"sources":["../../../src/internal/build/configure-build.ts"],"mappings":";;;;UAyBU,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"}
|