@interfere/next 0.0.14 → 0.0.15-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +48 -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 +73 -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 -295
- 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 -363
- 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 -153
- package/dist/__tests__/integration/release-upload.test.js.map +0 -1
- package/dist/__tests__/provider.test.d.ts +0 -2
- package/dist/__tests__/provider.test.d.ts.map +0 -1
- package/dist/__tests__/provider.test.js +0 -84
- package/dist/__tests__/provider.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 -40
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -340
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -37
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -49
- package/dist/index.js.map +0 -1
- package/dist/index.jsx +0 -87
- 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
package/README.md
CHANGED
|
@@ -258,14 +258,9 @@ init({
|
|
|
258
258
|
|
|
259
259
|
The SDK automatically captures these event types:
|
|
260
260
|
|
|
261
|
-
- `error` -
|
|
262
|
-
- `server_error` - Server-side errors in API routes and server components
|
|
263
|
-
- `edge_error` - Edge runtime errors in middleware
|
|
264
|
-
- `server_req` - Server request events (API routes)
|
|
265
|
-
- `edge_req` - Edge request events (middleware)
|
|
261
|
+
- `error` - Runtime errors (client, server, and edge); origin is indicated by `errorSource` in the payload (`client` | `server` | `edge`).
|
|
266
262
|
- `ui_event` - User interface events
|
|
267
263
|
- `custom` - Custom application events
|
|
268
|
-
- `network` - Network request events (coming soon)
|
|
269
264
|
- `rage_click` - rage clicks
|
|
270
265
|
|
|
271
266
|
## Best Practices
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NonEmptyString } from "../lib/types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/build/env-config.d.ts
|
|
4
|
+
declare function resolveApiUrl(): string;
|
|
5
|
+
declare function normalizeSecretKey(raw: string | undefined): NonEmptyString | null;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { normalizeSecretKey, resolveApiUrl };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-config.d.mts","names":[],"sources":["../../src/build/env-config.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,aAAA,CAAA;iBAWA,kBAAA,2BAEb"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { toNonEmptyString } from "../lib/types.mjs";
|
|
2
|
+
import { API_URL } from "@interfere/constants/api";
|
|
3
|
+
|
|
4
|
+
//#region src/build/env-config.ts
|
|
5
|
+
function resolveApiUrl() {
|
|
6
|
+
const raw = process.env.INTERFERE_API_URL;
|
|
7
|
+
const trimmed = typeof raw === "string" ? raw.trim() : "";
|
|
8
|
+
if (trimmed.length > 0) return trimmed;
|
|
9
|
+
return API_URL;
|
|
10
|
+
}
|
|
11
|
+
function normalizeSecretKey(raw) {
|
|
12
|
+
if (typeof raw !== "string") return null;
|
|
13
|
+
return toNonEmptyString(raw.trim().replace(/^['"]|['"]$/g, ""));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { normalizeSecretKey, resolveApiUrl };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-config.mjs","names":[],"sources":["../../src/build/env-config.ts"],"sourcesContent":["import { API_URL } from \"@interfere/constants/api\";\nimport { type NonEmptyString, toNonEmptyString } from \"../lib/types.js\";\n\nexport function resolveApiUrl(): string {\n const raw = process.env.INTERFERE_API_URL;\n const trimmed = typeof raw === \"string\" ? raw.trim() : \"\";\n\n if (trimmed.length > 0) {\n return trimmed;\n }\n\n return API_URL;\n}\n\nexport function normalizeSecretKey(\n raw: string | undefined\n): NonEmptyString | null {\n if (typeof raw !== \"string\") {\n return null;\n }\n\n const trimmed = raw.trim();\n const cleaned = trimmed.replace(/^['\"]|['\"]$/g, \"\");\n\n return toNonEmptyString(cleaned);\n}\n\n\n"],"mappings":";;;;AAGA,SAAgB,gBAAwB;CACtC,MAAM,MAAM,QAAQ,IAAI;CACxB,MAAM,UAAU,OAAO,QAAQ,WAAW,IAAI,MAAM,GAAG;AAEvD,KAAI,QAAQ,SAAS,EACnB,QAAO;AAGT,QAAO;;AAGT,SAAgB,mBACd,KACuB;AACvB,KAAI,OAAO,QAAQ,SACjB,QAAO;AAMT,QAAO,iBAHS,IAAI,MAAM,CACF,QAAQ,gBAAgB,GAAG,CAEnB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Effect, LogLevel, Logger } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/build/logger.d.ts
|
|
4
|
+
declare const nextBuildLogger: Logger.Logger<unknown, void>;
|
|
5
|
+
declare function logBuildResult(level: LogLevel.Literal, title: string, lines: string[]): Effect.Effect<void, never, never>;
|
|
6
|
+
declare function setBuildLogTitle(level: LogLevel.Literal, title: string): Effect.Effect<void, never, never>;
|
|
7
|
+
declare function appendBuildLogLine(line: string): Effect.Effect<void, never, never>;
|
|
8
|
+
declare function flushBuildLog(): Effect.Effect<void, never, never>;
|
|
9
|
+
declare function withBufferedBuildLog(level: LogLevel.Literal, title: string, use: (log: (line: string) => ReturnType<typeof appendBuildLogLine>) => Effect.Effect<unknown, unknown, unknown>): Effect.Effect<unknown, unknown, unknown>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { appendBuildLogLine, flushBuildLog, logBuildResult, nextBuildLogger, setBuildLogTitle, withBufferedBuildLog };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.mts","names":[],"sources":["../../src/build/logger.ts"],"sourcesContent":[],"mappings":";;;cA+CM,iBAAe,MAAA,CAAA;AAAf,iBA0HU,cAAA,CA1HK,KAAA,EA0HiB,QAAA,CAAS,OA1H1B,EAAA,KAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,CAAA,EA0HiE,MAAA,CAAA,MA1HjE,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;AA0HL,iBAyCA,gBAAA,CAzC+B,KAAA,EA0CtC,QAAA,CAAS,OA1CoE,EAAA,KAAA,EAAA,MAAA,CAAA,EA2CvE,MAAA,CAAA,MA3CuE,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;AAyCtE,iBAUA,kBAAA,CATE,IAAA,EAAA,MACH,CAAA,EAQgC,MAAA,CAAA,MARhC,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;AAQC,iBAWA,aAAA,CAAA,CAX+B,EAWlB,MAAA,CAAA,MAXkB,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;AAW/B,iBAmBA,oBAAA,CAnBa,KAAA,EAoBpB,QAAA,CAAS,OApBW,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,EAAA,CAAA,GAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAuBF,UAvBE,CAAA,OAuBgB,kBAvBhB,CAAA,EAAA,GAwBtB,MAAA,CAAO,MAxBe,CAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA,CAAA,EAwBkB,MAAA,CAAA,MAxBlB,CAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { InterfereLogger } from "@interfere/effect-utils/observability";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { Cause, Effect, LogLevel, Logger } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/build/logger.ts
|
|
6
|
+
const buildConsole = globalThis.console;
|
|
7
|
+
const prefixes = {
|
|
8
|
+
Info: chalk.cyan.bold(" "),
|
|
9
|
+
Debug: chalk.gray.bold(" "),
|
|
10
|
+
All: chalk.gray.bold(" "),
|
|
11
|
+
Trace: chalk.magenta.bold(" "),
|
|
12
|
+
Warning: chalk.yellow.bold("⚠"),
|
|
13
|
+
Error: chalk.red.bold("⨯"),
|
|
14
|
+
Fatal: chalk.red.bold("⨯"),
|
|
15
|
+
None: chalk.white.bold(" ")
|
|
16
|
+
};
|
|
17
|
+
const textStyles = {
|
|
18
|
+
Info: chalk.cyan.bold,
|
|
19
|
+
Debug: chalk.gray.bold,
|
|
20
|
+
All: chalk.gray.bold,
|
|
21
|
+
Trace: chalk.magenta.bold,
|
|
22
|
+
Warning: chalk.yellow.bold,
|
|
23
|
+
Error: chalk.red.bold,
|
|
24
|
+
Fatal: chalk.red.bold,
|
|
25
|
+
None: chalk.white.bold
|
|
26
|
+
};
|
|
27
|
+
const logMethods = {
|
|
28
|
+
Warning: "warn",
|
|
29
|
+
Error: "error"
|
|
30
|
+
};
|
|
31
|
+
function tagForLevel(level) {
|
|
32
|
+
switch (level) {
|
|
33
|
+
case "Error":
|
|
34
|
+
case "Fatal": return "[error]";
|
|
35
|
+
case "Warning": return "[warn]";
|
|
36
|
+
case "Debug": return "[debug]";
|
|
37
|
+
default: return "";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const nextBuildLogger = Logger.make(({ logLevel, message, cause }) => {
|
|
41
|
+
if (!shouldLog(logLevel._tag)) return;
|
|
42
|
+
const renderedMessage = coerceToArray(message).map(formatValue).filter(Boolean).join(" ").trim();
|
|
43
|
+
if (renderedMessage.length > 0) levelLog(logLevel._tag, renderedMessage);
|
|
44
|
+
else levelLog(logLevel._tag);
|
|
45
|
+
if (!Cause.isEmpty(cause)) levelLog(logLevel._tag, `${chalk.dim("details")} ${Cause.pretty(cause, { renderErrorCause: true })}`);
|
|
46
|
+
});
|
|
47
|
+
function systemLog(level, ...message) {
|
|
48
|
+
if (!shouldLog(level)) return;
|
|
49
|
+
const consoleFn = buildConsole[logMethods[level] ?? "log"];
|
|
50
|
+
if (typeof consoleFn !== "function") return;
|
|
51
|
+
const invoke = (...args) => Reflect.apply(consoleFn, buildConsole, args);
|
|
52
|
+
if (message.length === 0) {
|
|
53
|
+
invoke("");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (message.length === 1) {
|
|
57
|
+
invoke(` ${message[0]}`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
invoke(` `, ...message);
|
|
61
|
+
}
|
|
62
|
+
function coerceToArray(value) {
|
|
63
|
+
if (Array.isArray(value)) return value.map(formatValue);
|
|
64
|
+
return [formatValue(value)];
|
|
65
|
+
}
|
|
66
|
+
function formatValue(value) {
|
|
67
|
+
if (typeof value === "string") return value;
|
|
68
|
+
if (value instanceof Error) return value.stack ?? value.message;
|
|
69
|
+
if (value === null || value === void 0) return "";
|
|
70
|
+
try {
|
|
71
|
+
return JSON.stringify(value);
|
|
72
|
+
} catch {
|
|
73
|
+
return String(value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function levelLog(level, ...message) {
|
|
77
|
+
if (!shouldLog(level)) return;
|
|
78
|
+
const consoleMethod = logMethods[level] ?? "log";
|
|
79
|
+
const prefix = prefixes[level] ?? prefixes.Info;
|
|
80
|
+
const tag = tagForLevel(level);
|
|
81
|
+
const consoleFn = buildConsole[consoleMethod];
|
|
82
|
+
if (typeof consoleFn !== "function") return;
|
|
83
|
+
const invoke = (...args) => Reflect.apply(consoleFn, buildConsole, args);
|
|
84
|
+
if (message.length === 0) {
|
|
85
|
+
invoke("");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const tagPart = tag ? ` ${tag}` : "";
|
|
89
|
+
if (message.length === 1) {
|
|
90
|
+
invoke(` ${prefix}${tagPart} ${message[0]}`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
invoke(` ${prefix}${tagPart}`, ...message);
|
|
94
|
+
}
|
|
95
|
+
function logBuildResult(level, title, lines) {
|
|
96
|
+
if (!shouldLog(level)) return Effect.void;
|
|
97
|
+
return Effect.sync(() => {
|
|
98
|
+
systemLog(level, `❖ ${chalk.white("Interfere →")} ${textStyles[level](title)}`);
|
|
99
|
+
if (lines.length === 0) return;
|
|
100
|
+
const prefix = prefixes[level] ?? prefixes.Info;
|
|
101
|
+
const tag = tagForLevel(level);
|
|
102
|
+
const tagPart = tag ? `${tag} ` : "";
|
|
103
|
+
const consoleFn = buildConsole[logMethods[level] ?? "log"];
|
|
104
|
+
if (typeof consoleFn !== "function") return;
|
|
105
|
+
const invoke = (...args) => Reflect.apply(consoleFn, buildConsole, args);
|
|
106
|
+
if (lines.length === 1) {
|
|
107
|
+
invoke(` ${prefix} └ ${tagPart}${lines[0]}`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
lines.forEach((line, index) => {
|
|
111
|
+
invoke(` ${prefix} ${index === lines.length - 1 ? "└" : "├"} ${tagPart}${line}`);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function setBuildLogTitle(level, title) {
|
|
116
|
+
return Effect.sync(() => {
|
|
117
|
+
buildLogState.level = level;
|
|
118
|
+
buildLogState.title = title;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function appendBuildLogLine(line) {
|
|
122
|
+
return Effect.sync(() => {
|
|
123
|
+
const trimmed = line.trim();
|
|
124
|
+
if (trimmed.length === 0) return;
|
|
125
|
+
buildLogState.lines.push(trimmed);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function flushBuildLog() {
|
|
129
|
+
return Effect.gen(function* () {
|
|
130
|
+
if (!buildLogState.title || buildLogState.lines.length === 0) return;
|
|
131
|
+
const level = buildLogState.level;
|
|
132
|
+
const title = buildLogState.title;
|
|
133
|
+
const lines = [...buildLogState.lines];
|
|
134
|
+
buildLogState.level = "Info";
|
|
135
|
+
buildLogState.title = null;
|
|
136
|
+
buildLogState.lines = [];
|
|
137
|
+
yield* logBuildResult(level, title, lines);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function withBufferedBuildLog(level, title, use) {
|
|
141
|
+
return Effect.acquireUseRelease(setBuildLogTitle(level, title), () => use((line) => appendBuildLogLine(line)), (_, _exit) => flushBuildLog());
|
|
142
|
+
}
|
|
143
|
+
const buildLogState = {
|
|
144
|
+
level: "Info",
|
|
145
|
+
title: null,
|
|
146
|
+
lines: []
|
|
147
|
+
};
|
|
148
|
+
function shouldLog(level) {
|
|
149
|
+
const minLevel = process.env.INTERFERE_PLUGIN_DEBUG === "1" ? LogLevel.Debug : InterfereLogger.minimumLevel();
|
|
150
|
+
const currentLevel = LogLevel.fromLiteral(level);
|
|
151
|
+
return LogLevel.greaterThanEqual(currentLevel, minLevel);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
export { appendBuildLogLine, flushBuildLog, logBuildResult, nextBuildLogger, setBuildLogTitle, withBufferedBuildLog };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.mjs","names":["prefixes: Record<LogLevel.Literal, string>","textStyles: Record<LogLevel.Literal, ChalkInstance>","logMethods: Partial<Record<LogLevel.Literal, keyof Console>>","buildLogState: BuildLogState"],"sources":["../../src/build/logger.ts"],"sourcesContent":["import { InterfereLogger } from \"@interfere/effect-utils/observability\";\nimport chalk, { type ChalkInstance } from \"chalk\";\nimport { Cause, Effect, Logger, LogLevel } from \"effect\";\n\nconst buildConsole = globalThis.console;\n\nconst prefixes: Record<LogLevel.Literal, string> = {\n Info: chalk.cyan.bold(\" \"),\n Debug: chalk.gray.bold(\" \"),\n All: chalk.gray.bold(\" \"),\n Trace: chalk.magenta.bold(\" \"),\n Warning: chalk.yellow.bold(\"⚠\"),\n Error: chalk.red.bold(\"⨯\"),\n Fatal: chalk.red.bold(\"⨯\"),\n None: chalk.white.bold(\" \"),\n} as const;\n\nconst textStyles: Record<LogLevel.Literal, ChalkInstance> = {\n Info: chalk.cyan.bold,\n Debug: chalk.gray.bold,\n All: chalk.gray.bold,\n Trace: chalk.magenta.bold,\n Warning: chalk.yellow.bold,\n Error: chalk.red.bold,\n Fatal: chalk.red.bold,\n None: chalk.white.bold,\n}\n\nconst logMethods: Partial<Record<LogLevel.Literal, keyof Console>> = {\n Warning: \"warn\",\n Error: \"error\",\n};\n\nfunction tagForLevel(level: LogLevel.Literal) {\n switch (level) {\n case \"Error\":\n case \"Fatal\":\n return \"[error]\";\n case \"Warning\":\n return \"[warn]\";\n case \"Debug\":\n return \"[debug]\";\n default:\n return \"\";\n }\n}\n\nconst nextBuildLogger = Logger.make<unknown, void>(\n ({ logLevel, message, cause }) => {\n if (!shouldLog(logLevel._tag)) {\n return;\n }\n\n const renderedMessage = coerceToArray(message)\n .map(formatValue)\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n if (renderedMessage.length > 0) {\n levelLog(logLevel._tag, renderedMessage);\n } else {\n levelLog(logLevel._tag);\n }\n\n if (!Cause.isEmpty(cause)) {\n levelLog(\n logLevel._tag,\n `${chalk.dim(\"details\")} ${Cause.pretty(cause, {\n renderErrorCause: true,\n })}`\n );\n }\n }\n);\n\n\n\nfunction systemLog(level: LogLevel.Literal, ...message: string[]) {\n if (!shouldLog(level)) {\n return;\n }\n\n const consoleMethod = logMethods[level] ?? \"log\";\n\n const consoleFn = buildConsole[consoleMethod];\n if (typeof consoleFn !== \"function\") {\n return;\n }\n\n const invoke = (...args: unknown[]) =>\n Reflect.apply(consoleFn, buildConsole, args);\n\n if (message.length === 0) {\n invoke(\"\");\n return;\n }\n\n if (message.length === 1) {\n invoke(` ${message[0]}`);\n return;\n }\n\n invoke(` `, ...message);\n}\n\nfunction coerceToArray(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(formatValue);\n }\n\n return [formatValue(value)];\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value instanceof Error) {\n return value.stack ?? value.message;\n }\n\n if (value === null || value === undefined) {\n return \"\";\n }\n\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport { nextBuildLogger };\n\nfunction levelLog(level: LogLevel.Literal, ...message: string[]) {\n if (!shouldLog(level)) {\n return;\n }\n\n const consoleMethod = logMethods[level] ?? \"log\";\n const prefix = prefixes[level] ?? prefixes.Info;\n const tag = tagForLevel(level);\n\n const consoleFn = buildConsole[consoleMethod];\n\n if (typeof consoleFn !== \"function\") {\n return;\n }\n\n const invoke = (...args: unknown[]) =>\n Reflect.apply(consoleFn, buildConsole, args);\n\n if (message.length === 0) {\n invoke(\"\");\n return;\n }\n\n const tagPart = tag ? ` ${tag}` : \"\";\n\n if (message.length === 1) {\n invoke(` ${prefix}${tagPart} ${message[0]}`);\n return;\n }\n\n invoke(` ${prefix}${tagPart}`, ...message);\n}\n\nexport function logBuildResult(level: LogLevel.Literal, title: string, lines: string[]) {\n if (!shouldLog(level)) {\n return Effect.void;\n }\n\n return Effect.sync(() => {\n systemLog(level, `❖ ${chalk.white(\"Interfere →\")} ${textStyles[level](title)}`);\n\n if (lines.length === 0) {\n return;\n }\n\n const prefix = prefixes[level] ?? prefixes.Info;\n const tag = tagForLevel(level);\n const tagPart = tag ? `${tag} ` : \"\";\n const consoleMethod = logMethods[level] ?? \"log\";\n const consoleFn = buildConsole[consoleMethod];\n\n if (typeof consoleFn !== \"function\") {\n return;\n }\n\n const invoke = (...args: unknown[]) =>\n Reflect.apply(consoleFn, buildConsole, args);\n\n if (lines.length === 1) {\n // Single line - connector plus tag after the connector\n const connector = \"└\";\n invoke(` ${prefix} ${connector} ${tagPart}${lines[0]}`);\n return;\n }\n\n // Multi-line - tree structure with connectors and tag after connector\n lines.forEach((line, index) => {\n const isLast = index === lines.length - 1;\n const connector = isLast ? \"└\" : \"├\";\n invoke(` ${prefix} ${connector} ${tagPart}${line}`);\n });\n });\n}\n\nexport function setBuildLogTitle(\n level: LogLevel.Literal,\n title: string\n) {\n return Effect.sync(() => {\n buildLogState.level = level;\n buildLogState.title = title;\n });\n}\n\nexport function appendBuildLogLine(line: string) {\n return Effect.sync(() => {\n const trimmed = line.trim();\n if (trimmed.length === 0) {\n return;\n }\n\n buildLogState.lines.push(trimmed);\n });\n}\n\nexport function flushBuildLog() {\n return Effect.gen(function* () {\n if (!buildLogState.title || buildLogState.lines.length === 0) {\n return;\n }\n\n const level = buildLogState.level;\n const title = buildLogState.title;\n const lines = [...buildLogState.lines];\n\n // Reset state before logging in case logging itself fails\n buildLogState.level = \"Info\";\n buildLogState.title = null;\n buildLogState.lines = [];\n\n yield* logBuildResult(level, title, lines);\n });\n}\n\nexport function withBufferedBuildLog(\n level: LogLevel.Literal,\n title: string,\n use: (\n log: (line: string) => ReturnType<typeof appendBuildLogLine>\n ) => Effect.Effect<unknown, unknown, unknown>\n) {\n return Effect.acquireUseRelease(\n setBuildLogTitle(level, title),\n () => use((line) => appendBuildLogLine(line)),\n (_, _exit) => flushBuildLog()\n );\n}\n\ntype BuildLogState = {\n level: LogLevel.Literal;\n title: string | null;\n lines: string[];\n};\n\nconst buildLogState: BuildLogState = {\n level: \"Info\",\n title: null,\n lines: [],\n};\n\nfunction shouldLog(level: LogLevel.Literal) {\n const debugEnabled = process.env.INTERFERE_PLUGIN_DEBUG === \"1\";\n const minLevel = debugEnabled ? LogLevel.Debug : InterfereLogger.minimumLevel();\n const currentLevel = LogLevel.fromLiteral(level);\n return LogLevel.greaterThanEqual(currentLevel, minLevel);\n}\n\n"],"mappings":";;;;;AAIA,MAAM,eAAe,WAAW;AAEhC,MAAMA,WAA6C;CACjD,MAAM,MAAM,KAAK,KAAK,IAAI;CAC1B,OAAO,MAAM,KAAK,KAAK,IAAI;CAC3B,KAAK,MAAM,KAAK,KAAK,IAAI;CACzB,OAAO,MAAM,QAAQ,KAAK,IAAI;CAC9B,SAAS,MAAM,OAAO,KAAK,IAAI;CAC/B,OAAO,MAAM,IAAI,KAAK,IAAI;CAC1B,OAAO,MAAM,IAAI,KAAK,IAAI;CAC1B,MAAM,MAAM,MAAM,KAAK,IAAI;CAC5B;AAED,MAAMC,aAAsD;CAC1D,MAAM,MAAM,KAAK;CACjB,OAAO,MAAM,KAAK;CAClB,KAAK,MAAM,KAAK;CAChB,OAAO,MAAM,QAAQ;CACrB,SAAS,MAAM,OAAO;CACtB,OAAO,MAAM,IAAI;CACjB,OAAO,MAAM,IAAI;CACjB,MAAM,MAAM,MAAM;CACnB;AAED,MAAMC,aAA+D;CACnE,SAAS;CACT,OAAO;CACR;AAED,SAAS,YAAY,OAAyB;AAC5C,SAAQ,OAAR;EACE,KAAK;EACL,KAAK,QACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,QACE,QAAO;;;AAIb,MAAM,kBAAkB,OAAO,MAC5B,EAAE,UAAU,SAAS,YAAY;AAChC,KAAI,CAAC,UAAU,SAAS,KAAK,CAC3B;CAGF,MAAM,kBAAkB,cAAc,QAAQ,CAC3C,IAAI,YAAY,CAChB,OAAO,QAAQ,CACf,KAAK,IAAI,CACT,MAAM;AAET,KAAI,gBAAgB,SAAS,EAC3B,UAAS,SAAS,MAAM,gBAAgB;KAExC,UAAS,SAAS,KAAK;AAGzB,KAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,UACE,SAAS,MACT,GAAG,MAAM,IAAI,UAAU,CAAC,GAAG,MAAM,OAAO,OAAO,EAC7C,kBAAkB,MACnB,CAAC,GACH;EAGN;AAID,SAAS,UAAU,OAAyB,GAAG,SAAmB;AAChE,KAAI,CAAC,UAAU,MAAM,CACnB;CAKF,MAAM,YAAY,aAFI,WAAW,UAAU;AAG3C,KAAI,OAAO,cAAc,WACvB;CAGF,MAAM,UAAU,GAAG,SACjB,QAAQ,MAAM,WAAW,cAAc,KAAK;AAE9C,KAAI,QAAQ,WAAW,GAAG;AACxB,SAAO,GAAG;AACV;;AAGF,KAAI,QAAQ,WAAW,GAAG;AACxB,SAAO,IAAI,QAAQ,KAAK;AACxB;;AAGF,QAAO,KAAK,GAAG,QAAQ;;AAGzB,SAAS,cAAc,OAA0B;AAC/C,KAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,IAAI,YAAY;AAG/B,QAAO,CAAC,YAAY,MAAM,CAAC;;AAG7B,SAAS,YAAY,OAAwB;AAC3C,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI,iBAAiB,MACnB,QAAO,MAAM,SAAS,MAAM;AAG9B,KAAI,UAAU,QAAQ,UAAU,OAC9B,QAAO;AAGT,KAAI;AACF,SAAO,KAAK,UAAU,MAAM;SACtB;AACN,SAAO,OAAO,MAAM;;;AAMxB,SAAS,SAAS,OAAyB,GAAG,SAAmB;AAC/D,KAAI,CAAC,UAAU,MAAM,CACnB;CAGF,MAAM,gBAAgB,WAAW,UAAU;CAC3C,MAAM,SAAS,SAAS,UAAU,SAAS;CAC3C,MAAM,MAAM,YAAY,MAAM;CAE9B,MAAM,YAAY,aAAa;AAE/B,KAAI,OAAO,cAAc,WACvB;CAGF,MAAM,UAAU,GAAG,SACjB,QAAQ,MAAM,WAAW,cAAc,KAAK;AAE9C,KAAI,QAAQ,WAAW,GAAG;AACxB,SAAO,GAAG;AACV;;CAGF,MAAM,UAAU,MAAM,IAAI,QAAQ;AAElC,KAAI,QAAQ,WAAW,GAAG;AACxB,SAAO,IAAI,SAAS,QAAQ,GAAG,QAAQ,KAAK;AAC5C;;AAGF,QAAO,IAAI,SAAS,WAAW,GAAG,QAAQ;;AAG5C,SAAgB,eAAe,OAAyB,OAAe,OAAiB;AACtF,KAAI,CAAC,UAAU,MAAM,CACnB,QAAO,OAAO;AAGhB,QAAO,OAAO,WAAW;AACvB,YAAU,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC,GAAG,WAAW,OAAO,MAAM,GAAG;AAE/E,MAAI,MAAM,WAAW,EACnB;EAGF,MAAM,SAAS,SAAS,UAAU,SAAS;EAC3C,MAAM,MAAM,YAAY,MAAM;EAC9B,MAAM,UAAU,MAAM,GAAG,IAAI,KAAK;EAElC,MAAM,YAAY,aADI,WAAW,UAAU;AAG3C,MAAI,OAAO,cAAc,WACvB;EAGF,MAAM,UAAU,GAAG,SACjB,QAAQ,MAAM,WAAW,cAAc,KAAK;AAE9C,MAAI,MAAM,WAAW,GAAG;AAGtB,UAAO,IAAI,OAAO,KAAgB,UAAU,MAAM,KAAK;AACvD;;AAIF,QAAM,SAAS,MAAM,UAAU;AAG7B,UAAO,IAAI,OAAO,GAFH,UAAU,MAAM,SAAS,IACb,MAAM,IACF,GAAG,UAAU,OAAO;IACnD;GACF;;AAGJ,SAAgB,iBACd,OACA,OACA;AACA,QAAO,OAAO,WAAW;AACvB,gBAAc,QAAQ;AACtB,gBAAc,QAAQ;GACtB;;AAGJ,SAAgB,mBAAmB,MAAc;AAC/C,QAAO,OAAO,WAAW;EACvB,MAAM,UAAU,KAAK,MAAM;AAC3B,MAAI,QAAQ,WAAW,EACrB;AAGF,gBAAc,MAAM,KAAK,QAAQ;GACjC;;AAGJ,SAAgB,gBAAgB;AAC9B,QAAO,OAAO,IAAI,aAAa;AAC7B,MAAI,CAAC,cAAc,SAAS,cAAc,MAAM,WAAW,EACzD;EAGF,MAAM,QAAQ,cAAc;EAC5B,MAAM,QAAQ,cAAc;EAC5B,MAAM,QAAQ,CAAC,GAAG,cAAc,MAAM;AAGtC,gBAAc,QAAQ;AACtB,gBAAc,QAAQ;AACtB,gBAAc,QAAQ,EAAE;AAExB,SAAO,eAAe,OAAO,OAAO,MAAM;GAC1C;;AAGJ,SAAgB,qBACd,OACA,OACA,KAGA;AACA,QAAO,OAAO,kBACZ,iBAAiB,OAAO,MAAM,QACxB,KAAK,SAAS,mBAAmB,KAAK,CAAC,GAC5C,GAAG,UAAU,eAAe,CAC9B;;AASH,MAAMC,gBAA+B;CACnC,OAAO;CACP,OAAO;CACP,OAAO,EAAE;CACV;AAED,SAAS,UAAU,OAAyB;CAE1C,MAAM,WADe,QAAQ,IAAI,2BAA2B,MAC5B,SAAS,QAAQ,gBAAgB,cAAc;CAC/E,MAAM,eAAe,SAAS,YAAY,MAAM;AAChD,QAAO,SAAS,iBAAiB,cAAc,SAAS"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PreflightConfig } from "../lib/types.mjs";
|
|
2
|
+
import { ConfigService } from "./services/config.service.mjs";
|
|
3
|
+
import { ReleaseIdentityService } from "./services/release-identity.service.mjs";
|
|
4
|
+
import { SourceMapService } from "./services/source-map.service.mjs";
|
|
5
|
+
import { Effect, Layer } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/build/release-program.d.ts
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The main release upload program.
|
|
11
|
+
* This is a single Effect that orchestrates the entire release process.
|
|
12
|
+
*/
|
|
13
|
+
declare const releaseProgram: Effect.Effect<unknown, unknown, unknown>;
|
|
14
|
+
/**
|
|
15
|
+
* Create the layer stack for the release program
|
|
16
|
+
*/
|
|
17
|
+
declare const createReleaseLayers: (config: PreflightConfig) => Layer.Layer<SourceMapService | ConfigService | ReleaseIdentityService, never, never>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { createReleaseLayers, releaseProgram };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-program.d.mts","names":[],"sources":["../../src/build/release-program.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAuBA;AA6IA;AAA4C,cA7I/B,cA6I+B,EA7IjB,MAAA,CAAA,MA6IiB,CAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA;;;;AAAe,cAA9C,mBAA8C,EAAA,CAAA,MAAA,EAAf,eAAe,EAAA,GAAA,KAAA,CAAA,KAAA,CAAA,gBAAA,GAAA,aAAA,GAAA,sBAAA,EAAA,KAAA,EAAA,KAAA,CAAA"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { resolveApiUrl } from "./env-config.mjs";
|
|
2
|
+
import { logBuildResult, withBufferedBuildLog } from "./logger.mjs";
|
|
3
|
+
import { ConfigService, ConfigServiceLive } from "./services/config.service.mjs";
|
|
4
|
+
import { ReleaseIdentityService, ReleaseIdentityServiceLive } from "./services/release-identity.service.mjs";
|
|
5
|
+
import { createRelease } from "./source-maps/api.mjs";
|
|
6
|
+
import { maybeCleanupAfterFailure } from "./source-maps/files.mjs";
|
|
7
|
+
import { SourceMapService, SourceMapServiceLive } from "./services/source-map.service.mjs";
|
|
8
|
+
import { Effect, Layer } from "effect";
|
|
9
|
+
|
|
10
|
+
//#region src/build/release-program.ts
|
|
11
|
+
/**
|
|
12
|
+
* The main release upload program.
|
|
13
|
+
* This is a single Effect that orchestrates the entire release process.
|
|
14
|
+
*/
|
|
15
|
+
const releaseProgram = Effect.gen(function* () {
|
|
16
|
+
const config = yield* ConfigService;
|
|
17
|
+
if (process.env.NODE_ENV === "development") {
|
|
18
|
+
yield* logBuildResult("Info", "Skipping Release", ["Development build detected"]);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!config.enabled) {
|
|
22
|
+
yield* logBuildResult("Warning", "Skipping Release", ["Interfere is disabled. (`interfere.enabled` is `false` in your `next.config.(js|ts)`)"]);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const sourceMapService = yield* SourceMapService;
|
|
26
|
+
if (!config.secretKey) {
|
|
27
|
+
yield* logBuildResult("Warning", "Skipping Release", ["Missing secret key. Please set the `INTERFERE_SECRET_KEY` environment variable."]);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
yield* Effect.logDebug("Getting release identity");
|
|
31
|
+
const identityStart = Date.now();
|
|
32
|
+
const identity = yield* yield* ReleaseIdentityService;
|
|
33
|
+
yield* Effect.logDebug(`Release identity resolved in ${Date.now() - identityStart}ms`);
|
|
34
|
+
if (!identity.sourceControl) {
|
|
35
|
+
yield* logBuildResult("Warning", "Skipping Release", ["Could not determine source control metadata (no supported VCS provider detected).", "Ensure your CI checks out the git repository and that a supported provider is configured."]);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!identity.deployment) {
|
|
39
|
+
yield* logBuildResult("Warning", "Skipping Release", ["Could not determine deployment metadata (no supported deployment provider detected).", "If this is a local build you can ignore this. Otherwise, expose your platform's system env vars (e.g. VERCEL_*)."]);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
yield* Effect.logDebug("Finding source maps");
|
|
43
|
+
const findStart = Date.now();
|
|
44
|
+
const sourceMapFiles = yield* sourceMapService.find;
|
|
45
|
+
yield* Effect.logDebug(`Found ${sourceMapFiles.length} source maps in ${Date.now() - findStart}ms`);
|
|
46
|
+
if (sourceMapFiles.length === 0) {
|
|
47
|
+
yield* logBuildResult("Warning", "Skipping Release", ["No source maps found. Is `productionBrowserSourceMaps` set to `false` in your `next.config.js`?"]);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
yield* Effect.logDebug("Creating release");
|
|
51
|
+
const createStart = Date.now();
|
|
52
|
+
const releaseResponse = yield* createRelease(config, {
|
|
53
|
+
environment: config.environment,
|
|
54
|
+
sourceId: identity.buildId,
|
|
55
|
+
sourceType: identity.sourceControl.type,
|
|
56
|
+
sourceMetadata: identity.sourceControl.metadata,
|
|
57
|
+
destinationType: identity.deployment.type,
|
|
58
|
+
destinationMetadata: identity.deployment.metadata
|
|
59
|
+
});
|
|
60
|
+
yield* Effect.logDebug(`Release created in ${Date.now() - createStart}ms`);
|
|
61
|
+
yield* Effect.logDebug("Reading source maps");
|
|
62
|
+
const readStart = Date.now();
|
|
63
|
+
const sourceMaps = yield* sourceMapService.read(sourceMapFiles);
|
|
64
|
+
yield* Effect.logDebug(`Read ${sourceMaps.length} source maps in ${Date.now() - readStart}ms`);
|
|
65
|
+
yield* Effect.logDebug("Uploading source maps");
|
|
66
|
+
const uploadStart = Date.now();
|
|
67
|
+
yield* sourceMapService.upload(sourceMaps, {
|
|
68
|
+
...releaseResponse,
|
|
69
|
+
apiUrl: resolveApiUrl()
|
|
70
|
+
});
|
|
71
|
+
yield* Effect.logDebug(`Source maps uploaded in ${Date.now() - uploadStart}ms`);
|
|
72
|
+
yield* Effect.logDebug("Cleaning up source maps");
|
|
73
|
+
const cleanupStart = Date.now();
|
|
74
|
+
yield* sourceMapService.cleanup(sourceMapFiles, !!config.debug);
|
|
75
|
+
yield* Effect.logDebug(`Cleanup completed in ${Date.now() - cleanupStart}ms`);
|
|
76
|
+
}).pipe(Effect.catchIf((error) => error._tag !== "MissingBuildIdError" && error._tag !== "MissingReleaseIdError", (error) => withBufferedBuildLog("Error", "Failed to upload source maps", (log) => Effect.gen(function* () {
|
|
77
|
+
const config = yield* ConfigService;
|
|
78
|
+
yield* log(String(error));
|
|
79
|
+
if (config.environment === "production" && config.cleanupSourceMaps !== false) yield* maybeCleanupAfterFailure(!!config.debug);
|
|
80
|
+
}))), Effect.withSpan("interfere.release"));
|
|
81
|
+
/**
|
|
82
|
+
* Create the layer stack for the release program
|
|
83
|
+
*/
|
|
84
|
+
const createReleaseLayers = (config) => {
|
|
85
|
+
const configLayer = ConfigServiceLive(config);
|
|
86
|
+
const identityLayer = ReleaseIdentityServiceLive;
|
|
87
|
+
const sourceMapLayer = SourceMapServiceLive.pipe(Layer.provide(configLayer));
|
|
88
|
+
return Layer.mergeAll(configLayer, identityLayer, sourceMapLayer);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { createReleaseLayers, releaseProgram };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-program.mjs","names":[],"sources":["../../src/build/release-program.ts"],"sourcesContent":["import { Effect, Layer } from \"effect\";\nimport type { PreflightConfig } from \"../lib/types.js\";\nimport { resolveApiUrl } from \"./env-config.js\";\nimport {\n logBuildResult,\n withBufferedBuildLog,\n} from \"./logger.js\";\nimport {\n ConfigService,\n ConfigServiceLive,\n} from \"./services/config.service.js\";\nimport {\n ReleaseIdentityService,\n ReleaseIdentityServiceLive,\n} from \"./services/release-identity.service.js\";\nimport { SourceMapService, SourceMapServiceLive } from \"./services/source-map.service.js\";\nimport { createRelease } from \"./source-maps/api.js\";\nimport { maybeCleanupAfterFailure } from \"./source-maps/files.js\";\n\n/**\n * The main release upload program.\n * This is a single Effect that orchestrates the entire release process.\n */\nexport const releaseProgram = Effect.gen(function* () {\n const config = yield* ConfigService;\n\n // Early exits\n if (process.env.NODE_ENV === \"development\") {\n yield* logBuildResult(\"Info\", \"Skipping Release\", [\"Development build detected\"]);\n return;\n }\n\n if (!config.enabled) {\n yield* logBuildResult(\n \"Warning\",\n \"Skipping Release\",\n [\"Interfere is disabled. (`interfere.enabled` is `false` in your `next.config.(js|ts)`)\"]\n );\n return;\n }\n\n const sourceMapService = yield* SourceMapService;\n\n if (!config.secretKey) {\n yield* logBuildResult(\n \"Warning\",\n \"Skipping Release\",\n [\"Missing secret key. Please set the `INTERFERE_SECRET_KEY` environment variable.\"]\n );\n return;\n }\n\n // Get release identity (will fail if can't determine)\n yield* Effect.logDebug(\"Getting release identity\");\n const identityStart = Date.now();\n const identityEffect = yield* ReleaseIdentityService;\n const identity = yield* identityEffect;\n yield* Effect.logDebug(`Release identity resolved in ${Date.now() - identityStart}ms`);\n\n // Check for required metadata\n if (!identity.sourceControl) {\n yield* logBuildResult(\n \"Warning\",\n \"Skipping Release\",\n [\n \"Could not determine source control metadata (no supported VCS provider detected).\",\n \"Ensure your CI checks out the git repository and that a supported provider is configured.\",\n ]\n );\n return;\n }\n\n if (!identity.deployment) {\n yield* logBuildResult(\n \"Warning\",\n \"Skipping Release\",\n [\n \"Could not determine deployment metadata (no supported deployment provider detected).\",\n \"If this is a local build you can ignore this. Otherwise, expose your platform's system env vars (e.g. VERCEL_*).\",\n ]\n );\n return;\n }\n\n // Find source maps\n yield* Effect.logDebug(\"Finding source maps\");\n const findStart = Date.now();\n const sourceMapFiles = yield* sourceMapService.find;\n yield* Effect.logDebug(`Found ${sourceMapFiles.length} source maps in ${Date.now() - findStart}ms`);\n\n if (sourceMapFiles.length === 0) {\n yield* logBuildResult(\n \"Warning\",\n \"Skipping Release\",\n [\"No source maps found. Is `productionBrowserSourceMaps` set to `false` in your `next.config.js`?\"]\n );\n return;\n }\n\n // Create release\n yield* Effect.logDebug(\"Creating release\");\n const createStart = Date.now();\n const releaseResponse = yield* createRelease(config, {\n environment: config.environment,\n sourceId: identity.buildId,\n sourceType: identity.sourceControl.type,\n sourceMetadata: identity.sourceControl.metadata,\n destinationType: identity.deployment.type,\n destinationMetadata: identity.deployment.metadata,\n });\n yield* Effect.logDebug(`Release created in ${Date.now() - createStart}ms`);\n\n // Read and upload source maps\n yield* Effect.logDebug(\"Reading source maps\");\n const readStart = Date.now();\n const sourceMaps = yield* sourceMapService.read(sourceMapFiles);\n yield* Effect.logDebug(`Read ${sourceMaps.length} source maps in ${Date.now() - readStart}ms`);\n \n yield* Effect.logDebug(\"Uploading source maps\");\n const uploadStart = Date.now();\n yield* sourceMapService.upload(sourceMaps, {\n ...releaseResponse,\n apiUrl: resolveApiUrl(),\n });\n yield* Effect.logDebug(`Source maps uploaded in ${Date.now() - uploadStart}ms`);\n\n // Cleanup\n yield* Effect.logDebug(\"Cleaning up source maps\");\n const cleanupStart = Date.now();\n yield* sourceMapService.cleanup(sourceMapFiles, !!config.debug);\n yield* Effect.logDebug(`Cleanup completed in ${Date.now() - cleanupStart}ms`);\n}).pipe(\n Effect.catchIf(\n // Only catch upload-related errors, let identity errors propagate\n (error) =>\n error._tag !== \"MissingBuildIdError\" &&\n error._tag !== \"MissingReleaseIdError\",\n (error) =>\n withBufferedBuildLog(\"Error\", \"Failed to upload source maps\", (log) =>\n Effect.gen(function* () {\n const config = yield* ConfigService;\n\n // Queue up build log lines so they appear in a single structured block\n yield* log(String(error));\n\n // Cleanup on failure\n if (\n config.environment === \"production\" &&\n config.cleanupSourceMaps !== false\n ) {\n yield* maybeCleanupAfterFailure(!!config.debug);\n }\n\n // Swallow the error so we don't surface a noisy FiberFailure stack trace\n return;\n })\n )\n ),\n Effect.withSpan(\"interfere.release\")\n);\n\n/**\n * Create the layer stack for the release program\n */\nexport const createReleaseLayers = (config: PreflightConfig) => {\n const configLayer = ConfigServiceLive(config);\n\n const identityLayer = ReleaseIdentityServiceLive;\n \n const sourceMapLayer = SourceMapServiceLive.pipe(\n Layer.provide(configLayer)\n );\n \n return Layer.mergeAll(\n configLayer,\n identityLayer,\n sourceMapLayer\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/build/secret-key.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Parse surface slug from secret key
|
|
4
|
+
* Format: int_sk_{surfaceSlug}_{random}
|
|
5
|
+
* Note: This is for display/validation purposes only.
|
|
6
|
+
* The actual surface lookup should use the key hash via Redis/DB.
|
|
7
|
+
*/
|
|
8
|
+
declare function parseSurfaceSlugFromSecretKey(secretKey: string): string | undefined;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { parseSurfaceSlugFromSecretKey };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-key.d.mts","names":[],"sources":["../../src/build/secret-key.ts"],"sourcesContent":[],"mappings":";;AAQA;;;;;iBAAgB,6BAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SECRET_KEY_REGEX } from "@interfere/types/auth/secret-key";
|
|
2
|
+
|
|
3
|
+
//#region src/build/secret-key.ts
|
|
4
|
+
/**
|
|
5
|
+
* Parse surface slug from secret key
|
|
6
|
+
* Format: int_sk_{surfaceSlug}_{random}
|
|
7
|
+
* Note: This is for display/validation purposes only.
|
|
8
|
+
* The actual surface lookup should use the key hash via Redis/DB.
|
|
9
|
+
*/
|
|
10
|
+
function parseSurfaceSlugFromSecretKey(secretKey) {
|
|
11
|
+
const match = secretKey.match(SECRET_KEY_REGEX);
|
|
12
|
+
if (match) return match[1];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { parseSurfaceSlugFromSecretKey };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-key.mjs","names":[],"sources":["../../src/build/secret-key.ts"],"sourcesContent":["import { SECRET_KEY_REGEX } from \"@interfere/types/auth/secret-key\";\n\n/**\n * Parse surface slug from secret key\n * Format: int_sk_{surfaceSlug}_{random}\n * Note: This is for display/validation purposes only.\n * The actual surface lookup should use the key hash via Redis/DB.\n */\nexport function parseSurfaceSlugFromSecretKey(\n secretKey: string\n): string | undefined {\n const match = secretKey.match(SECRET_KEY_REGEX);\n\n if (match) {\n return match[1];\n }\n\n return;\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,8BACd,WACoB;CACpB,MAAM,QAAQ,UAAU,MAAM,iBAAiB;AAE/C,KAAI,MACF,QAAO,MAAM"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PreflightConfig } from "../../lib/types.mjs";
|
|
2
|
+
import { Context, Layer } from "effect";
|
|
3
|
+
|
|
4
|
+
//#region src/build/services/config.service.d.ts
|
|
5
|
+
declare const ConfigService_base: Context.TagClass<ConfigService, "ConfigService", PreflightConfig>;
|
|
6
|
+
declare class ConfigService extends ConfigService_base {}
|
|
7
|
+
declare const ConfigServiceLive: (config: PreflightConfig) => Layer.Layer<ConfigService, never, never>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { ConfigService, ConfigServiceLive };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.service.d.mts","names":[],"sources":["../../../src/build/services/config.service.ts"],"sourcesContent":[],"mappings":";;;;cAC0E;cAE7D,aAAA,SAAsB,kBAAA;cAKtB,4BAA6B,oBAAe,KAAA,CAAA,MAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/build/services/config.service.ts
|
|
4
|
+
var ConfigService = class extends Context.Tag("ConfigService")() {};
|
|
5
|
+
const ConfigServiceLive = (config) => Layer.succeed(ConfigService, config);
|
|
6
|
+
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ConfigService, ConfigServiceLive };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.service.mjs","names":[],"sources":["../../../src/build/services/config.service.ts"],"sourcesContent":["import { Context, Layer } from \"effect\";\nimport type { NonEmptyString, PreflightConfig } from \"../../lib/types.js\";\n\nexport class ConfigService extends Context.Tag(\"ConfigService\")<\n ConfigService,\n PreflightConfig\n>() {}\n\nexport const ConfigServiceLive = (config: PreflightConfig) =>\n Layer.succeed(ConfigService, config);\n"],"mappings":";;;AAGA,IAAa,gBAAb,cAAmC,QAAQ,IAAI,gBAAgB,EAG5D,CAAC;AAEJ,MAAa,qBAAqB,WAChC,MAAM,QAAQ,eAAe,OAAO"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NonEmptyString, PreflightConfig } from "../../lib/types.mjs";
|
|
2
|
+
import { InvalidSecretKeyError, WithInterfereUsageError } from "../source-maps/errors.mjs";
|
|
3
|
+
import { Context, Effect, Layer } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/build/services/preflight.service.d.ts
|
|
6
|
+
declare const PreflightService_base: Context.TagClass<PreflightService, "PreflightService", {
|
|
7
|
+
readonly validateEnvironment: () => Effect.Effect<void, WithInterfereUsageError>;
|
|
8
|
+
readonly validateSecretKey: (key: string | null) => Effect.Effect<NonEmptyString, InvalidSecretKeyError>;
|
|
9
|
+
readonly extractSurfaceSlug: (key: NonEmptyString) => Effect.Effect<NonEmptyString, InvalidSecretKeyError>;
|
|
10
|
+
readonly buildConfig: (options: {
|
|
11
|
+
environment?: string;
|
|
12
|
+
debug?: boolean;
|
|
13
|
+
cleanupSourceMaps?: boolean;
|
|
14
|
+
}) => Effect.Effect<PreflightConfig, WithInterfereUsageError>;
|
|
15
|
+
}>;
|
|
16
|
+
declare class PreflightService extends PreflightService_base {}
|
|
17
|
+
declare const PreflightServiceLive: Layer.Layer<PreflightService, never, never>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { PreflightService, PreflightServiceLive };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.service.d.mts","names":[],"sources":["../../../src/build/services/preflight.service.ts"],"sourcesContent":[],"mappings":";;;;;cAWkC;sCAKM,MAAA,CAAO,aAAa;EAL1B,SAAA,iBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,GAAA,IAAA,EAAA,GAMsB,MAAA,CAAO,MAN7B,CAMoC,cANpC,EAMoD,qBANpD,CAAA;qCAOK,mBAAmB,MAAA,CAAO,OAAO,gBAAgB;EAF5B,SAAA,WAAA,EAAA,CAAA,OAAA,EAAA;IAAb,WAAA,CAAA,EAAA,MAAA;IACuB,KAAA,CAAA,EAAA,OAAA;IAAgB,iBAAA,CAAA,EAAA,OAAA;EAA9B,CAAA,EAAA,GAM9C,MAAA,CAAO,MAN8C,CAMvC,eANuC,EAMtB,uBANsB,CAAA;CACxB,CAAA;AAAiC,cAL3D,gBAAA,SAAyB,qBAAA,CAKkC;AAAd,cAgF7C,oBAhFoD,EAgFhC,KAAA,CAAA,KAhFgC,CAgFhC,gBAhFgC,EAAA,KAAA,EAAA,KAAA,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { toNonEmptyString } from "../../lib/types.mjs";
|
|
2
|
+
import { logBuildResult } from "../logger.mjs";
|
|
3
|
+
import { InvalidSecretKeyError, WithInterfereUsageError } from "../source-maps/errors.mjs";
|
|
4
|
+
import { parseSurfaceSlugFromSecretKey } from "../secret-key.mjs";
|
|
5
|
+
import { Context, Effect, Layer } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/build/services/preflight.service.ts
|
|
8
|
+
var PreflightService = class extends Context.Tag("PreflightService")() {};
|
|
9
|
+
const validateEnvironment = () => Effect.gen(function* () {
|
|
10
|
+
if (typeof window !== "undefined") return yield* Effect.fail(new WithInterfereUsageError({ message: "Security Error: withInterfere must only be used in next.config.js (server-side). It should never be imported in client-side code." }));
|
|
11
|
+
if (typeof process === "undefined" || !process.versions?.node) return yield* Effect.fail(new WithInterfereUsageError({ message: "Security Error: withInterfere requires Node.js environment. It should only run during build time, not in the browser." }));
|
|
12
|
+
if (typeof process.env.INTERFERE_SECRET_KEY === "string" && process.env.INTERFERE_SECRET_KEY.startsWith("NEXT_PUBLIC_")) return yield* Effect.fail(new WithInterfereUsageError({ message: "Security Error: Secret key should NOT use NEXT_PUBLIC_ prefix. Use INTERFERE_SECRET_KEY instead to keep it server-side only." }));
|
|
13
|
+
});
|
|
14
|
+
const validateSecretKey = (raw) => Effect.gen(function* () {
|
|
15
|
+
if (typeof raw !== "string") return yield* Effect.fail(new InvalidSecretKeyError({ message: "Missing secret key. Set the INTERFERE_SECRET_KEY environment variable" }));
|
|
16
|
+
const result = toNonEmptyString(raw.trim().replace(/^['"]|['"]$/g, ""));
|
|
17
|
+
if (!result) return yield* Effect.fail(new InvalidSecretKeyError({ message: "Invalid secret key. Set the INTERFERE_SECRET_KEY environment variable" }));
|
|
18
|
+
return result;
|
|
19
|
+
});
|
|
20
|
+
const extractSurfaceSlug = (secretKey) => Effect.gen(function* () {
|
|
21
|
+
const parsed = parseSurfaceSlugFromSecretKey(secretKey);
|
|
22
|
+
const result = parsed ? toNonEmptyString(parsed) : void 0;
|
|
23
|
+
if (!result) return yield* Effect.fail(new InvalidSecretKeyError({ message: "Invalid secret key format. Please use the secret key provided in your Interfere dashboard." }));
|
|
24
|
+
return result;
|
|
25
|
+
});
|
|
26
|
+
const PreflightServiceLive = Layer.succeed(PreflightService, {
|
|
27
|
+
validateEnvironment,
|
|
28
|
+
validateSecretKey,
|
|
29
|
+
extractSurfaceSlug,
|
|
30
|
+
buildConfig: (options) => Effect.gen(function* () {
|
|
31
|
+
yield* validateEnvironment();
|
|
32
|
+
const secretKeyRaw = process.env.INTERFERE_SECRET_KEY;
|
|
33
|
+
const secretKeyResult = yield* validateSecretKey(secretKeyRaw ?? null).pipe(Effect.either);
|
|
34
|
+
if (secretKeyResult._tag === "Left") {
|
|
35
|
+
const message = secretKeyResult.left.message;
|
|
36
|
+
yield* logBuildResult("Warning", "Interfere disabled (invalid secret key)", [
|
|
37
|
+
message,
|
|
38
|
+
"Source maps will not be uploaded for this build.",
|
|
39
|
+
"Set a valid INTERFERE_SECRET_KEY in your environment to enable Interfere."
|
|
40
|
+
]);
|
|
41
|
+
return {
|
|
42
|
+
enabled: false,
|
|
43
|
+
environment: options.environment || process.env.NODE_ENV,
|
|
44
|
+
debug: options.debug ?? false,
|
|
45
|
+
cleanupSourceMaps: options.cleanupSourceMaps ?? true
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const secretKey = secretKeyResult.right;
|
|
49
|
+
const surfaceSlugResult = yield* extractSurfaceSlug(secretKey).pipe(Effect.either);
|
|
50
|
+
if (surfaceSlugResult._tag === "Left") {
|
|
51
|
+
const message = surfaceSlugResult.left.message;
|
|
52
|
+
yield* logBuildResult("Warning", "Interfere disabled (invalid secret key format)", [
|
|
53
|
+
message,
|
|
54
|
+
"Source maps will not be uploaded for this build.",
|
|
55
|
+
"Please use the secret key provided in your Interfere dashboard."
|
|
56
|
+
]);
|
|
57
|
+
return {
|
|
58
|
+
enabled: false,
|
|
59
|
+
environment: options.environment || process.env.NODE_ENV,
|
|
60
|
+
debug: options.debug ?? false,
|
|
61
|
+
cleanupSourceMaps: options.cleanupSourceMaps ?? true
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
enabled: true,
|
|
66
|
+
surface: surfaceSlugResult.right,
|
|
67
|
+
secretKey,
|
|
68
|
+
environment: options.environment || process.env.NODE_ENV,
|
|
69
|
+
debug: options.debug ?? false,
|
|
70
|
+
cleanupSourceMaps: options.cleanupSourceMaps ?? true
|
|
71
|
+
};
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { PreflightService, PreflightServiceLive };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.service.mjs","names":[],"sources":["../../../src/build/services/preflight.service.ts"],"sourcesContent":["import { Context, Effect, Layer } from \"effect\";\nimport {\n type NonEmptyString,\n type PreflightConfig,\n toNonEmptyString,\n} from \"../../lib/types.js\";\nimport { logBuildResult } from \"../logger.js\";\nimport { parseSurfaceSlugFromSecretKey } from \"../secret-key.js\";\nimport {\n InvalidSecretKeyError,\n WithInterfereUsageError,\n} from \"../source-maps/errors.js\";\n\nexport class PreflightService extends Context.Tag(\"PreflightService\")<\n PreflightService,\n {\n readonly validateEnvironment: () => Effect.Effect<void, WithInterfereUsageError>;\n readonly validateSecretKey: (key: string | null) => Effect.Effect<NonEmptyString, InvalidSecretKeyError>;\n readonly extractSurfaceSlug: (key: NonEmptyString) => Effect.Effect<NonEmptyString, InvalidSecretKeyError>;\n readonly buildConfig: (options: {\n environment?: string;\n debug?: boolean;\n cleanupSourceMaps?: boolean;\n }) => Effect.Effect<PreflightConfig, WithInterfereUsageError>;\n }\n>() {}\n\nconst validateEnvironment = () =>\n Effect.gen(function* () {\n if (typeof window !== \"undefined\") {\n return yield* Effect.fail(\n new WithInterfereUsageError({\n message: \"Security Error: withInterfere must only be used in next.config.js (server-side). It should never be imported in client-side code.\"\n })\n );\n }\n\n if (typeof process === \"undefined\" || !process.versions?.node) {\n return yield* Effect.fail(\n new WithInterfereUsageError({\n message: \"Security Error: withInterfere requires Node.js environment. It should only run during build time, not in the browser.\"\n })\n );\n }\n\n if (\n typeof process.env.INTERFERE_SECRET_KEY === \"string\" &&\n process.env.INTERFERE_SECRET_KEY.startsWith(\"NEXT_PUBLIC_\")\n ) {\n return yield* Effect.fail(\n new WithInterfereUsageError({\n message: \"Security Error: Secret key should NOT use NEXT_PUBLIC_ prefix. Use INTERFERE_SECRET_KEY instead to keep it server-side only.\"\n })\n );\n }\n });\n\nconst validateSecretKey = (raw: string | null) =>\n Effect.gen(function* () {\n if (typeof raw !== \"string\") {\n return yield* Effect.fail(\n new InvalidSecretKeyError(\n { message: \"Missing secret key. Set the INTERFERE_SECRET_KEY environment variable\" }\n )\n );\n }\n\n const trimmed = raw.trim();\n const cleaned = trimmed.replace(/^['\"]|['\"]$/g, \"\");\n const result = toNonEmptyString(cleaned);\n\n if (!result) {\n return yield* Effect.fail(\n new InvalidSecretKeyError(\n { message: \"Invalid secret key. Set the INTERFERE_SECRET_KEY environment variable\" }\n )\n );\n }\n\n return result;\n });\n\nconst extractSurfaceSlug = (secretKey: NonEmptyString) =>\n Effect.gen(function* () {\n const parsed = parseSurfaceSlugFromSecretKey(secretKey);\n const result = parsed ? (toNonEmptyString(parsed) as NonEmptyString) : undefined;\n\n if (!result) {\n return yield* Effect.fail(\n new InvalidSecretKeyError(\n { message: \"Invalid secret key format. Please use the secret key provided in your Interfere dashboard.\" }\n )\n );\n }\n\n return result;\n });\n\nexport const PreflightServiceLive = Layer.succeed(\n PreflightService,\n {\n validateEnvironment,\n validateSecretKey,\n extractSurfaceSlug,\n buildConfig: (options) =>\n Effect.gen(function* () {\n yield* validateEnvironment();\n \n const secretKeyRaw = process.env.INTERFERE_SECRET_KEY;\n \n // Try to get secret key and surface slug\n const secretKeyResult = yield* validateSecretKey(\n secretKeyRaw ?? null\n ).pipe(Effect.either);\n\n if (secretKeyResult._tag === \"Left\") {\n const message = secretKeyResult.left.message;\n\n yield* logBuildResult(\n \"Warning\",\n \"Interfere disabled (invalid secret key)\",\n [\n message,\n \"Source maps will not be uploaded for this build.\",\n \"Set a valid INTERFERE_SECRET_KEY in your environment to enable Interfere.\",\n ]\n );\n\n // Return disabled config if no valid secret key\n return {\n enabled: false as const,\n environment: options.environment || process.env.NODE_ENV,\n debug: options.debug ?? false,\n cleanupSourceMaps: options.cleanupSourceMaps ?? true,\n };\n }\n \n const secretKey = secretKeyResult.right;\n const surfaceSlugResult = yield* extractSurfaceSlug(secretKey).pipe(\n Effect.either\n );\n\n if (surfaceSlugResult._tag === \"Left\") {\n const message = surfaceSlugResult.left.message;\n\n yield* logBuildResult(\n \"Warning\",\n \"Interfere disabled (invalid secret key format)\",\n [\n message,\n \"Source maps will not be uploaded for this build.\",\n \"Please use the secret key provided in your Interfere dashboard.\",\n ]\n );\n\n // Return disabled config if no valid surface slug\n return {\n enabled: false as const,\n environment: options.environment || process.env.NODE_ENV,\n debug: options.debug ?? false,\n cleanupSourceMaps: options.cleanupSourceMaps ?? true,\n };\n }\n\n return {\n enabled: true as const,\n surface: surfaceSlugResult.right,\n secretKey,\n environment: options.environment || process.env.NODE_ENV,\n debug: options.debug ?? false,\n cleanupSourceMaps: options.cleanupSourceMaps ?? true,\n };\n }),\n }\n);\n"],"mappings":";;;;;;;AAaA,IAAa,mBAAb,cAAsC,QAAQ,IAAI,mBAAmB,EAYlE,CAAC;AAEJ,MAAM,4BACJ,OAAO,IAAI,aAAa;AACtB,KAAI,OAAO,WAAW,YACpB,QAAO,OAAO,OAAO,KACnB,IAAI,wBAAwB,EAC1B,SAAS,qIACV,CAAC,CACH;AAGH,KAAI,OAAO,YAAY,eAAe,CAAC,QAAQ,UAAU,KACvD,QAAO,OAAO,OAAO,KACnB,IAAI,wBAAwB,EAC1B,SAAS,yHACV,CAAC,CACH;AAGH,KACE,OAAO,QAAQ,IAAI,yBAAyB,YAC5C,QAAQ,IAAI,qBAAqB,WAAW,eAAe,CAE3D,QAAO,OAAO,OAAO,KACnB,IAAI,wBAAwB,EAC1B,SAAS,gIACV,CAAC,CACH;EAEH;AAEJ,MAAM,qBAAqB,QACzB,OAAO,IAAI,aAAa;AACtB,KAAI,OAAO,QAAQ,SACjB,QAAO,OAAO,OAAO,KACnB,IAAI,sBACF,EAAE,SAAS,yEAAyE,CACrF,CACF;CAKH,MAAM,SAAS,iBAFC,IAAI,MAAM,CACF,QAAQ,gBAAgB,GAAG,CACX;AAExC,KAAI,CAAC,OACH,QAAO,OAAO,OAAO,KACnB,IAAI,sBACF,EAAE,SAAS,yEAAyE,CACrF,CACF;AAGH,QAAO;EACP;AAEJ,MAAM,sBAAsB,cAC1B,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,8BAA8B,UAAU;CACvD,MAAM,SAAS,SAAU,iBAAiB,OAAO,GAAsB;AAEvE,KAAI,CAAC,OACH,QAAO,OAAO,OAAO,KACnB,IAAI,sBACF,EAAE,SAAS,8FAA8F,CAC1G,CACF;AAGH,QAAO;EACP;AAEJ,MAAa,uBAAuB,MAAM,QACxC,kBACA;CACE;CACA;CACA;CACA,cAAc,YACZ,OAAO,IAAI,aAAa;AACtB,SAAO,qBAAqB;EAE5B,MAAM,eAAe,QAAQ,IAAI;EAGjC,MAAM,kBAAkB,OAAO,kBAC7B,gBAAgB,KACjB,CAAC,KAAK,OAAO,OAAO;AAErB,MAAI,gBAAgB,SAAS,QAAQ;GACnC,MAAM,UAAU,gBAAgB,KAAK;AAErC,UAAO,eACL,WACA,2CACA;IACE;IACA;IACA;IACD,CACF;AAGD,UAAO;IACL,SAAS;IACT,aAAa,QAAQ,eAAe,QAAQ,IAAI;IAChD,OAAO,QAAQ,SAAS;IACxB,mBAAmB,QAAQ,qBAAqB;IACjD;;EAGH,MAAM,YAAY,gBAAgB;EAClC,MAAM,oBAAoB,OAAO,mBAAmB,UAAU,CAAC,KAC7D,OAAO,OACR;AAED,MAAI,kBAAkB,SAAS,QAAQ;GACrC,MAAM,UAAU,kBAAkB,KAAK;AAEvC,UAAO,eACL,WACA,kDACA;IACE;IACA;IACA;IACD,CACF;AAGD,UAAO;IACL,SAAS;IACT,aAAa,QAAQ,eAAe,QAAQ,IAAI;IAChD,OAAO,QAAQ,SAAS;IACxB,mBAAmB,QAAQ,qBAAqB;IACjD;;AAGH,SAAO;GACL,SAAS;GACT,SAAS,kBAAkB;GAC3B;GACA,aAAa,QAAQ,eAAe,QAAQ,IAAI;GAChD,OAAO,QAAQ,SAAS;GACxB,mBAAmB,QAAQ,qBAAqB;GACjD;GACD;CACL,CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MissingBuildIdError, MissingReleaseIdError } from "../source-maps/errors.mjs";
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import { ReleaseDestinationMetadata, ReleaseDestinationType, ReleaseSourceMetadata, ReleaseSourceType } from "@interfere/types/releases/definition";
|
|
4
|
+
|
|
5
|
+
//#region src/build/services/release-identity.service.d.ts
|
|
6
|
+
type ReleaseIdentity = {
|
|
7
|
+
buildId: string;
|
|
8
|
+
releaseId: string;
|
|
9
|
+
sourceControl?: {
|
|
10
|
+
type: ReleaseSourceType;
|
|
11
|
+
metadata: ReleaseSourceMetadata;
|
|
12
|
+
};
|
|
13
|
+
deployment?: {
|
|
14
|
+
type: ReleaseDestinationType;
|
|
15
|
+
metadata: ReleaseDestinationMetadata;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
declare const ReleaseIdentityService_base: Context.TagClass<ReleaseIdentityService, "ReleaseIdentityService", Effect.Effect<ReleaseIdentity, MissingBuildIdError | MissingReleaseIdError, never>>;
|
|
19
|
+
declare class ReleaseIdentityService extends ReleaseIdentityService_base {}
|
|
20
|
+
declare const ReleaseIdentityServiceLive: Layer.Layer<ReleaseIdentityService, never, never>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { ReleaseIdentity, ReleaseIdentityService, ReleaseIdentityServiceLive };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-identity.service.d.mts","names":[],"sources":["../../../src/build/services/release-identity.service.ts"],"sourcesContent":[],"mappings":";;;;;KAUY,eAAA;;EAAA,SAAA,EAAA,MAAA;EAIF,aAAA,CAAA,EAAA;IACI,IAAA,EADJ,iBACI;IAGJ,QAAA,EAHI,qBAGJ;EACI,CAAA;EAA0B,UAAA,CAAA,EAAA;IAEtC,IAAA,EAHQ,sBAGR;cAFY;;;cAEZ;cAEW,sBAAA,SAA+B,2BAAA;cAoG/B,4BAA0B,KAAA,CAAA,MAAA"}
|