@interfere/next 11.0.0-canary.2 → 11.0.0-canary.3
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 +3 -2
- package/dist/config.mjs +1 -1
- package/dist/instrument-client.d.mts +1 -0
- package/dist/instrumentation.d.mts +4 -2
- package/dist/instrumentation.edge.d.mts +16 -23
- package/dist/instrumentation.edge.mjs +1 -1
- package/dist/instrumentation.mjs +1 -1
- package/dist/internal/build/configure-build.mjs +1 -1
- package/dist/internal/build/pipeline.d.mts +1 -14
- package/dist/internal/build/release/destinations/cli.d.mts +7 -0
- package/dist/internal/build/release/destinations/cli.mjs +1 -0
- package/dist/internal/build/release/destinations/cloudflare.d.mts +6 -0
- package/dist/internal/build/release/destinations/cloudflare.mjs +1 -0
- package/dist/internal/build/release/destinations/index.d.mts +5 -4
- package/dist/internal/build/release/destinations/index.mjs +1 -1
- package/dist/internal/build/release/index.mjs +1 -1
- package/dist/internal/build/source-maps/discover-webpack.d.mts +1 -7
- package/dist/internal/build/source-maps/discover-webpack.mjs +1 -1
- package/dist/internal/env.mjs +1 -1
- package/dist/internal/release-slug.d.mts +1 -17
- package/dist/internal/release-slug.mjs +1 -1
- package/dist/internal/route/proxy.d.mts +1 -21
- package/dist/internal/route/proxy.mjs +1 -1
- package/dist/internal/server/capture.d.mts +6 -1
- package/dist/internal/server/capture.mjs +1 -1
- package/dist/internal/server/edge-exporter.d.mts +14 -0
- package/dist/internal/server/edge-exporter.mjs +1 -0
- package/dist/internal/server/global-handlers.d.mts +11 -0
- package/dist/internal/server/global-handlers.mjs +1 -0
- package/dist/internal/server/instrumentation-options.d.mts +15 -1
- package/dist/internal/server/server-action-marker.d.mts +9 -0
- package/dist/internal/server/server-action-marker.mjs +1 -0
- package/dist/internal/server/trace-meta.d.mts +1 -1
- package/dist/internal/server/types.d.mts +5 -0
- package/dist/internal/server/wrap-proxy.d.mts +22 -0
- package/dist/internal/server/wrap-proxy.mjs +1 -0
- package/dist/internal/server/wrap-server-action.d.mts +34 -0
- package/dist/internal/server/wrap-server-action.mjs +1 -0
- package/dist/package.mjs +1 -1
- package/dist/server.d.mts +3 -1
- package/dist/server.mjs +1 -1
- package/package.json +22 -23
- package/dist/config.d.mts.map +0 -1
- package/dist/config.mjs.map +0 -1
- package/dist/instrument-client.d.mts.map +0 -1
- package/dist/instrument-client.mjs.map +0 -1
- package/dist/instrumentation-client.mjs.map +0 -1
- package/dist/instrumentation.d.mts.map +0 -1
- package/dist/instrumentation.edge.d.mts.map +0 -1
- package/dist/instrumentation.edge.mjs.map +0 -1
- package/dist/instrumentation.mjs.map +0 -1
- package/dist/internal/build/configure-build.d.mts.map +0 -1
- package/dist/internal/build/configure-build.mjs.map +0 -1
- package/dist/internal/build/detect-bundler.d.mts.map +0 -1
- package/dist/internal/build/detect-bundler.mjs.map +0 -1
- package/dist/internal/build/pipeline.d.mts.map +0 -1
- package/dist/internal/build/pipeline.mjs.map +0 -1
- package/dist/internal/build/release/destinations/index.d.mts.map +0 -1
- package/dist/internal/build/release/destinations/index.mjs.map +0 -1
- package/dist/internal/build/release/destinations/vercel.d.mts.map +0 -1
- package/dist/internal/build/release/destinations/vercel.mjs.map +0 -1
- package/dist/internal/build/release/git.d.mts.map +0 -1
- package/dist/internal/build/release/git.mjs.map +0 -1
- package/dist/internal/build/release/index.d.mts.map +0 -1
- package/dist/internal/build/release/index.mjs.map +0 -1
- package/dist/internal/build/release/sources/github.d.mts.map +0 -1
- package/dist/internal/build/release/sources/github.mjs.map +0 -1
- package/dist/internal/build/release/sources/index.d.mts.map +0 -1
- package/dist/internal/build/release/sources/index.mjs.map +0 -1
- package/dist/internal/build/source-maps/discover-turbopack.d.mts.map +0 -1
- package/dist/internal/build/source-maps/discover-turbopack.mjs.map +0 -1
- package/dist/internal/build/source-maps/discover-webpack.d.mts.map +0 -1
- package/dist/internal/build/source-maps/discover-webpack.mjs.map +0 -1
- package/dist/internal/build/source-maps/discover.d.mts.map +0 -1
- package/dist/internal/build/source-maps/discover.mjs.map +0 -1
- package/dist/internal/build/source-maps/index.d.mts.map +0 -1
- package/dist/internal/build/source-maps/index.mjs.map +0 -1
- package/dist/internal/build/source-maps/paths.d.mts.map +0 -1
- package/dist/internal/build/source-maps/paths.mjs.map +0 -1
- package/dist/internal/build/source-maps/upload.d.mts.map +0 -1
- package/dist/internal/build/source-maps/upload.mjs.map +0 -1
- package/dist/internal/build/value-injection-loader.d.mts.map +0 -1
- package/dist/internal/build/value-injection-loader.mjs.map +0 -1
- package/dist/internal/env.d.mts.map +0 -1
- package/dist/internal/env.mjs.map +0 -1
- package/dist/internal/logger.d.mts.map +0 -1
- package/dist/internal/logger.mjs.map +0 -1
- package/dist/internal/release-slug.d.mts.map +0 -1
- package/dist/internal/release-slug.mjs.map +0 -1
- package/dist/internal/route/handle-get.d.mts.map +0 -1
- package/dist/internal/route/handle-get.mjs.map +0 -1
- package/dist/internal/route/handle-post.d.mts.map +0 -1
- package/dist/internal/route/handle-post.mjs.map +0 -1
- package/dist/internal/route/proxy.d.mts.map +0 -1
- package/dist/internal/route/proxy.mjs.map +0 -1
- package/dist/internal/server/capture.d.mts.map +0 -1
- package/dist/internal/server/capture.mjs.map +0 -1
- package/dist/internal/server/console-bridge.d.mts.map +0 -1
- package/dist/internal/server/console-bridge.mjs.map +0 -1
- package/dist/internal/server/id-generator.d.mts.map +0 -1
- package/dist/internal/server/id-generator.mjs.map +0 -1
- package/dist/internal/server/instrumentation-options.d.mts.map +0 -1
- package/dist/internal/server/remote-config.d.mts.map +0 -1
- package/dist/internal/server/remote-config.mjs.map +0 -1
- package/dist/internal/server/trace-meta.d.mts.map +0 -1
- package/dist/internal/server/trace-meta.mjs.map +0 -1
- package/dist/internal/server/traceparent.d.mts.map +0 -1
- package/dist/internal/server/traceparent.mjs.map +0 -1
- package/dist/internal/server/types.d.mts.map +0 -1
- package/dist/internal/setup-warnings.d.mts.map +0 -1
- package/dist/internal/setup-warnings.mjs.map +0 -1
- package/dist/internal/url.d.mts.map +0 -1
- package/dist/internal/url.mjs.map +0 -1
- package/dist/internal/version.d.mts.map +0 -1
- package/dist/internal/version.mjs.map +0 -1
- package/dist/package.mjs.map +0 -1
- package/dist/provider.d.mts.map +0 -1
- package/dist/provider.mjs.map +0 -1
- package/dist/route-handler.d.mts.map +0 -1
- package/dist/route-handler.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.mjs","names":[],"sources":["../../../src/internal/route/proxy.ts"],"sourcesContent":["import { resolveRoutePrefix } from \"@interfere/constants/route-prefix\";\nimport { omitUndefined } from \"@interfere/helpers/omit-undefined\";\nimport { extractCountryHeader } from \"@interfere/types/sdk/geo\";\n\nimport { type InterfereEnv, readInterfereEnv } from \"../env.js\";\nimport { log } from \"../logger.js\";\n\nconst STRIPPED_AUTH_HEADERS = [\n \"authorization\",\n \"x-api-key\",\n \"x-interfere-api-key\",\n] as const;\n\nconst STRIPPED_TRANSPORT_HEADERS = [\n \"host\",\n \"content-length\",\n \"connection\",\n \"keep-alive\",\n \"transfer-encoding\",\n \"te\",\n \"trailer\",\n \"upgrade\",\n \"proxy-authenticate\",\n \"proxy-authorization\",\n] as const;\n\n/**\n * Clone the inbound request's headers, removing entries that should never\n * cross the proxy boundary. Returns a mutable `Headers` so callers can\n * `.set()`/`.delete()` upstream-specific values without having to merge\n * record literals (which lose case-insensitivity and create the precedence\n * footguns that masked the 2026-05-01 incident in code review).\n */\nexport function forwardedHeaders(request: Request): Headers {\n const headers = new Headers(request.headers);\n for (const name of STRIPPED_AUTH_HEADERS) {\n headers.delete(name);\n }\n for (const name of STRIPPED_TRANSPORT_HEADERS) {\n headers.delete(name);\n }\n return headers;\n}\n\nexport interface AuthenticatedEnv {\n apiUrl: string;\n publicKey: string | null;\n release: InterfereEnv[\"release\"];\n}\n\nexport function resolveAuthenticatedEnv(): AuthenticatedEnv {\n const env = readInterfereEnv();\n return {\n apiUrl: env.apiUrl,\n publicKey: env.publicKey,\n release: env.release,\n };\n}\n\n/** True when the proxy can attach a publishable key from env or the request. */\nexport function hasPublicKeyCredential(\n request: Request,\n envPublicKey: string | null\n): boolean {\n if (envPublicKey) {\n return true;\n }\n return new URL(request.url).searchParams.has(\"pk\");\n}\n\nexport function notConfiguredResponse(): Response {\n log.warn(\"Not configured\", [\n \"INTERFERE_PUBLIC_KEY is not set and the request has no ?pk= query param. The proxy route will return 503.\",\n ]);\n return Response.json(\n {\n code: \"INTERFERE_NOT_CONFIGURED\",\n message: \"INTERFERE_PUBLIC_KEY is required.\",\n },\n { status: 503 }\n );\n}\n\nexport function extractSubPath(request: Request): string {\n const prefix = resolveRoutePrefix();\n const url = new URL(request.url);\n const idx = url.pathname.indexOf(prefix);\n if (idx === -1) {\n return \"/\";\n }\n const remainder = url.pathname.slice(idx + prefix.length);\n if (remainder === \"\") {\n return \"/\";\n }\n return remainder.startsWith(\"/\") ? remainder : `/${remainder}`;\n}\n\n/**\n * Preserve any query string verbatim when forwarding upstream.\n *\n * The browser SDK uses `?_pv=…` and `?pk=…` (and `?_pt=…` in direct\n * mode) as a `navigator.sendBeacon` fallback when `visibilitychange→\n * hidden` aborts the keepalive fetch path. The collector's\n * `otlpProducerGuard` and `surfacePkAuth` accept those values verbatim\n * — but only if the proxy actually forwards them. Passing\n * `request.url`'s `search` through (`\"\"` when absent, leading `?`\n * when present) keeps the rewrite transparent.\n */\nexport function extractSearch(request: Request): string {\n return new URL(request.url).search;\n}\n\nexport function formatProxyError(error: unknown): {\n message: string;\n lines: string[];\n} {\n if (!(error instanceof Error)) {\n return { message: String(error), lines: [String(error)] };\n }\n\n const lines = [`${error.name}: ${error.message}`];\n\n if (\"cause\" in error && error.cause) {\n const cause =\n error.cause instanceof Error ? error.cause.message : String(error.cause);\n lines.push(`cause: ${cause}`);\n }\n\n if (\n \"code\" in error &&\n typeof (error as NodeJS.ErrnoException).code === \"string\"\n ) {\n lines.push(`code: ${(error as NodeJS.ErrnoException).code}`);\n }\n\n return { message: `${error.name}: ${error.message}`, lines };\n}\n\n/**\n * Append `?pk=` to the outbound URL from the server env. Proxy mode\n * means the browser never sees `INTERFERE_PUBLIC_KEY` (it's not\n * `NEXT_PUBLIC_`-exposed), so the proxy is the only place the\n * credential can attach to the request. Preserves any existing query\n * params (e.g. `_pv=` debug flag). If the inbound request already\n * carries `?pk=`, that value wins — a misconfigured server-env pk\n * shouldn't clobber an explicit one from the SDK.\n */\nfunction buildUpstreamUrl(\n apiUrl: string,\n subPath: string,\n request: Request,\n publicKey: string | null\n): string {\n const incoming = new URL(request.url);\n const upstream = new URL(`${apiUrl}${subPath}`);\n\n for (const [key, value] of incoming.searchParams) {\n upstream.searchParams.append(key, value);\n }\n\n if (publicKey && !upstream.searchParams.has(\"pk\")) {\n upstream.searchParams.set(\"pk\", publicKey);\n }\n\n return upstream.toString();\n}\n\nexport async function forwardToCollector(\n request: Request,\n env: AuthenticatedEnv,\n subPath: string\n): Promise<Response> {\n const url = buildUpstreamUrl(env.apiUrl, subPath, request, env.publicKey);\n const hasBody = request.method !== \"GET\" && request.method !== \"HEAD\";\n const body = hasBody\n ? new Uint8Array(await request.arrayBuffer())\n : undefined;\n\n const headers = forwardedHeaders(request);\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n const country = extractCountryHeader(request);\n if (country !== null) {\n headers.set(\"x-country-code\", country);\n }\n\n const upstream = await fetch(url, {\n ...omitUndefined({ body }),\n method: request.method,\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!upstream.ok) {\n const text = await upstream.text().catch(() => \"\");\n\n if (upstream.status >= 500) {\n log.error(\n `Upstream ${upstream.status} for ${request.method} ${subPath}`,\n [text]\n );\n return Response.json(\n { code: \"INTERFERE_UPSTREAM_ERROR\", message: text },\n { status: upstream.status }\n );\n }\n if (upstream.status >= 400) {\n log.warn(`Upstream ${upstream.status} for ${request.method} ${subPath}`, [\n text,\n ]);\n return Response.json(\n { code: \"INTERFERE_UPSTREAM_WARNING\", message: text },\n { status: upstream.status }\n );\n }\n\n log.error(`Upstream ${upstream.status} for ${request.method} ${subPath}`, [\n text,\n ]);\n return Response.json(\n { code: \"INTERFERE_UPSTREAM_ERROR\", message: text },\n { status: upstream.status }\n );\n }\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: {\n \"content-type\":\n upstream.headers.get(\"content-type\") ?? \"application/json\",\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.mts","names":[],"sources":["../../../src/internal/server/capture.ts"],"mappings":";;;iBAsGgB,YAAA,CACd,KAAA,WACA,QAAA,YACA,OAAA,GAAU,mBAAmB;AAAA,iBAwBf,cAAA,CACd,KAAA,EAAO,KAAA;EAAU,MAAA;AAAA,GACjB,QAAA,WACA,OAAA,EAAS,qBAAqB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capture.mjs","names":[],"sources":["../../../src/internal/server/capture.ts"],"sourcesContent":["import {\n isNonErrorException,\n MECHANISM_TYPE,\n type NonErrorException,\n toException,\n} from \"@interfere/types/sdk/errors\";\nimport type { ErrorMechanism } from \"@interfere/types/sdk/plugins/payload/errors\";\n\nimport { SpanKind, SpanStatusCode, trace } from \"@opentelemetry/api\";\n\nimport { isEnabledOnServer } from \"../env.js\";\nimport { isPluginEnabled } from \"./remote-config.js\";\nimport type { CaptureErrorContext, OnRequestErrorContext } from \"./types.js\";\n\nconst TRACER_NAME = \"@interfere/next/server\";\n\nconst ON_REQUEST_ERROR_MECHANISM: ErrorMechanism = {\n type: MECHANISM_TYPE.nextjs.onRequestError,\n handled: false,\n synthetic: false,\n};\n\nconst DEFAULT_CAPTURE_ERROR_MECHANISM: ErrorMechanism = {\n type: MECHANISM_TYPE.nextjs.captureError,\n handled: true,\n};\n\nconst seen = new WeakSet<Error>();\n\ninterface RecordExceptionInput {\n context?: CaptureErrorContext | undefined;\n error: unknown;\n mechanism: ErrorMechanism;\n}\n\nfunction buildAttrs(\n value: Error | NonErrorException,\n mechanism: ErrorMechanism,\n context: CaptureErrorContext | undefined\n): Record<string, string> {\n const attrs: Record<string, string> = {\n \"interfere.exception.mechanism\": mechanism.type,\n \"interfere.exception.handled\": String(mechanism.handled),\n };\n const digest = context?.nextjs?.errorDigest;\n if (digest) {\n attrs[\"interfere.error.digest\"] = digest;\n }\n if (context?.nextjs?.requestMethod) {\n attrs[\"http.request.method\"] = context.nextjs.requestMethod;\n }\n if (context?.nextjs?.requestPath) {\n attrs[\"url.path\"] = context.nextjs.requestPath;\n }\n if (isNonErrorException(value)) {\n attrs[\"exception.type\"] = value.type;\n attrs[\"exception.message\"] = value.value;\n attrs[\"interfere.exception.kind\"] = \"non-error\";\n return attrs;\n }\n attrs[\"exception.type\"] = value.name;\n attrs[\"exception.message\"] = value.message;\n if (value.stack) {\n attrs[\"exception.stacktrace\"] = value.stack;\n }\n return attrs;\n}\n\nfunction recordException({\n error,\n mechanism,\n context,\n}: RecordExceptionInput): void {\n const value = toException(error);\n const attrs = buildAttrs(value, mechanism, context);\n\n const tracer = trace.getTracer(TRACER_NAME);\n const active = trace.getActiveSpan();\n if (active) {\n active.addEvent(\"exception\", attrs);\n if (!mechanism.handled) {\n active.setStatus({\n code: SpanStatusCode.ERROR,\n message: isNonErrorException(value) ? value.value : value.message,\n });\n }\n return;\n }\n\n const span = tracer.startSpan(\"interfere.captureError\", {\n kind: SpanKind.INTERNAL,\n });\n span.addEvent(\"exception\", attrs);\n if (!mechanism.handled) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: isNonErrorException(value) ? value.value : value.message,\n });\n }\n span.end();\n}\n\nexport function captureError(\n error: unknown,\n _request?: unknown,\n context?: CaptureErrorContext\n): void {\n if (!isEnabledOnServer()) {\n return;\n }\n\n if (!isPluginEnabled(\"errors\")) {\n return;\n }\n\n if (error instanceof Error) {\n if (seen.has(error)) {\n return;\n }\n seen.add(error);\n }\n\n recordException({\n error,\n mechanism: context?.mechanism ?? DEFAULT_CAPTURE_ERROR_MECHANISM,\n context,\n });\n}\n\nexport function onRequestError(\n error: Error & { digest?: string },\n _request: unknown,\n context: OnRequestErrorContext\n): void {\n if (seen.has(error)) {\n return;\n }\n seen.add(error);\n\n if (!isEnabledOnServer()) {\n return;\n }\n if (!isPluginEnabled(\"errors\")) {\n return;\n }\n\n recordException({\n error,\n mechanism: ON_REQUEST_ERROR_MECHANISM,\n context: {\n mechanism: ON_REQUEST_ERROR_MECHANISM,\n nextjs: {\n ...context,\n ...(error.digest ? { errorDigest: error.digest } : {}),\n },\n },\n });\n}\n"],"mappings":"iPAcA,MAEM,2BAA6C,CACjD,KAAM,eAAe,OAAO,eAC5B,QAAS,GACT,UAAW,EACb,EAEM,gCAAkD,CACtD,KAAM,eAAe,OAAO,aAC5B,QAAS,EACX,EAEM,KAAO,IAAI,QAQjB,SAAS,WACP,MACA,UACA,QACwB,CACxB,IAAM,MAAgC,CACpC,gCAAiC,UAAU,KAC3C,8BAA+B,OAAO,UAAU,OAAO,CACzD,EACM,OAAS,SAAS,QAAQ,YAqBhC,OApBI,SACF,MAAM,0BAA4B,QAEhC,SAAS,QAAQ,gBACnB,MAAM,uBAAyB,QAAQ,OAAO,eAE5C,SAAS,QAAQ,cACnB,MAAM,YAAc,QAAQ,OAAO,aAEjC,oBAAoB,KAAK,GAC3B,MAAM,kBAAoB,MAAM,KAChC,MAAM,qBAAuB,MAAM,MACnC,MAAM,4BAA8B,YAC7B,QAET,MAAM,kBAAoB,MAAM,KAChC,MAAM,qBAAuB,MAAM,QAC/B,MAAM,QACR,MAAM,wBAA0B,MAAM,OAEjC,MACT,CAEA,SAAS,gBAAgB,CACvB,MACA,UACA,SAC6B,CAC7B,IAAM,MAAQ,YAAY,KAAK,EACzB,MAAQ,WAAW,MAAO,UAAW,OAAO,EAE5C,OAAS,MAAM,UAAU,wBAAW,EACpC,OAAS,MAAM,cAAc,EACnC,GAAI,OAAQ,CACV,OAAO,SAAS,YAAa,KAAK,EAC7B,UAAU,SACb,OAAO,UAAU,CACf,KAAM,eAAe,MACrB,QAAS,oBAAoB,KAAK,EAAI,MAAM,MAAQ,MAAM,OAC5D,CAAC,EAEH,MACF,CAEA,IAAM,KAAO,OAAO,UAAU,yBAA0B,CACtD,KAAM,SAAS,QACjB,CAAC,EACD,KAAK,SAAS,YAAa,KAAK,EAC3B,UAAU,SACb,KAAK,UAAU,CACb,KAAM,eAAe,MACrB,QAAS,oBAAoB,KAAK,EAAI,MAAM,MAAQ,MAAM,OAC5D,CAAC,EAEH,KAAK,IAAI,CACX,CAEA,SAAgB,aACd,MACA,SACA,QACM,CACD,qBAAkB,GAIlB,gBAAgB,QAAQ,EAI7B,IAAI,iBAAiB,MAAO,CAC1B,GAAI,KAAK,IAAI,KAAK,EAChB,OAEF,KAAK,IAAI,KAAK,CAChB,CAEA,gBAAgB,CACd,MACA,UAAW,SAAS,WAAa,gCACjC,OACF,CAAC,CAND,CAOF,CAEA,SAAgB,eACd,MACA,SACA,QACM,CACF,KAAK,IAAI,KAAK,IAGlB,KAAK,IAAI,KAAK,EAET,kBAAkB,GAGlB,gBAAgB,QAAQ,GAI7B,gBAAgB,CACd,MACA,UAAW,2BACX,QAAS,CACP,UAAW,2BACX,OAAQ,CACN,GAAG,QACH,GAAI,MAAM,OAAS,CAAE,YAAa,MAAM,MAAO,EAAI,CAAC,CACtD,CACF,CACF,CAAC,EACH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"console-bridge.d.mts","names":[],"sources":["../../../src/internal/server/console-bridge.ts"],"mappings":";;AAgFA;;;;AAAmC;;;;;;;;;;iBAAnB,mBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"console-bridge.mjs","names":[],"sources":["../../../src/internal/server/console-bridge.ts"],"sourcesContent":["import { context, trace } from \"@opentelemetry/api\";\nimport { logs, type SeverityNumber } from \"@opentelemetry/api-logs\";\n\nconst ATTR_EXCEPTION_TYPE = \"exception.type\" as const;\nconst ATTR_EXCEPTION_MESSAGE = \"exception.message\" as const;\nconst ATTR_EXCEPTION_STACKTRACE = \"exception.stacktrace\" as const;\n\nconst CONSOLE_METHODS = [\"debug\", \"log\", \"info\", \"warn\", \"error\"] as const;\ntype ConsoleMethod = (typeof CONSOLE_METHODS)[number];\n\nconst SEVERITY: Record<ConsoleMethod, SeverityNumber> = {\n debug: 5,\n log: 9,\n info: 9,\n warn: 13,\n error: 17,\n};\n\n/**\n * Bound at first failure log; subsequent failures only re-log every Nth\n * occurrence so a misconfigured logger backend doesn't itself spam the\n * console with bridge errors at line rate.\n */\nconst BRIDGE_FAILURE_LOG_INTERVAL = 100;\n\nfunction stringify(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof Error) {\n return value.stack ?? `${value.name}: ${value.message}`;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction extractException(args: unknown[]): Error | undefined {\n for (const arg of args) {\n if (arg instanceof Error) {\n return arg;\n }\n }\n return;\n}\n\nfunction buildExceptionAttributes(\n args: unknown[]\n): Record<string, string> | undefined {\n const exception = extractException(args);\n if (!exception) {\n return;\n }\n const attrs: Record<string, string> = {\n [ATTR_EXCEPTION_TYPE]: exception.name,\n [ATTR_EXCEPTION_MESSAGE]: exception.message,\n };\n if (exception.stack) {\n attrs[ATTR_EXCEPTION_STACKTRACE] = exception.stack;\n }\n return attrs;\n}\n\n/**\n * Patches `console.{debug,log,info,warn,error}` to additionally emit OTel\n * `LogRecord`s alongside the original output. Every log record carries\n * the active span's context (so trace ↔ log correlation works in\n * dashboards) and any `Error` arg gets unpacked into semconv exception\n * attrs.\n *\n * Returns a disposer that restores the original `console.*` methods.\n *\n * Cycle protection: `emitting` guards against the bridge re-entering\n * itself if a logger backend itself logs to console (which would\n * recursively emit forever). Failures are bounded-rate logged via the\n * original `console.error` so a broken backend doesn't drown the\n * customer's logs in bridge-failure messages.\n */\nexport function bridgeConsoleToOtel(): () => void {\n const logger = logs.getLogger(\"@interfere/next/console\");\n let emitting = false;\n let bridgeFailures = 0;\n\n const original: Record<ConsoleMethod, (...args: unknown[]) => void> = {\n debug: console.debug,\n log: console.log,\n info: console.info,\n warn: console.warn,\n error: console.error,\n };\n\n function emitLog(\n orig: (...args: unknown[]) => void,\n severity: SeverityNumber,\n method: ConsoleMethod,\n body: string,\n activeContext: ReturnType<typeof context.active>,\n activeSpan: ReturnType<typeof trace.getSpan>,\n attributes: Record<string, string> | undefined\n ): void {\n if (emitting) {\n return;\n }\n emitting = true;\n try {\n logger.emit({\n severityNumber: severity,\n severityText: method.toUpperCase(),\n body,\n ...(activeSpan ? { context: activeContext } : {}),\n ...(attributes ? { attributes } : {}),\n });\n } catch (error) {\n bridgeFailures++;\n if (bridgeFailures % BRIDGE_FAILURE_LOG_INTERVAL === 1) {\n orig.call(\n console,\n `[interfere] console→OTel bridge emission failed (${bridgeFailures} total):`,\n error\n );\n }\n } finally {\n emitting = false;\n }\n }\n\n for (const method of CONSOLE_METHODS) {\n const orig = original[method];\n const severity = SEVERITY[method];\n console[method] = (...args: unknown[]) => {\n orig.apply(console, args);\n\n const body = args.map(stringify).join(\" \");\n const activeContext = context.active();\n const activeSpan = trace.getSpan(activeContext);\n const attributes = buildExceptionAttributes(args);\n\n queueMicrotask(() => {\n emitLog(\n orig,\n severity,\n method,\n body,\n activeContext,\n activeSpan,\n attributes\n );\n });\n };\n }\n\n return () => {\n for (const method of CONSOLE_METHODS) {\n console[method] = original[method];\n }\n };\n}\n"],"mappings":"wFAGA,MAIM,gBAAkB,CAAC,QAAS,MAAO,OAAQ,OAAQ,OAAO,EAG1D,SAAkD,CACtD,MAAO,EACP,IAAK,EACL,KAAM,EACN,KAAM,GACN,MAAO,EACT,EASA,SAAS,UAAU,MAAwB,CACzC,GAAI,OAAO,OAAU,SACnB,OAAO,MAET,GAAI,iBAAiB,MACnB,OAAO,MAAM,OAAS,GAAG,MAAM,KAAK,IAAI,MAAM,UAEhD,GAAI,CACF,OAAO,KAAK,UAAU,KAAK,CAC7B,MAAQ,CACN,OAAO,OAAO,KAAK,CACrB,CACF,CAEA,SAAS,iBAAiB,KAAoC,CAC5D,IAAK,IAAM,OAAO,KAChB,GAAI,eAAe,MACjB,OAAO,GAIb,CAEA,SAAS,yBACP,KACoC,CACpC,IAAM,UAAY,iBAAiB,IAAI,EACvC,GAAI,CAAC,UACH,OAEF,IAAM,MAAgC,CACnC,iBAAsB,UAAU,KAChC,oBAAyB,UAAU,OACtC,EAIA,OAHI,UAAU,QACZ,MAAM,wBAA6B,UAAU,OAExC,KACT,CAiBA,SAAgB,qBAAkC,CAChD,IAAM,OAAS,KAAK,UAAU,yBAAyB,EACnD,SAAW,GACX,eAAiB,EAEf,SAAgE,CACpE,MAAO,QAAQ,MACf,IAAK,QAAQ,IACb,KAAM,QAAQ,KACd,KAAM,QAAQ,KACd,MAAO,QAAQ,KACjB,EAEA,SAAS,QACP,KACA,SACA,OACA,KACA,cACA,WACA,WACM,CACF,aAGJ,UAAW,GACX,GAAI,CACF,OAAO,KAAK,CACV,eAAgB,SAChB,aAAc,OAAO,YAAY,EACjC,KACA,GAAI,WAAa,CAAE,QAAS,aAAc,EAAI,CAAC,EAC/C,GAAI,WAAa,CAAE,UAAW,EAAI,CAAC,CACrC,CAAC,CACH,OAAS,MAAO,CACd,iBACI,eAAiB,KAAgC,GACnD,KAAK,KACH,QACA,oDAAoD,eAAe,UACnE,KACF,CAEJ,QAAU,CACR,SAAW,EACb,CApBW,CAqBb,CAEA,IAAK,IAAM,UAAU,gBAAiB,CACpC,IAAM,KAAO,SAAS,QAChB,SAAW,SAAS,QAC1B,QAAQ,SAAW,GAAG,OAAoB,CACxC,KAAK,MAAM,QAAS,IAAI,EAExB,IAAM,KAAO,KAAK,IAAI,SAAS,EAAE,KAAK,GAAG,EACnC,cAAgB,QAAQ,OAAO,EAC/B,WAAa,MAAM,QAAQ,aAAa,EACxC,WAAa,yBAAyB,IAAI,EAEhD,mBAAqB,CACnB,QACE,KACA,SACA,OACA,KACA,cACA,WACA,UACF,CACF,CAAC,CACH,CACF,CAEA,UAAa,CACX,IAAK,IAAM,UAAU,gBACnB,QAAQ,QAAU,SAAS,OAE/B,CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"id-generator.d.mts","names":[],"sources":["../../../src/internal/server/id-generator.ts"],"mappings":";;;;;AAoCA;;;;;;;;;;;;;;;;AAuCwB;;;cAvCX,wBAAA,YAAoC,WAAW;EAAA,iBACzC,MAAA;EAAA,iBACA,WAAA;EAAA,iBACA,UAAA;EAAA,QACT,YAAA;EAAA,QACA,WAAA;;EAUR,eAAA;EAQA,cAAA;EAAA,QAQQ,eAAA;EAAA,QAQA,cAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"id-generator.mjs","names":[],"sources":["../../../src/internal/server/id-generator.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport {\n type IdGenerator,\n RandomIdGenerator,\n} from \"@opentelemetry/sdk-trace-base\";\n\nconst TRACE_ID_HEX_LEN = 32;\nconst SPAN_ID_HEX_LEN = 16;\nconst TRACE_PREFIX_HEX_LEN = 24;\nconst SPAN_PREFIX_HEX_LEN = 12;\nconst TRACE_COUNTER_HEX_LEN = TRACE_ID_HEX_LEN - TRACE_PREFIX_HEX_LEN;\nconst SPAN_COUNTER_HEX_LEN = SPAN_ID_HEX_LEN - SPAN_PREFIX_HEX_LEN;\nconst TRACE_COUNTER_MODULUS = 2 ** (TRACE_COUNTER_HEX_LEN * 4);\nconst SPAN_COUNTER_MODULUS = 2 ** (SPAN_COUNTER_HEX_LEN * 4);\n\n/**\n * IdGenerator hybrid that uses OTel's default `RandomIdGenerator` whenever\n * available and falls back to a counter-based generator inside Next 16's\n * prerender contexts.\n *\n * Why: Next 16's prerender extension throws synchronously on any\n * `Math.random()` / `crypto.getRandomValues()` call inside a Server\n * Component that hasn't first awaited Request data\n * (`next-prerender-random` / `next-prerender-crypto`). OTel's default\n * generator hits `Math.random()` on every span creation, so spans Next\n * opens around prerendered route renders blow up the build.\n *\n * The hybrid path keeps full 128-bit trace IDs / 64-bit span IDs for the\n * common case (SSR, runtime requests, fluid-compute invocations) and only\n * degrades inside prerender — where the alternative is build failure.\n *\n * Inside prerender, IDs are minted from a per-process random prefix\n * (seeded once at construction time, outside any prerender ALS frame) plus\n * a monotonic counter. Counter widths are masked to keep IDs at their\n * spec-mandated lengths even after wrap.\n */\nexport class PrerenderSafeIdGenerator implements IdGenerator {\n private readonly random = new RandomIdGenerator();\n private readonly tracePrefix: string;\n private readonly spanPrefix: string;\n private traceCounter = 0;\n private spanCounter = 0;\n\n constructor() {\n const seed = randomBytes((TRACE_PREFIX_HEX_LEN + SPAN_PREFIX_HEX_LEN) / 2);\n this.tracePrefix = seed\n .subarray(0, TRACE_PREFIX_HEX_LEN / 2)\n .toString(\"hex\");\n this.spanPrefix = seed.subarray(TRACE_PREFIX_HEX_LEN / 2).toString(\"hex\");\n }\n\n generateTraceId(): string {\n try {\n return this.random.generateTraceId();\n } catch {\n return this.fallbackTraceId();\n }\n }\n\n generateSpanId(): string {\n try {\n return this.random.generateSpanId();\n } catch {\n return this.fallbackSpanId();\n }\n }\n\n private fallbackTraceId(): string {\n this.traceCounter = (this.traceCounter + 1) % TRACE_COUNTER_MODULUS;\n return (\n this.tracePrefix +\n this.traceCounter.toString(16).padStart(TRACE_COUNTER_HEX_LEN, \"0\")\n );\n }\n\n private fallbackSpanId(): string {\n this.spanCounter = (this.spanCounter + 1) % SPAN_COUNTER_MODULUS;\n return (\n this.spanPrefix +\n this.spanCounter.toString(16).padStart(SPAN_COUNTER_HEX_LEN, \"0\")\n );\n }\n}\n"],"mappings":"kGAMA,MAMM,sBAAwB,GAAM,GAC9B,qBAAuB,GAAM,GAuBnC,IAAa,yBAAb,KAA6D,CAC3D,OAA0B,IAAI,kBAC9B,YACA,WACA,aAAuB,EACvB,YAAsB,EAEtB,aAAc,CACZ,IAAM,KAAO,YAAa,GAA8C,CAAC,EACzE,KAAK,YAAc,KAChB,SAAS,EAAG,GAAuB,CAAC,EACpC,SAAS,KAAK,EACjB,KAAK,WAAa,KAAK,SAAS,GAAuB,CAAC,EAAE,SAAS,KAAK,CAC1E,CAEA,iBAA0B,CACxB,GAAI,CACF,OAAO,KAAK,OAAO,gBAAgB,CACrC,MAAQ,CACN,OAAO,KAAK,gBAAgB,CAC9B,CACF,CAEA,gBAAyB,CACvB,GAAI,CACF,OAAO,KAAK,OAAO,eAAe,CACpC,MAAQ,CACN,OAAO,KAAK,eAAe,CAC7B,CACF,CAEA,iBAAkC,CAEhC,MADA,MAAK,cAAgB,KAAK,aAAe,GAAK,sBAE5C,KAAK,YACL,KAAK,aAAa,SAAS,EAAE,EAAE,SAAS,EAAuB,GAAG,CAEtE,CAEA,gBAAiC,CAE/B,MADA,MAAK,aAAe,KAAK,YAAc,GAAK,qBAE1C,KAAK,WACL,KAAK,YAAY,SAAS,EAAE,EAAE,SAAS,EAAsB,GAAG,CAEpE,CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation-options.d.mts","names":[],"sources":["../../../src/internal/server/instrumentation-options.ts"],"mappings":";;;;;;;AAyBA;;;;;;;;;;;;;;;;;;;UAAiB,4BAAA;EAmDkB;;;AAKtB;;;;;;EA9CX,sCAAA,GAAyC,kBAAA;;;;;;;;;;;;EAYzC,gCAAA,GAAmC,YAAA;;;;;;;EAOnC,iCAAA,GAAoC,aAAA;;;;;;;EAOpC,aAAA;;;;;;;EAOA,UAAA,aAAuB,MAAA;;;;;;;;EAQvB,oBAAA,aAAiC,MAAA;;;;;EAKjC,WAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"remote-config.d.mts","names":[],"sources":["../../../src/internal/server/remote-config.ts"],"mappings":";iBAWsB,yBAAA,IAA6B,OAAO;AAAA,iBAoC1C,eAAA,CAAgB,MAAc"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"remote-config.mjs","names":[],"sources":["../../../src/internal/server/remote-config.ts"],"sourcesContent":["import { API_PATHS } from \"@interfere/constants/api\";\nimport type {\n RemoteConfig,\n RemotePluginConfig,\n} from \"@interfere/types/sdk/remote-config\";\n\nimport { isEnabledOnServer, readInterfereEnv } from \"../env.js\";\nimport { withPublicKey } from \"../url.js\";\n\nlet cachedConfig: RemotePluginConfig | null = null;\n\nexport async function fetchAndCacheRemoteConfig(): Promise<void> {\n if (!isEnabledOnServer()) {\n return;\n }\n\n const env = readInterfereEnv();\n if (env.publicKey === null) {\n return;\n }\n\n try {\n const url = withPublicKey(\n `${env.apiUrl}${API_PATHS.CONFIG}`,\n env.publicKey\n );\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"content-type\": \"application/json\",\n },\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n return;\n }\n\n const config = (await response.json()) as RemoteConfig;\n if (config?.plugins) {\n cachedConfig = config.plugins;\n }\n } catch {\n return;\n }\n}\n\nexport function isPluginEnabled(plugin: string): boolean {\n if (!cachedConfig) {\n return true;\n }\n return cachedConfig[plugin as keyof RemotePluginConfig] !== false;\n}\n"],"mappings":"iJASA,IAAI,aAA0C,KAE9C,eAAsB,2BAA2C,CAC/D,GAAI,CAAC,kBAAkB,EACrB,OAGF,IAAM,IAAM,iBAAiB,EACzB,OAAI,YAAc,KAItB,GAAI,CACF,IAAM,IAAM,cACV,GAAG,IAAI,SAAS,UAAU,SAC1B,IAAI,SACN,EACM,SAAW,MAAM,MAAM,IAAK,CAChC,OAAQ,MACR,QAAS,CACP,eAAgB,kBAClB,EACA,OAAQ,YAAY,QAAQ,GAAM,CACpC,CAAC,EAED,GAAI,CAAC,SAAS,GACZ,OAGF,IAAM,OAAU,MAAM,SAAS,KAAK,EAChC,QAAQ,UACV,aAAe,OAAO,QAE1B,MAAQ,CACN,MACF,CACF,CAEA,SAAgB,gBAAgB,OAAyB,CAIvD,OAHK,aAGE,aAAa,UAAwC,GAFnD,EAGX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trace-meta.d.mts","names":[],"sources":["../../../src/internal/server/trace-meta.tsx"],"mappings":";;AA8BA;;;;AAAyB;;;;;;;;;;;;;;;;;;;;;;;iBAAT,SAAA,gCAAS,GAAA,CAAA,OAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trace-meta.mjs","names":[],"sources":["../../../src/internal/server/trace-meta.tsx"],"sourcesContent":["import { activeTraceparent } from \"./traceparent.js\";\n\n/**\n * Server Component that emits a `<meta name=\"traceparent\">` tag so the\n * client SDK can stitch every browser span onto the server-side trace.\n *\n * Customer usage — drop into the root layout's `<head>`:\n *\n * ```tsx\n * import { TraceMeta } from \"@interfere/next/server\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <head>\n * <TraceMeta />\n * </head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n * ```\n *\n * Renders nothing when no OTel span is active (dev without OTel\n * registered, edge runtime where `@interfere/next/instrumentation`'s\n * async `register()` hasn't completed before the layout renders, or\n * unsampled traces). The client SDK's propagation reader handles a\n * missing meta tag the same as no parent — every browser span starts a\n * fresh root, which is at least internally consistent.\n */\nexport function TraceMeta() {\n const traceparent = activeTraceparent();\n if (!traceparent) {\n return null;\n }\n return <meta content={traceparent} name=\"traceparent\" />;\n}\n"],"mappings":"oFA8BA,SAAgB,WAAY,CAC1B,IAAM,YAAc,kBAAkB,EAItC,OAHK,YAGE,IAAC,OAAD,CAAM,QAAS,YAAa,KAAK,aAAe,CAAA,EAF9C,IAGX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"traceparent.d.mts","names":[],"sources":["../../../src/internal/server/traceparent.ts"],"mappings":";;AAiBA;;;;AAAiC;;;;;;;iBAAjB,iBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"traceparent.mjs","names":[],"sources":["../../../src/internal/server/traceparent.ts"],"sourcesContent":["import { TraceFlags, trace } from \"@opentelemetry/api\";\n\nconst SAMPLED_BIT = TraceFlags.SAMPLED;\nconst W3C_TRACECONTEXT_VERSION = \"00\";\n\n/**\n * Build a W3C `traceparent` string from the currently-active OTel\n * span, or `null` if no span is active or the trace is not sampled.\n *\n * Server-side counterpart to the client SDK's\n * `internal/otel/propagation.ts`: both ends of the wire filter\n * unsampled traces. The browser doesn't honor the `sampled` bit when\n * creating child spans, so propagating an unsampled trace_id from the\n * server would orphan every browser span under a trace with no\n * recorded server segments. Returning null lets the browser fall back\n * to its own root, which is at least internally consistent.\n */\nexport function activeTraceparent(): string | null {\n const span = trace.getActiveSpan();\n if (!span) {\n return null;\n }\n const ctx = span.spanContext();\n // biome-ignore lint/suspicious/noBitwiseOperators: W3C trace_flags is a bitmask; SAMPLED (0x01) must be tested independently of any future reserved flags.\n if ((ctx.traceFlags & SAMPLED_BIT) !== SAMPLED_BIT) {\n return null;\n }\n const flags = ctx.traceFlags.toString(16).padStart(2, \"0\");\n return `${W3C_TRACECONTEXT_VERSION}-${ctx.traceId}-${ctx.spanId}-${flags}`;\n}\n"],"mappings":"iDAEA,MAAM,YAAc,WAAW,QAe/B,SAAgB,mBAAmC,CACjD,IAAM,KAAO,MAAM,cAAc,EACjC,GAAI,CAAC,KACH,OAAO,KAET,IAAM,IAAM,KAAK,YAAY,EAE7B,IAAK,IAAI,WAAa,eAAiB,YACrC,OAAO,KAET,IAAM,MAAQ,IAAI,WAAW,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EACzD,MAAO,MAA+B,IAAI,QAAQ,GAAG,IAAI,OAAO,GAAG,OACrE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/internal/server/types.ts"],"mappings":";;;;KAGY,qBAAA,GAAwB,IAAI,CACtC,aAAA;AAAA,UAIe,mBAAA;EAAA,SACN,SAAA,GAAY,cAAA;EAAA,SACZ,MAAA,GAAS,IAAA,CAAK,aAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup-warnings.d.mts","names":[],"sources":["../../src/internal/setup-warnings.ts"],"mappings":";;AA8BA;;;;AAAqE;AAerE;iBAfgB,kCAAA,CAAmC,UAAkB;;;AAed;;;iBAAvC,oBAAA,CAAqB,UAAkB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup-warnings.mjs","names":[],"sources":["../../src/internal/setup-warnings.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { resolve } from \"node:path\";\n\nimport { log } from \"./logger.js\";\n\nconst SERVER_INSTRUMENTATION_FILES = [\n \"instrumentation.ts\",\n \"instrumentation.tsx\",\n \"instrumentation.js\",\n \"instrumentation.jsx\",\n \"src/instrumentation.ts\",\n \"src/instrumentation.tsx\",\n \"src/instrumentation.js\",\n \"src/instrumentation.jsx\",\n] as const;\n\nfunction hasServerInstrumentation(projectDir: string): boolean {\n return SERVER_INSTRUMENTATION_FILES.some((c) =>\n existsSync(resolve(projectDir, c))\n );\n}\n\n/**\n * Best-effort warning when the customer set `INTERFERE_PUBLIC_KEY` but never\n * created `instrumentation.ts`. Server-side tracing then silently does\n * nothing — that's surprising and there's no other place we get to tell\n * them. Never blocks the build: some customers genuinely don't want\n * server-side tracing.\n */\nexport function warnIfServerInstrumentationMissing(projectDir: string): void {\n if (hasServerInstrumentation(projectDir)) {\n return;\n }\n log.warn(\"No instrumentation.ts found\", [\n \"Server-side traces will be skipped. To enable, create instrumentation.ts at the project root with:\",\n \" export { register } from '@interfere/next/instrumentation';\",\n ]);\n}\n\n/**\n * Reads the customer's installed `next` package version. Returns `null` if\n * Next isn't resolvable from `projectDir` (e.g. running outside a Next app),\n * in which case callers should skip version-conditional behaviour.\n */\nexport function readNextMajorVersion(projectDir: string): number | null {\n try {\n const require = createRequire(`${projectDir}/_`);\n const pkg = require(\"next/package.json\") as { version?: string };\n const major = Number.parseInt(pkg.version?.split(\".\")[0] ?? \"\", 10);\n return Number.isFinite(major) ? major : null;\n } catch {\n return null;\n }\n}\n"],"mappings":"oIAMA,MAAM,6BAA+B,CACnC,qBACA,sBACA,qBACA,sBACA,yBACA,0BACA,yBACA,yBACF,EAEA,SAAS,yBAAyB,WAA6B,CAC7D,OAAO,6BAA6B,KAAM,GACxC,WAAW,QAAQ,WAAY,CAAC,CAAC,CACnC,CACF,CASA,SAAgB,mCAAmC,WAA0B,CACvE,yBAAyB,UAAU,GAGvC,IAAI,KAAK,8BAA+B,CACtC,qGACA,+DACF,CAAC,CACH,CAOA,SAAgB,qBAAqB,WAAmC,CACtE,GAAI,CAEF,IAAM,IADU,cAAc,GAAG,WAAW,GAC1B,EAAE,mBAAmB,EACjC,MAAQ,OAAO,SAAS,IAAI,SAAS,MAAM,GAAG,EAAE,IAAM,GAAI,EAAE,EAClE,OAAO,OAAO,SAAS,KAAK,EAAI,MAAQ,IAC1C,MAAQ,CACN,OAAO,IACT,CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.mts","names":[],"sources":["../../src/internal/url.ts"],"mappings":";iBAEgB,aAAA,CAAc,GAAA,UAAa,SAAiB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"url.mjs","names":[],"sources":["../../src/internal/url.ts"],"sourcesContent":["const PUBLIC_KEY_QUERY = \"pk\";\n\nexport function withPublicKey(url: string, publicKey: string): string {\n const next = new URL(url);\n next.searchParams.set(PUBLIC_KEY_QUERY, publicKey);\n return next.toString();\n}\n"],"mappings":"AAEA,SAAgB,cAAc,IAAa,UAA2B,CACpE,IAAM,KAAO,IAAI,IAAI,GAAG,EAExB,OADA,KAAK,aAAa,IAAI,KAAkB,SAAS,EAC1C,KAAK,SAAS,CACvB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.mts","names":[],"sources":["../../src/internal/version.ts"],"mappings":";cAEa,gBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.mjs","names":["pkg.name","pkg.version"],"sources":["../../src/internal/version.ts"],"sourcesContent":["import pkg from \"../../package.json\" with { type: \"json\" };\n\nexport const PRODUCER_VERSION = `${pkg.name}@${pkg.version}`;\n"],"mappings":"yCAEA,MAAa,iBAAmB,GAAGA,KAAS,GAAGC"}
|
package/dist/package.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package.mjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
|
package/dist/provider.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.mts","names":[],"sources":["../src/provider.tsx"],"mappings":";;;;;UAeU,sBAAA,SAA+B,iBAAiB;EACxD,OAAA,GAAU,cAAA;EACV,aAAA;AAAA;;;;;;;;;iBAWc,iBAAA;EACd,QAAA;EACA,OAAA;EACA;AAAA,GACC,sBAAA,GAAyB,SAAA"}
|
package/dist/provider.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider.mjs","names":["CoreInterfereProvider"],"sources":["../src/provider.tsx"],"sourcesContent":["\"use client\";\n\nimport { InterfereProvider as CoreInterfereProvider } from \"@interfere/react/provider\";\nimport type { ConsentState } from \"@interfere/types/sdk/plugins/manifest\";\n\nimport {\n type PropsWithChildren,\n type ReactNode,\n useSyncExternalStore,\n} from \"react\";\n\nimport { getKernelOrNull, subscribeToKernel } from \"./instrument-client.js\";\n\nconst nullSnapshot = () => null;\n\ninterface InterfereProviderProps extends PropsWithChildren {\n consent?: ConsentState | undefined;\n errorBoundary?: boolean;\n}\n\n/**\n * Next.js wrapper around `@interfere/react`'s provider that resolves the\n * kernel from module scope (set by the matching `init()` call). Customer\n * code never passes the kernel explicitly. Uses `getKernelOrNull()` so the\n * provider is safe to render during SSR/SSG when `init()` hasn't run\n * (`init()` is client-only); the core provider mounts with null-safe\n * accessors and switches to the real kernel on client hydration.\n */\nexport function InterfereProvider({\n children,\n consent,\n errorBoundary,\n}: InterfereProviderProps): ReactNode {\n const kernel = useSyncExternalStore(\n subscribeToKernel,\n getKernelOrNull,\n nullSnapshot\n );\n return (\n <CoreInterfereProvider\n kernel={kernel}\n {...(consent === undefined ? {} : { consent })}\n {...(errorBoundary === undefined ? {} : { errorBoundary })}\n >\n {children}\n </CoreInterfereProvider>\n );\n}\n\n// biome-ignore lint/performance/noBarrelFile: Next.js provider entrypoint re-exports the React SDK hooks for one-line customer setup.\nexport { useInterfere, useSession } from \"@interfere/react/provider\";\nexport type {\n ConsentCategory,\n ConsentState,\n GateableCategory,\n} from \"@interfere/types/sdk/plugins/manifest\";\n"],"mappings":"uQAaA,MAAM,iBAAqB,KAe3B,SAAgB,kBAAkB,CAChC,SACA,QACA,eACoC,CAMpC,OACE,IAACA,oBAAD,CACE,OAPW,qBACb,kBACA,gBACA,YAIe,EACb,GAAK,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAC5C,GAAK,gBAAkB,IAAA,GAAY,CAAC,EAAI,CAAE,aAAc,EAEvD,QACoB,CAAA,CAE3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"route-handler.d.mts","names":[],"sources":["../src/route-handler.ts"],"mappings":";;AAaA;;;;;iBAAsB,GAAA,CAAI,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA;AAAA,iBAOrC,IAAA,CAAK,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA;AAAA,iBAchC,OAAA,IAAW,QAAQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"route-handler.mjs","names":[],"sources":["../src/route-handler.ts"],"sourcesContent":["/**\n * Customers consume this module via `export * from \"@interfere/next/route-handler\"`\n * so any HTTP method we add later (PATCH, DELETE, …) is picked up\n * without a customer file change. Do NOT add non-method exports here —\n * `route-handler.lint.test.ts` will fail the build if you do.\n */\n\nimport { isEnabledOnServer } from \"./internal/env.js\";\nimport { handleGet } from \"./internal/route/handle-get.js\";\nimport { handlePost } from \"./internal/route/handle-post.js\";\n\nconst DISABLED = () => new Response(null, { status: 204 });\n\nexport async function GET(request: Request): Promise<Response> {\n if (!isEnabledOnServer()) {\n return DISABLED();\n }\n return await handleGet(request);\n}\n\nexport function POST(request: Request): Promise<Response> {\n if (!isEnabledOnServer()) {\n return Promise.resolve(DISABLED());\n }\n return handlePost(request);\n}\n\nconst CORS_HEADERS = {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n \"Access-Control-Max-Age\": \"86400\",\n};\n\nexport function OPTIONS(): Response {\n return new Response(null, { status: 200, headers: CORS_HEADERS });\n}\n"],"mappings":"kKAWA,MAAM,aAAiB,IAAI,SAAS,KAAM,CAAE,OAAQ,GAAI,CAAC,EAEzD,eAAsB,IAAI,QAAqC,CAI7D,OAHK,kBAAkB,EAGhB,MAAM,UAAU,OAAO,EAFrB,SAAS,CAGpB,CAEA,SAAgB,KAAK,QAAqC,CAIxD,OAHK,kBAAkB,EAGhB,WAAW,OAAO,EAFhB,QAAQ,QAAQ,SAAS,CAAC,CAGrC,CAEA,MAAM,aAAe,CACnB,8BAA+B,IAC/B,+BAAgC,qBAChC,+BAAgC,eAChC,yBAA0B,OAC5B,EAEA,SAAgB,SAAoB,CAClC,OAAO,IAAI,SAAS,KAAM,CAAE,OAAQ,IAAK,QAAS,YAAa,CAAC,CAClE"}
|