@interfere/next 0.0.15-alpha.8 → 0.1.0-alpha.11

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.
Files changed (146) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +36 -8
  3. package/dist/_virtual/_rolldown/runtime.mjs +7 -0
  4. package/dist/build/env-config.d.mts +3 -1
  5. package/dist/build/env-config.d.mts.map +1 -1
  6. package/dist/build/env-config.mjs +9 -1
  7. package/dist/build/env-config.mjs.map +1 -1
  8. package/dist/build/exchange-surface.d.mts +9 -0
  9. package/dist/build/exchange-surface.d.mts.map +1 -0
  10. package/dist/build/exchange-surface.mjs +36 -0
  11. package/dist/build/exchange-surface.mjs.map +1 -0
  12. package/dist/build/loaders/value-injection-loader.d.mts +22 -0
  13. package/dist/build/loaders/value-injection-loader.d.mts.map +1 -0
  14. package/dist/build/loaders/value-injection-loader.mjs +35 -0
  15. package/dist/build/loaders/value-injection-loader.mjs.map +1 -0
  16. package/dist/build/logger.d.mts +2 -2
  17. package/dist/build/logger.d.mts.map +1 -1
  18. package/dist/build/logger.mjs +10 -12
  19. package/dist/build/logger.mjs.map +1 -1
  20. package/dist/build/nextjs-version.d.mts +40 -0
  21. package/dist/build/nextjs-version.d.mts.map +1 -0
  22. package/dist/build/nextjs-version.mjs +66 -0
  23. package/dist/build/nextjs-version.mjs.map +1 -0
  24. package/dist/build/release-program.d.mts +5 -3
  25. package/dist/build/release-program.d.mts.map +1 -1
  26. package/dist/build/release-program.mjs +11 -12
  27. package/dist/build/release-program.mjs.map +1 -1
  28. package/dist/build/services/config.service.d.mts.map +1 -1
  29. package/dist/build/services/config.service.mjs.map +1 -1
  30. package/dist/build/services/instrumentation-detection.service.d.mts +19 -0
  31. package/dist/build/services/instrumentation-detection.service.d.mts.map +1 -0
  32. package/dist/build/services/instrumentation-detection.service.mjs +77 -0
  33. package/dist/build/services/instrumentation-detection.service.mjs.map +1 -0
  34. package/dist/build/services/preflight.service.d.mts +2 -3
  35. package/dist/build/services/preflight.service.d.mts.map +1 -1
  36. package/dist/build/services/preflight.service.mjs +28 -37
  37. package/dist/build/services/preflight.service.mjs.map +1 -1
  38. package/dist/build/services/release-api.service.d.mts +11 -0
  39. package/dist/build/services/release-api.service.d.mts.map +1 -0
  40. package/dist/build/services/release-api.service.mjs +9 -0
  41. package/dist/build/services/release-api.service.mjs.map +1 -0
  42. package/dist/build/services/release-identity.service.d.mts +4 -3
  43. package/dist/build/services/release-identity.service.d.mts.map +1 -1
  44. package/dist/build/services/release-identity.service.mjs +28 -15
  45. package/dist/build/services/release-identity.service.mjs.map +1 -1
  46. package/dist/build/services/source-map-failure-cleanup.service.d.mts +11 -0
  47. package/dist/build/services/source-map-failure-cleanup.service.d.mts.map +1 -0
  48. package/dist/build/services/source-map-failure-cleanup.service.mjs +9 -0
  49. package/dist/build/services/source-map-failure-cleanup.service.mjs.map +1 -0
  50. package/dist/build/services/source-map.service.d.mts +4 -8
  51. package/dist/build/services/source-map.service.d.mts.map +1 -1
  52. package/dist/build/services/source-map.service.mjs +2 -4
  53. package/dist/build/services/source-map.service.mjs.map +1 -1
  54. package/dist/build/source-maps/api.d.mts +25 -16
  55. package/dist/build/source-maps/api.d.mts.map +1 -1
  56. package/dist/build/source-maps/api.mjs +11 -8
  57. package/dist/build/source-maps/api.mjs.map +1 -1
  58. package/dist/build/source-maps/client.d.mts +11 -2
  59. package/dist/build/source-maps/client.d.mts.map +1 -1
  60. package/dist/build/source-maps/client.mjs +25 -14
  61. package/dist/build/source-maps/client.mjs.map +1 -1
  62. package/dist/build/source-maps/errors.d.mts +118 -106
  63. package/dist/build/source-maps/errors.d.mts.map +1 -1
  64. package/dist/build/source-maps/errors.mjs +42 -18
  65. package/dist/build/source-maps/errors.mjs.map +1 -1
  66. package/dist/build/source-maps/files.d.mts +1 -1
  67. package/dist/build/source-maps/files.d.mts.map +1 -1
  68. package/dist/build/source-maps/files.mjs +13 -15
  69. package/dist/build/source-maps/files.mjs.map +1 -1
  70. package/dist/build/source-maps/providers/deployment/detector.d.mts +8 -17
  71. package/dist/build/source-maps/providers/deployment/detector.d.mts.map +1 -1
  72. package/dist/build/source-maps/providers/deployment/detector.mjs +11 -13
  73. package/dist/build/source-maps/providers/deployment/detector.mjs.map +1 -1
  74. package/dist/build/source-maps/providers/deployment/types.d.mts +2 -2
  75. package/dist/build/source-maps/providers/deployment/types.d.mts.map +1 -1
  76. package/dist/build/source-maps/providers/deployment/vercel.d.mts.map +1 -1
  77. package/dist/build/source-maps/providers/deployment/vercel.mjs +8 -19
  78. package/dist/build/source-maps/providers/deployment/vercel.mjs.map +1 -1
  79. package/dist/build/source-maps/providers/source-control/detector.d.mts +6 -5
  80. package/dist/build/source-maps/providers/source-control/detector.d.mts.map +1 -1
  81. package/dist/build/source-maps/providers/source-control/detector.mjs +11 -13
  82. package/dist/build/source-maps/providers/source-control/detector.mjs.map +1 -1
  83. package/dist/build/source-maps/providers/source-control/git.d.mts.map +1 -1
  84. package/dist/build/source-maps/providers/source-control/git.mjs +5 -8
  85. package/dist/build/source-maps/providers/source-control/git.mjs.map +1 -1
  86. package/dist/build/source-maps/providers/source-control/types.d.mts +5 -3
  87. package/dist/build/source-maps/providers/source-control/types.d.mts.map +1 -1
  88. package/dist/build/with-interfere.d.mts +25 -3
  89. package/dist/build/with-interfere.d.mts.map +1 -1
  90. package/dist/build/with-interfere.mjs +131 -24
  91. package/dist/build/with-interfere.mjs.map +1 -1
  92. package/dist/client/auto-init.d.mts +91 -0
  93. package/dist/client/auto-init.d.mts.map +1 -0
  94. package/dist/client/auto-init.mjs +121 -0
  95. package/dist/client/auto-init.mjs.map +1 -0
  96. package/dist/client/provider.d.mts +3 -3
  97. package/dist/client/provider.d.mts.map +1 -1
  98. package/dist/client/provider.mjs +21 -8
  99. package/dist/client/provider.mjs.map +1 -1
  100. package/dist/lib/env.d.mts.map +1 -1
  101. package/dist/lib/types.d.mts +6 -6
  102. package/dist/lib/types.d.mts.map +1 -1
  103. package/dist/lib/types.mjs.map +1 -1
  104. package/dist/server/auto-init.d.mts +88 -0
  105. package/dist/server/auto-init.d.mts.map +1 -0
  106. package/dist/server/auto-init.mjs +101 -0
  107. package/dist/server/auto-init.mjs.map +1 -0
  108. package/dist/server/middleware.d.mts.map +1 -1
  109. package/dist/server/middleware.mjs +20 -13
  110. package/dist/server/middleware.mjs.map +1 -1
  111. package/dist/server/on-request-error.d.mts +27 -0
  112. package/dist/server/on-request-error.d.mts.map +1 -0
  113. package/dist/server/on-request-error.mjs +74 -0
  114. package/dist/server/on-request-error.mjs.map +1 -0
  115. package/dist/server/proxy.d.mts.map +1 -1
  116. package/dist/server/proxy.mjs +4 -5
  117. package/dist/server/proxy.mjs.map +1 -1
  118. package/dist/server/route-handler.d.mts +31 -1
  119. package/dist/server/route-handler.d.mts.map +1 -1
  120. package/dist/server/route-handler.mjs +78 -79
  121. package/dist/server/route-handler.mjs.map +1 -1
  122. package/dist/server/sdk.d.mts +96 -0
  123. package/dist/server/sdk.d.mts.map +1 -0
  124. package/dist/server/sdk.mjs +152 -0
  125. package/dist/server/sdk.mjs.map +1 -0
  126. package/dist/server/services/config.service.d.mts +33 -6
  127. package/dist/server/services/config.service.d.mts.map +1 -1
  128. package/dist/server/services/config.service.mjs +54 -30
  129. package/dist/server/services/config.service.mjs.map +1 -1
  130. package/dist/server/services/error-tracking.service.d.mts +3 -3
  131. package/dist/server/services/error-tracking.service.d.mts.map +1 -1
  132. package/dist/server/services/error-tracking.service.mjs +5 -3
  133. package/dist/server/services/error-tracking.service.mjs.map +1 -1
  134. package/dist/server/session-context.d.mts +60 -0
  135. package/dist/server/session-context.d.mts.map +1 -0
  136. package/dist/server/session-context.mjs +62 -0
  137. package/dist/server/session-context.mjs.map +1 -0
  138. package/package.json +58 -34
  139. package/dist/build/secret-key.d.mts +0 -10
  140. package/dist/build/secret-key.d.mts.map +0 -1
  141. package/dist/build/secret-key.mjs +0 -16
  142. package/dist/build/secret-key.mjs.map +0 -1
  143. package/dist/lib/test-utils/make-next-request.d.mts +0 -6
  144. package/dist/lib/test-utils/make-next-request.d.mts.map +0 -1
  145. package/dist/lib/test-utils/make-next-request.mjs +0 -12
  146. package/dist/lib/test-utils/make-next-request.mjs.map +0 -1
@@ -0,0 +1,91 @@
1
+ import { Config } from "@interfere/types/sdk/config";
2
+
3
+ //#region src/client/auto-init.d.ts
4
+ /**
5
+ * Feature flags that can be injected at build time.
6
+ */
7
+ interface InjectedFeatures {
8
+ errorTracking?: boolean;
9
+ performanceMonitoring?: boolean;
10
+ replay?: boolean;
11
+ }
12
+ /**
13
+ * Build-time injected values set by the value-injection-loader.
14
+ * These are populated when instrumentation-client.ts is processed during build.
15
+ */
16
+ declare global {
17
+ var __INTERFERE_BUILD_ID__: string | null | undefined;
18
+ var __INTERFERE_RELEASE_ID__: string | null | undefined;
19
+ var __INTERFERE_ENVIRONMENT__: string | undefined;
20
+ var __INTERFERE_ENABLED__: boolean | undefined;
21
+ var __INTERFERE_FEATURES__: InjectedFeatures | undefined;
22
+ var __INTERFERE_INITIALIZED__: boolean | undefined;
23
+ }
24
+ /**
25
+ * The injected config keys that the value-injection-loader sets.
26
+ * This is the canonical list of keys - keep in sync with withInterfere.
27
+ */
28
+ declare const INJECTED_CONFIG_KEYS: readonly ["__INTERFERE_BUILD_ID__", "__INTERFERE_RELEASE_ID__", "__INTERFERE_ENVIRONMENT__", "__INTERFERE_ENABLED__", "__INTERFERE_FEATURES__"];
29
+ type InjectedConfigKey = (typeof INJECTED_CONFIG_KEYS)[number];
30
+ /**
31
+ * Partial config that can be provided by users to override injected values.
32
+ */
33
+ interface AutoInitConfigOverrides {
34
+ batch?: Config["batch"];
35
+ features?: Config["features"];
36
+ metadata?: Partial<Config["metadata"]>;
37
+ offline?: Config["offline"];
38
+ proxyUrl?: string;
39
+ }
40
+ /**
41
+ * Reads configuration from build-time injected values.
42
+ *
43
+ * The value-injection-loader prepends code to instrumentation-client.ts
44
+ * that sets these globalThis values during the build process.
45
+ *
46
+ * @returns Partial config from injected values, or null if SDK is disabled
47
+ */
48
+ declare function getInjectedConfig(): Partial<Config> | null;
49
+ /**
50
+ * Initialize Interfere client automatically from build-time injected config.
51
+ *
52
+ * Call this from instrumentation-client.ts for zero-config initialization.
53
+ * User-provided overrides take precedence over injected values.
54
+ *
55
+ * @param userConfig - Optional configuration overrides
56
+ * @returns Parsed config if initialization succeeded, null if SDK is disabled or already initialized
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * // instrumentation-client.ts
61
+ * import { autoInitClient } from "@interfere/next/auto-init";
62
+ *
63
+ * const config = autoInitClient();
64
+ * if (config) {
65
+ * console.log("[Interfere] Client initialized", config.metadata);
66
+ * }
67
+ * ```
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * // With overrides
72
+ * import { autoInitClient } from "@interfere/next/auto-init";
73
+ *
74
+ * const config = autoInitClient({
75
+ * features: { replay: false },
76
+ * batch: { size: 25, ms: 500 }
77
+ * });
78
+ * ```
79
+ */
80
+ declare function autoInitClient(userConfig?: AutoInitConfigOverrides): Config | null;
81
+ /**
82
+ * Check if Interfere has already been initialized.
83
+ */
84
+ declare function isInitialized(): boolean;
85
+ /**
86
+ * Reset initialization state. Only use for testing.
87
+ * @internal
88
+ */
89
+ declare function resetInitializationState(): void;
90
+ //#endregion
91
+ export { AutoInitConfigOverrides, INJECTED_CONFIG_KEYS, InjectedConfigKey, autoInitClient, getInjectedConfig, isInitialized, resetInitializationState };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-init.d.mts","names":[],"sources":["../../src/client/auto-init.ts"],"mappings":";;;;;AAEwE;UAM9D,gBAAA;EACR,aAAA;EACA,qBAAA;EACA,MAAA;AAAA;;;;AAAM;QAOA,MAAA;EAAA,IAEF,sBAAA;EAAA,IAEA,wBAAA;EAAA,IAEA,yBAAA;EAAA,IAEA,qBAAA;EAAA,IAEA,sBAAA,EAAwB,gBAAA;EAAA,IAExB,yBAAA;AAAA;;;;;cAOO,oBAAA;AAAA,KAQD,iBAAA,WAA4B,oBAAA;AARxC;;;AAAA,UAaiB,uBAAA;EACf,KAAA,GAAQ,MAAA;EACR,QAAA,GAAW,MAAA;EACX,QAAA,GAAW,OAAA,CAAQ,MAAA;EACnB,OAAA,GAAU,MAAA;EACV,QAAA;AAAA;AALF;;;;;;;;AAAA,iBAgBgB,iBAAA,CAAA,GAAqB,OAAA,CAAQ,MAAA;;;;;;;;;;;;;;AAA7C;;;;;AAmEA;;;;;;;;;AAkDA;;;;iBAlDgB,cAAA,CACd,UAAA,GAAa,uBAAA,GACZ,MAAA;AAwDH;;;AAAA,iBARgB,aAAA,CAAA;;;;;iBAQA,wBAAA,CAAA"}
@@ -0,0 +1,121 @@
1
+ "use client";
2
+
3
+ import { configSchema } from "@interfere/types/sdk/config";
4
+ import { envSchema } from "@interfere/types/sdk/runtime";
5
+
6
+ //#region src/client/auto-init.ts
7
+ /**
8
+ * The injected config keys that the value-injection-loader sets.
9
+ * This is the canonical list of keys - keep in sync with withInterfere.
10
+ */
11
+ const INJECTED_CONFIG_KEYS = [
12
+ "__INTERFERE_BUILD_ID__",
13
+ "__INTERFERE_RELEASE_ID__",
14
+ "__INTERFERE_ENVIRONMENT__",
15
+ "__INTERFERE_ENABLED__",
16
+ "__INTERFERE_FEATURES__"
17
+ ];
18
+ /**
19
+ * Reads configuration from build-time injected values.
20
+ *
21
+ * The value-injection-loader prepends code to instrumentation-client.ts
22
+ * that sets these globalThis values during the build process.
23
+ *
24
+ * @returns Partial config from injected values, or null if SDK is disabled
25
+ */
26
+ function getInjectedConfig() {
27
+ if (typeof globalThis === "undefined") return null;
28
+ const buildId = globalThis.__INTERFERE_BUILD_ID__;
29
+ const releaseId = globalThis.__INTERFERE_RELEASE_ID__;
30
+ const environmentRaw = globalThis.__INTERFERE_ENVIRONMENT__;
31
+ const enabled = globalThis.__INTERFERE_ENABLED__;
32
+ const features = globalThis.__INTERFERE_FEATURES__;
33
+ if (!enabled) return null;
34
+ const environment = environmentRaw ? envSchema.safeParse(environmentRaw).data ?? "production" : "production";
35
+ return {
36
+ metadata: {
37
+ buildId: buildId ?? null,
38
+ releaseId: releaseId ?? null,
39
+ environment,
40
+ runtime: "browser"
41
+ },
42
+ proxyUrl: "/api/interfere",
43
+ ...features && { features }
44
+ };
45
+ }
46
+ /**
47
+ * Initialize Interfere client automatically from build-time injected config.
48
+ *
49
+ * Call this from instrumentation-client.ts for zero-config initialization.
50
+ * User-provided overrides take precedence over injected values.
51
+ *
52
+ * @param userConfig - Optional configuration overrides
53
+ * @returns Parsed config if initialization succeeded, null if SDK is disabled or already initialized
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * // instrumentation-client.ts
58
+ * import { autoInitClient } from "@interfere/next/auto-init";
59
+ *
60
+ * const config = autoInitClient();
61
+ * if (config) {
62
+ * console.log("[Interfere] Client initialized", config.metadata);
63
+ * }
64
+ * ```
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * // With overrides
69
+ * import { autoInitClient } from "@interfere/next/auto-init";
70
+ *
71
+ * const config = autoInitClient({
72
+ * features: { replay: false },
73
+ * batch: { size: 25, ms: 500 }
74
+ * });
75
+ * ```
76
+ */
77
+ function autoInitClient(userConfig) {
78
+ if (globalThis.__INTERFERE_INITIALIZED__) {
79
+ if (process.env.NODE_ENV === "development") console.warn("[Interfere] Already initialized, skipping duplicate init");
80
+ return null;
81
+ }
82
+ const injectedConfig = getInjectedConfig();
83
+ if (!injectedConfig) {
84
+ if (process.env.NODE_ENV === "development") console.info("[Interfere] No injected config found. SDK disabled. Ensure INTERFERE_API_KEY is set and withInterfere() is configured.");
85
+ return null;
86
+ }
87
+ const mergedConfig = {
88
+ ...injectedConfig,
89
+ ...userConfig?.features && { features: userConfig.features },
90
+ ...userConfig?.batch && { batch: userConfig.batch },
91
+ ...userConfig?.offline && { offline: userConfig.offline },
92
+ ...userConfig?.proxyUrl && { proxyUrl: userConfig.proxyUrl },
93
+ metadata: {
94
+ ...injectedConfig.metadata,
95
+ ...userConfig?.metadata
96
+ }
97
+ };
98
+ const parseResult = configSchema.safeParse(mergedConfig);
99
+ if (!parseResult.success) {
100
+ console.error("[Interfere] Failed to parse config:", parseResult.error);
101
+ return null;
102
+ }
103
+ globalThis.__INTERFERE_INITIALIZED__ = true;
104
+ return parseResult.data;
105
+ }
106
+ /**
107
+ * Check if Interfere has already been initialized.
108
+ */
109
+ function isInitialized() {
110
+ return globalThis.__INTERFERE_INITIALIZED__ === true;
111
+ }
112
+ /**
113
+ * Reset initialization state. Only use for testing.
114
+ * @internal
115
+ */
116
+ function resetInitializationState() {
117
+ globalThis.__INTERFERE_INITIALIZED__ = void 0;
118
+ }
119
+
120
+ //#endregion
121
+ export { INJECTED_CONFIG_KEYS, autoInitClient, getInjectedConfig, isInitialized, resetInitializationState };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-init.mjs","names":[],"sources":["../../src/client/auto-init.ts"],"sourcesContent":["\"use client\";\n\nimport { type Config, configSchema } from \"@interfere/types/sdk/config\";\nimport { envSchema } from \"@interfere/types/sdk/runtime\";\n\n/**\n * Feature flags that can be injected at build time.\n */\ninterface InjectedFeatures {\n errorTracking?: boolean;\n performanceMonitoring?: boolean;\n replay?: boolean;\n}\n\n/**\n * Build-time injected values set by the value-injection-loader.\n * These are populated when instrumentation-client.ts is processed during build.\n */\ndeclare global {\n // eslint-disable-next-line no-var\n var __INTERFERE_BUILD_ID__: string | null | undefined;\n // eslint-disable-next-line no-var\n var __INTERFERE_RELEASE_ID__: string | null | undefined;\n // eslint-disable-next-line no-var\n var __INTERFERE_ENVIRONMENT__: string | undefined;\n // eslint-disable-next-line no-var\n var __INTERFERE_ENABLED__: boolean | undefined;\n // eslint-disable-next-line no-var\n var __INTERFERE_FEATURES__: InjectedFeatures | undefined;\n // eslint-disable-next-line no-var\n var __INTERFERE_INITIALIZED__: boolean | undefined;\n}\n\n/**\n * The injected config keys that the value-injection-loader sets.\n * This is the canonical list of keys - keep in sync with withInterfere.\n */\nexport const INJECTED_CONFIG_KEYS = [\n \"__INTERFERE_BUILD_ID__\",\n \"__INTERFERE_RELEASE_ID__\",\n \"__INTERFERE_ENVIRONMENT__\",\n \"__INTERFERE_ENABLED__\",\n \"__INTERFERE_FEATURES__\",\n] as const;\n\nexport type InjectedConfigKey = (typeof INJECTED_CONFIG_KEYS)[number];\n\n/**\n * Partial config that can be provided by users to override injected values.\n */\nexport interface AutoInitConfigOverrides {\n batch?: Config[\"batch\"];\n features?: Config[\"features\"];\n metadata?: Partial<Config[\"metadata\"]>;\n offline?: Config[\"offline\"];\n proxyUrl?: string;\n}\n\n/**\n * Reads configuration from build-time injected values.\n *\n * The value-injection-loader prepends code to instrumentation-client.ts\n * that sets these globalThis values during the build process.\n *\n * @returns Partial config from injected values, or null if SDK is disabled\n */\nexport function getInjectedConfig(): Partial<Config> | null {\n if (typeof globalThis === \"undefined\") {\n return null;\n }\n\n const buildId = globalThis.__INTERFERE_BUILD_ID__;\n const releaseId = globalThis.__INTERFERE_RELEASE_ID__;\n const environmentRaw = globalThis.__INTERFERE_ENVIRONMENT__;\n const enabled = globalThis.__INTERFERE_ENABLED__;\n const features = globalThis.__INTERFERE_FEATURES__;\n\n // If not enabled, SDK was disabled (no valid INTERFERE_API_KEY was set at build)\n if (!enabled) {\n return null;\n }\n\n // Parse environment with fallback\n const environment = environmentRaw\n ? (envSchema.safeParse(environmentRaw).data ?? \"production\")\n : \"production\";\n\n // For Next.js, we always use proxy mode - the proxy handles authentication\n // This means the client doesn't need the surface token at all\n return {\n metadata: {\n buildId: buildId ?? null,\n releaseId: releaseId ?? null,\n environment,\n runtime: \"browser\",\n },\n proxyUrl: \"/api/interfere\",\n // Include features if they were injected\n ...(features && { features }),\n };\n}\n\n/**\n * Initialize Interfere client automatically from build-time injected config.\n *\n * Call this from instrumentation-client.ts for zero-config initialization.\n * User-provided overrides take precedence over injected values.\n *\n * @param userConfig - Optional configuration overrides\n * @returns Parsed config if initialization succeeded, null if SDK is disabled or already initialized\n *\n * @example\n * ```ts\n * // instrumentation-client.ts\n * import { autoInitClient } from \"@interfere/next/auto-init\";\n *\n * const config = autoInitClient();\n * if (config) {\n * console.log(\"[Interfere] Client initialized\", config.metadata);\n * }\n * ```\n *\n * @example\n * ```ts\n * // With overrides\n * import { autoInitClient } from \"@interfere/next/auto-init\";\n *\n * const config = autoInitClient({\n * features: { replay: false },\n * batch: { size: 25, ms: 500 }\n * });\n * ```\n */\nexport function autoInitClient(\n userConfig?: AutoInitConfigOverrides\n): Config | null {\n // Prevent double initialization\n if (globalThis.__INTERFERE_INITIALIZED__) {\n if (process.env.NODE_ENV === \"development\") {\n console.warn(\"[Interfere] Already initialized, skipping duplicate init\");\n }\n return null;\n }\n\n const injectedConfig = getInjectedConfig();\n if (!injectedConfig) {\n if (process.env.NODE_ENV === \"development\") {\n console.info(\n \"[Interfere] No injected config found. SDK disabled. \" +\n \"Ensure INTERFERE_API_KEY is set and withInterfere() is configured.\"\n );\n }\n return null;\n }\n\n // Merge injected config with user overrides\n // User overrides take precedence\n const mergedConfig = {\n ...injectedConfig,\n ...(userConfig?.features && { features: userConfig.features }),\n ...(userConfig?.batch && { batch: userConfig.batch }),\n ...(userConfig?.offline && { offline: userConfig.offline }),\n ...(userConfig?.proxyUrl && { proxyUrl: userConfig.proxyUrl }),\n metadata: {\n ...injectedConfig.metadata,\n ...userConfig?.metadata,\n },\n };\n\n // Validate and parse the merged config\n const parseResult = configSchema.safeParse(mergedConfig);\n if (!parseResult.success) {\n console.error(\"[Interfere] Failed to parse config:\", parseResult.error);\n return null;\n }\n\n globalThis.__INTERFERE_INITIALIZED__ = true;\n return parseResult.data;\n}\n\n/**\n * Check if Interfere has already been initialized.\n */\nexport function isInitialized(): boolean {\n return globalThis.__INTERFERE_INITIALIZED__ === true;\n}\n\n/**\n * Reset initialization state. Only use for testing.\n * @internal\n */\nexport function resetInitializationState(): void {\n globalThis.__INTERFERE_INITIALIZED__ = undefined;\n}\n"],"mappings":";;;;;;;;;;AAqCA,MAAa,uBAAuB;CAClC;CACA;CACA;CACA;CACA;CACD;;;;;;;;;AAuBD,SAAgB,oBAA4C;AAC1D,KAAI,OAAO,eAAe,YACxB,QAAO;CAGT,MAAM,UAAU,WAAW;CAC3B,MAAM,YAAY,WAAW;CAC7B,MAAM,iBAAiB,WAAW;CAClC,MAAM,UAAU,WAAW;CAC3B,MAAM,WAAW,WAAW;AAG5B,KAAI,CAAC,QACH,QAAO;CAIT,MAAM,cAAc,iBACf,UAAU,UAAU,eAAe,CAAC,QAAQ,eAC7C;AAIJ,QAAO;EACL,UAAU;GACR,SAAS,WAAW;GACpB,WAAW,aAAa;GACxB;GACA,SAAS;GACV;EACD,UAAU;EAEV,GAAI,YAAY,EAAE,UAAU;EAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCH,SAAgB,eACd,YACe;AAEf,KAAI,WAAW,2BAA2B;AACxC,MAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,KAAK,2DAA2D;AAE1E,SAAO;;CAGT,MAAM,iBAAiB,mBAAmB;AAC1C,KAAI,CAAC,gBAAgB;AACnB,MAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,KACN,yHAED;AAEH,SAAO;;CAKT,MAAM,eAAe;EACnB,GAAG;EACH,GAAI,YAAY,YAAY,EAAE,UAAU,WAAW,UAAU;EAC7D,GAAI,YAAY,SAAS,EAAE,OAAO,WAAW,OAAO;EACpD,GAAI,YAAY,WAAW,EAAE,SAAS,WAAW,SAAS;EAC1D,GAAI,YAAY,YAAY,EAAE,UAAU,WAAW,UAAU;EAC7D,UAAU;GACR,GAAG,eAAe;GAClB,GAAG,YAAY;GAChB;EACF;CAGD,MAAM,cAAc,aAAa,UAAU,aAAa;AACxD,KAAI,CAAC,YAAY,SAAS;AACxB,UAAQ,MAAM,uCAAuC,YAAY,MAAM;AACvE,SAAO;;AAGT,YAAW,4BAA4B;AACvC,QAAO,YAAY;;;;;AAMrB,SAAgB,gBAAyB;AACvC,QAAO,WAAW,8BAA8B;;;;;;AAOlD,SAAgB,2BAAiC;AAC/C,YAAW,4BAA4B"}
@@ -1,14 +1,14 @@
1
- import { InterfereProviderProps } from "@interfere/react/provider";
2
1
  import { ConfigInput } from "@interfere/types/sdk/config";
2
+ import { InterfereProviderProps } from "@interfere/react/provider";
3
3
  import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/client/provider.d.ts
6
6
  interface NextConfigInput {
7
+ batch?: ConfigInput["batch"];
7
8
  features?: ConfigInput["features"];
9
+ ingestUrl?: string;
8
10
  metadata?: ConfigInput["metadata"];
9
- batch?: ConfigInput["batch"];
10
11
  proxyUrl?: string;
11
- ingestUrl?: string;
12
12
  surfaceToken?: string;
13
13
  }
14
14
  declare function InterfereProvider({
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.mts","names":[],"sources":["../../src/client/provider.tsx"],"sourcesContent":[],"mappings":";;;;;UAyBU,eAAA;aACG;aACA;EAFH,KAAA,CAAA,EAGA,WAHe,CAAA,OAAA,CAAA;EACZ,QAAA,CAAA,EAAA,MAAA;EACA,SAAA,CAAA,EAAA,MAAA;EACH,YAAA,CAAA,EAAA,MAAA;;AAgCM,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,kBAAA,CAAA,GAAA,CAAA,OAFtE"}
1
+ {"version":3,"file":"provider.d.mts","names":[],"sources":["../../src/client/provider.tsx"],"mappings":";;;;;UA2CU,eAAA;EACR,KAAA,GAAQ,WAAA;EACR,QAAA,GAAW,WAAA;EACX,SAAA;EACA,QAAA,GAAW,WAAA;EACX,QAAA;EACA,YAAA;AAAA;AAAA,iBA8Bc,iBAAA,CAAA;EACd,QAAA;EACA,MAAA;EAAA,GACG;AAAA,GACF,IAAA,CAAK,sBAAA;EAAsC,MAAA,GAAS,eAAA;AAAA,IAAiB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1,19 +1,32 @@
1
1
  "use client";
2
2
 
3
- import { InterfereProvider as InterfereProvider$1 } from "@interfere/react/provider";
4
- import { getRuntime } from "@interfere/react/core/runtime/config";
3
+ import { getInjectedConfig } from "./auto-init.mjs";
5
4
  import { configSchema } from "@interfere/types/sdk/config";
6
5
  import { envSchema } from "@interfere/types/sdk/runtime";
6
+ import { InterfereProvider as InterfereProvider$1 } from "@interfere/react/provider";
7
+ import { getRuntime } from "@interfere/react/core/runtime/config";
7
8
  import { jsx } from "react/jsx-runtime";
8
9
 
9
10
  //#region src/client/provider.tsx
10
- const defaults = {
11
- buildId: process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID ?? null,
12
- releaseId: process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID ?? null,
13
- environment: process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT ? envSchema.parse(process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT) : "production",
14
- runtime: getRuntime()
15
- };
11
+ /**
12
+ * Get default metadata from environment variables (legacy approach)
13
+ * or from injected config (instrumentation approach).
14
+ */
15
+ function getDefaultMetadata() {
16
+ const injectedConfig = getInjectedConfig();
17
+ if (injectedConfig?.metadata) return {
18
+ ...injectedConfig.metadata,
19
+ runtime: getRuntime()
20
+ };
21
+ return {
22
+ buildId: process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID ?? null,
23
+ releaseId: process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID ?? null,
24
+ environment: process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT ? envSchema.parse(process.env.NEXT_PUBLIC_INTERFERE_ENVIRONMENT) : "production",
25
+ runtime: getRuntime()
26
+ };
27
+ }
16
28
  function mergeConfig(config) {
29
+ const defaults = getDefaultMetadata();
17
30
  const incomingMeta = config.metadata ?? {};
18
31
  const transportConfig = typeof config.proxyUrl !== "undefined" || typeof config.ingestUrl !== "undefined" || typeof config.surfaceToken !== "undefined" ? config : { proxyUrl: "/api/interfere" };
19
32
  return configSchema.parse({
@@ -1 +1 @@
1
- {"version":3,"file":"provider.mjs","names":["defaults: ConfigInput[\"metadata\"]","InterfereProviderReact"],"sources":["../../src/client/provider.tsx"],"sourcesContent":["\"use client\";\n\nimport { getRuntime } from \"@interfere/react/core/runtime/config\";\nimport {\n type InterfereProviderProps,\n InterfereProvider as InterfereProviderReact,\n} from \"@interfere/react/provider\";\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\ninterface 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;AAGxE,QACE,oBAACC;EAAuB,QAHL,YAAY,OAAO;EAGQ,GAAI;EAC/C;GACsB"}
1
+ {"version":3,"file":"provider.mjs","names":["InterfereProviderReact"],"sources":["../../src/client/provider.tsx"],"sourcesContent":["\"use client\";\n\nimport { getRuntime } from \"@interfere/react/core/runtime/config\";\nimport {\n type InterfereProviderProps,\n InterfereProvider as InterfereProviderReact,\n} from \"@interfere/react/provider\";\nimport {\n type Config,\n type ConfigInput,\n configSchema,\n} from \"@interfere/types/sdk/config\";\nimport { envSchema } from \"@interfere/types/sdk/runtime\";\n\nimport { getInjectedConfig } from \"./auto-init.js\";\n\n/**\n * Get default metadata from environment variables (legacy approach)\n * or from injected config (instrumentation approach).\n */\nfunction getDefaultMetadata(): ConfigInput[\"metadata\"] {\n // First, try to get injected config from instrumentation-client.ts\n const injectedConfig = getInjectedConfig();\n if (injectedConfig?.metadata) {\n return {\n ...injectedConfig.metadata,\n runtime: getRuntime(),\n };\n }\n\n // Fallback to environment variables (legacy approach)\n return {\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\n// Next.js-specific config type that allows omitting transport\n// because Next.js can provide its own proxy endpoint\ninterface NextConfigInput {\n batch?: ConfigInput[\"batch\"];\n features?: ConfigInput[\"features\"];\n ingestUrl?: string;\n metadata?: ConfigInput[\"metadata\"];\n proxyUrl?: string;\n surfaceToken?: string;\n}\n\nfunction mergeConfig(config: NextConfigInput): Config {\n const defaults = getDefaultMetadata();\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":";;;;;;;;;;;;;;AAoBA,SAAS,qBAA8C;CAErD,MAAM,iBAAiB,mBAAmB;AAC1C,KAAI,gBAAgB,SAClB,QAAO;EACL,GAAG,eAAe;EAClB,SAAS,YAAY;EACtB;AAIH,QAAO;EACL,SAAS,QAAQ,IAAI,kCAAkC;EACvD,WAAW,QAAQ,IAAI,oCAAoC;EAC3D,aAAa,QAAQ,IAAI,oCACrB,UAAU,MAAM,QAAQ,IAAI,kCAAkC,GAC9D;EACJ,SAAS,YAAY;EACtB;;AAcH,SAAS,YAAY,QAAiC;CACpD,MAAM,WAAW,oBAAoB;CACrC,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;AAGxE,QACE,oBAACA;EAAuB,QAHL,YAAY,OAAO;EAGQ,GAAI;EAC/C;GACsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.mts","names":[],"sources":["../../src/lib/env.ts"],"sourcesContent":[],"mappings":";;AAQA;AAQA;;;;;iBARgB,aAAA,CAAA;iBAQA,eAAA,CAAA"}
1
+ {"version":3,"file":"env.d.mts","names":[],"sources":["../../src/lib/env.ts"],"mappings":";;AAQA;;;;;AAQA;iBARgB,aAAA,CAAA;AAAA,iBAQA,eAAA,CAAA"}
@@ -4,18 +4,18 @@ type NonEmptyString = string & {
4
4
  };
5
5
  declare function toNonEmptyString(value: string): NonEmptyString | null;
6
6
  interface PreflightEnabled {
7
+ apiKey: NonEmptyString;
8
+ cleanupSourceMaps: boolean;
9
+ debug: boolean;
7
10
  enabled: true;
8
- surface: NonEmptyString;
9
- secretKey: NonEmptyString;
10
11
  environment: string;
11
- debug: boolean;
12
- cleanupSourceMaps: boolean;
12
+ surface: NonEmptyString;
13
13
  }
14
14
  interface PreflightDisabled {
15
+ cleanupSourceMaps: boolean;
16
+ debug: boolean;
15
17
  enabled: false;
16
18
  environment: string | undefined;
17
- debug: boolean;
18
- cleanupSourceMaps: boolean;
19
19
  }
20
20
  type PreflightConfig = PreflightEnabled | PreflightDisabled;
21
21
  //#endregion
@@ -1 +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;AAIiB,iBAJD,gBAAA,CAML,KAAA,EAAA,MACE,CAAA,EAPoC,cAOtB,GAAA,IAAA;AAMV,UATA,gBAAA,CASiB;EAOtB,OAAA,EAAA,IAAA;WAdD;aACE;;;;;UAMI,iBAAA;;;;;;KAOL,eAAA,GAAkB,mBAAmB"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/lib/types.ts"],"mappings":";KACY,cAAA;EAAA,SAAqC,OAAA;AAAA;AAAA,iBAEjC,gBAAA,CAAiB,KAAA,WAAgB,cAAA;AAAA,UAIhC,gBAAA;EACf,MAAA,EAAQ,cAAA;EACR,iBAAA;EACA,KAAA;EACA,OAAA;EACA,WAAA;EACA,OAAA,EAAS,cAAA;AAAA;AAAA,UAGM,iBAAA;EACf,iBAAA;EACA,KAAA;EACA,OAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA,GAAkB,gBAAA,GAAmB,iBAAA"}
@@ -1 +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 interface PreflightEnabled {\n enabled: true;\n surface: NonEmptyString;\n secretKey: NonEmptyString;\n environment: string;\n debug: boolean;\n cleanupSourceMaps: boolean;\n}\n\nexport interface 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"}
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 interface PreflightEnabled {\n apiKey: NonEmptyString;\n cleanupSourceMaps: boolean;\n debug: boolean;\n enabled: true;\n environment: string;\n surface: NonEmptyString;\n}\n\nexport interface PreflightDisabled {\n cleanupSourceMaps: boolean;\n debug: boolean;\n enabled: false;\n environment: string | undefined;\n}\n\nexport type PreflightConfig = PreflightEnabled | PreflightDisabled;\n"],"mappings":";AAGA,SAAgB,iBAAiB,OAAsC;AACrE,QAAO,MAAM,SAAS,IAAK,QAA2B"}
@@ -0,0 +1,88 @@
1
+ import { ServerSDK, ServerSDKConfig } from "./sdk.mjs";
2
+
3
+ //#region src/server/auto-init.d.ts
4
+ interface InjectedFeatures {
5
+ errorTracking?: boolean;
6
+ performanceMonitoring?: boolean;
7
+ replay?: boolean;
8
+ }
9
+ declare global {
10
+ var __INTERFERE_BUILD_ID__: string | null | undefined;
11
+ var __INTERFERE_RELEASE_ID__: string | null | undefined;
12
+ var __INTERFERE_ENVIRONMENT__: string | undefined;
13
+ var __INTERFERE_ENABLED__: boolean | undefined;
14
+ var __INTERFERE_FEATURES__: InjectedFeatures | undefined;
15
+ var __INTERFERE_SURFACE_SLUG__: string | undefined;
16
+ var __INTERFERE_SERVER_SDK__: ServerSDK | undefined;
17
+ }
18
+ interface AutoInitServerOptions {
19
+ /**
20
+ * Override the environment detected at build time.
21
+ */
22
+ environment?: string;
23
+ /**
24
+ * Override feature flags.
25
+ */
26
+ features?: Partial<ServerSDKConfig["features"]>;
27
+ /**
28
+ * Whether to install global error handlers (uncaughtException, unhandledRejection).
29
+ * @default true
30
+ */
31
+ installGlobalHandlers?: boolean;
32
+ }
33
+ /**
34
+ * Result of auto-initialization.
35
+ */
36
+ interface AutoInitResult {
37
+ /** Whether the SDK was successfully initialized */
38
+ readonly initialized: boolean;
39
+ /** Reason for not initializing, if applicable */
40
+ readonly reason?: string;
41
+ /** The SDK instance if initialized */
42
+ readonly sdk: ServerSDK | null;
43
+ }
44
+ /**
45
+ * Automatically initialize the server-side Interfere SDK.
46
+ *
47
+ * This function reads build-time values injected by `withInterfere()` and
48
+ * initializes the SDK singleton. It should be called from `instrumentation.ts`.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * // instrumentation.ts
53
+ * export async function register() {
54
+ * if (process.env.NEXT_RUNTIME === 'nodejs') {
55
+ * const { autoInitServer } = await import('@interfere/next/server/auto-init');
56
+ * autoInitServer();
57
+ * }
58
+ * }
59
+ * ```
60
+ *
61
+ * @example With custom options
62
+ * ```ts
63
+ * // instrumentation.ts
64
+ * export async function register() {
65
+ * if (process.env.NEXT_RUNTIME === 'nodejs') {
66
+ * const { autoInitServer } = await import('@interfere/next/server/auto-init');
67
+ * autoInitServer({
68
+ * features: {
69
+ * errorTracking: true,
70
+ * performanceMonitoring: process.env.NODE_ENV === 'production',
71
+ * },
72
+ * });
73
+ * }
74
+ * }
75
+ * ```
76
+ */
77
+ declare function autoInitServer(options?: AutoInitServerOptions): AutoInitResult;
78
+ /**
79
+ * Get the initialized server SDK instance.
80
+ * Returns null if the SDK has not been initialized.
81
+ */
82
+ declare function getServerSDK(): ServerSDK | null;
83
+ /**
84
+ * Check if the server SDK is initialized.
85
+ */
86
+ declare function isServerSDKInitialized(): boolean;
87
+ //#endregion
88
+ export { AutoInitResult, AutoInitServerOptions, autoInitServer, getServerSDK, isServerSDKInitialized };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-init.d.mts","names":[],"sources":["../../src/server/auto-init.ts"],"mappings":";;;UAEU,gBAAA;EACR,aAAA;EACA,qBAAA;EACA,MAAA;AAAA;AAAA,QAGM,MAAA;EAAA,IACF,sBAAA;EAAA,IACA,wBAAA;EAAA,IACA,yBAAA;EAAA,IACA,qBAAA;EAAA,IACA,sBAAA,EAAwB,gBAAA;EAAA,IACxB,0BAAA;EAAA,IACA,wBAAA,EAA0B,SAAA;AAAA;AAAA,UAGf,qBAAA;EAVT;;;EAcN,WAAA;EAVI;;;EAeJ,QAAA,GAAW,OAAA,CAAQ,eAAA;EAZW;;;;EAkB9B,qBAAA;AAAA;;;;UAMe,cAAA;EAZf;EAAA,SAcS,WAAA;EAdU;EAAA,SAgBV,MAAA;EAVY;EAAA,SAYZ,GAAA,EAAK,SAAA;AAAA;;;;;;;;;;AAoChB;;;;;;;;;AA8DA;;;;;AAOA;;;;;;;;;;iBArEgB,cAAA,CACd,OAAA,GAAU,qBAAA,GACT,cAAA;;;;;iBA4Da,YAAA,CAAA,GAAgB,SAAA;;;;iBAOhB,sBAAA,CAAA"}
@@ -0,0 +1,101 @@
1
+ import { ServerSDK } from "./sdk.mjs";
2
+
3
+ //#region src/server/auto-init.ts
4
+ /**
5
+ * Automatically initialize the server-side Interfere SDK.
6
+ *
7
+ * This function reads build-time values injected by `withInterfere()` and
8
+ * initializes the SDK singleton. It should be called from `instrumentation.ts`.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * // instrumentation.ts
13
+ * export async function register() {
14
+ * if (process.env.NEXT_RUNTIME === 'nodejs') {
15
+ * const { autoInitServer } = await import('@interfere/next/server/auto-init');
16
+ * autoInitServer();
17
+ * }
18
+ * }
19
+ * ```
20
+ *
21
+ * @example With custom options
22
+ * ```ts
23
+ * // instrumentation.ts
24
+ * export async function register() {
25
+ * if (process.env.NEXT_RUNTIME === 'nodejs') {
26
+ * const { autoInitServer } = await import('@interfere/next/server/auto-init');
27
+ * autoInitServer({
28
+ * features: {
29
+ * errorTracking: true,
30
+ * performanceMonitoring: process.env.NODE_ENV === 'production',
31
+ * },
32
+ * });
33
+ * }
34
+ * }
35
+ * ```
36
+ */
37
+ function autoInitServer(options) {
38
+ if (globalThis.__INTERFERE_SERVER_SDK__) return {
39
+ initialized: true,
40
+ sdk: globalThis.__INTERFERE_SERVER_SDK__,
41
+ reason: "already_initialized"
42
+ };
43
+ if (globalThis.__INTERFERE_ENABLED__ === false) {
44
+ if (process.env.NODE_ENV === "development") console.log("[Interfere] Server SDK disabled via build config");
45
+ return {
46
+ initialized: false,
47
+ sdk: null,
48
+ reason: "disabled_by_config"
49
+ };
50
+ }
51
+ if (!process.env.INTERFERE_API_KEY) {
52
+ if (process.env.NODE_ENV === "development") console.warn("[Interfere] Server SDK not initialized: INTERFERE_API_KEY not set.\nTo enable server-side error tracking, add INTERFERE_API_KEY to your environment. Ensure you are using the correct key.");
53
+ return {
54
+ initialized: false,
55
+ sdk: null,
56
+ reason: "missing_api_key"
57
+ };
58
+ }
59
+ const config = {
60
+ metadata: {
61
+ buildId: globalThis.__INTERFERE_BUILD_ID__ ?? null,
62
+ releaseId: globalThis.__INTERFERE_RELEASE_ID__ ?? null,
63
+ environment: options?.environment ?? globalThis.__INTERFERE_ENVIRONMENT__ ?? process.env.NODE_ENV ?? "production",
64
+ runtime: detectRuntime()
65
+ },
66
+ features: {
67
+ errorTracking: true,
68
+ performanceMonitoring: true,
69
+ ...globalThis.__INTERFERE_FEATURES__ ?? {},
70
+ ...options?.features
71
+ }
72
+ };
73
+ const sdk = ServerSDK.init(config);
74
+ if (options?.installGlobalHandlers !== false) sdk.installGlobalHandlers();
75
+ globalThis.__INTERFERE_SERVER_SDK__ = sdk;
76
+ return {
77
+ initialized: true,
78
+ sdk
79
+ };
80
+ }
81
+ /**
82
+ * Get the initialized server SDK instance.
83
+ * Returns null if the SDK has not been initialized.
84
+ */
85
+ function getServerSDK() {
86
+ return globalThis.__INTERFERE_SERVER_SDK__ ?? ServerSDK.getInstance();
87
+ }
88
+ /**
89
+ * Check if the server SDK is initialized.
90
+ */
91
+ function isServerSDKInitialized() {
92
+ return Boolean(globalThis.__INTERFERE_SERVER_SDK__) || ServerSDK.isInitialized();
93
+ }
94
+ function detectRuntime() {
95
+ if (process.env.NEXT_RUNTIME === "edge") return "edge";
96
+ if (typeof globalThis.EdgeRuntime !== "undefined") return "edge";
97
+ return "nodejs";
98
+ }
99
+
100
+ //#endregion
101
+ export { autoInitServer, getServerSDK, isServerSDKInitialized };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-init.mjs","names":[],"sources":["../../src/server/auto-init.ts"],"sourcesContent":["import { ServerSDK, type ServerSDKConfig } from \"./sdk.js\";\n\ninterface InjectedFeatures {\n errorTracking?: boolean;\n performanceMonitoring?: boolean;\n replay?: boolean;\n}\n\ndeclare global {\n var __INTERFERE_BUILD_ID__: string | null | undefined;\n var __INTERFERE_RELEASE_ID__: string | null | undefined;\n var __INTERFERE_ENVIRONMENT__: string | undefined;\n var __INTERFERE_ENABLED__: boolean | undefined;\n var __INTERFERE_FEATURES__: InjectedFeatures | undefined;\n var __INTERFERE_SURFACE_SLUG__: string | undefined;\n var __INTERFERE_SERVER_SDK__: ServerSDK | undefined;\n}\n\nexport interface AutoInitServerOptions {\n /**\n * Override the environment detected at build time.\n */\n environment?: string;\n\n /**\n * Override feature flags.\n */\n features?: Partial<ServerSDKConfig[\"features\"]>;\n\n /**\n * Whether to install global error handlers (uncaughtException, unhandledRejection).\n * @default true\n */\n installGlobalHandlers?: boolean;\n}\n\n/**\n * Result of auto-initialization.\n */\nexport interface AutoInitResult {\n /** Whether the SDK was successfully initialized */\n readonly initialized: boolean;\n /** Reason for not initializing, if applicable */\n readonly reason?: string;\n /** The SDK instance if initialized */\n readonly sdk: ServerSDK | null;\n}\n\n/**\n * Automatically initialize the server-side Interfere SDK.\n *\n * This function reads build-time values injected by `withInterfere()` and\n * initializes the SDK singleton. It should be called from `instrumentation.ts`.\n *\n * @example\n * ```ts\n * // instrumentation.ts\n * export async function register() {\n * if (process.env.NEXT_RUNTIME === 'nodejs') {\n * const { autoInitServer } = await import('@interfere/next/server/auto-init');\n * autoInitServer();\n * }\n * }\n * ```\n *\n * @example With custom options\n * ```ts\n * // instrumentation.ts\n * export async function register() {\n * if (process.env.NEXT_RUNTIME === 'nodejs') {\n * const { autoInitServer } = await import('@interfere/next/server/auto-init');\n * autoInitServer({\n * features: {\n * errorTracking: true,\n * performanceMonitoring: process.env.NODE_ENV === 'production',\n * },\n * });\n * }\n * }\n * ```\n */\nexport function autoInitServer(\n options?: AutoInitServerOptions\n): AutoInitResult {\n if (globalThis.__INTERFERE_SERVER_SDK__) {\n return {\n initialized: true,\n sdk: globalThis.__INTERFERE_SERVER_SDK__,\n reason: \"already_initialized\",\n };\n }\n\n if (globalThis.__INTERFERE_ENABLED__ === false) {\n if (process.env.NODE_ENV === \"development\") {\n console.log(\"[Interfere] Server SDK disabled via build config\");\n }\n return { initialized: false, sdk: null, reason: \"disabled_by_config\" };\n }\n\n if (!process.env.INTERFERE_API_KEY) {\n if (process.env.NODE_ENV === \"development\") {\n console.warn(\n \"[Interfere] Server SDK not initialized: INTERFERE_API_KEY not set.\\n\" +\n \"To enable server-side error tracking, add INTERFERE_API_KEY to your environment. Ensure you are using the correct key.\"\n );\n }\n return { initialized: false, sdk: null, reason: \"missing_api_key\" };\n }\n\n const config: ServerSDKConfig = {\n metadata: {\n buildId: globalThis.__INTERFERE_BUILD_ID__ ?? null,\n releaseId: globalThis.__INTERFERE_RELEASE_ID__ ?? null,\n environment:\n options?.environment ??\n globalThis.__INTERFERE_ENVIRONMENT__ ??\n process.env.NODE_ENV ??\n \"production\",\n runtime: detectRuntime(),\n },\n features: {\n errorTracking: true,\n performanceMonitoring: true,\n ...(globalThis.__INTERFERE_FEATURES__ ?? {}),\n ...options?.features,\n },\n };\n\n const sdk = ServerSDK.init(config);\n\n if (options?.installGlobalHandlers !== false) {\n sdk.installGlobalHandlers();\n }\n\n globalThis.__INTERFERE_SERVER_SDK__ = sdk;\n\n return { initialized: true, sdk };\n}\n\n/**\n * Get the initialized server SDK instance.\n * Returns null if the SDK has not been initialized.\n */\nexport function getServerSDK(): ServerSDK | null {\n return globalThis.__INTERFERE_SERVER_SDK__ ?? ServerSDK.getInstance();\n}\n\n/**\n * Check if the server SDK is initialized.\n */\nexport function isServerSDKInitialized(): boolean {\n return (\n Boolean(globalThis.__INTERFERE_SERVER_SDK__) || ServerSDK.isInitialized()\n );\n}\n\nfunction detectRuntime(): \"nodejs\" | \"edge\" {\n if (process.env.NEXT_RUNTIME === \"edge\") {\n return \"edge\";\n }\n if (\n typeof (globalThis as { EdgeRuntime?: unknown }).EdgeRuntime !== \"undefined\"\n ) {\n return \"edge\";\n }\n return \"nodejs\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,SAAgB,eACd,SACgB;AAChB,KAAI,WAAW,yBACb,QAAO;EACL,aAAa;EACb,KAAK,WAAW;EAChB,QAAQ;EACT;AAGH,KAAI,WAAW,0BAA0B,OAAO;AAC9C,MAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,IAAI,mDAAmD;AAEjE,SAAO;GAAE,aAAa;GAAO,KAAK;GAAM,QAAQ;GAAsB;;AAGxE,KAAI,CAAC,QAAQ,IAAI,mBAAmB;AAClC,MAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,KACN,6LAED;AAEH,SAAO;GAAE,aAAa;GAAO,KAAK;GAAM,QAAQ;GAAmB;;CAGrE,MAAM,SAA0B;EAC9B,UAAU;GACR,SAAS,WAAW,0BAA0B;GAC9C,WAAW,WAAW,4BAA4B;GAClD,aACE,SAAS,eACT,WAAW,6BACX,QAAQ,IAAI,YACZ;GACF,SAAS,eAAe;GACzB;EACD,UAAU;GACR,eAAe;GACf,uBAAuB;GACvB,GAAI,WAAW,0BAA0B,EAAE;GAC3C,GAAG,SAAS;GACb;EACF;CAED,MAAM,MAAM,UAAU,KAAK,OAAO;AAElC,KAAI,SAAS,0BAA0B,MACrC,KAAI,uBAAuB;AAG7B,YAAW,2BAA2B;AAEtC,QAAO;EAAE,aAAa;EAAM;EAAK;;;;;;AAOnC,SAAgB,eAAiC;AAC/C,QAAO,WAAW,4BAA4B,UAAU,aAAa;;;;;AAMvE,SAAgB,yBAAkC;AAChD,QACE,QAAQ,WAAW,yBAAyB,IAAI,UAAU,eAAe;;AAI7E,SAAS,gBAAmC;AAC1C,KAAI,QAAQ,IAAI,iBAAiB,OAC/B,QAAO;AAET,KACE,OAAQ,WAAyC,gBAAgB,YAEjE,QAAO;AAET,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/server/middleware.ts"],"sourcesContent":[],"mappings":";;;iBAiBgB,uBAAA,uBACQ,gBAAgB,QAAQ,gBAAgB,yBAIvC,gBAAW,QAAA;iBA0CpB,qBAAA,gBACC,gBAAgB,QAAQ,kBAIpB,gBAAW,QAAA;AApDhB,iBA8FA,4BA9FuB,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GA+FH,OA/FG,CAAA,OAAA,CAAA,CAAA,CAAA,SAAA,EAgG1B,CAhG0B,EAAA,aAAA,CAAA,EAAA,MAAA,CAAA,EAgGE,CAhGF;AACf,iBA8IR,2BAAA,CAAA,CA9IQ,EAAA,CAAA,KAAA,EAiJD,KAjJC,EAAA,SAAA,EAAA;EAAwB,MAAA,CAAA,EAAA,MAAA;CAAR,EAAA,GAiJoB,OAjJpB,CAAA,IAAA,CAAA"}
1
+ {"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/server/middleware.ts"],"mappings":";;;iBAgBgB,uBAAA,CACd,UAAA,GAAa,OAAA,EAAS,WAAA,KAAgB,OAAA,CAAQ,YAAA,IAAgB,YAAA,IAIhD,OAAA,EAAS,WAAA,KAAW,OAAA,CAAA,YAAA;AAAA,iBA0CpB,qBAAA,CACd,OAAA,GAAU,GAAA,EAAK,WAAA,KAAgB,OAAA,CAAQ,QAAA,KAIzB,GAAA,EAAK,WAAA,KAAW,OAAA,CAAA,QAAA;AAAA,iBA0ChB,4BAAA,eACA,IAAA,gBAAoB,OAAA,UAAA,CAClC,SAAA,EAAW,CAAA,EAAG,aAAA,YAAyB,CAAA;AAAA,iBA8DzB,2BAAA,CAAA,IAGA,KAAA,EAAO,KAAA,EAAO,SAAA;EAAa,MAAA;AAAA,MAAiB,OAAA"}