@interfere/next 0.0.13 → 0.0.15-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -6
- package/dist/build/env-config.d.mts +7 -0
- package/dist/build/env-config.d.mts.map +1 -0
- package/dist/build/env-config.mjs +17 -0
- package/dist/build/env-config.mjs.map +1 -0
- package/dist/build/logger.d.mts +11 -0
- package/dist/build/logger.d.mts.map +1 -0
- package/dist/build/logger.mjs +155 -0
- package/dist/build/logger.mjs.map +1 -0
- package/dist/build/release-program.d.mts +19 -0
- package/dist/build/release-program.d.mts.map +1 -0
- package/dist/build/release-program.mjs +92 -0
- package/dist/build/release-program.mjs.map +1 -0
- package/dist/build/secret-key.d.mts +10 -0
- package/dist/build/secret-key.d.mts.map +1 -0
- package/dist/build/secret-key.mjs +16 -0
- package/dist/build/secret-key.mjs.map +1 -0
- package/dist/build/services/config.service.d.mts +9 -0
- package/dist/build/services/config.service.d.mts.map +1 -0
- package/dist/build/services/config.service.mjs +8 -0
- package/dist/build/services/config.service.mjs.map +1 -0
- package/dist/build/services/preflight.service.d.mts +19 -0
- package/dist/build/services/preflight.service.d.mts.map +1 -0
- package/dist/build/services/preflight.service.mjs +76 -0
- package/dist/build/services/preflight.service.mjs.map +1 -0
- package/dist/build/services/release-identity.service.d.mts +22 -0
- package/dist/build/services/release-identity.service.d.mts.map +1 -0
- package/dist/build/services/release-identity.service.mjs +48 -0
- package/dist/build/services/release-identity.service.mjs.map +1 -0
- package/dist/build/services/source-map.service.d.mts +24 -0
- package/dist/build/services/source-map.service.d.mts.map +1 -0
- package/dist/build/services/source-map.service.mjs +58 -0
- package/dist/build/services/source-map.service.mjs.map +1 -0
- package/dist/build/source-maps/api.d.mts +35 -0
- package/dist/build/source-maps/api.d.mts.map +1 -0
- package/dist/build/source-maps/api.mjs +61 -0
- package/dist/build/source-maps/api.mjs.map +1 -0
- package/dist/build/source-maps/client.d.mts +73 -0
- package/dist/build/source-maps/client.d.mts.map +1 -0
- package/dist/build/source-maps/client.mjs +228 -0
- package/dist/build/source-maps/client.mjs.map +1 -0
- package/dist/build/source-maps/errors.d.mts +109 -0
- package/dist/build/source-maps/errors.d.mts.map +1 -0
- package/dist/build/source-maps/errors.mjs +22 -0
- package/dist/build/source-maps/errors.mjs.map +1 -0
- package/dist/build/source-maps/files.d.mts +35 -0
- package/dist/build/source-maps/files.d.mts.map +1 -0
- package/dist/build/source-maps/files.mjs +222 -0
- package/dist/build/source-maps/files.mjs.map +1 -0
- package/dist/build/source-maps/providers/deployment/detector.d.mts +26 -0
- package/dist/build/source-maps/providers/deployment/detector.d.mts.map +1 -0
- package/dist/build/source-maps/providers/deployment/detector.mjs +22 -0
- package/dist/build/source-maps/providers/deployment/detector.mjs.map +1 -0
- package/dist/build/source-maps/providers/deployment/types.d.mts +12 -0
- package/dist/build/source-maps/providers/deployment/types.d.mts.map +1 -0
- package/dist/build/source-maps/providers/deployment/types.mjs +3 -0
- package/dist/build/source-maps/providers/deployment/vercel.d.mts +6 -0
- package/dist/build/source-maps/providers/deployment/vercel.d.mts.map +1 -0
- package/dist/build/source-maps/providers/deployment/vercel.mjs +44 -0
- package/dist/build/source-maps/providers/deployment/vercel.mjs.map +1 -0
- package/dist/build/source-maps/providers/source-control/detector.d.mts +15 -0
- package/dist/build/source-maps/providers/source-control/detector.d.mts.map +1 -0
- package/dist/build/source-maps/providers/source-control/detector.mjs +22 -0
- package/dist/build/source-maps/providers/source-control/detector.mjs.map +1 -0
- package/dist/build/source-maps/providers/source-control/git.d.mts +6 -0
- package/dist/build/source-maps/providers/source-control/git.d.mts.map +1 -0
- package/dist/build/source-maps/providers/source-control/git.mjs +50 -0
- package/dist/build/source-maps/providers/source-control/git.mjs.map +1 -0
- package/dist/build/source-maps/providers/source-control/types.d.mts +12 -0
- package/dist/build/source-maps/providers/source-control/types.d.mts.map +1 -0
- package/dist/build/source-maps/providers/source-control/types.mjs +3 -0
- package/dist/build/with-interfere.d.mts +49 -0
- package/dist/build/with-interfere.d.mts.map +1 -0
- package/dist/build/with-interfere.mjs +75 -0
- package/dist/build/with-interfere.mjs.map +1 -0
- package/dist/client/client.d.mts +3 -0
- package/dist/client/client.mjs +5 -0
- package/dist/client/provider.d.mts +22 -0
- package/dist/client/provider.d.mts.map +1 -0
- package/dist/client/provider.mjs +33 -0
- package/dist/client/provider.mjs.map +1 -0
- package/dist/lib/env.d.mts +12 -0
- package/dist/lib/env.d.mts.map +1 -0
- package/dist/lib/env.mjs +17 -0
- package/dist/lib/env.mjs.map +1 -0
- package/dist/lib/test-utils/make-next-request.d.mts +6 -0
- package/dist/lib/test-utils/make-next-request.d.mts.map +1 -0
- package/dist/lib/test-utils/make-next-request.mjs +12 -0
- package/dist/lib/test-utils/make-next-request.mjs.map +1 -0
- package/dist/lib/types.d.mts +22 -0
- package/dist/lib/types.d.mts.map +1 -0
- package/dist/lib/types.mjs +7 -0
- package/dist/lib/types.mjs.map +1 -0
- package/dist/server/middleware.d.mts +11 -0
- package/dist/server/middleware.d.mts.map +1 -0
- package/dist/server/middleware.mjs +84 -0
- package/dist/server/middleware.mjs.map +1 -0
- package/dist/server/proxy.d.mts +6 -0
- package/dist/server/proxy.d.mts.map +1 -0
- package/dist/server/proxy.mjs +29 -0
- package/dist/server/proxy.mjs.map +1 -0
- package/dist/server/route-handler.d.mts +9 -0
- package/dist/server/route-handler.d.mts.map +1 -0
- package/dist/server/route-handler.mjs +172 -0
- package/dist/server/route-handler.mjs.map +1 -0
- package/dist/server/services/config.service.d.mts +21 -0
- package/dist/server/services/config.service.d.mts.map +1 -0
- package/dist/server/services/config.service.mjs +43 -0
- package/dist/server/services/config.service.mjs.map +1 -0
- package/dist/server/services/error-tracking.service.d.mts +19 -0
- package/dist/server/services/error-tracking.service.d.mts.map +1 -0
- package/dist/server/services/error-tracking.service.mjs +31 -0
- package/dist/server/services/error-tracking.service.mjs.map +1 -0
- package/package.json +67 -36
- package/dist/__tests__/build/with-interfere-coverage.test.d.ts +0 -2
- package/dist/__tests__/build/with-interfere-coverage.test.d.ts.map +0 -1
- package/dist/__tests__/build/with-interfere-coverage.test.js +0 -325
- package/dist/__tests__/build/with-interfere-coverage.test.js.map +0 -1
- package/dist/__tests__/build/with-interfere.test.d.ts +0 -2
- package/dist/__tests__/build/with-interfere.test.d.ts.map +0 -1
- package/dist/__tests__/build/with-interfere.test.js +0 -424
- package/dist/__tests__/build/with-interfere.test.js.map +0 -1
- package/dist/__tests__/core/client.test.d.ts +0 -2
- package/dist/__tests__/core/client.test.d.ts.map +0 -1
- package/dist/__tests__/core/client.test.js +0 -373
- package/dist/__tests__/core/client.test.js.map +0 -1
- package/dist/__tests__/core/encoders.test.d.ts +0 -2
- package/dist/__tests__/core/encoders.test.d.ts.map +0 -1
- package/dist/__tests__/core/encoders.test.js +0 -56
- package/dist/__tests__/core/encoders.test.js.map +0 -1
- package/dist/__tests__/core/rage-click.test.d.ts +0 -2
- package/dist/__tests__/core/rage-click.test.d.ts.map +0 -1
- package/dist/__tests__/core/rage-click.test.js +0 -121
- package/dist/__tests__/core/rage-click.test.js.map +0 -1
- package/dist/__tests__/core/session-manager.test.d.ts +0 -2
- package/dist/__tests__/core/session-manager.test.d.ts.map +0 -1
- package/dist/__tests__/core/session-manager.test.js +0 -1168
- package/dist/__tests__/core/session-manager.test.js.map +0 -1
- package/dist/__tests__/integration/release-upload.test.d.ts +0 -2
- package/dist/__tests__/integration/release-upload.test.d.ts.map +0 -1
- package/dist/__tests__/integration/release-upload.test.js +0 -167
- package/dist/__tests__/integration/release-upload.test.js.map +0 -1
- package/dist/__tests__/session/persistence.test.d.ts +0 -2
- package/dist/__tests__/session/persistence.test.d.ts.map +0 -1
- package/dist/__tests__/session/persistence.test.js +0 -129
- package/dist/__tests__/session/persistence.test.js.map +0 -1
- package/dist/__tests__/session/session-summary.test.d.ts +0 -2
- package/dist/__tests__/session/session-summary.test.d.ts.map +0 -1
- package/dist/__tests__/session/session-summary.test.js +0 -763
- package/dist/__tests__/session/session-summary.test.js.map +0 -1
- package/dist/client.d.ts +0 -75
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -123
- package/dist/client.js.map +0 -1
- package/dist/config.d.ts +0 -61
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -315
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.jsx +0 -50
- package/dist/index.jsx.map +0 -1
- package/dist/lib/core/client-core.d.ts +0 -27
- package/dist/lib/core/client-core.d.ts.map +0 -1
- package/dist/lib/core/client-core.js +0 -152
- package/dist/lib/core/client-core.js.map +0 -1
- package/dist/lib/core/constants.d.ts +0 -12
- package/dist/lib/core/constants.d.ts.map +0 -1
- package/dist/lib/core/constants.js +0 -17
- package/dist/lib/core/constants.js.map +0 -1
- package/dist/lib/core/debug.d.ts +0 -47
- package/dist/lib/core/debug.d.ts.map +0 -1
- package/dist/lib/core/debug.js +0 -79
- package/dist/lib/core/debug.js.map +0 -1
- package/dist/lib/core/encoders.d.ts +0 -3
- package/dist/lib/core/encoders.d.ts.map +0 -1
- package/dist/lib/core/encoders.js +0 -5
- package/dist/lib/core/encoders.js.map +0 -1
- package/dist/lib/core/error-handlers.d.ts +0 -14
- package/dist/lib/core/error-handlers.d.ts.map +0 -1
- package/dist/lib/core/error-handlers.js +0 -191
- package/dist/lib/core/error-handlers.js.map +0 -1
- package/dist/lib/core/runtime.d.ts +0 -7
- package/dist/lib/core/runtime.d.ts.map +0 -1
- package/dist/lib/core/runtime.js +0 -16
- package/dist/lib/core/runtime.js.map +0 -1
- package/dist/lib/persistence/storage.d.ts +0 -5
- package/dist/lib/persistence/storage.d.ts.map +0 -1
- package/dist/lib/persistence/storage.js +0 -67
- package/dist/lib/persistence/storage.js.map +0 -1
- package/dist/lib/session/constants.d.ts +0 -19
- package/dist/lib/session/constants.d.ts.map +0 -1
- package/dist/lib/session/constants.js +0 -34
- package/dist/lib/session/constants.js.map +0 -1
- package/dist/lib/session/persistence.d.ts +0 -58
- package/dist/lib/session/persistence.d.ts.map +0 -1
- package/dist/lib/session/persistence.js +0 -179
- package/dist/lib/session/persistence.js.map +0 -1
- package/dist/lib/session/rage-click.d.ts +0 -17
- package/dist/lib/session/rage-click.d.ts.map +0 -1
- package/dist/lib/session/rage-click.js +0 -104
- package/dist/lib/session/rage-click.js.map +0 -1
- package/dist/lib/session/replay.d.ts +0 -3
- package/dist/lib/session/replay.d.ts.map +0 -1
- package/dist/lib/session/replay.js +0 -109
- package/dist/lib/session/replay.js.map +0 -1
- package/dist/lib/session/session-manager.d.ts +0 -126
- package/dist/lib/session/session-manager.d.ts.map +0 -1
- package/dist/lib/session/session-manager.js +0 -635
- package/dist/lib/session/session-manager.js.map +0 -1
- package/dist/lib/session/session-summary.d.ts +0 -3
- package/dist/lib/session/session-summary.d.ts.map +0 -1
- package/dist/lib/session/session-summary.js +0 -214
- package/dist/lib/session/session-summary.js.map +0 -1
- package/dist/middleware.d.ts +0 -8
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js +0 -139
- package/dist/middleware.js.map +0 -1
- package/dist/types/storage.d.ts +0 -7
- package/dist/types/storage.d.ts.map +0 -1
- package/dist/types/storage.js +0 -2
- package/dist/types/storage.js.map +0 -1
- package/dist/types.d.ts +0 -6
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -4
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.mjs","names":["providers: SourceControlProvider[]"],"sources":["../../../../../src/build/source-maps/providers/source-control/detector.ts"],"sourcesContent":["import { Effect } from \"effect\";\n\nimport { SourceControlDetectionError } from \"../../errors.js\";\nimport { gitProvider } from \"./git.js\";\nimport type { SourceControlProvider } from \"./types.js\";\n\nconst providers: SourceControlProvider[] = [gitProvider];\n\nexport function detectSourceControl() {\n return Effect.gen(function* () {\n for (const provider of providers) {\n const supported = yield* provider.detect;\n\n if (!supported) {\n continue;\n }\n\n const metadata = yield* provider.getMetadata;\n\n return {\n type: provider.type,\n metadata: metadata,\n };\n }\n\n return yield* Effect.fail(\n new SourceControlDetectionError({ message: \"No source control provider detected\" })\n );\n });\n}\n\n\n"],"mappings":";;;;;AAMA,MAAMA,YAAqC,CAAC,YAAY;AAExD,SAAgB,sBAAsB;AACpC,QAAO,OAAO,IAAI,aAAa;AAC7B,OAAK,MAAM,YAAY,WAAW;AAGhC,OAAI,EAFc,OAAO,SAAS,QAGhC;GAGF,MAAM,WAAW,OAAO,SAAS;AAEjC,UAAO;IACL,MAAM,SAAS;IACL;IACX;;AAGH,SAAO,OAAO,OAAO,KACnB,IAAI,4BAA4B,EAAE,SAAS,uCAAuC,CAAC,CACpF;GACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.mts","names":[],"sources":["../../../../../src/build/source-maps/providers/source-control/git.ts"],"sourcesContent":[],"mappings":";;;cA4Da,aAAa"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SourceControlDetectionError } from "../../errors.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { versionControlTypeSchema } from "@interfere/types/releases/sources/version-control";
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
|
|
6
|
+
//#region src/build/source-maps/providers/source-control/git.ts
|
|
7
|
+
function getGitSha() {
|
|
8
|
+
try {
|
|
9
|
+
return execSync("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
10
|
+
} catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function getGitBranch() {
|
|
15
|
+
try {
|
|
16
|
+
return execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function getCommitMessage() {
|
|
22
|
+
try {
|
|
23
|
+
return execSync("git log -1 --pretty=%B", { encoding: "utf8" }).trim();
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const providerType = versionControlTypeSchema.enum.git;
|
|
29
|
+
function buildMetadata(sourceId) {
|
|
30
|
+
const branch = getGitBranch();
|
|
31
|
+
const commitMessage = getCommitMessage();
|
|
32
|
+
return {
|
|
33
|
+
type: versionControlTypeSchema.enum.git,
|
|
34
|
+
gitCommitMessage: commitMessage ?? "",
|
|
35
|
+
gitBranch: branch ?? "",
|
|
36
|
+
gitCommitSha: sourceId
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const gitProvider = {
|
|
40
|
+
type: providerType,
|
|
41
|
+
detect: Effect.sync(() => getGitSha() !== null),
|
|
42
|
+
getMetadata: Effect.gen(function* () {
|
|
43
|
+
const sha = getGitSha();
|
|
44
|
+
if (!sha) return yield* Effect.fail(new SourceControlDetectionError({ message: "Could not determine git SHA" }));
|
|
45
|
+
return buildMetadata(sha);
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { gitProvider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.mjs","names":["providerType: ReleaseSourceType","gitProvider: SourceControlProvider"],"sources":["../../../../../src/build/source-maps/providers/source-control/git.ts"],"sourcesContent":["import type {\n ReleaseSourceMetadata,\n ReleaseSourceType,\n} from \"@interfere/types/releases/definition\";\n\nimport {\n type VersionControlMetadata,\n versionControlTypeSchema,\n} from \"@interfere/types/releases/sources/version-control\";\n\nimport { execSync } from \"child_process\";\n\nimport { Effect } from \"effect\";\n\nimport { SourceControlDetectionError } from \"../../errors.js\";\nimport type { SourceControlProvider } from \"./types.js\";\n\n// Git helper functions (only used within this provider)\nfunction getGitSha(): string | null {\n try {\n return execSync(\"git rev-parse HEAD\", { encoding: \"utf8\" }).trim();\n } catch {\n return null;\n }\n}\n\nfunction getGitBranch(): string | null {\n try {\n return execSync(\"git rev-parse --abbrev-ref HEAD\", {\n encoding: \"utf8\",\n }).trim();\n } catch {\n return null;\n }\n}\n\nfunction getCommitMessage(): string | null {\n try {\n return execSync(\"git log -1 --pretty=%B\", { encoding: \"utf8\" }).trim();\n } catch {\n return null;\n }\n}\n\nconst providerType: ReleaseSourceType = versionControlTypeSchema.enum.git;\n\nfunction buildMetadata(sourceId: string): ReleaseSourceMetadata {\n const branch = getGitBranch();\n const commitMessage = getCommitMessage();\n\n const metadata = {\n type: versionControlTypeSchema.enum.git,\n gitCommitMessage: commitMessage ?? \"\",\n gitBranch: branch ?? \"\",\n gitCommitSha: sourceId,\n } satisfies VersionControlMetadata;\n\n return metadata;\n}\n\nexport const gitProvider: SourceControlProvider = {\n type: providerType,\n detect: Effect.sync(() => getGitSha() !== null),\n getMetadata: Effect.gen(function* () {\n const sha = getGitSha();\n\n if (!sha) {\n return yield* Effect.fail(\n new SourceControlDetectionError({ message: \"Could not determine git SHA\" })\n );\n }\n\n return buildMetadata(sha);\n }),\n};\n\n\n"],"mappings":";;;;;;AAkBA,SAAS,YAA2B;AAClC,KAAI;AACF,SAAO,SAAS,sBAAsB,EAAE,UAAU,QAAQ,CAAC,CAAC,MAAM;SAC5D;AACN,SAAO;;;AAIX,SAAS,eAA8B;AACrC,KAAI;AACF,SAAO,SAAS,mCAAmC,EACjD,UAAU,QACX,CAAC,CAAC,MAAM;SACH;AACN,SAAO;;;AAIX,SAAS,mBAAkC;AACzC,KAAI;AACF,SAAO,SAAS,0BAA0B,EAAE,UAAU,QAAQ,CAAC,CAAC,MAAM;SAChE;AACN,SAAO;;;AAIX,MAAMA,eAAkC,yBAAyB,KAAK;AAEtE,SAAS,cAAc,UAAyC;CAC9D,MAAM,SAAS,cAAc;CAC7B,MAAM,gBAAgB,kBAAkB;AASxC,QAPiB;EACf,MAAM,yBAAyB,KAAK;EACpC,kBAAkB,iBAAiB;EACnC,WAAW,UAAU;EACrB,cAAc;EACf;;AAKH,MAAaC,cAAqC;CAChD,MAAM;CACN,QAAQ,OAAO,WAAW,WAAW,KAAK,KAAK;CAC/C,aAAa,OAAO,IAAI,aAAa;EACnC,MAAM,MAAM,WAAW;AAEvB,MAAI,CAAC,IACH,QAAO,OAAO,OAAO,KACnB,IAAI,4BAA4B,EAAE,SAAS,+BAA+B,CAAC,CAC5E;AAGH,SAAO,cAAc,IAAI;GACzB;CACH"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SourceControlDetectionError } from "../../errors.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { ReleaseSourceMetadata, ReleaseSourceType } from "@interfere/types/releases/definition";
|
|
4
|
+
|
|
5
|
+
//#region src/build/source-maps/providers/source-control/types.d.ts
|
|
6
|
+
type SourceControlProvider = {
|
|
7
|
+
type: ReleaseSourceType;
|
|
8
|
+
detect: Effect.Effect<boolean>;
|
|
9
|
+
getMetadata: Effect.Effect<ReleaseSourceMetadata, SourceControlDetectionError>;
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { SourceControlProvider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../src/build/source-maps/providers/source-control/types.ts"],"sourcesContent":[],"mappings":";;;;;KASY,qBAAA;QACJ;EADI,MAAA,EAEF,MAAA,CAAO,MAFL,CAAA,OAAqB,CAAA;EACzB,WAAA,EAEO,MAAA,CAAO,MAFd,CAGJ,qBAHI,EAIJ,2BAJI,CAAA;CACE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { NextConfig } from "next";
|
|
2
|
+
|
|
3
|
+
//#region src/build/with-interfere.d.ts
|
|
4
|
+
type InterfereOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Environment name
|
|
7
|
+
* @default "production"
|
|
8
|
+
*/
|
|
9
|
+
environment?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Enable debug logging
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
debug?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to delete source maps after upload to prevent leakage
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
cleanupSourceMaps?: boolean;
|
|
20
|
+
};
|
|
21
|
+
type NextConfigWithInterfere = NextConfig & {
|
|
22
|
+
interfere?: InterfereOptions;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Next.js configuration wrapper that automatically uploads source maps in production builds
|
|
26
|
+
*
|
|
27
|
+
* SECURITY: Secret key must be set via INTERFERE_SECRET_KEY env var (without NEXT_PUBLIC_ prefix)
|
|
28
|
+
* Format: int_sk_{surfaceId}_{random}
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```js
|
|
32
|
+
* // next.config.js
|
|
33
|
+
* const { withInterfere } = require('@interfere/next/build');
|
|
34
|
+
*
|
|
35
|
+
* module.exports = withInterfere({
|
|
36
|
+
* environment: 'staging',
|
|
37
|
+
* debug: true,
|
|
38
|
+
* cleanupSourceMaps: true
|
|
39
|
+
* })({
|
|
40
|
+
* // Your Next.js config
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function withInterfere({
|
|
45
|
+
interfere,
|
|
46
|
+
...nextConfig
|
|
47
|
+
}?: NextConfigWithInterfere): () => NextConfig;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { InterfereOptions, withInterfere };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-interfere.d.mts","names":[],"sources":["../../src/build/with-interfere.ts"],"sourcesContent":[],"mappings":";;;KAQY,gBAAA;;AAAZ;AAkBE;AA0BF;EACE,WAAA,CAAA,EAAA,MAAA;EAEC;;;;;;;;;;;KA3BE,uBAAA,GAA0B;cACjB;;;;;;;;;;;;;;;;;;;;;;iBAuBE,aAAA;;;IAGb,gCAAqC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { nextBuildLogger } from "./logger.mjs";
|
|
2
|
+
import { ReleaseIdentityService, ReleaseIdentityServiceLive } from "./services/release-identity.service.mjs";
|
|
3
|
+
import { createReleaseLayers, releaseProgram } from "./release-program.mjs";
|
|
4
|
+
import { PreflightService, PreflightServiceLive } from "./services/preflight.service.mjs";
|
|
5
|
+
import { withInterfereLogger } from "@interfere/effect-utils/observability";
|
|
6
|
+
import { Effect, Layer, LogLevel, Logger, Option } from "effect";
|
|
7
|
+
|
|
8
|
+
//#region src/build/with-interfere.ts
|
|
9
|
+
/**
|
|
10
|
+
* Next.js configuration wrapper that automatically uploads source maps in production builds
|
|
11
|
+
*
|
|
12
|
+
* SECURITY: Secret key must be set via INTERFERE_SECRET_KEY env var (without NEXT_PUBLIC_ prefix)
|
|
13
|
+
* Format: int_sk_{surfaceId}_{random}
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```js
|
|
17
|
+
* // next.config.js
|
|
18
|
+
* const { withInterfere } = require('@interfere/next/build');
|
|
19
|
+
*
|
|
20
|
+
* module.exports = withInterfere({
|
|
21
|
+
* environment: 'staging',
|
|
22
|
+
* debug: true,
|
|
23
|
+
* cleanupSourceMaps: true
|
|
24
|
+
* })({
|
|
25
|
+
* // Your Next.js config
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function withInterfere({ interfere = {}, ...nextConfig } = {}) {
|
|
30
|
+
const interfereConfig = Effect.gen(function* () {
|
|
31
|
+
return yield* (yield* PreflightService).buildConfig(interfere);
|
|
32
|
+
}).pipe(Effect.provide(PreflightServiceLive), Effect.runSync);
|
|
33
|
+
const identityProgram = Effect.gen(function* () {
|
|
34
|
+
return yield* (yield* ReleaseIdentityService).pipe(Effect.option);
|
|
35
|
+
}).pipe(Effect.provide(ReleaseIdentityServiceLive), Effect.runSync);
|
|
36
|
+
const identity = Option.getOrUndefined(identityProgram);
|
|
37
|
+
return function buildConfig() {
|
|
38
|
+
const env = {
|
|
39
|
+
...nextConfig.env,
|
|
40
|
+
NEXT_PUBLIC_INTERFERE_ENVIRONMENT: interfereConfig.environment,
|
|
41
|
+
...identity?.buildId ? { NEXT_PUBLIC_INTERFERE_BUILD_ID: identity.buildId } : {},
|
|
42
|
+
...identity?.releaseId ? { NEXT_PUBLIC_INTERFERE_RELEASE_ID: identity.releaseId } : {}
|
|
43
|
+
};
|
|
44
|
+
const compiler = !interfereConfig.enabled ? nextConfig.compiler : {
|
|
45
|
+
...nextConfig.compiler,
|
|
46
|
+
runAfterProductionCompile: async (ctx) => {
|
|
47
|
+
const debugEnabled = process.env.INTERFERE_PLUGIN_DEBUG === "1";
|
|
48
|
+
const startTime = Date.now();
|
|
49
|
+
if (debugEnabled) console.log("[Interfere Plugin] Starting runAfterProductionCompile");
|
|
50
|
+
const existingHook = nextConfig.compiler?.runAfterProductionCompile;
|
|
51
|
+
if (existingHook) {
|
|
52
|
+
const hookStart = Date.now();
|
|
53
|
+
await existingHook(ctx);
|
|
54
|
+
if (debugEnabled) console.log(`[Interfere Plugin] Existing hook completed in ${Date.now() - hookStart}ms`);
|
|
55
|
+
}
|
|
56
|
+
const scopedProgram = releaseProgram.pipe(Effect.provide(createReleaseLayers(interfereConfig)), Effect.scoped, debugEnabled ? Logger.withMinimumLogLevel(LogLevel.Debug) : (x) => x);
|
|
57
|
+
const programStart = Date.now();
|
|
58
|
+
await Effect.runPromise(withInterfereLogger("next", scopedProgram, { logger: nextBuildLogger }));
|
|
59
|
+
if (debugEnabled) {
|
|
60
|
+
console.log(`[Interfere Plugin] Release program completed in ${Date.now() - programStart}ms`);
|
|
61
|
+
console.log(`[Interfere Plugin] Total runAfterProductionCompile time: ${Date.now() - startTime}ms`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
...nextConfig,
|
|
67
|
+
compiler,
|
|
68
|
+
env,
|
|
69
|
+
productionBrowserSourceMaps: interfereConfig.enabled ? true : nextConfig.productionBrowserSourceMaps
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
export { withInterfere };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-interfere.mjs","names":[],"sources":["../../src/build/with-interfere.ts"],"sourcesContent":["import { withInterfereLogger } from \"@interfere/effect-utils/observability\";\nimport { Effect, Layer, Logger, LogLevel, Option } from \"effect\";\nimport type { NextConfig } from \"next\";\nimport { nextBuildLogger } from \"./logger.js\";\nimport { createReleaseLayers, releaseProgram } from \"./release-program.js\";\nimport { PreflightService, PreflightServiceLive } from \"./services/preflight.service.js\";\nimport { ReleaseIdentityService, ReleaseIdentityServiceLive } from \"./services/release-identity.service.js\";\n\nexport type InterfereOptions = {\n /**\n * Environment name\n * @default \"production\"\n */\n environment?: string;\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Whether to delete source maps after upload to prevent leakage\n * @default true\n */\n cleanupSourceMaps?: boolean;\n};\n\ntype NextConfigWithInterfere = NextConfig & {\n interfere?: InterfereOptions;\n};\n\n/**\n * Next.js configuration wrapper that automatically uploads source maps in production builds\n *\n * SECURITY: Secret key must be set via INTERFERE_SECRET_KEY env var (without NEXT_PUBLIC_ prefix)\n * Format: int_sk_{surfaceId}_{random}\n *\n * @example\n * ```js\n * // next.config.js\n * const { withInterfere } = require('@interfere/next/build');\n *\n * module.exports = withInterfere({\n * environment: 'staging',\n * debug: true,\n * cleanupSourceMaps: true\n * })({\n * // Your Next.js config\n * });\n * ```\n */\nexport function withInterfere({\n interfere = {},\n ...nextConfig\n}: NextConfigWithInterfere = {}): () => NextConfig {\n // Build the preflight config using the service\n const configProgram = Effect.gen(function* () {\n const preflight = yield* PreflightService;\n return yield* preflight.buildConfig(interfere);\n }).pipe(\n Effect.provide(PreflightServiceLive),\n Effect.runSync\n );\n\n const interfereConfig = configProgram;\n \n // Use the ReleaseIdentityService to infer build/release IDs\n // This runs the same logic that the release program uses\n const identityProgram = Effect.gen(function* () {\n const identityEffect = yield* ReleaseIdentityService;\n return yield* identityEffect.pipe(Effect.option);\n }).pipe(\n Effect.provide(ReleaseIdentityServiceLive),\n Effect.runSync\n );\n \n const identity = Option.getOrUndefined(identityProgram);\n\n return function buildConfig() {\n // Use the same release identity logic that the release program uses\n // This ensures consistency between what gets uploaded and what the client SDK sends\n const env = {\n ...nextConfig.env,\n // Pass the deduced/configured environment to the client SDK\n // (it defaults to NODE_ENV in preflight service)\n NEXT_PUBLIC_INTERFERE_ENVIRONMENT: interfereConfig.environment,\n // Pass the inferred build/release IDs to the client SDK\n // These come from the same ReleaseIdentityService that the release program uses\n ...(identity?.buildId\n ? { NEXT_PUBLIC_INTERFERE_BUILD_ID: identity.buildId }\n : {}),\n ...(identity?.releaseId\n ? { NEXT_PUBLIC_INTERFERE_RELEASE_ID: identity.releaseId }\n : {}),\n };\n\n // Set up compiler hook if enabled\n const compiler = !interfereConfig.enabled\n ? nextConfig.compiler\n : {\n ...nextConfig.compiler,\n runAfterProductionCompile: async (ctx: {\n projectDir: string;\n distDir: string;\n }) => {\n const debugEnabled = process.env.INTERFERE_PLUGIN_DEBUG === \"1\";\n const startTime = Date.now();\n\n if (debugEnabled) {\n console.log(\"[Interfere Plugin] Starting runAfterProductionCompile\");\n }\n\n // Run existing hook first\n const existingHook = nextConfig.compiler?.runAfterProductionCompile;\n if (existingHook) {\n const hookStart = Date.now();\n await existingHook(ctx);\n if (debugEnabled) {\n console.log(`[Interfere Plugin] Existing hook completed in ${Date.now() - hookStart}ms`);\n }\n }\n\n // Run the unified release program with all layers\n const scopedProgram = releaseProgram.pipe(\n Effect.provide(createReleaseLayers(interfereConfig)),\n Effect.scoped,\n debugEnabled\n ? Logger.withMinimumLogLevel(LogLevel.Debug)\n : (x) => x\n ) as Effect.Effect<unknown, unknown, never>;\n\n const programStart = Date.now();\n await Effect.runPromise(\n withInterfereLogger(\"next\", scopedProgram, { logger: nextBuildLogger })\n );\n if (debugEnabled) {\n console.log(`[Interfere Plugin] Release program completed in ${Date.now() - programStart}ms`);\n console.log(`[Interfere Plugin] Total runAfterProductionCompile time: ${Date.now() - startTime}ms`);\n }\n },\n };\n\n return {\n ...nextConfig,\n compiler,\n env,\n // Automatically enable browser source maps when Interfere is enabled\n productionBrowserSourceMaps: interfereConfig.enabled\n ? true\n : nextConfig.productionBrowserSourceMaps,\n };\n };\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgB,cAAc,EAC5B,YAAY,EAAE,EACd,GAAG,eACwB,EAAE,EAAoB;CAUjD,MAAM,kBARgB,OAAO,IAAI,aAAa;AAE5C,SAAO,QADW,OAAO,kBACD,YAAY,UAAU;GAC9C,CAAC,KACD,OAAO,QAAQ,qBAAqB,EACpC,OAAO,QACR;CAMD,MAAM,kBAAkB,OAAO,IAAI,aAAa;AAE9C,SAAO,QADgB,OAAO,wBACD,KAAK,OAAO,OAAO;GAChD,CAAC,KACD,OAAO,QAAQ,2BAA2B,EAC1C,OAAO,QACR;CAED,MAAM,WAAW,OAAO,eAAe,gBAAgB;AAEvD,QAAO,SAAS,cAAc;EAG5B,MAAM,MAAM;GACV,GAAG,WAAW;GAGd,mCAAmC,gBAAgB;GAGnD,GAAI,UAAU,UACV,EAAE,gCAAgC,SAAS,SAAS,GACpD,EAAE;GACN,GAAI,UAAU,YACV,EAAE,kCAAkC,SAAS,WAAW,GACxD,EAAE;GACP;EAGD,MAAM,WAAW,CAAC,gBAAgB,UAC9B,WAAW,WACX;GACE,GAAG,WAAW;GACd,2BAA2B,OAAO,QAG5B;IACJ,MAAM,eAAe,QAAQ,IAAI,2BAA2B;IAC5D,MAAM,YAAY,KAAK,KAAK;AAE5B,QAAI,aACF,SAAQ,IAAI,wDAAwD;IAItE,MAAM,eAAe,WAAW,UAAU;AAC1C,QAAI,cAAc;KAChB,MAAM,YAAY,KAAK,KAAK;AAC5B,WAAM,aAAa,IAAI;AACvB,SAAI,aACF,SAAQ,IAAI,iDAAiD,KAAK,KAAK,GAAG,UAAU,IAAI;;IAK5F,MAAM,gBAAgB,eAAe,KACnC,OAAO,QAAQ,oBAAoB,gBAAgB,CAAC,EACpD,OAAO,QACP,eACI,OAAO,oBAAoB,SAAS,MAAM,IACzC,MAAM,EACZ;IAED,MAAM,eAAe,KAAK,KAAK;AAC/B,UAAM,OAAO,WACX,oBAAoB,QAAQ,eAAe,EAAE,QAAQ,iBAAiB,CAAC,CACxE;AACD,QAAI,cAAc;AAChB,aAAQ,IAAI,mDAAmD,KAAK,KAAK,GAAG,aAAa,IAAI;AAC7F,aAAQ,IAAI,4DAA4D,KAAK,KAAK,GAAG,UAAU,IAAI;;;GAGxG;AAEL,SAAO;GACL,GAAG;GACH;GACA;GAEA,6BAA6B,gBAAgB,UACzC,OACA,WAAW;GAChB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InterfereProviderProps } from "@interfere/react/provider";
|
|
2
|
+
import { ConfigInput } from "@interfere/types/sdk/config";
|
|
3
|
+
import * as react0 from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/client/provider.d.ts
|
|
6
|
+
type NextConfigInput = {
|
|
7
|
+
features?: ConfigInput["features"];
|
|
8
|
+
metadata?: ConfigInput["metadata"];
|
|
9
|
+
batch?: ConfigInput["batch"];
|
|
10
|
+
proxyUrl?: string;
|
|
11
|
+
ingestUrl?: string;
|
|
12
|
+
surfaceToken?: string;
|
|
13
|
+
};
|
|
14
|
+
declare function InterfereProvider({
|
|
15
|
+
children,
|
|
16
|
+
config,
|
|
17
|
+
...rest
|
|
18
|
+
}: Omit<InterfereProviderProps, "config"> & {
|
|
19
|
+
config?: NextConfigInput;
|
|
20
|
+
}): react0.JSX.Element;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { InterfereProvider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.mts","names":[],"sources":["../../src/client/provider.tsx"],"sourcesContent":[],"mappings":";;;;;KAyBK,eAAA;aACQ;aACA;EAFR,KAAA,CAAA,EAGK,WAHU,CAAA,OAAA,CAAA;EACP,QAAA,CAAA,EAAA,MAAA;EACA,SAAA,CAAA,EAAA,MAAA;EACH,YAAA,CAAA,EAAA,MAAA;CAAW;AAgCL,iBAAA,iBAAA,CAAiB;EAAA,QAAA;EAAA,MAAA;EAAA,GAAA;CAAA,EAI9B,IAJ8B,CAIzB,sBAJyB,EAAA,QAAA,CAAA,GAAA;EAC/B,MAAA,CAAA,EAGqD,eAHrD;CACA,CAAA,EAEsE,MAAA,CAAA,GAAA,CAAA,OAFtE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InterfereProvider as InterfereProvider$1 } from "@interfere/react/provider";
|
|
2
|
+
import { getRuntime } from "@interfere/react/core/runtime/config";
|
|
3
|
+
import { configSchema } from "@interfere/types/sdk/config";
|
|
4
|
+
import { envSchema } from "@interfere/types/sdk/runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/client/provider.tsx
|
|
7
|
+
const defaults = {
|
|
8
|
+
buildId: process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID ?? null,
|
|
9
|
+
releaseId: process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID ?? null,
|
|
10
|
+
environment: process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT ? envSchema.parse(process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT) : "production",
|
|
11
|
+
runtime: getRuntime()
|
|
12
|
+
};
|
|
13
|
+
function mergeConfig(config) {
|
|
14
|
+
const incomingMeta = config.metadata ?? {};
|
|
15
|
+
const transportConfig = typeof config.proxyUrl !== "undefined" || typeof config.ingestUrl !== "undefined" || typeof config.surfaceToken !== "undefined" ? config : { proxyUrl: "/api/interfere" };
|
|
16
|
+
return configSchema.parse({
|
|
17
|
+
...transportConfig,
|
|
18
|
+
...config,
|
|
19
|
+
metadata: {
|
|
20
|
+
...defaults,
|
|
21
|
+
...incomingMeta
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function InterfereProvider({ children, config = {}, ...rest }) {
|
|
26
|
+
const mergedConfig = mergeConfig(config);
|
|
27
|
+
return <InterfereProvider$1 config={mergedConfig} {...rest}>
|
|
28
|
+
{children}
|
|
29
|
+
</InterfereProvider$1>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { InterfereProvider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.mjs","names":["defaults: ConfigInput[\"metadata\"]","InterfereProviderReact"],"sources":["../../src/client/provider.tsx"],"sourcesContent":["import { getRuntime } from \"@interfere/react/core/runtime/config\";\n\nimport {\n type InterfereProviderProps,\n InterfereProvider as InterfereProviderReact,\n} from \"@interfere/react/provider\";\n\nimport {\n type Config,\n type ConfigInput,\n configSchema,\n} from \"@interfere/types/sdk/config\";\nimport { envSchema } from \"@interfere/types/sdk/runtime\";\n\nconst defaults: ConfigInput[\"metadata\"] = {\n buildId: process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID ?? null,\n releaseId: process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID ?? null,\n environment: process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT\n ? envSchema.parse(process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT)\n : \"production\",\n runtime: getRuntime(),\n};\n\n// Next.js-specific config type that allows omitting transport\n// because Next.js can provide its own proxy endpoint\ntype NextConfigInput = {\n features?: ConfigInput[\"features\"];\n metadata?: ConfigInput[\"metadata\"];\n batch?: ConfigInput[\"batch\"];\n proxyUrl?: string;\n ingestUrl?: string;\n surfaceToken?: string;\n};\n\nfunction mergeConfig(config: NextConfigInput): Config {\n const incomingMeta = config.metadata ?? {};\n\n // Determine transport config:\n // - If they explicitly set proxyUrl, use proxy mode\n // - If they set ingestUrl or surfaceToken, use direct mode (let schema validate)\n // - Otherwise, default to Next.js proxy\n const hasTransportConfig =\n typeof config.proxyUrl !== \"undefined\" ||\n typeof config.ingestUrl !== \"undefined\" ||\n typeof config.surfaceToken !== \"undefined\";\n\n const transportConfig = hasTransportConfig\n ? config\n : { proxyUrl: \"/api/interfere\" }; // Default Next.js proxy endpoint\n\n return configSchema.parse({\n ...transportConfig,\n ...config,\n metadata: {\n ...defaults,\n ...incomingMeta,\n },\n });\n}\n\nexport function InterfereProvider({\n children,\n config = {},\n ...rest\n}: Omit<InterfereProviderProps, \"config\"> & { config?: NextConfigInput }) {\n const mergedConfig = mergeConfig(config);\n\n return (\n <InterfereProviderReact config={mergedConfig} {...rest}>\n {children}\n </InterfereProviderReact>\n );\n}\n"],"mappings":";;;;;;AAcA,MAAMA,WAAoC;CACxC,SAAS,QAAQ,IAAI,kCAAkC;CACvD,WAAW,QAAQ,IAAI,oCAAoC;CAC3D,aAAa,QAAQ,IAAI,oCACrB,UAAU,MAAM,QAAQ,IAAI,kCAAkC,GAC9D;CACJ,SAAS,YAAY;CACtB;AAaD,SAAS,YAAY,QAAiC;CACpD,MAAM,eAAe,OAAO,YAAY,EAAE;CAW1C,MAAM,kBAJJ,OAAO,OAAO,aAAa,eAC3B,OAAO,OAAO,cAAc,eAC5B,OAAO,OAAO,iBAAiB,cAG7B,SACA,EAAE,UAAU,kBAAkB;AAElC,QAAO,aAAa,MAAM;EACxB,GAAG;EACH,GAAG;EACH,UAAU;GACR,GAAG;GACH,GAAG;GACJ;EACF,CAAC;;AAGJ,SAAgB,kBAAkB,EAChC,UACA,SAAS,EAAE,EACX,GAAG,QACqE;CACxE,MAAM,eAAe,YAAY,OAAO;AAExC,QACE,CAACC,oBAAuB,QAAQ,kBAAkB,MAAM;OACrD,SAAS;IACZ,EAAEA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/lib/env.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for Interfere-specific environment values that can be used
|
|
4
|
+
* safely at both build time and runtime.
|
|
5
|
+
*
|
|
6
|
+
* Provider-specific environment variables (Vercel, Netlify, etc.) should live
|
|
7
|
+
* in their respective provider modules instead of this file.
|
|
8
|
+
*/
|
|
9
|
+
declare function getEnvBuildId(): string | null;
|
|
10
|
+
declare function getEnvReleaseId(): string | null;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { getEnvBuildId, getEnvReleaseId };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.mts","names":[],"sources":["../../src/lib/env.ts"],"sourcesContent":[],"mappings":";;AAQA;AAQA;;;;;iBARgB,aAAA,CAAA;iBAQA,eAAA,CAAA"}
|
package/dist/lib/env.mjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/lib/env.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for Interfere-specific environment values that can be used
|
|
4
|
+
* safely at both build time and runtime.
|
|
5
|
+
*
|
|
6
|
+
* Provider-specific environment variables (Vercel, Netlify, etc.) should live
|
|
7
|
+
* in their respective provider modules instead of this file.
|
|
8
|
+
*/
|
|
9
|
+
function getEnvBuildId() {
|
|
10
|
+
return process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID || process.env.NEXT_BUILD_ID || null;
|
|
11
|
+
}
|
|
12
|
+
function getEnvReleaseId() {
|
|
13
|
+
return process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID || null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { getEnvBuildId, getEnvReleaseId };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.mjs","names":[],"sources":["../../src/lib/env.ts"],"sourcesContent":["/**\n * Shared helpers for Interfere-specific environment values that can be used\n * safely at both build time and runtime.\n *\n * Provider-specific environment variables (Vercel, Netlify, etc.) should live\n * in their respective provider modules instead of this file.\n */\n\nexport function getEnvBuildId(): string | null {\n return (\n process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID ||\n process.env.NEXT_BUILD_ID ||\n null\n );\n}\n\nexport function getEnvReleaseId(): string | null {\n return process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID || null;\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,gBAA+B;AAC7C,QACE,QAAQ,IAAI,kCACZ,QAAQ,IAAI,iBACZ;;AAIJ,SAAgB,kBAAiC;AAC/C,QAAO,QAAQ,IAAI,oCAAoC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make-next-request.d.mts","names":[],"sources":["../../../src/lib/test-utils/make-next-request.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,eAAA,eACA,YACP,cACN"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NextRequest } from "next/server";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/test-utils/make-next-request.ts
|
|
4
|
+
function makeNextRequest(url, init) {
|
|
5
|
+
return new NextRequest(url, {
|
|
6
|
+
...init,
|
|
7
|
+
signal: init?.signal ?? void 0
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { makeNextRequest };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make-next-request.mjs","names":["NextRequestCtor"],"sources":["../../../src/lib/test-utils/make-next-request.ts"],"sourcesContent":["import type { NextRequest } from \"next/server\";\nimport { NextRequest as NextRequestCtor } from \"next/server\";\n\nexport function makeNextRequest(\n url: string | URL,\n init?: RequestInit\n): NextRequest {\n // The NextRequest constructor mirrors the standard Request but augments with nextUrl, cookies, etc.\n // Using the real constructor keeps types intact and avoids casts in tests.\n return new NextRequestCtor(url, {\n ...init,\n signal: init?.signal ?? undefined,\n });\n}\n"],"mappings":";;;AAGA,SAAgB,gBACd,KACA,MACa;AAGb,QAAO,IAAIA,YAAgB,KAAK;EAC9B,GAAG;EACH,QAAQ,MAAM,UAAU;EACzB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/lib/types.d.ts
|
|
2
|
+
type NonEmptyString = string & {
|
|
3
|
+
readonly __brand: unique symbol;
|
|
4
|
+
};
|
|
5
|
+
declare function toNonEmptyString(value: string): NonEmptyString | null;
|
|
6
|
+
type PreflightEnabled = {
|
|
7
|
+
enabled: true;
|
|
8
|
+
surface: NonEmptyString;
|
|
9
|
+
secretKey: NonEmptyString;
|
|
10
|
+
environment: string;
|
|
11
|
+
debug: boolean;
|
|
12
|
+
cleanupSourceMaps: boolean;
|
|
13
|
+
};
|
|
14
|
+
type PreflightDisabled = {
|
|
15
|
+
enabled: false;
|
|
16
|
+
environment: string | undefined;
|
|
17
|
+
debug: boolean;
|
|
18
|
+
cleanupSourceMaps: boolean;
|
|
19
|
+
};
|
|
20
|
+
type PreflightConfig = PreflightEnabled | PreflightDisabled;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { NonEmptyString, PreflightConfig, PreflightDisabled, PreflightEnabled, toNonEmptyString };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":[],"mappings":";KACY,cAAA;EAAA,SAAA,OAAA,EAAc,OAAA,MAAA;AAE1B,CAAA;AAIY,iBAJI,gBAAA,CAML,KAAA,EAAA,MACE,CAAA,EAPoC,cAOtB,GAAA,IAAA;AAMf,KATA,gBAAA,GASiB;EAOjB,OAAA,EAAA,IAAA;WAdD;aACE;;;;;KAMD,iBAAA;;;;;;KAOA,eAAA,GAAkB,mBAAmB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.mjs","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":["// Branded non-empty string type to prevent passing empty strings accidentally\nexport type NonEmptyString = string & { readonly __brand: unique symbol };\n\nexport function toNonEmptyString(value: string): NonEmptyString | null {\n return value.length > 0 ? (value as NonEmptyString) : null;\n}\n\nexport type PreflightEnabled = {\n enabled: true;\n surface: NonEmptyString;\n secretKey: NonEmptyString;\n environment: string;\n debug: boolean;\n cleanupSourceMaps: boolean;\n};\n\nexport type PreflightDisabled = {\n enabled: false;\n environment: string | undefined;\n debug: boolean;\n cleanupSourceMaps: boolean;\n};\n\nexport type PreflightConfig = PreflightEnabled | PreflightDisabled;\n"],"mappings":";AAGA,SAAgB,iBAAiB,OAAsC;AACrE,QAAO,MAAM,SAAS,IAAK,QAA2B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
|
|
3
|
+
//#region src/server/middleware.d.ts
|
|
4
|
+
declare function withInterfereMiddleware(middleware: (request: NextRequest) => Promise<NextResponse> | NextResponse): (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
5
|
+
declare function withInterfereApiRoute(handler: (req: NextRequest) => Promise<Response>): (req: NextRequest) => Promise<Response>;
|
|
6
|
+
declare function withInterfereServerComponent<T extends (...args: unknown[]) => Promise<unknown>>(component: T, componentName?: string): T;
|
|
7
|
+
declare function createInterfereErrorHandler(): (error: Error, errorInfo: {
|
|
8
|
+
digest?: string;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { createInterfereErrorHandler, withInterfereApiRoute, withInterfereMiddleware, withInterfereServerComponent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/server/middleware.ts"],"sourcesContent":[],"mappings":";;;iBAWgB,uBAAA,uBACQ,gBAAgB,QAAQ,gBAAgB,yBAIvC,gBAAW,QAAA;iBAoCpB,qBAAA,gBACC,gBAAgB,QAAQ,kBAIpB,gBAAW,QAAA;AA9ChB,iBAkFA,4BAlFuB,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAmFH,OAnFG,CAAA,OAAA,CAAA,CAAA,CAAA,SAAA,EAoF1B,CApF0B,EAAA,aAAA,CAAA,EAAA,MAAA,CAAA,EAoFE,CApFF;AACf,iBA4HR,2BAAA,CAAA,CA5HQ,EAAA,CAAA,KAAA,EA+HD,KA/HC,EAAA,SAAA,EAAA;EAAwB,MAAA,CAAA,EAAA,MAAA;CAAR,EAAA,GA+HoB,OA/HpB,CAAA,IAAA,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ConfigServiceLive } from "./services/config.service.mjs";
|
|
2
|
+
import { ErrorTrackingService, ErrorTrackingServiceLive } from "./services/error-tracking.service.mjs";
|
|
3
|
+
import { withInterfereLogger } from "@interfere/effect-utils/observability";
|
|
4
|
+
import { Effect, Layer } from "effect";
|
|
5
|
+
import { withSpan } from "@interfere/react/effect/layers/tracer.layer";
|
|
6
|
+
|
|
7
|
+
//#region src/server/middleware.ts
|
|
8
|
+
function withInterfereMiddleware(middleware) {
|
|
9
|
+
const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);
|
|
10
|
+
return async (request) => {
|
|
11
|
+
if (request.nextUrl.pathname.startsWith("/api/interfere")) return middleware(request);
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const program = Effect.gen(function* () {
|
|
14
|
+
const errorTracking = yield* ErrorTrackingService;
|
|
15
|
+
return yield* withSpan("middleware.request", Effect.tryPromise({
|
|
16
|
+
try: () => Promise.resolve(middleware(request)),
|
|
17
|
+
catch: (error) => error
|
|
18
|
+
}), { attributes: { path: request.nextUrl.pathname } }).pipe(Effect.tapError((error) => errorTracking.captureError(error, request, {
|
|
19
|
+
pathname: request.nextUrl.pathname,
|
|
20
|
+
middleware: true,
|
|
21
|
+
duration: Date.now() - startTime
|
|
22
|
+
})));
|
|
23
|
+
}).pipe(Effect.provide(layer));
|
|
24
|
+
return await Effect.runPromise(withInterfereLogger("next", program));
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function withInterfereApiRoute(handler) {
|
|
28
|
+
const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);
|
|
29
|
+
return async (req) => {
|
|
30
|
+
if (req.nextUrl.pathname.startsWith("/api/interfere")) return handler(req);
|
|
31
|
+
const startTime = Date.now();
|
|
32
|
+
const program = Effect.gen(function* () {
|
|
33
|
+
const errorTracking = yield* ErrorTrackingService;
|
|
34
|
+
return yield* withSpan("api.request", Effect.tryPromise({
|
|
35
|
+
try: () => handler(req),
|
|
36
|
+
catch: (error) => error
|
|
37
|
+
}), { attributes: { path: req.nextUrl.pathname } }).pipe(Effect.tapError((error) => errorTracking.captureError(error, req, {
|
|
38
|
+
pathname: req.nextUrl.pathname,
|
|
39
|
+
type: "api_route",
|
|
40
|
+
duration: Date.now() - startTime
|
|
41
|
+
})));
|
|
42
|
+
}).pipe(Effect.provide(layer));
|
|
43
|
+
return await Effect.runPromise(withInterfereLogger("next", program));
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function withInterfereServerComponent(component, componentName) {
|
|
47
|
+
const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);
|
|
48
|
+
async function wrapped(...args) {
|
|
49
|
+
const self = this;
|
|
50
|
+
const program = Effect.gen(function* () {
|
|
51
|
+
const errorTracking = yield* ErrorTrackingService;
|
|
52
|
+
return yield* Effect.tryPromise({
|
|
53
|
+
try: () => component.apply(self, args),
|
|
54
|
+
catch: (error) => error
|
|
55
|
+
}).pipe(Effect.tapError((error) => errorTracking.captureError(error, void 0, {
|
|
56
|
+
type: "server_component",
|
|
57
|
+
componentName: componentName || component.name
|
|
58
|
+
})));
|
|
59
|
+
}).pipe(Effect.provide(layer));
|
|
60
|
+
return await Effect.runPromise(withInterfereLogger("next", program));
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
Object.defineProperty(wrapped, "name", {
|
|
64
|
+
value: component.name,
|
|
65
|
+
configurable: true
|
|
66
|
+
});
|
|
67
|
+
} catch {}
|
|
68
|
+
return wrapped;
|
|
69
|
+
}
|
|
70
|
+
function createInterfereErrorHandler() {
|
|
71
|
+
const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);
|
|
72
|
+
return async (error, errorInfo) => {
|
|
73
|
+
const program = Effect.gen(function* () {
|
|
74
|
+
yield* (yield* ErrorTrackingService).captureError(error, void 0, {
|
|
75
|
+
digest: errorInfo.digest,
|
|
76
|
+
type: "app_directory_error"
|
|
77
|
+
});
|
|
78
|
+
}).pipe(Effect.provide(layer), Effect.catchAll(() => Effect.void));
|
|
79
|
+
await Effect.runPromise(withInterfereLogger("next", program));
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
export { createInterfereErrorHandler, withInterfereApiRoute, withInterfereMiddleware, withInterfereServerComponent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.mjs","names":[],"sources":["../../src/server/middleware.ts"],"sourcesContent":["import { withInterfereLogger } from \"@interfere/effect-utils/observability\";\nimport { withSpan } from \"@interfere/react/effect/layers/tracer.layer\";\nimport { Effect, Layer } from \"effect\";\nimport type { NextRequest, NextResponse } from \"next/server\";\nimport { ConfigServiceLive } from \"./services/config.service\";\nimport {\n ErrorTrackingService,\n ErrorTrackingServiceLive,\n} from \"./services/error-tracking.service\";\n\n// Middleware wrapper to capture errors with proper Effect handling\nexport function withInterfereMiddleware(\n middleware: (request: NextRequest) => Promise<NextResponse> | NextResponse\n) {\n const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);\n\n return async (request: NextRequest) => {\n // Skip capturing for Interfere's own endpoint to avoid recursion\n if (request.nextUrl.pathname.startsWith(\"/api/interfere\")) {\n return middleware(request);\n }\n\n const startTime = Date.now();\n\n const program = Effect.gen(function* () {\n const errorTracking = yield* ErrorTrackingService;\n\n const response = yield* withSpan(\n \"middleware.request\",\n Effect.tryPromise({\n try: () => Promise.resolve(middleware(request)),\n catch: (error) => error as Error,\n }),\n { attributes: { path: request.nextUrl.pathname } }\n ).pipe(\n Effect.tapError((error) =>\n errorTracking.captureError(error, request, {\n pathname: request.nextUrl.pathname,\n middleware: true,\n duration: Date.now() - startTime,\n })\n )\n );\n\n return response;\n }).pipe(Effect.provide(layer));\n\n return await Effect.runPromise(withInterfereLogger(\"next\", program));\n };\n}\n\n// Helper for API route error handling with Effect\nexport function withInterfereApiRoute(\n handler: (req: NextRequest) => Promise<Response>\n) {\n const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);\n\n return async (req: NextRequest) => {\n // Skip capturing for Interfere's own endpoint to avoid recursion\n if (req.nextUrl.pathname.startsWith(\"/api/interfere\")) {\n return handler(req);\n }\n\n const startTime = Date.now();\n\n const program = Effect.gen(function* () {\n const errorTracking = yield* ErrorTrackingService;\n\n const response = yield* withSpan(\n \"api.request\",\n Effect.tryPromise({\n try: () => handler(req),\n catch: (error) => error as Error,\n }),\n { attributes: { path: req.nextUrl.pathname } }\n ).pipe(\n Effect.tapError((error) =>\n errorTracking.captureError(error, req, {\n pathname: req.nextUrl.pathname,\n type: \"api_route\",\n duration: Date.now() - startTime,\n })\n )\n );\n\n return response;\n }).pipe(Effect.provide(layer));\n\n return await Effect.runPromise(withInterfereLogger(\"next\", program));\n };\n}\n\n// Helper for server component error handling with Effect\nexport function withInterfereServerComponent<\n T extends (...args: unknown[]) => Promise<unknown>,\n>(component: T, componentName?: string): T {\n const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);\n\n async function wrapped(this: unknown, ...args: Parameters<T>) {\n const self = this;\n\n const program = Effect.gen(function* () {\n const errorTracking = yield* ErrorTrackingService;\n\n const result = yield* Effect.tryPromise({\n try: () => component.apply(self as never, args as never),\n catch: (error) => error as Error,\n }).pipe(\n Effect.tapError((error) =>\n errorTracking.captureError(error, undefined, {\n type: \"server_component\",\n componentName: componentName || component.name,\n })\n )\n );\n\n return result;\n }).pipe(Effect.provide(layer));\n\n return await Effect.runPromise(withInterfereLogger(\"next\", program));\n }\n\n // Preserve the original function name for diagnostics and tests\n try {\n Object.defineProperty(wrapped, \"name\", {\n value: component.name,\n configurable: true,\n });\n } catch {\n // Non-critical if we cannot redefine the name\n }\n\n return wrapped as unknown as T;\n}\n\n// App directory error handling with Effect\nexport function createInterfereErrorHandler() {\n const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);\n\n return async (error: Error, errorInfo: { digest?: string }) => {\n const program = Effect.gen(function* () {\n const errorTracking = yield* ErrorTrackingService;\n\n yield* errorTracking.captureError(error, undefined, {\n digest: errorInfo.digest,\n type: \"app_directory_error\",\n });\n }).pipe(\n Effect.provide(layer),\n Effect.catchAll(() => Effect.void) // Best-effort\n );\n\n await Effect.runPromise(withInterfereLogger(\"next\", program));\n };\n}\n"],"mappings":";;;;;;;AAWA,SAAgB,wBACd,YACA;CACA,MAAM,QAAQ,MAAM,SAAS,mBAAmB,yBAAyB;AAEzE,QAAO,OAAO,YAAyB;AAErC,MAAI,QAAQ,QAAQ,SAAS,WAAW,iBAAiB,CACvD,QAAO,WAAW,QAAQ;EAG5B,MAAM,YAAY,KAAK,KAAK;EAE5B,MAAM,UAAU,OAAO,IAAI,aAAa;GACtC,MAAM,gBAAgB,OAAO;AAmB7B,UAjBiB,OAAO,SACtB,sBACA,OAAO,WAAW;IAChB,WAAW,QAAQ,QAAQ,WAAW,QAAQ,CAAC;IAC/C,QAAQ,UAAU;IACnB,CAAC,EACF,EAAE,YAAY,EAAE,MAAM,QAAQ,QAAQ,UAAU,EAAE,CACnD,CAAC,KACA,OAAO,UAAU,UACf,cAAc,aAAa,OAAO,SAAS;IACzC,UAAU,QAAQ,QAAQ;IAC1B,YAAY;IACZ,UAAU,KAAK,KAAK,GAAG;IACxB,CAAC,CACH,CACF;IAGD,CAAC,KAAK,OAAO,QAAQ,MAAM,CAAC;AAE9B,SAAO,MAAM,OAAO,WAAW,oBAAoB,QAAQ,QAAQ,CAAC;;;AAKxE,SAAgB,sBACd,SACA;CACA,MAAM,QAAQ,MAAM,SAAS,mBAAmB,yBAAyB;AAEzE,QAAO,OAAO,QAAqB;AAEjC,MAAI,IAAI,QAAQ,SAAS,WAAW,iBAAiB,CACnD,QAAO,QAAQ,IAAI;EAGrB,MAAM,YAAY,KAAK,KAAK;EAE5B,MAAM,UAAU,OAAO,IAAI,aAAa;GACtC,MAAM,gBAAgB,OAAO;AAmB7B,UAjBiB,OAAO,SACtB,eACA,OAAO,WAAW;IAChB,WAAW,QAAQ,IAAI;IACvB,QAAQ,UAAU;IACnB,CAAC,EACF,EAAE,YAAY,EAAE,MAAM,IAAI,QAAQ,UAAU,EAAE,CAC/C,CAAC,KACA,OAAO,UAAU,UACf,cAAc,aAAa,OAAO,KAAK;IACrC,UAAU,IAAI,QAAQ;IACtB,MAAM;IACN,UAAU,KAAK,KAAK,GAAG;IACxB,CAAC,CACH,CACF;IAGD,CAAC,KAAK,OAAO,QAAQ,MAAM,CAAC;AAE9B,SAAO,MAAM,OAAO,WAAW,oBAAoB,QAAQ,QAAQ,CAAC;;;AAKxE,SAAgB,6BAEd,WAAc,eAA2B;CACzC,MAAM,QAAQ,MAAM,SAAS,mBAAmB,yBAAyB;CAEzE,eAAe,QAAuB,GAAG,MAAqB;EAC5D,MAAM,OAAO;EAEb,MAAM,UAAU,OAAO,IAAI,aAAa;GACtC,MAAM,gBAAgB,OAAO;AAc7B,UAZe,OAAO,OAAO,WAAW;IACtC,WAAW,UAAU,MAAM,MAAe,KAAc;IACxD,QAAQ,UAAU;IACnB,CAAC,CAAC,KACD,OAAO,UAAU,UACf,cAAc,aAAa,OAAO,QAAW;IAC3C,MAAM;IACN,eAAe,iBAAiB,UAAU;IAC3C,CAAC,CACH,CACF;IAGD,CAAC,KAAK,OAAO,QAAQ,MAAM,CAAC;AAE9B,SAAO,MAAM,OAAO,WAAW,oBAAoB,QAAQ,QAAQ,CAAC;;AAItE,KAAI;AACF,SAAO,eAAe,SAAS,QAAQ;GACrC,OAAO,UAAU;GACjB,cAAc;GACf,CAAC;SACI;AAIR,QAAO;;AAIT,SAAgB,8BAA8B;CAC5C,MAAM,QAAQ,MAAM,SAAS,mBAAmB,yBAAyB;AAEzE,QAAO,OAAO,OAAc,cAAmC;EAC7D,MAAM,UAAU,OAAO,IAAI,aAAa;AAGtC,WAFsB,OAAO,sBAER,aAAa,OAAO,QAAW;IAClD,QAAQ,UAAU;IAClB,MAAM;IACP,CAAC;IACF,CAAC,KACD,OAAO,QAAQ,MAAM,EACrB,OAAO,eAAe,OAAO,KAAK,CACnC;AAED,QAAM,OAAO,WAAW,oBAAoB,QAAQ,QAAQ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NextFetchEvent, NextRequest } from "next/server";
|
|
2
|
+
|
|
3
|
+
//#region src/server/proxy.d.ts
|
|
4
|
+
declare function withInterfereProxy(handler: (req: NextRequest, event: NextFetchEvent) => Promise<Response> | Response): (req: NextRequest, event: NextFetchEvent) => Promise<Response>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { withInterfereProxy };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.mts","names":[],"sources":["../../src/server/proxy.ts"],"sourcesContent":[],"mappings":";;;iBAWgB,kBAAA,gBAEP,oBACE,mBACJ,QAAQ,YAAY,iBAIN,oBAAoB,mBAAc,QAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ConfigServiceLive } from "./services/config.service.mjs";
|
|
2
|
+
import { ErrorTrackingService, ErrorTrackingServiceLive } from "./services/error-tracking.service.mjs";
|
|
3
|
+
import { withInterfereLogger } from "@interfere/effect-utils/observability";
|
|
4
|
+
import { Effect, Layer } from "effect";
|
|
5
|
+
import { withSpan } from "@interfere/react/effect/layers/tracer.layer";
|
|
6
|
+
|
|
7
|
+
//#region src/server/proxy.ts
|
|
8
|
+
function withInterfereProxy(handler) {
|
|
9
|
+
const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);
|
|
10
|
+
return async (req, event) => {
|
|
11
|
+
if (req.nextUrl.pathname.startsWith("/api/interfere")) return handler(req, event);
|
|
12
|
+
const started = Date.now();
|
|
13
|
+
const program = Effect.gen(function* () {
|
|
14
|
+
const errorTracking = yield* ErrorTrackingService;
|
|
15
|
+
return yield* withSpan("proxy.request", Effect.tryPromise({
|
|
16
|
+
try: () => Promise.resolve(handler(req, event)),
|
|
17
|
+
catch: (error) => error
|
|
18
|
+
}), { attributes: { path: req.nextUrl.pathname } }).pipe(Effect.tapError((error) => errorTracking.captureError(error, req, {
|
|
19
|
+
pathname: req.nextUrl.pathname,
|
|
20
|
+
proxy: true,
|
|
21
|
+
duration: Date.now() - started
|
|
22
|
+
})));
|
|
23
|
+
}).pipe(Effect.provide(layer));
|
|
24
|
+
return await Effect.runPromise(withInterfereLogger("next", program));
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { withInterfereProxy };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.mjs","names":[],"sources":["../../src/server/proxy.ts"],"sourcesContent":["import { withInterfereLogger } from \"@interfere/effect-utils/observability\";\nimport { withSpan } from \"@interfere/react/effect/layers/tracer.layer\";\nimport { Effect, Layer } from \"effect\";\nimport type { NextFetchEvent, NextRequest } from \"next/server\";\nimport { ConfigServiceLive } from \"./services/config.service\";\nimport {\n ErrorTrackingService,\n ErrorTrackingServiceLive,\n} from \"./services/error-tracking.service\";\n\n// Proxy wrapper compatible with Next 16 `proxy.ts` with Effect\nexport function withInterfereProxy(\n handler: (\n req: NextRequest,\n event: NextFetchEvent\n ) => Promise<Response> | Response\n) {\n const layer = Layer.mergeAll(ConfigServiceLive, ErrorTrackingServiceLive);\n\n return async (req: NextRequest, event: NextFetchEvent) => {\n if (req.nextUrl.pathname.startsWith(\"/api/interfere\")) {\n return handler(req, event);\n }\n\n const started = Date.now();\n\n const program = Effect.gen(function* () {\n const errorTracking = yield* ErrorTrackingService;\n\n const response = yield* withSpan(\n \"proxy.request\",\n Effect.tryPromise({\n try: () => Promise.resolve(handler(req, event)),\n catch: (error) => error as Error,\n }),\n { attributes: { path: req.nextUrl.pathname } }\n ).pipe(\n Effect.tapError((error) =>\n errorTracking.captureError(error, req, {\n pathname: req.nextUrl.pathname,\n proxy: true,\n duration: Date.now() - started,\n })\n )\n );\n\n return response;\n }).pipe(Effect.provide(layer));\n\n return await Effect.runPromise(withInterfereLogger(\"next\", program));\n };\n}\n"],"mappings":";;;;;;;AAWA,SAAgB,mBACd,SAIA;CACA,MAAM,QAAQ,MAAM,SAAS,mBAAmB,yBAAyB;AAEzE,QAAO,OAAO,KAAkB,UAA0B;AACxD,MAAI,IAAI,QAAQ,SAAS,WAAW,iBAAiB,CACnD,QAAO,QAAQ,KAAK,MAAM;EAG5B,MAAM,UAAU,KAAK,KAAK;EAE1B,MAAM,UAAU,OAAO,IAAI,aAAa;GACtC,MAAM,gBAAgB,OAAO;AAmB7B,UAjBiB,OAAO,SACtB,iBACA,OAAO,WAAW;IAChB,WAAW,QAAQ,QAAQ,QAAQ,KAAK,MAAM,CAAC;IAC/C,QAAQ,UAAU;IACnB,CAAC,EACF,EAAE,YAAY,EAAE,MAAM,IAAI,QAAQ,UAAU,EAAE,CAC/C,CAAC,KACA,OAAO,UAAU,UACf,cAAc,aAAa,OAAO,KAAK;IACrC,UAAU,IAAI,QAAQ;IACtB,OAAO;IACP,UAAU,KAAK,KAAK,GAAG;IACxB,CAAC,CACH,CACF;IAGD,CAAC,KAAK,OAAO,QAAQ,MAAM,CAAC;AAE9B,SAAO,MAAM,OAAO,WAAW,oBAAoB,QAAQ,QAAQ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NextRequest } from "next/server";
|
|
2
|
+
|
|
3
|
+
//#region src/server/route-handler.d.ts
|
|
4
|
+
type RouteHandler = (request: NextRequest) => Promise<Response>;
|
|
5
|
+
declare const GET: RouteHandler;
|
|
6
|
+
declare const POST: RouteHandler;
|
|
7
|
+
declare const OPTIONS: RouteHandler;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { GET, OPTIONS, POST };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-handler.d.mts","names":[],"sources":["../../src/server/route-handler.ts"],"sourcesContent":[],"mappings":";;;KAsBK,YAAA,aAAyB,gBAAgB,QAAQ;cAmBzC,KAAK;AAnBb,cA2JQ,IA3JI,EA2JE,YA3JF;AAAa,cAoQjB,OApQiB,EAoQR,YApQQ"}
|