@interfere/next 10.0.0 → 10.0.1-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +6 -1
  2. package/dist/config.d.mts +1 -0
  3. package/dist/config.d.mts.map +1 -1
  4. package/dist/config.mjs +1 -110
  5. package/dist/config.mjs.map +1 -1
  6. package/dist/instrument-client.d.mts +7 -10
  7. package/dist/instrument-client.d.mts.map +1 -1
  8. package/dist/instrument-client.mjs +1 -9
  9. package/dist/instrument-client.mjs.map +1 -1
  10. package/dist/instrumentation-client.mjs +1 -22
  11. package/dist/instrumentation-client.mjs.map +1 -1
  12. package/dist/instrumentation.d.mts +3 -3
  13. package/dist/instrumentation.d.mts.map +1 -1
  14. package/dist/instrumentation.edge.d.mts +1 -1
  15. package/dist/instrumentation.edge.d.mts.map +1 -1
  16. package/dist/instrumentation.edge.mjs +1 -34
  17. package/dist/instrumentation.edge.mjs.map +1 -1
  18. package/dist/instrumentation.mjs +1 -165
  19. package/dist/instrumentation.mjs.map +1 -1
  20. package/dist/internal/build/configure-build.d.mts +2 -0
  21. package/dist/internal/build/configure-build.d.mts.map +1 -1
  22. package/dist/internal/build/configure-build.mjs +1 -95
  23. package/dist/internal/build/configure-build.mjs.map +1 -1
  24. package/dist/internal/build/detect-bundler.d.mts +3 -2
  25. package/dist/internal/build/detect-bundler.d.mts.map +1 -1
  26. package/dist/internal/build/detect-bundler.mjs +1 -9
  27. package/dist/internal/build/detect-bundler.mjs.map +1 -1
  28. package/dist/internal/build/pipeline.d.mts +5 -7
  29. package/dist/internal/build/pipeline.d.mts.map +1 -1
  30. package/dist/internal/build/pipeline.mjs +1 -82
  31. package/dist/internal/build/pipeline.mjs.map +1 -1
  32. package/dist/internal/build/release/destinations/index.mjs +1 -13
  33. package/dist/internal/build/release/destinations/index.mjs.map +1 -1
  34. package/dist/internal/build/release/destinations/vercel.d.mts.map +1 -1
  35. package/dist/internal/build/release/destinations/vercel.mjs +1 -23
  36. package/dist/internal/build/release/destinations/vercel.mjs.map +1 -1
  37. package/dist/internal/build/release/git.d.mts.map +1 -1
  38. package/dist/internal/build/release/git.mjs +1 -32
  39. package/dist/internal/build/release/git.mjs.map +1 -1
  40. package/dist/internal/build/release/index.d.mts.map +1 -1
  41. package/dist/internal/build/release/index.mjs +1 -18
  42. package/dist/internal/build/release/index.mjs.map +1 -1
  43. package/dist/internal/build/release/sources/github.d.mts.map +1 -1
  44. package/dist/internal/build/release/sources/github.mjs +1 -13
  45. package/dist/internal/build/release/sources/github.mjs.map +1 -1
  46. package/dist/internal/build/release/sources/index.d.mts.map +1 -1
  47. package/dist/internal/build/release/sources/index.mjs +1 -20
  48. package/dist/internal/build/release/sources/index.mjs.map +1 -1
  49. package/dist/internal/build/source-maps/discover-turbopack.d.mts.map +1 -1
  50. package/dist/internal/build/source-maps/discover-turbopack.mjs +1 -68
  51. package/dist/internal/build/source-maps/discover-turbopack.mjs.map +1 -1
  52. package/dist/internal/build/source-maps/discover-webpack.d.mts.map +1 -1
  53. package/dist/internal/build/source-maps/discover-webpack.mjs +1 -112
  54. package/dist/internal/build/source-maps/discover-webpack.mjs.map +1 -1
  55. package/dist/internal/build/source-maps/discover.d.mts +4 -4
  56. package/dist/internal/build/source-maps/discover.d.mts.map +1 -1
  57. package/dist/internal/build/source-maps/discover.mjs +1 -26
  58. package/dist/internal/build/source-maps/discover.mjs.map +1 -1
  59. package/dist/internal/build/source-maps/index.d.mts.map +1 -1
  60. package/dist/internal/build/source-maps/index.mjs +1 -18
  61. package/dist/internal/build/source-maps/index.mjs.map +1 -1
  62. package/dist/internal/build/source-maps/paths.d.mts.map +1 -1
  63. package/dist/internal/build/source-maps/paths.mjs +1 -49
  64. package/dist/internal/build/source-maps/paths.mjs.map +1 -1
  65. package/dist/internal/build/source-maps/upload.d.mts.map +1 -1
  66. package/dist/internal/build/source-maps/upload.mjs +1 -134
  67. package/dist/internal/build/source-maps/upload.mjs.map +1 -1
  68. package/dist/internal/build/value-injection-loader.d.mts.map +1 -1
  69. package/dist/internal/build/value-injection-loader.mjs +2 -24
  70. package/dist/internal/build/value-injection-loader.mjs.map +1 -1
  71. package/dist/internal/env.d.mts +2 -1
  72. package/dist/internal/env.d.mts.map +1 -1
  73. package/dist/internal/env.mjs +1 -32
  74. package/dist/internal/env.mjs.map +1 -1
  75. package/dist/internal/logger.d.mts.map +1 -1
  76. package/dist/internal/logger.mjs +1 -68
  77. package/dist/internal/logger.mjs.map +1 -1
  78. package/dist/internal/release-slug.d.mts.map +1 -1
  79. package/dist/internal/release-slug.mjs +1 -32
  80. package/dist/internal/release-slug.mjs.map +1 -1
  81. package/dist/internal/route/handle-get.d.mts.map +1 -1
  82. package/dist/internal/route/handle-get.mjs +1 -43
  83. package/dist/internal/route/handle-get.mjs.map +1 -1
  84. package/dist/internal/route/handle-post.d.mts.map +1 -1
  85. package/dist/internal/route/handle-post.mjs +1 -31
  86. package/dist/internal/route/handle-post.mjs.map +1 -1
  87. package/dist/internal/route/proxy.d.mts +8 -6
  88. package/dist/internal/route/proxy.d.mts.map +1 -1
  89. package/dist/internal/route/proxy.mjs +1 -134
  90. package/dist/internal/route/proxy.mjs.map +1 -1
  91. package/dist/internal/server/capture.d.mts.map +1 -1
  92. package/dist/internal/server/capture.mjs +1 -89
  93. package/dist/internal/server/capture.mjs.map +1 -1
  94. package/dist/internal/server/console-bridge.d.mts.map +1 -1
  95. package/dist/internal/server/console-bridge.mjs +1 -112
  96. package/dist/internal/server/console-bridge.mjs.map +1 -1
  97. package/dist/internal/server/id-generator.d.mts.map +1 -1
  98. package/dist/internal/server/id-generator.mjs +1 -68
  99. package/dist/internal/server/id-generator.mjs.map +1 -1
  100. package/dist/internal/server/instrumentation-options.d.mts.map +1 -1
  101. package/dist/internal/server/instrumentation-options.mjs +1 -1
  102. package/dist/internal/server/remote-config.d.mts.map +1 -1
  103. package/dist/internal/server/remote-config.mjs +1 -29
  104. package/dist/internal/server/remote-config.mjs.map +1 -1
  105. package/dist/internal/server/trace-meta.d.mts +1 -3
  106. package/dist/internal/server/trace-meta.d.mts.map +1 -1
  107. package/dist/internal/server/trace-meta.mjs +1 -41
  108. package/dist/internal/server/trace-meta.mjs.map +1 -1
  109. package/dist/internal/server/traceparent.d.mts.map +1 -1
  110. package/dist/internal/server/traceparent.mjs +1 -26
  111. package/dist/internal/server/traceparent.mjs.map +1 -1
  112. package/dist/internal/server/types.d.mts.map +1 -1
  113. package/dist/internal/server/types.mjs +1 -1
  114. package/dist/internal/setup-warnings.d.mts +1 -1
  115. package/dist/internal/setup-warnings.d.mts.map +1 -1
  116. package/dist/internal/setup-warnings.mjs +1 -45
  117. package/dist/internal/setup-warnings.mjs.map +1 -1
  118. package/dist/internal/url.d.mts +4 -0
  119. package/dist/internal/url.d.mts.map +1 -0
  120. package/dist/internal/url.mjs +1 -0
  121. package/dist/internal/url.mjs.map +1 -0
  122. package/dist/internal/version.mjs +1 -5
  123. package/dist/internal/version.mjs.map +1 -1
  124. package/dist/package.mjs +1 -5
  125. package/dist/provider.d.mts.map +1 -1
  126. package/dist/provider.mjs +1 -25
  127. package/dist/provider.mjs.map +1 -1
  128. package/dist/route-handler.d.mts.map +1 -1
  129. package/dist/route-handler.mjs +1 -33
  130. package/dist/route-handler.mjs.map +1 -1
  131. package/dist/server.mjs +1 -3
  132. package/package.json +29 -30
@@ -1,134 +1 @@
1
- //#region src/internal/build/source-maps/upload.ts
2
- const PUT_CONCURRENCY = 12;
3
- /**
4
- * Drives the three-step presigned-URL flow:
5
- *
6
- * 1. POST `/v1/releases/:slug/source-maps/sign` with per-file metadata.
7
- * 2. PUT each file's content directly to R2 in parallel (concurrency
8
- * bounded so a build with 1000+ chunks doesn't open 1000 sockets).
9
- * 3. POST `/v1/releases/:slug/source-maps/complete` to materialize the
10
- * manifest and update the release row.
11
- *
12
- * The collector never sees source-map bytes — uploads scale with R2
13
- * limits, not Cloudflare worker / load-balancer body-size caps. The
14
- * legacy multipart endpoint is still wired for older SDKs.
15
- */
16
- async function uploadSourceMaps({ apiUrl, bundler, discovered, httpClient, releaseSlug }) {
17
- const filesByPath = new Map(discovered.files.map((f) => [f.path, f]));
18
- const signRequest = { files: discovered.files.map((file) => ({
19
- path: file.path,
20
- sizeBytes: byteLengthOf(file.content),
21
- ...extractRichness(file.content)
22
- })) };
23
- const signResponse = await postJson(httpClient, new URL(`/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/sign`, apiUrl), signRequest);
24
- let totalBytes = 0;
25
- await mapWithConcurrency(signResponse.uploads, PUT_CONCURRENCY, async (upload) => {
26
- const file = filesByPath.get(upload.path);
27
- if (!file) throw new Error(`Sign response referenced unknown path "${upload.path}"`);
28
- totalBytes += byteLengthOf(file.content);
29
- await putToR2(upload.presignedUrl, file.content);
30
- });
31
- const completeRequest = {
32
- files: discovered.files.map((file) => ({
33
- path: file.path,
34
- hash: file.hash,
35
- debugId: file.debugId,
36
- chunkUrl: file.chunkUrl
37
- })),
38
- sourceFileCount: discovered.sourceFileCount,
39
- bundler
40
- };
41
- return {
42
- fileCount: (await postJson(httpClient, new URL(`/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/complete`, apiUrl), completeRequest)).fileCount,
43
- totalBytes
44
- };
45
- }
46
- function byteLengthOf(content) {
47
- return new TextEncoder().encode(content).byteLength;
48
- }
49
- const EMPTY_RICHNESS = {
50
- hasSourcesContent: false,
51
- hasNames: false,
52
- hasFile: false,
53
- mappingsPresent: false
54
- };
55
- function leafRichness(map) {
56
- const sourcesContent = map["sourcesContent"];
57
- const names = map["names"];
58
- const file = map["file"];
59
- const mappings = map["mappings"];
60
- return {
61
- hasSourcesContent: Array.isArray(sourcesContent) && sourcesContent.length > 0,
62
- hasNames: Array.isArray(names) && names.length > 0,
63
- hasFile: typeof file === "string" && file.length > 0,
64
- mappingsPresent: typeof mappings === "string" && mappings.length > 0
65
- };
66
- }
67
- function extractRichness(content) {
68
- let parsed;
69
- try {
70
- parsed = JSON.parse(content);
71
- } catch {
72
- return EMPTY_RICHNESS;
73
- }
74
- if (!(parsed && typeof parsed === "object")) return EMPTY_RICHNESS;
75
- const top = parsed;
76
- const sections = top["sections"];
77
- if (!Array.isArray(sections)) return leafRichness(top);
78
- const merged = {
79
- hasSourcesContent: false,
80
- hasNames: false,
81
- hasFile: typeof top["file"] === "string" && top["file"].length > 0,
82
- mappingsPresent: false
83
- };
84
- for (const section of sections) {
85
- const inner = section?.map;
86
- if (!(inner && typeof inner === "object")) continue;
87
- const r = leafRichness(inner);
88
- merged.hasSourcesContent ||= r.hasSourcesContent;
89
- merged.hasNames ||= r.hasNames;
90
- merged.mappingsPresent ||= r.mappingsPresent;
91
- }
92
- return merged;
93
- }
94
- async function postJson(httpClient, url, body) {
95
- const response = await httpClient.request(new Request(url, {
96
- method: "POST",
97
- headers: {
98
- "content-type": "application/json",
99
- accept: "application/json"
100
- },
101
- body: JSON.stringify(body)
102
- }));
103
- if (!response.ok) {
104
- const detail = await response.text().catch(() => "");
105
- throw new Error(`Source-map API request failed: POST ${url.pathname} -> ${response.status} ${detail}`);
106
- }
107
- return await response.json();
108
- }
109
- async function putToR2(presignedUrl, content) {
110
- const response = await fetch(presignedUrl, {
111
- method: "PUT",
112
- headers: { "content-type": "application/json" },
113
- body: content
114
- });
115
- if (!response.ok) {
116
- const detail = await response.text().catch(() => "");
117
- throw new Error(`Source-map upload to R2 failed: ${response.status} ${detail}`);
118
- }
119
- }
120
- async function mapWithConcurrency(items, concurrency, fn) {
121
- let cursor = 0;
122
- async function worker() {
123
- while (true) {
124
- const i = cursor++;
125
- if (i >= items.length) return;
126
- const item = items[i];
127
- if (item === void 0) return;
128
- await fn(item, i);
129
- }
130
- }
131
- await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
132
- }
133
- //#endregion
134
- export { extractRichness, uploadSourceMaps };
1
+ async function uploadSourceMaps({apiUrl,bundler,discovered,httpClient,releaseSlug}){let filesByPath=new Map(discovered.files.map(f=>[f.path,f])),signRequest={files:discovered.files.map(file=>({path:file.path,sizeBytes:byteLengthOf(file.content),...extractRichness(file.content)}))},signResponse=await postJson(httpClient,new URL(`/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/sign`,apiUrl),signRequest),totalBytes=0;await mapWithConcurrency(signResponse.uploads,12,async upload=>{let file=filesByPath.get(upload.path);if(!file)throw Error(`Sign response referenced unknown path "${upload.path}"`);totalBytes+=byteLengthOf(file.content),await putToR2(upload.presignedUrl,file.content)});let completeRequest={files:discovered.files.map(file=>({path:file.path,hash:file.hash,debugId:file.debugId,chunkUrl:file.chunkUrl})),sourceFileCount:discovered.sourceFileCount,bundler};return{fileCount:(await postJson(httpClient,new URL(`/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/complete`,apiUrl),completeRequest)).fileCount,totalBytes}}function byteLengthOf(content){return new TextEncoder().encode(content).byteLength}const EMPTY_RICHNESS={hasSourcesContent:!1,hasNames:!1,hasFile:!1,mappingsPresent:!1};function leafRichness(map){let sourcesContent=map.sourcesContent,names=map.names,file=map.file,mappings=map.mappings;return{hasSourcesContent:Array.isArray(sourcesContent)&&sourcesContent.length>0,hasNames:Array.isArray(names)&&names.length>0,hasFile:typeof file==`string`&&file.length>0,mappingsPresent:typeof mappings==`string`&&mappings.length>0}}function extractRichness(content){let parsed;try{parsed=JSON.parse(content)}catch{return EMPTY_RICHNESS}if(!(parsed&&typeof parsed==`object`))return EMPTY_RICHNESS;let top=parsed,sections=top.sections;if(!Array.isArray(sections))return leafRichness(top);let merged={hasSourcesContent:!1,hasNames:!1,hasFile:typeof top.file==`string`&&top.file.length>0,mappingsPresent:!1};for(let section of sections){let inner=section?.map;if(!(inner&&typeof inner==`object`))continue;let r=leafRichness(inner);merged.hasSourcesContent||=r.hasSourcesContent,merged.hasNames||=r.hasNames,merged.mappingsPresent||=r.mappingsPresent}return merged}async function postJson(httpClient,url,body){let response=await httpClient.request(new Request(url,{method:`POST`,headers:{"content-type":`application/json`,accept:`application/json`},body:JSON.stringify(body)}));if(!response.ok){let detail=await response.text().catch(()=>``);throw Error(`Source-map API request failed: POST ${url.pathname} -> ${response.status} ${detail}`)}return await response.json()}async function putToR2(presignedUrl,content){let response=await fetch(presignedUrl,{method:`PUT`,headers:{"content-type":`application/json`},body:content});if(!response.ok){let detail=await response.text().catch(()=>``);throw Error(`Release metadata file upload failed: ${response.status} ${detail}`)}}async function mapWithConcurrency(items,concurrency,fn){let cursor=0;async function worker(){for(;;){let i=cursor++;if(i>=items.length)return;let item=items[i];if(item===void 0)return;await fn(item,i)}}await Promise.all(Array.from({length:Math.min(concurrency,items.length)},()=>worker()))}export{extractRichness,uploadSourceMaps};
@@ -1 +1 @@
1
- {"version":3,"file":"upload.mjs","names":[],"sources":["../../../../src/internal/build/source-maps/upload.ts"],"sourcesContent":["import type { HTTPClient } from \"@interfere/sdk\";\nimport type { ReleaseSlug } from \"@interfere/types/releases/slug\";\nimport type {\n CompleteSourceMapsRequest,\n CompleteSourceMapsResponse,\n ManifestBundler,\n SignSourceMapsRequest,\n SignSourceMapsResponse,\n} from \"@interfere/types/data/source-maps\";\n\nimport type { DiscoveryResult } from \"./discover.js\";\n\nconst PUT_CONCURRENCY = 12;\n\nexport interface UploadResult {\n fileCount: number;\n totalBytes: number;\n}\n\ninterface UploadParams {\n apiUrl: string;\n bundler: ManifestBundler;\n discovered: DiscoveryResult;\n httpClient: HTTPClient;\n releaseSlug: ReleaseSlug;\n}\n\n/**\n * Drives the three-step presigned-URL flow:\n *\n * 1. POST `/v1/releases/:slug/source-maps/sign` with per-file metadata.\n * 2. PUT each file's content directly to R2 in parallel (concurrency\n * bounded so a build with 1000+ chunks doesn't open 1000 sockets).\n * 3. POST `/v1/releases/:slug/source-maps/complete` to materialize the\n * manifest and update the release row.\n *\n * The collector never sees source-map bytes — uploads scale with R2\n * limits, not Cloudflare worker / load-balancer body-size caps. The\n * legacy multipart endpoint is still wired for older SDKs.\n */\nexport async function uploadSourceMaps({\n apiUrl,\n bundler,\n discovered,\n httpClient,\n releaseSlug,\n}: UploadParams): Promise<UploadResult> {\n const filesByPath = new Map(discovered.files.map((f) => [f.path, f]));\n\n const signRequest = {\n files: discovered.files.map((file) => ({\n path: file.path,\n sizeBytes: byteLengthOf(file.content),\n ...extractRichness(file.content),\n })),\n } satisfies SignSourceMapsRequest;\n\n const signResponse = await postJson<SignSourceMapsResponse>(\n httpClient,\n new URL(\n `/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/sign`,\n apiUrl\n ),\n signRequest\n );\n\n let totalBytes = 0;\n\n await mapWithConcurrency(\n signResponse.uploads,\n PUT_CONCURRENCY,\n async (upload) => {\n const file = filesByPath.get(upload.path);\n if (!file) {\n throw new Error(\n `Sign response referenced unknown path \"${upload.path}\"`\n );\n }\n\n totalBytes += byteLengthOf(file.content);\n await putToR2(upload.presignedUrl, file.content);\n }\n );\n\n const completeRequest = {\n files: discovered.files.map((file) => ({\n path: file.path,\n hash: file.hash,\n debugId: file.debugId,\n chunkUrl: file.chunkUrl,\n })),\n sourceFileCount: discovered.sourceFileCount,\n bundler,\n } satisfies CompleteSourceMapsRequest;\n\n const completeResponse = await postJson<CompleteSourceMapsResponse>(\n httpClient,\n new URL(\n `/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/complete`,\n apiUrl\n ),\n completeRequest\n );\n\n return {\n fileCount: completeResponse.fileCount,\n totalBytes,\n };\n}\n\nfunction byteLengthOf(content: string) {\n return new TextEncoder().encode(content).byteLength;\n}\n\ninterface SourceMapRichness {\n hasSourcesContent: boolean;\n hasNames: boolean;\n hasFile: boolean;\n mappingsPresent: boolean;\n}\n\nconst EMPTY_RICHNESS: SourceMapRichness = {\n hasSourcesContent: false,\n hasNames: false,\n hasFile: false,\n mappingsPresent: false,\n};\n\nfunction leafRichness(map: Record<string, unknown>): SourceMapRichness {\n const sourcesContent = map[\"sourcesContent\"];\n const names = map[\"names\"];\n const file = map[\"file\"];\n const mappings = map[\"mappings\"];\n\n return {\n hasSourcesContent:\n Array.isArray(sourcesContent) && sourcesContent.length > 0,\n hasNames: Array.isArray(names) && names.length > 0,\n hasFile: typeof file === \"string\" && file.length > 0,\n mappingsPresent: typeof mappings === \"string\" && mappings.length > 0,\n };\n}\n\nexport function extractRichness(content: string): SourceMapRichness {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return EMPTY_RICHNESS;\n }\n\n if (!(parsed && typeof parsed === \"object\")) {\n return EMPTY_RICHNESS;\n }\n\n const top = parsed as Record<string, unknown>;\n const sections = top[\"sections\"];\n\n if (!Array.isArray(sections)) {\n return leafRichness(top);\n }\n\n const merged: SourceMapRichness = {\n hasSourcesContent: false,\n hasNames: false,\n hasFile: typeof top[\"file\"] === \"string\" && (top[\"file\"] as string).length > 0,\n mappingsPresent: false,\n };\n\n for (const section of sections) {\n const inner = (section as { map?: unknown } | null)?.map;\n if (!(inner && typeof inner === \"object\")) {\n continue;\n }\n const r = leafRichness(inner as Record<string, unknown>);\n merged.hasSourcesContent ||= r.hasSourcesContent;\n merged.hasNames ||= r.hasNames;\n merged.mappingsPresent ||= r.mappingsPresent;\n }\n\n return merged;\n}\n\nasync function postJson<T>(\n httpClient: HTTPClient,\n url: URL,\n body: unknown\n): Promise<T> {\n const response = await httpClient.request(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n },\n body: JSON.stringify(body),\n })\n );\n\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new Error(\n `Source-map API request failed: POST ${url.pathname} -> ${response.status} ${detail}`\n );\n }\n\n return (await response.json()) as T;\n}\n\nasync function putToR2(presignedUrl: string, content: string) {\n const response = await fetch(presignedUrl, {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: content,\n });\n\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new Error(\n `Source-map upload to R2 failed: ${response.status} ${detail}`\n );\n }\n}\n\nasync function mapWithConcurrency<T>(\n items: T[],\n concurrency: number,\n fn: (item: T, index: number) => Promise<void>\n): Promise<void> {\n let cursor = 0;\n\n async function worker() {\n while (true) {\n const i = cursor++;\n if (i >= items.length) {\n return;\n }\n const item = items[i];\n // Index is bounded by `items.length` above; the assertion is\n // narrowing for noUncheckedIndexedAccess, not a runtime check.\n if (item === undefined) {\n return;\n }\n await fn(item, i);\n }\n }\n\n await Promise.all(\n Array.from({ length: Math.min(concurrency, items.length) }, () => worker())\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"upload.mjs","names":[],"sources":["../../../../src/internal/build/source-maps/upload.ts"],"sourcesContent":["import type { HTTPClient } from \"@interfere/sdk\";\nimport type { ReleaseSlug } from \"@interfere/types/releases/slug\";\nimport type {\n CompleteSourceMapsRequest,\n CompleteSourceMapsResponse,\n ManifestBundler,\n SignSourceMapsRequest,\n SignSourceMapsResponse,\n} from \"@interfere/types/data/source-maps\";\n\nimport type { DiscoveryResult } from \"./discover.js\";\n\nconst PUT_CONCURRENCY = 12;\n\nexport interface UploadResult {\n fileCount: number;\n totalBytes: number;\n}\n\ninterface UploadParams {\n apiUrl: string;\n bundler: ManifestBundler;\n discovered: DiscoveryResult;\n httpClient: HTTPClient;\n releaseSlug: ReleaseSlug;\n}\n\n/**\n * Drives the three-step presigned-URL flow:\n *\n * 1. POST `/v1/releases/:slug/source-maps/sign` with per-file metadata.\n * 2. PUT each file's content directly to R2 in parallel (concurrency\n * bounded so a build with 1000+ chunks doesn't open 1000 sockets).\n * 3. POST `/v1/releases/:slug/source-maps/complete` to materialize the\n * manifest and update the release row.\n *\n * The collector never sees source-map bytes — uploads scale with R2\n * limits, not Cloudflare worker / load-balancer body-size caps. The\n * legacy multipart endpoint is still wired for older SDKs.\n */\nexport async function uploadSourceMaps({\n apiUrl,\n bundler,\n discovered,\n httpClient,\n releaseSlug,\n}: UploadParams): Promise<UploadResult> {\n const filesByPath = new Map(discovered.files.map((f) => [f.path, f]));\n\n const signRequest = {\n files: discovered.files.map((file) => ({\n path: file.path,\n sizeBytes: byteLengthOf(file.content),\n ...extractRichness(file.content),\n })),\n } satisfies SignSourceMapsRequest;\n\n const signResponse = await postJson<SignSourceMapsResponse>(\n httpClient,\n new URL(\n `/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/sign`,\n apiUrl\n ),\n signRequest\n );\n\n let totalBytes = 0;\n\n await mapWithConcurrency(\n signResponse.uploads,\n PUT_CONCURRENCY,\n async (upload) => {\n const file = filesByPath.get(upload.path);\n if (!file) {\n throw new Error(\n `Sign response referenced unknown path \"${upload.path}\"`\n );\n }\n\n totalBytes += byteLengthOf(file.content);\n await putToR2(upload.presignedUrl, file.content);\n }\n );\n\n const completeRequest = {\n files: discovered.files.map((file) => ({\n path: file.path,\n hash: file.hash,\n debugId: file.debugId,\n chunkUrl: file.chunkUrl,\n })),\n sourceFileCount: discovered.sourceFileCount,\n bundler,\n } satisfies CompleteSourceMapsRequest;\n\n const completeResponse = await postJson<CompleteSourceMapsResponse>(\n httpClient,\n new URL(\n `/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/complete`,\n apiUrl\n ),\n completeRequest\n );\n\n return {\n fileCount: completeResponse.fileCount,\n totalBytes,\n };\n}\n\nfunction byteLengthOf(content: string) {\n return new TextEncoder().encode(content).byteLength;\n}\n\ninterface SourceMapRichness {\n hasSourcesContent: boolean;\n hasNames: boolean;\n hasFile: boolean;\n mappingsPresent: boolean;\n}\n\nconst EMPTY_RICHNESS: SourceMapRichness = {\n hasSourcesContent: false,\n hasNames: false,\n hasFile: false,\n mappingsPresent: false,\n};\n\nfunction leafRichness(map: Record<string, unknown>): SourceMapRichness {\n const sourcesContent = map[\"sourcesContent\"];\n const names = map[\"names\"];\n const file = map[\"file\"];\n const mappings = map[\"mappings\"];\n\n return {\n hasSourcesContent:\n Array.isArray(sourcesContent) && sourcesContent.length > 0,\n hasNames: Array.isArray(names) && names.length > 0,\n hasFile: typeof file === \"string\" && file.length > 0,\n mappingsPresent: typeof mappings === \"string\" && mappings.length > 0,\n };\n}\n\nexport function extractRichness(content: string): SourceMapRichness {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return EMPTY_RICHNESS;\n }\n\n if (!(parsed && typeof parsed === \"object\")) {\n return EMPTY_RICHNESS;\n }\n\n const top = parsed as Record<string, unknown>;\n const sections = top[\"sections\"];\n\n if (!Array.isArray(sections)) {\n return leafRichness(top);\n }\n\n const merged: SourceMapRichness = {\n hasSourcesContent: false,\n hasNames: false,\n hasFile: typeof top[\"file\"] === \"string\" && (top[\"file\"] as string).length > 0,\n mappingsPresent: false,\n };\n\n for (const section of sections) {\n const inner = (section as { map?: unknown } | null)?.map;\n if (!(inner && typeof inner === \"object\")) {\n continue;\n }\n const r = leafRichness(inner as Record<string, unknown>);\n merged.hasSourcesContent ||= r.hasSourcesContent;\n merged.hasNames ||= r.hasNames;\n merged.mappingsPresent ||= r.mappingsPresent;\n }\n\n return merged;\n}\n\nasync function postJson<T>(\n httpClient: HTTPClient,\n url: URL,\n body: unknown\n): Promise<T> {\n const response = await httpClient.request(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n },\n body: JSON.stringify(body),\n })\n );\n\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new Error(\n `Source-map API request failed: POST ${url.pathname} -> ${response.status} ${detail}`\n );\n }\n\n return (await response.json()) as T;\n}\n\nasync function putToR2(presignedUrl: string, content: string) {\n const response = await fetch(presignedUrl, {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: content,\n });\n\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new Error(\n `Release metadata file upload failed: ${response.status} ${detail}`\n );\n }\n}\n\nasync function mapWithConcurrency<T>(\n items: T[],\n concurrency: number,\n fn: (item: T, index: number) => Promise<void>\n): Promise<void> {\n let cursor = 0;\n\n async function worker() {\n while (true) {\n const i = cursor++;\n if (i >= items.length) {\n return;\n }\n const item = items[i];\n // Index is bounded by `items.length` above; the assertion is\n // narrowing for noUncheckedIndexedAccess, not a runtime check.\n if (item === undefined) {\n return;\n }\n await fn(item, i);\n }\n }\n\n await Promise.all(\n Array.from({ length: Math.min(concurrency, items.length) }, () => worker())\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"value-injection-loader.d.mts","names":[],"sources":["../../../src/internal/build/value-injection-loader.ts"],"mappings":";;;UAEiB,2BAAA;EAAA,SACN,gBAAA;EAAA,SACA,MAAA,GAAS,OAAA,CAAQ,uBAAA;AAAA;AAAA,UAGlB,UAAA;EACR,UAAA,IAAc,CAAA;AAAA;AAAA,iBAGQ,oBAAA,CACtB,IAAA,EAAM,UAAA,CAAW,2BAAA,GACjB,QAAA"}
1
+ {"version":3,"file":"value-injection-loader.d.mts","names":[],"sources":["../../../src/internal/build/value-injection-loader.ts"],"mappings":";;;UAEiB,2BAAA;EAAA,SACN,gBAAA;EAAA,SACA,MAAA,GAAS,OAAO,CAAC,uBAAA;AAAA;AAAA,UAGlB,UAAA;EACR,UAAA,IAAc,CAAC;AAAA;AAAA,iBAGO,oBAAA,CACtB,IAAA,EAAM,UAAU,CAAC,2BAAA,GACjB,QAAA"}
@@ -1,24 +1,2 @@
1
- //#region src/internal/build/value-injection-loader.ts
2
- function valueInjectionLoader(userCode) {
3
- const values = resolveValues(this.getOptions());
4
- const lines = Object.entries(values).filter(([, value]) => value !== void 0).map(([key, value]) => {
5
- return `globalThis["${key.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"] = ${JSON.stringify(value)};`;
6
- });
7
- if (lines.length === 0) return userCode;
8
- return `${lines.join("\n")}\n${userCode}`;
9
- }
10
- function resolveValues(options) {
11
- if (typeof options.serializedValues === "string") try {
12
- const parsed = JSON.parse(options.serializedValues);
13
- if (isRecord(parsed)) return parsed;
14
- return {};
15
- } catch {
16
- return {};
17
- }
18
- return options.values ?? {};
19
- }
20
- function isRecord(value) {
21
- return typeof value === "object" && value !== null && !Array.isArray(value);
22
- }
23
- //#endregion
24
- export { valueInjectionLoader as default };
1
+ function valueInjectionLoader(userCode){let values=resolveValues(this.getOptions()),lines=Object.entries(values).filter(([,value])=>value!==void 0).map(([key,value])=>`globalThis["${key.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"] = ${JSON.stringify(value)};`);return lines.length===0?userCode:`${lines.join(`
2
+ `)}\n${userCode}`}function resolveValues(options){if(typeof options.serializedValues==`string`)try{let parsed=JSON.parse(options.serializedValues);return isRecord(parsed)?parsed:{}}catch{return{}}return options.values??{}}function isRecord(value){return typeof value==`object`&&!!value&&!Array.isArray(value)}export{valueInjectionLoader as default};
@@ -1 +1 @@
1
- {"version":3,"file":"value-injection-loader.mjs","names":[],"sources":["../../../src/internal/build/value-injection-loader.ts"],"sourcesContent":["import type { InterfereInjectedValues } from \"./configure-build.js\";\n\nexport interface ValueInjectionLoaderOptions {\n readonly serializedValues?: string;\n readonly values?: Partial<InterfereInjectedValues>;\n}\n\ninterface LoaderThis<T> {\n getOptions(): T;\n}\n\nexport default function valueInjectionLoader(\n this: LoaderThis<ValueInjectionLoaderOptions>,\n userCode: string\n): string {\n const values = resolveValues(this.getOptions());\n const lines = Object.entries(values)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => {\n const escapedKey = key.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n return `globalThis[\"${escapedKey}\"] = ${JSON.stringify(value)};`;\n });\n\n if (lines.length === 0) {\n return userCode;\n }\n\n return `${lines.join(\"\\n\")}\\n${userCode}`;\n}\n\nfunction resolveValues(\n options: ValueInjectionLoaderOptions\n): Record<string, unknown> {\n if (typeof options.serializedValues === \"string\") {\n try {\n const parsed = JSON.parse(options.serializedValues);\n if (isRecord(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n }\n\n return options.values ?? {};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";AAWA,SAAwB,qBAEtB,UACQ;CACR,MAAM,SAAS,cAAc,KAAK,YAAY,CAAC;CAC/C,MAAM,QAAQ,OAAO,QAAQ,OAAO,CACjC,QAAQ,GAAG,WAAW,UAAU,KAAA,EAAU,CAC1C,KAAK,CAAC,KAAK,WAAW;EAErB,OAAO,eADY,IAAI,QAAQ,OAAO,OAAO,CAAC,QAAQ,MAAM,OAC5B,CAAC,OAAO,KAAK,UAAU,MAAM,CAAC;GAC9D;CAEJ,IAAI,MAAM,WAAW,GACnB,OAAO;CAGT,OAAO,GAAG,MAAM,KAAK,KAAK,CAAC,IAAI;;AAGjC,SAAS,cACP,SACyB;CACzB,IAAI,OAAO,QAAQ,qBAAqB,UACtC,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,QAAQ,iBAAiB;EACnD,IAAI,SAAS,OAAO,EAClB,OAAO;EAET,OAAO,EAAE;SACH;EACN,OAAO,EAAE;;CAIb,OAAO,QAAQ,UAAU,EAAE;;AAG7B,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
1
+ {"version":3,"file":"value-injection-loader.mjs","names":[],"sources":["../../../src/internal/build/value-injection-loader.ts"],"sourcesContent":["import type { InterfereInjectedValues } from \"./configure-build.js\";\n\nexport interface ValueInjectionLoaderOptions {\n readonly serializedValues?: string;\n readonly values?: Partial<InterfereInjectedValues>;\n}\n\ninterface LoaderThis<T> {\n getOptions(): T;\n}\n\nexport default function valueInjectionLoader(\n this: LoaderThis<ValueInjectionLoaderOptions>,\n userCode: string\n): string {\n const values = resolveValues(this.getOptions());\n const lines = Object.entries(values)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => {\n const escapedKey = key.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n return `globalThis[\"${escapedKey}\"] = ${JSON.stringify(value)};`;\n });\n\n if (lines.length === 0) {\n return userCode;\n }\n\n return `${lines.join(\"\\n\")}\\n${userCode}`;\n}\n\nfunction resolveValues(\n options: ValueInjectionLoaderOptions\n): Record<string, unknown> {\n if (typeof options.serializedValues === \"string\") {\n try {\n const parsed = JSON.parse(options.serializedValues);\n if (isRecord(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n }\n\n return options.values ?? {};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"AAWA,SAAwB,qBAEtB,SACQ,CACR,IAAM,OAAS,cAAc,KAAK,WAAW,CAAC,EACxC,MAAQ,OAAO,QAAQ,MAAM,EAChC,QAAQ,EAAG,SAAW,QAAU,IAAA,EAAS,EACzC,KAAK,CAAC,IAAK,SAEH,eADY,IAAI,QAAQ,MAAO,MAAM,EAAE,QAAQ,KAAM,KAC7B,EAAE,OAAO,KAAK,UAAU,KAAK,EAAE,EAC/D,EAMH,OAJI,MAAM,SAAW,EACZ,SAGF,GAAG,MAAM,KAAK;CAAI,EAAE,IAAI,UACjC,CAEA,SAAS,cACP,QACyB,CACzB,GAAI,OAAO,QAAQ,kBAAqB,SACtC,GAAI,CACF,IAAM,OAAS,KAAK,MAAM,QAAQ,gBAAgB,EAIlD,OAHI,SAAS,MAAM,EACV,OAEF,CAAC,CACV,MAAQ,CACN,MAAO,CAAC,CACV,CAGF,OAAO,QAAQ,QAAU,CAAC,CAC5B,CAEA,SAAS,SAAS,MAAkD,CAClE,OAAO,OAAO,OAAU,YAAY,OAAkB,CAAC,MAAM,QAAQ,KAAK,CAC5E"}
@@ -5,7 +5,8 @@ interface InterfereEnv {
5
5
  readonly apiKey: string | null;
6
6
  readonly apiUrl: string;
7
7
  readonly nextRuntime: string | null;
8
- readonly nodeEnvironment: Exclude<Env, null>;
8
+ readonly nodeEnvironment: Env;
9
+ readonly publicKey: string | null;
9
10
  readonly release: {
10
11
  readonly sourceId: string | null;
11
12
  readonly destinationId: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.mts","names":[],"sources":["../../src/internal/env.ts"],"mappings":";;;UAKiB,YAAA;EAAA,SACN,MAAA;EAAA,SACA,MAAA;EAAA,SACA,WAAA;EAAA,SACA,eAAA,EAAiB,OAAA,CAAQ,GAAA;EAAA,SACzB,OAAA;IAAA,SACE,QAAA;IAAA,SACA,aAAA;EAAA;AAAA;;;;;;;;AAab;;iBAAgB,iBAAA,CAAA;AAAA,iBAOA,gBAAA,CAAA,GAAoB,YAAA"}
1
+ {"version":3,"file":"env.d.mts","names":[],"sources":["../../src/internal/env.ts"],"mappings":";;;UAKiB,YAAA;EAAA,SACN,MAAA;EAAA,SACA,MAAA;EAAA,SACA,WAAA;EAAA,SACA,eAAA,EAAiB,GAAG;EAAA,SACpB,SAAA;EAAA,SACA,OAAA;IAAA,SACE,QAAA;IAAA,SACA,aAAA;EAAA;AAAA;;;;;;AAAa;AAa1B;;;iBAAgB,iBAAA,CAAA;AAAA,iBAOA,gBAAA,CAAA,GAAoB,YAAY"}
@@ -1,32 +1 @@
1
- import { API_URL } from "@interfere/constants/api";
2
- import { parseEnvValue } from "@interfere/types/sdk/env";
3
- import { normalizeEnv } from "@interfere/types/sdk/runtime";
4
- //#region src/internal/env.ts
5
- /**
6
- * Server-side gate for the proxy route handler, the `captureError` /
7
- * `onRequestError` helpers, and the remote-config fetcher. Distinct
8
- * from the browser-side `isEnabledByEnvironment` (in
9
- * `@interfere/react/internal/kernel`) because the server has different
10
- * env conventions: `NEXT_PUBLIC_INTERFERE_FORCE_ENABLE` is the dev
11
- * opt-in, and there's no "unknown runtime, default enabled" case the
12
- * way the browser SDK has for plain-browser / Vite hosts.
13
- */
14
- function isEnabledOnServer() {
15
- if (process.env["NODE_ENV"] === "production") return true;
16
- return !!process.env["NEXT_PUBLIC_INTERFERE_FORCE_ENABLE"];
17
- }
18
- function readInterfereEnv() {
19
- const nodeEnvironment = normalizeEnv(process.env["NODE_ENV"]) ?? "production";
20
- return {
21
- apiKey: parseEnvValue(process.env["INTERFERE_API_KEY"]),
22
- apiUrl: parseEnvValue(process.env["INTERFERE_API_URL"]) ?? API_URL,
23
- nextRuntime: parseEnvValue(process.env["NEXT_RUNTIME"]),
24
- nodeEnvironment,
25
- release: {
26
- sourceId: parseEnvValue(process.env["NEXT_PUBLIC_INTERFERE_BUILD_ID"]),
27
- destinationId: parseEnvValue(process.env["NEXT_PUBLIC_INTERFERE_RELEASE_ID"])
28
- }
29
- };
30
- }
31
- //#endregion
32
- export { isEnabledOnServer, readInterfereEnv };
1
+ import{API_URL}from"@interfere/constants/api";import{parseEnvValue}from"@interfere/types/sdk/env";import{normalizeEnv}from"@interfere/types/sdk/runtime";function isEnabledOnServer(){return process.env.NODE_ENV===`production`?!0:!!process.env.NEXT_PUBLIC_INTERFERE_FORCE_ENABLE}function readInterfereEnv(){let nodeEnvironment=normalizeEnv(process.env.NODE_ENV);return{apiKey:parseEnvValue(process.env.INTERFERE_API_KEY),apiUrl:parseEnvValue(process.env.INTERFERE_API_URL)??API_URL,nextRuntime:parseEnvValue(process.env.NEXT_RUNTIME),nodeEnvironment,publicKey:parseEnvValue(process.env.INTERFERE_PUBLIC_KEY),release:{sourceId:parseEnvValue(process.env.NEXT_PUBLIC_INTERFERE_BUILD_ID),destinationId:parseEnvValue(process.env.NEXT_PUBLIC_INTERFERE_RELEASE_ID)}}}export{isEnabledOnServer,readInterfereEnv};
@@ -1 +1 @@
1
- {"version":3,"file":"env.mjs","names":[],"sources":["../../src/internal/env.ts"],"sourcesContent":["import { API_URL } from \"@interfere/constants/api\";\nimport { parseEnvValue } from \"@interfere/types/sdk/env\";\nimport type { Env } from \"@interfere/types/sdk/runtime\";\nimport { normalizeEnv } from \"@interfere/types/sdk/runtime\";\n\nexport interface InterfereEnv {\n readonly apiKey: string | null;\n readonly apiUrl: string;\n readonly nextRuntime: string | null;\n readonly nodeEnvironment: Exclude<Env, null>;\n readonly release: {\n readonly sourceId: string | null;\n readonly destinationId: string | null;\n };\n}\n\n/**\n * Server-side gate for the proxy route handler, the `captureError` /\n * `onRequestError` helpers, and the remote-config fetcher. Distinct\n * from the browser-side `isEnabledByEnvironment` (in\n * `@interfere/react/internal/kernel`) because the server has different\n * env conventions: `NEXT_PUBLIC_INTERFERE_FORCE_ENABLE` is the dev\n * opt-in, and there's no \"unknown runtime, default enabled\" case the\n * way the browser SDK has for plain-browser / Vite hosts.\n */\nexport function isEnabledOnServer(): boolean {\n if (process.env[\"NODE_ENV\"] === \"production\") {\n return true;\n }\n return !!process.env[\"NEXT_PUBLIC_INTERFERE_FORCE_ENABLE\"];\n}\n\nexport function readInterfereEnv(): InterfereEnv {\n const nodeEnvironment = normalizeEnv(process.env[\"NODE_ENV\"]) ?? \"production\";\n\n return {\n apiKey: parseEnvValue(process.env[\"INTERFERE_API_KEY\"]),\n apiUrl: parseEnvValue(process.env[\"INTERFERE_API_URL\"]) ?? API_URL,\n nextRuntime: parseEnvValue(process.env[\"NEXT_RUNTIME\"]),\n nodeEnvironment,\n release: {\n sourceId: parseEnvValue(process.env[\"NEXT_PUBLIC_INTERFERE_BUILD_ID\"]),\n destinationId: parseEnvValue(\n process.env[\"NEXT_PUBLIC_INTERFERE_RELEASE_ID\"]\n ),\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAyBA,SAAgB,oBAA6B;CAC3C,IAAI,QAAQ,IAAI,gBAAgB,cAC9B,OAAO;CAET,OAAO,CAAC,CAAC,QAAQ,IAAI;;AAGvB,SAAgB,mBAAiC;CAC/C,MAAM,kBAAkB,aAAa,QAAQ,IAAI,YAAY,IAAI;CAEjE,OAAO;EACL,QAAQ,cAAc,QAAQ,IAAI,qBAAqB;EACvD,QAAQ,cAAc,QAAQ,IAAI,qBAAqB,IAAI;EAC3D,aAAa,cAAc,QAAQ,IAAI,gBAAgB;EACvD;EACA,SAAS;GACP,UAAU,cAAc,QAAQ,IAAI,kCAAkC;GACtE,eAAe,cACb,QAAQ,IAAI,oCACb;GACF;EACF"}
1
+ {"version":3,"file":"env.mjs","names":[],"sources":["../../src/internal/env.ts"],"sourcesContent":["import { API_URL } from \"@interfere/constants/api\";\nimport { parseEnvValue } from \"@interfere/types/sdk/env\";\nimport type { Env } from \"@interfere/types/sdk/runtime\";\nimport { normalizeEnv } from \"@interfere/types/sdk/runtime\";\n\nexport interface InterfereEnv {\n readonly apiKey: string | null;\n readonly apiUrl: string;\n readonly nextRuntime: string | null;\n readonly nodeEnvironment: Env;\n readonly publicKey: string | null;\n readonly release: {\n readonly sourceId: string | null;\n readonly destinationId: string | null;\n };\n}\n\n/**\n * Server-side gate for the proxy route handler, the `captureError` /\n * `onRequestError` helpers, and the remote-config fetcher. Distinct\n * from the browser-side `isEnabledByEnvironment` (in\n * `@interfere/react/internal/kernel`) because the server has different\n * env conventions: `NEXT_PUBLIC_INTERFERE_FORCE_ENABLE` is the dev\n * opt-in, and there's no \"unknown runtime, default enabled\" case the\n * way the browser SDK has for plain-browser / Vite hosts.\n */\nexport function isEnabledOnServer(): boolean {\n if (process.env[\"NODE_ENV\"] === \"production\") {\n return true;\n }\n return !!process.env[\"NEXT_PUBLIC_INTERFERE_FORCE_ENABLE\"];\n}\n\nexport function readInterfereEnv(): InterfereEnv {\n const nodeEnvironment = normalizeEnv(process.env[\"NODE_ENV\"]);\n\n return {\n apiKey: parseEnvValue(process.env[\"INTERFERE_API_KEY\"]),\n apiUrl: parseEnvValue(process.env[\"INTERFERE_API_URL\"]) ?? API_URL,\n nextRuntime: parseEnvValue(process.env[\"NEXT_RUNTIME\"]),\n nodeEnvironment,\n publicKey: parseEnvValue(process.env[\"INTERFERE_PUBLIC_KEY\"]),\n release: {\n sourceId: parseEnvValue(process.env[\"NEXT_PUBLIC_INTERFERE_BUILD_ID\"]),\n destinationId: parseEnvValue(\n process.env[\"NEXT_PUBLIC_INTERFERE_RELEASE_ID\"]\n ),\n },\n };\n}\n"],"mappings":"yJA0BA,SAAgB,mBAA6B,CAI3C,OAHI,QAAQ,IAAI,WAAgB,aACvB,GAEF,CAAC,CAAC,QAAQ,IAAI,kCACvB,CAEA,SAAgB,kBAAiC,CAC/C,IAAM,gBAAkB,aAAa,QAAQ,IAAI,QAAW,EAE5D,MAAO,CACL,OAAQ,cAAc,QAAQ,IAAI,iBAAoB,EACtD,OAAQ,cAAc,QAAQ,IAAI,iBAAoB,GAAK,QAC3D,YAAa,cAAc,QAAQ,IAAI,YAAe,EACtD,gBACA,UAAW,cAAc,QAAQ,IAAI,oBAAuB,EAC5D,QAAS,CACP,SAAU,cAAc,QAAQ,IAAI,8BAAiC,EACrE,cAAe,cACb,QAAQ,IAAI,gCACd,CACF,CACF,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.mts","names":[],"sources":["../../src/internal/logger.ts"],"mappings":";;AAuDA;;;;cAAa,UAAA,SAAmB,KAAA;EAAA,SACZ,IAAA;AAAA;AAAA,cA8BP,GAAA;wBACS,KAAA;wBACA,KAAA;yBACC,KAAA;uBACF,KAAA;AAAA"}
1
+ {"version":3,"file":"logger.d.mts","names":[],"sources":["../../src/internal/logger.ts"],"mappings":";;AAuDA;;;;cAAa,UAAA,SAAmB,KAAK;EAAA,SACjB,IAAI;AAAA;AAAA,cA8BX,GAAA;wBACS,KAAA;wBACA,KAAA;yBACC,KAAA;uBACF,KAAA;AAAA"}
@@ -1,68 +1 @@
1
- import chalk from "chalk";
2
- //#region src/internal/logger.ts
3
- const styles = {
4
- info: {
5
- prefix: `${chalk.whiteBright.bold("❖")}`,
6
- text: chalk.cyan.bold,
7
- content: chalk.white,
8
- prependLevel: false
9
- },
10
- warn: {
11
- prefix: `${chalk.yellow.bold("⚠")} `,
12
- text: chalk.yellow.bold,
13
- content: chalk.yellowBright,
14
- prependLevel: false
15
- },
16
- error: {
17
- prefix: `${chalk.red.bold("⨯")} `,
18
- text: chalk.red.bold,
19
- content: chalk.redBright,
20
- prependLevel: true
21
- },
22
- fatal: {
23
- prefix: `${chalk.red.bold("⨯")} `,
24
- text: chalk.red.bold,
25
- content: chalk.redBright,
26
- prependLevel: true
27
- }
28
- };
29
- const consoleMethods = {
30
- info: "log",
31
- warn: "warn",
32
- error: "error",
33
- fatal: "error"
34
- };
35
- function isTestEnv() {
36
- return Boolean(process.env["VITEST"] || process.env["VITEST_WORKER_ID"]);
37
- }
38
- /**
39
- * Thrown by `log.fatal` in test environments where `process.exit` is not
40
- * appropriate. Tagged so callers' catch blocks can re-throw fatal errors and
41
- * keep test-env behavior aligned with the production hard-exit.
42
- */
43
- var FatalError = class extends Error {
44
- name = "FatalError";
45
- };
46
- function emit(level, title, lines) {
47
- if (isTestEnv()) return;
48
- const style = styles[level];
49
- const method = consoleMethods[level];
50
- const fn = globalThis.console[method];
51
- if (typeof fn !== "function") return;
52
- const invoke = (...args) => Reflect.apply(fn, globalThis.console, args);
53
- const prependLevel = style.prependLevel ? `[${style.text(level.toUpperCase())}] ` : "";
54
- invoke(`${prependLevel} ${chalk.white("Interfere →")} ${style.text(title)}`);
55
- for (const [i, line] of lines.entries()) invoke(`${prependLevel} ${i === lines.length - 1 ? "└" : "├"} ${style.content(line)}`);
56
- }
57
- const log = {
58
- info: (title, lines) => emit("info", title, lines),
59
- warn: (title, lines) => emit("warn", title, lines),
60
- error: (title, lines) => emit("error", title, lines),
61
- fatal(title, lines) {
62
- emit("fatal", title, lines);
63
- if (isTestEnv()) throw new FatalError(title);
64
- process.exit(1);
65
- }
66
- };
67
- //#endregion
68
- export { FatalError, log };
1
+ import chalk from"chalk";const styles={info:{prefix:`${chalk.whiteBright.bold(`❖`)}`,text:chalk.cyan.bold,content:chalk.white,prependLevel:!1},warn:{prefix:`${chalk.yellow.bold(`⚠`)} `,text:chalk.yellow.bold,content:chalk.yellowBright,prependLevel:!1},error:{prefix:`${chalk.red.bold(`⨯`)} `,text:chalk.red.bold,content:chalk.redBright,prependLevel:!0},fatal:{prefix:`${chalk.red.bold(`⨯`)} `,text:chalk.red.bold,content:chalk.redBright,prependLevel:!0}},consoleMethods={info:`log`,warn:`warn`,error:`error`,fatal:`error`};function isTestEnv(){return!!(process.env.VITEST||process.env.VITEST_WORKER_ID)}var FatalError=class extends Error{name=`FatalError`};function emit(level,title,lines){if(isTestEnv())return;let style=styles[level],method=consoleMethods[level],fn=globalThis.console[method];if(typeof fn!=`function`)return;let invoke=(...args)=>Reflect.apply(fn,globalThis.console,args),prependLevel=style.prependLevel?`[${style.text(level.toUpperCase())}] `:``;invoke(`${prependLevel} ${chalk.white(`Interfere →`)} ${style.text(title)}`);for(let[i,line]of lines.entries())invoke(`${prependLevel} ${i===lines.length-1?`└`:`├`} ${style.content(line)}`)}const log={info:(title,lines)=>emit(`info`,title,lines),warn:(title,lines)=>emit(`warn`,title,lines),error:(title,lines)=>emit(`error`,title,lines),fatal(title,lines){if(emit(`fatal`,title,lines),isTestEnv())throw new FatalError(title);process.exit(1)}};export{FatalError,log};
@@ -1 +1 @@
1
- {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/internal/logger.ts"],"sourcesContent":["import chalk from \"chalk\";\n\ntype LogLevel = \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nconst styles = {\n info: {\n prefix: `${chalk.whiteBright.bold(\"❖\")}`,\n text: chalk.cyan.bold,\n content: chalk.white,\n prependLevel: false,\n },\n warn: {\n prefix: `${chalk.yellow.bold(\"⚠\")} `,\n text: chalk.yellow.bold,\n content: chalk.yellowBright,\n prependLevel: false,\n },\n error: {\n prefix: `${chalk.red.bold(\"⨯\")} `,\n text: chalk.red.bold,\n content: chalk.redBright,\n prependLevel: true,\n },\n fatal: {\n prefix: `${chalk.red.bold(\"⨯\")} `,\n text: chalk.red.bold,\n content: chalk.redBright,\n prependLevel: true,\n },\n} satisfies Record<\n LogLevel,\n {\n prefix: string;\n text: typeof chalk.bold;\n content: typeof chalk;\n prependLevel: boolean;\n }\n>;\n\nconst consoleMethods = {\n info: \"log\",\n warn: \"warn\",\n error: \"error\",\n fatal: \"error\",\n} satisfies Record<LogLevel, string>;\n\nfunction isTestEnv() {\n return Boolean(process.env[\"VITEST\"] || process.env[\"VITEST_WORKER_ID\"]);\n}\n\n/**\n * Thrown by `log.fatal` in test environments where `process.exit` is not\n * appropriate. Tagged so callers' catch blocks can re-throw fatal errors and\n * keep test-env behavior aligned with the production hard-exit.\n */\nexport class FatalError extends Error {\n override readonly name = \"FatalError\";\n}\n\nfunction emit(level: LogLevel, title: string, lines: string[]) {\n if (isTestEnv()) {\n return;\n }\n\n const style = styles[level];\n const method = consoleMethods[level] as keyof Console;\n const fn = globalThis.console[method];\n if (typeof fn !== \"function\") {\n return;\n }\n\n const invoke = (...args: unknown[]) =>\n Reflect.apply(fn, globalThis.console, args);\n\n const prependLevel = style.prependLevel\n ? `[${style.text(level.toUpperCase())}] `\n : \"\";\n\n invoke(`${prependLevel} ${chalk.white(\"Interfere →\")} ${style.text(title)}`);\n\n for (const [i, line] of lines.entries()) {\n const connector = i === lines.length - 1 ? \"└\" : \"├\";\n invoke(`${prependLevel} ${connector} ${style.content(line)}`);\n }\n}\n\nexport const log = {\n info: (title: string, lines: string[]) => emit(\"info\", title, lines),\n warn: (title: string, lines: string[]) => emit(\"warn\", title, lines),\n error: (title: string, lines: string[]) => emit(\"error\", title, lines),\n fatal(title: string, lines: string[]): never {\n emit(\"fatal\", title, lines);\n\n if (isTestEnv()) {\n throw new FatalError(title);\n }\n\n process.exit(1);\n },\n};\n"],"mappings":";;AAIA,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ,GAAG,MAAM,YAAY,KAAK,IAAI;EACtC,MAAM,MAAM,KAAK;EACjB,SAAS,MAAM;EACf,cAAc;EACf;CACD,MAAM;EACJ,QAAQ,GAAG,MAAM,OAAO,KAAK,IAAI,CAAC;EAClC,MAAM,MAAM,OAAO;EACnB,SAAS,MAAM;EACf,cAAc;EACf;CACD,OAAO;EACL,QAAQ,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC;EAC/B,MAAM,MAAM,IAAI;EAChB,SAAS,MAAM;EACf,cAAc;EACf;CACD,OAAO;EACL,QAAQ,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC;EAC/B,MAAM,MAAM,IAAI;EAChB,SAAS,MAAM;EACf,cAAc;EACf;CACF;AAUD,MAAM,iBAAiB;CACrB,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;CACR;AAED,SAAS,YAAY;CACnB,OAAO,QAAQ,QAAQ,IAAI,aAAa,QAAQ,IAAI,oBAAoB;;;;;;;AAQ1E,IAAa,aAAb,cAAgC,MAAM;CACpC,OAAyB;;AAG3B,SAAS,KAAK,OAAiB,OAAe,OAAiB;CAC7D,IAAI,WAAW,EACb;CAGF,MAAM,QAAQ,OAAO;CACrB,MAAM,SAAS,eAAe;CAC9B,MAAM,KAAK,WAAW,QAAQ;CAC9B,IAAI,OAAO,OAAO,YAChB;CAGF,MAAM,UAAU,GAAG,SACjB,QAAQ,MAAM,IAAI,WAAW,SAAS,KAAK;CAE7C,MAAM,eAAe,MAAM,eACvB,IAAI,MAAM,KAAK,MAAM,aAAa,CAAC,CAAC,MACpC;CAEJ,OAAO,GAAG,aAAa,GAAG,MAAM,MAAM,cAAc,CAAC,GAAG,MAAM,KAAK,MAAM,GAAG;CAE5E,KAAK,MAAM,CAAC,GAAG,SAAS,MAAM,SAAS,EAErC,OAAO,GAAG,aAAa,GADL,MAAM,MAAM,SAAS,IAAI,MAAM,IACb,GAAG,MAAM,QAAQ,KAAK,GAAG;;AAIjE,MAAa,MAAM;CACjB,OAAO,OAAe,UAAoB,KAAK,QAAQ,OAAO,MAAM;CACpE,OAAO,OAAe,UAAoB,KAAK,QAAQ,OAAO,MAAM;CACpE,QAAQ,OAAe,UAAoB,KAAK,SAAS,OAAO,MAAM;CACtE,MAAM,OAAe,OAAwB;EAC3C,KAAK,SAAS,OAAO,MAAM;EAE3B,IAAI,WAAW,EACb,MAAM,IAAI,WAAW,MAAM;EAG7B,QAAQ,KAAK,EAAE;;CAElB"}
1
+ {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/internal/logger.ts"],"sourcesContent":["import chalk from \"chalk\";\n\ntype LogLevel = \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nconst styles = {\n info: {\n prefix: `${chalk.whiteBright.bold(\"❖\")}`,\n text: chalk.cyan.bold,\n content: chalk.white,\n prependLevel: false,\n },\n warn: {\n prefix: `${chalk.yellow.bold(\"⚠\")} `,\n text: chalk.yellow.bold,\n content: chalk.yellowBright,\n prependLevel: false,\n },\n error: {\n prefix: `${chalk.red.bold(\"⨯\")} `,\n text: chalk.red.bold,\n content: chalk.redBright,\n prependLevel: true,\n },\n fatal: {\n prefix: `${chalk.red.bold(\"⨯\")} `,\n text: chalk.red.bold,\n content: chalk.redBright,\n prependLevel: true,\n },\n} satisfies Record<\n LogLevel,\n {\n prefix: string;\n text: typeof chalk.bold;\n content: typeof chalk;\n prependLevel: boolean;\n }\n>;\n\nconst consoleMethods = {\n info: \"log\",\n warn: \"warn\",\n error: \"error\",\n fatal: \"error\",\n} satisfies Record<LogLevel, string>;\n\nfunction isTestEnv() {\n return Boolean(process.env[\"VITEST\"] || process.env[\"VITEST_WORKER_ID\"]);\n}\n\n/**\n * Thrown by `log.fatal` in test environments where `process.exit` is not\n * appropriate. Tagged so callers' catch blocks can re-throw fatal errors and\n * keep test-env behavior aligned with the production hard-exit.\n */\nexport class FatalError extends Error {\n override readonly name = \"FatalError\";\n}\n\nfunction emit(level: LogLevel, title: string, lines: string[]) {\n if (isTestEnv()) {\n return;\n }\n\n const style = styles[level];\n const method = consoleMethods[level] as keyof Console;\n const fn = globalThis.console[method];\n if (typeof fn !== \"function\") {\n return;\n }\n\n const invoke = (...args: unknown[]) =>\n Reflect.apply(fn, globalThis.console, args);\n\n const prependLevel = style.prependLevel\n ? `[${style.text(level.toUpperCase())}] `\n : \"\";\n\n invoke(`${prependLevel} ${chalk.white(\"Interfere →\")} ${style.text(title)}`);\n\n for (const [i, line] of lines.entries()) {\n const connector = i === lines.length - 1 ? \"└\" : \"├\";\n invoke(`${prependLevel} ${connector} ${style.content(line)}`);\n }\n}\n\nexport const log = {\n info: (title: string, lines: string[]) => emit(\"info\", title, lines),\n warn: (title: string, lines: string[]) => emit(\"warn\", title, lines),\n error: (title: string, lines: string[]) => emit(\"error\", title, lines),\n fatal(title: string, lines: string[]): never {\n emit(\"fatal\", title, lines);\n\n if (isTestEnv()) {\n throw new FatalError(title);\n }\n\n process.exit(1);\n },\n};\n"],"mappings":"yBAIA,MAAM,OAAS,CACb,KAAM,CACJ,OAAQ,GAAG,MAAM,YAAY,KAAK,GAAG,IACrC,KAAM,MAAM,KAAK,KACjB,QAAS,MAAM,MACf,aAAc,EAChB,EACA,KAAM,CACJ,OAAQ,GAAG,MAAM,OAAO,KAAK,GAAG,EAAE,GAClC,KAAM,MAAM,OAAO,KACnB,QAAS,MAAM,aACf,aAAc,EAChB,EACA,MAAO,CACL,OAAQ,GAAG,MAAM,IAAI,KAAK,GAAG,EAAE,GAC/B,KAAM,MAAM,IAAI,KAChB,QAAS,MAAM,UACf,aAAc,EAChB,EACA,MAAO,CACL,OAAQ,GAAG,MAAM,IAAI,KAAK,GAAG,EAAE,GAC/B,KAAM,MAAM,IAAI,KAChB,QAAS,MAAM,UACf,aAAc,EAChB,CACF,EAUM,eAAiB,CACrB,KAAM,MACN,KAAM,OACN,MAAO,QACP,MAAO,OACT,EAEA,SAAS,WAAY,CACnB,MAAO,GAAQ,QAAQ,IAAI,QAAa,QAAQ,IAAI,iBACtD,CAOA,IAAa,WAAb,cAAgC,KAAM,CACpC,KAAyB,YAC3B,EAEA,SAAS,KAAK,MAAiB,MAAe,MAAiB,CAC7D,GAAI,UAAU,EACZ,OAGF,IAAM,MAAQ,OAAO,OACf,OAAS,eAAe,OACxB,GAAK,WAAW,QAAQ,QAC9B,GAAI,OAAO,IAAO,WAChB,OAGF,IAAM,QAAU,GAAG,OACjB,QAAQ,MAAM,GAAI,WAAW,QAAS,IAAI,EAEtC,aAAe,MAAM,aACvB,IAAI,MAAM,KAAK,MAAM,YAAY,CAAC,EAAE,IACpC,GAEJ,OAAO,GAAG,aAAa,GAAG,MAAM,MAAM,aAAa,EAAE,GAAG,MAAM,KAAK,KAAK,GAAG,EAE3E,IAAK,GAAM,CAAC,EAAG,QAAS,MAAM,QAAQ,EAEpC,OAAO,GAAG,aAAa,GADL,IAAM,MAAM,OAAS,EAAI,IAAM,IACb,GAAG,MAAM,QAAQ,IAAI,GAAG,CAEhE,CAEA,MAAa,IAAM,CACjB,MAAO,MAAe,QAAoB,KAAK,OAAQ,MAAO,KAAK,EACnE,MAAO,MAAe,QAAoB,KAAK,OAAQ,MAAO,KAAK,EACnE,OAAQ,MAAe,QAAoB,KAAK,QAAS,MAAO,KAAK,EACrE,MAAM,MAAe,MAAwB,CAG3C,GAFA,KAAK,QAAS,MAAO,KAAK,EAEtB,UAAU,EACZ,MAAM,IAAI,WAAW,KAAK,EAG5B,QAAQ,KAAK,CAAC,CAChB,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"release-slug.d.mts","names":[],"sources":["../../src/internal/release-slug.ts"],"mappings":";;;;;AAwBA;;;;;AAOA;;;;;;;;iBAPgB,gBAAA,CAAA;AAAA,iBAOA,kBAAA,CAAA;EACd,SAAA;EACA,IAAA,EAAM,WAAA;AAAA"}
1
+ {"version":3,"file":"release-slug.d.mts","names":[],"sources":["../../src/internal/release-slug.ts"],"mappings":";;;;;AAwBA;;;;AAAgC;AAOhC;;;;;;;;iBAPgB,gBAAA,CAAA;AAAA,iBAOA,kBAAA,CAAA;EACd,SAAA;EACA,IAAA,EAAM,WAAW;AAAA"}
@@ -1,32 +1 @@
1
- import { runGitCommand } from "./build/release/git.mjs";
2
- import { readFirstEnvValue } from "@interfere/types/sdk/env";
3
- import { releaseSourceIdEnvKeys } from "@interfere/types/integrations";
4
- import { deriveReleaseSlug } from "@interfere/types/releases/slug";
5
- //#region src/internal/release-slug.ts
6
- /**
7
- * Walks the same env keys at build time (`withInterfere`) and at runtime
8
- * (server-side `register()`), then falls back to `git rev-parse HEAD`. Both
9
- * call sites resolving the same SHA → both derive the same `release.slug`,
10
- * so server and client spans agree by construction.
11
- *
12
- * Override path for non-CI builds: set `INTERFERE_SOURCE_ID` (or any other
13
- * key in `releaseSourceIdEnvKeys`) on both the build env and the runtime
14
- * env. The `interfere.buildId` next.config knob was removed in 10.0 because
15
- * it only worked at build time and caused server/client slug drift.
16
- *
17
- * `runGitCommand` (`node:child_process`) keeps this module on the Node side
18
- * of `@interfere/next`'s dual entry — the edge entrypoint
19
- * (`instrumentation.edge.ts`) intentionally doesn't import this file.
20
- */
21
- function resolveCommitSha() {
22
- return readFirstEnvValue(process.env, releaseSourceIdEnvKeys) ?? runGitCommand("git rev-parse HEAD");
23
- }
24
- function resolveReleaseSlug() {
25
- const commitSha = resolveCommitSha();
26
- return {
27
- commitSha,
28
- slug: commitSha ? deriveReleaseSlug(commitSha) : null
29
- };
30
- }
31
- //#endregion
32
- export { resolveCommitSha, resolveReleaseSlug };
1
+ import{runGitCommand}from"./build/release/git.mjs";import{deriveReleaseSlug}from"@interfere/types/releases/slug";import{readFirstEnvValue}from"@interfere/types/sdk/env";import{releaseSourceIdEnvKeys}from"@interfere/types/integrations";function resolveCommitSha(){return readFirstEnvValue(process.env,releaseSourceIdEnvKeys)??runGitCommand(`git rev-parse HEAD`)}function resolveReleaseSlug(){let commitSha=resolveCommitSha();return{commitSha,slug:commitSha?deriveReleaseSlug(commitSha):null}}export{resolveCommitSha,resolveReleaseSlug};
@@ -1 +1 @@
1
- {"version":3,"file":"release-slug.mjs","names":[],"sources":["../../src/internal/release-slug.ts"],"sourcesContent":["import { releaseSourceIdEnvKeys } from \"@interfere/types/integrations\";\nimport {\n deriveReleaseSlug,\n type ReleaseSlug,\n} from \"@interfere/types/releases/slug\";\nimport { readFirstEnvValue } from \"@interfere/types/sdk/env\";\n\nimport { runGitCommand } from \"./build/release/git.js\";\n\n/**\n * Walks the same env keys at build time (`withInterfere`) and at runtime\n * (server-side `register()`), then falls back to `git rev-parse HEAD`. Both\n * call sites resolving the same SHA → both derive the same `release.slug`,\n * so server and client spans agree by construction.\n *\n * Override path for non-CI builds: set `INTERFERE_SOURCE_ID` (or any other\n * key in `releaseSourceIdEnvKeys`) on both the build env and the runtime\n * env. The `interfere.buildId` next.config knob was removed in 10.0 because\n * it only worked at build time and caused server/client slug drift.\n *\n * `runGitCommand` (`node:child_process`) keeps this module on the Node side\n * of `@interfere/next`'s dual entry — the edge entrypoint\n * (`instrumentation.edge.ts`) intentionally doesn't import this file.\n */\nexport function resolveCommitSha(): string | null {\n return (\n readFirstEnvValue(process.env, releaseSourceIdEnvKeys) ??\n runGitCommand(\"git rev-parse HEAD\")\n );\n}\n\nexport function resolveReleaseSlug(): {\n commitSha: string | null;\n slug: ReleaseSlug | null;\n} {\n const commitSha = resolveCommitSha();\n return {\n commitSha,\n slug: commitSha ? deriveReleaseSlug(commitSha) : null,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,mBAAkC;CAChD,OACE,kBAAkB,QAAQ,KAAK,uBAAuB,IACtD,cAAc,qBAAqB;;AAIvC,SAAgB,qBAGd;CACA,MAAM,YAAY,kBAAkB;CACpC,OAAO;EACL;EACA,MAAM,YAAY,kBAAkB,UAAU,GAAG;EAClD"}
1
+ {"version":3,"file":"release-slug.mjs","names":[],"sources":["../../src/internal/release-slug.ts"],"sourcesContent":["import { releaseSourceIdEnvKeys } from \"@interfere/types/integrations\";\nimport {\n deriveReleaseSlug,\n type ReleaseSlug,\n} from \"@interfere/types/releases/slug\";\nimport { readFirstEnvValue } from \"@interfere/types/sdk/env\";\n\nimport { runGitCommand } from \"./build/release/git.js\";\n\n/**\n * Walks the same env keys at build time (`withInterfere`) and at runtime\n * (server-side `register()`), then falls back to `git rev-parse HEAD`. Both\n * call sites resolving the same SHA → both derive the same `release.slug`,\n * so server and client spans agree by construction.\n *\n * Override path for non-CI builds: set `INTERFERE_SOURCE_ID` (or any other\n * key in `releaseSourceIdEnvKeys`) on both the build env and the runtime\n * env. The `interfere.buildId` next.config knob was removed in 10.0 because\n * it only worked at build time and caused server/client slug drift.\n *\n * `runGitCommand` (`node:child_process`) keeps this module on the Node side\n * of `@interfere/next`'s dual entry — the edge entrypoint\n * (`instrumentation.edge.ts`) intentionally doesn't import this file.\n */\nexport function resolveCommitSha(): string | null {\n return (\n readFirstEnvValue(process.env, releaseSourceIdEnvKeys) ??\n runGitCommand(\"git rev-parse HEAD\")\n );\n}\n\nexport function resolveReleaseSlug(): {\n commitSha: string | null;\n slug: ReleaseSlug | null;\n} {\n const commitSha = resolveCommitSha();\n return {\n commitSha,\n slug: commitSha ? deriveReleaseSlug(commitSha) : null,\n };\n}\n"],"mappings":"2OAwBA,SAAgB,kBAAkC,CAChD,OACE,kBAAkB,QAAQ,IAAK,sBAAsB,GACrD,cAAc,oBAAoB,CAEtC,CAEA,SAAgB,oBAGd,CACA,IAAM,UAAY,iBAAiB,EACnC,MAAO,CACL,UACA,KAAM,UAAY,kBAAkB,SAAS,EAAI,IACnD,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"handle-get.d.mts","names":[],"sources":["../../../src/internal/route/handle-get.ts"],"mappings":";;AAoCA;;;;;;;;;;;;iBAAsB,SAAA,CAAU,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA"}
1
+ {"version":3,"file":"handle-get.d.mts","names":[],"sources":["../../../src/internal/route/handle-get.ts"],"mappings":";;AAqCA;;;;;;;;;;;;iBAAsB,SAAA,CAAU,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA"}
@@ -1,43 +1 @@
1
- import { log } from "../logger.mjs";
2
- import { extractSubPath, formatProxyError, forwardToCollector, notConfiguredResponse, resolveAuthenticatedEnv } from "./proxy.mjs";
3
- import { SW_SCRIPT } from "@interfere/react/sw";
4
- //#region src/internal/route/handle-get.ts
5
- const SW_HEADERS = {
6
- "content-type": "application/javascript; charset=utf-8",
7
- "service-worker-allowed": "/",
8
- "cache-control": "public, max-age=3600"
9
- };
10
- /**
11
- * Generic GET proxy. SDK 10.x routes `GET /v2/config` (and any future
12
- * GET-based endpoints) through here; SDK 9.x clients still hit
13
- * `GET /v1/config` and get the same delegated response on the collector
14
- * side.
15
- *
16
- * `/sw` is special-cased to serve the SDK's bundled service-worker
17
- * script directly out of the customer's Next.js process. `SW_SCRIPT`
18
- * is a string export emitted at @interfere/react build time
19
- * (`scripts/build-sw.ts`); on Node runtime the customer resolves it
20
- * via `node_modules`, on Edge runtime the customer's Next.js bundler
21
- * inlines it into the Edge worker. Either way, no `fs.readFileSync`.
22
- */
23
- async function handleGet(request) {
24
- const subPath = extractSubPath(request);
25
- if (subPath === "/sw") return new Response(SW_SCRIPT, {
26
- status: 200,
27
- headers: SW_HEADERS
28
- });
29
- const env = resolveAuthenticatedEnv();
30
- if (!env) return notConfiguredResponse();
31
- try {
32
- return await forwardToCollector(request, env, subPath);
33
- } catch (error) {
34
- const detail = formatProxyError(error);
35
- log.error(`Proxy ${request.method} ${subPath} failed`, detail.lines);
36
- return Response.json({
37
- code: "INTERFERE_PROXY_ERROR",
38
- message: detail.message
39
- }, { status: 502 });
40
- }
41
- }
42
- //#endregion
43
- export { handleGet };
1
+ import{log}from"../logger.mjs";import{extractSubPath,formatProxyError,forwardToCollector,hasPublicKeyCredential,notConfiguredResponse,resolveAuthenticatedEnv}from"./proxy.mjs";import{SW_SCRIPT}from"@interfere/react/sw";const SW_HEADERS={"content-type":`application/javascript; charset=utf-8`,"service-worker-allowed":`/`,"cache-control":`public, max-age=3600`};async function handleGet(request){let subPath=extractSubPath(request);if(subPath===`/sw`)return new Response(SW_SCRIPT,{status:200,headers:SW_HEADERS});let env=resolveAuthenticatedEnv();if(!hasPublicKeyCredential(request,env.publicKey))return notConfiguredResponse();try{return await forwardToCollector(request,env,subPath)}catch(error){let detail=formatProxyError(error);return log.error(`Proxy ${request.method} ${subPath} failed`,detail.lines),Response.json({code:`INTERFERE_PROXY_ERROR`,message:detail.message},{status:502})}}export{handleGet};
@@ -1 +1 @@
1
- {"version":3,"file":"handle-get.mjs","names":[],"sources":["../../../src/internal/route/handle-get.ts"],"sourcesContent":["import { SW_SCRIPT } from \"@interfere/react/sw\";\n\nimport { log } from \"../logger.js\";\nimport {\n extractSubPath,\n formatProxyError,\n forwardToCollector,\n notConfiguredResponse,\n resolveAuthenticatedEnv,\n} from \"./proxy.js\";\n\nconst SW_HEADERS: Record<string, string> = {\n \"content-type\": \"application/javascript; charset=utf-8\",\n // Allow the SW to control the whole origin, not just `/api/interfere/`.\n // The SDK still scopes its `register()` call narrowly; this header just\n // unlocks the option without re-issuing a new SW URL.\n \"service-worker-allowed\": \"/\",\n // Customers' edges (Vercel, Cloudflare) cache aggressively by default;\n // a 1-hour TTL balances \"pick up SW updates within a deploy cycle\"\n // against \"don't refetch on every navigation\".\n \"cache-control\": \"public, max-age=3600\",\n};\n\n/**\n * Generic GET proxy. SDK 10.x routes `GET /v2/config` (and any future\n * GET-based endpoints) through here; SDK 9.x clients still hit\n * `GET /v1/config` and get the same delegated response on the collector\n * side.\n *\n * `/sw` is special-cased to serve the SDK's bundled service-worker\n * script directly out of the customer's Next.js process. `SW_SCRIPT`\n * is a string export emitted at @interfere/react build time\n * (`scripts/build-sw.ts`); on Node runtime the customer resolves it\n * via `node_modules`, on Edge runtime the customer's Next.js bundler\n * inlines it into the Edge worker. Either way, no `fs.readFileSync`.\n */\nexport async function handleGet(request: Request): Promise<Response> {\n const subPath = extractSubPath(request);\n\n if (subPath === \"/sw\") {\n return new Response(SW_SCRIPT, { status: 200, headers: SW_HEADERS });\n }\n\n const env = resolveAuthenticatedEnv();\n if (!env) {\n return notConfiguredResponse();\n }\n try {\n return await forwardToCollector(request, env, subPath);\n } catch (error) {\n const detail = formatProxyError(error);\n log.error(`Proxy ${request.method} ${subPath} failed`, detail.lines);\n return Response.json(\n { code: \"INTERFERE_PROXY_ERROR\", message: detail.message },\n { status: 502 }\n );\n }\n}\n"],"mappings":";;;;AAWA,MAAM,aAAqC;CACzC,gBAAgB;CAIhB,0BAA0B;CAI1B,iBAAiB;CAClB;;;;;;;;;;;;;;AAeD,eAAsB,UAAU,SAAqC;CACnE,MAAM,UAAU,eAAe,QAAQ;CAEvC,IAAI,YAAY,OACd,OAAO,IAAI,SAAS,WAAW;EAAE,QAAQ;EAAK,SAAS;EAAY,CAAC;CAGtE,MAAM,MAAM,yBAAyB;CACrC,IAAI,CAAC,KACH,OAAO,uBAAuB;CAEhC,IAAI;EACF,OAAO,MAAM,mBAAmB,SAAS,KAAK,QAAQ;UAC/C,OAAO;EACd,MAAM,SAAS,iBAAiB,MAAM;EACtC,IAAI,MAAM,SAAS,QAAQ,OAAO,GAAG,QAAQ,UAAU,OAAO,MAAM;EACpE,OAAO,SAAS,KACd;GAAE,MAAM;GAAyB,SAAS,OAAO;GAAS,EAC1D,EAAE,QAAQ,KAAK,CAChB"}
1
+ {"version":3,"file":"handle-get.mjs","names":[],"sources":["../../../src/internal/route/handle-get.ts"],"sourcesContent":["import { SW_SCRIPT } from \"@interfere/react/sw\";\n\nimport { log } from \"../logger.js\";\nimport {\n extractSubPath,\n formatProxyError,\n forwardToCollector,\n hasPublicKeyCredential,\n notConfiguredResponse,\n resolveAuthenticatedEnv,\n} from \"./proxy.js\";\n\nconst SW_HEADERS: Record<string, string> = {\n \"content-type\": \"application/javascript; charset=utf-8\",\n // Allow the SW to control the whole origin, not just `/api/interfere/`.\n // The SDK still scopes its `register()` call narrowly; this header just\n // unlocks the option without re-issuing a new SW URL.\n \"service-worker-allowed\": \"/\",\n // Customers' edges (Vercel, Cloudflare) cache aggressively by default;\n // a 1-hour TTL balances \"pick up SW updates within a deploy cycle\"\n // against \"don't refetch on every navigation\".\n \"cache-control\": \"public, max-age=3600\",\n};\n\n/**\n * Generic GET proxy. SDK 10.x routes `GET /v2/config` (and any future\n * GET-based endpoints) through here; SDK 9.x clients still hit\n * `GET /v1/config` and get the same delegated response on the collector\n * side.\n *\n * `/sw` is special-cased to serve the SDK's bundled service-worker\n * script directly out of the customer's Next.js process. `SW_SCRIPT`\n * is a string export emitted at @interfere/react build time\n * (`scripts/build-sw.ts`); on Node runtime the customer resolves it\n * via `node_modules`, on Edge runtime the customer's Next.js bundler\n * inlines it into the Edge worker. Either way, no `fs.readFileSync`.\n */\nexport async function handleGet(request: Request): Promise<Response> {\n const subPath = extractSubPath(request);\n\n if (subPath === \"/sw\") {\n return new Response(SW_SCRIPT, { status: 200, headers: SW_HEADERS });\n }\n\n const env = resolveAuthenticatedEnv();\n if (!hasPublicKeyCredential(request, env.publicKey)) {\n return notConfiguredResponse();\n }\n try {\n return await forwardToCollector(request, env, subPath);\n } catch (error) {\n const detail = formatProxyError(error);\n log.error(`Proxy ${request.method} ${subPath} failed`, detail.lines);\n return Response.json(\n { code: \"INTERFERE_PROXY_ERROR\", message: detail.message },\n { status: 502 }\n );\n }\n}\n"],"mappings":"2NAYA,MAAM,WAAqC,CACzC,eAAgB,wCAIhB,yBAA0B,IAI1B,gBAAiB,sBACnB,EAeA,eAAsB,UAAU,QAAqC,CACnE,IAAM,QAAU,eAAe,OAAO,EAEtC,GAAI,UAAY,MACd,OAAO,IAAI,SAAS,UAAW,CAAE,OAAQ,IAAK,QAAS,UAAW,CAAC,EAGrE,IAAM,IAAM,wBAAwB,EACpC,GAAI,CAAC,uBAAuB,QAAS,IAAI,SAAS,EAChD,OAAO,sBAAsB,EAE/B,GAAI,CACF,OAAO,MAAM,mBAAmB,QAAS,IAAK,OAAO,CACvD,OAAS,MAAO,CACd,IAAM,OAAS,iBAAiB,KAAK,EAErC,OADA,IAAI,MAAM,SAAS,QAAQ,OAAO,GAAG,QAAQ,SAAU,OAAO,KAAK,EAC5D,SAAS,KACd,CAAE,KAAM,wBAAyB,QAAS,OAAO,OAAQ,EACzD,CAAE,OAAQ,GAAI,CAChB,CACF,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"handle-post.d.mts","names":[],"sources":["../../../src/internal/route/handle-post.ts"],"mappings":";;AAoBA;;;;;;;;;;iBAAsB,UAAA,CAAW,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA"}
1
+ {"version":3,"file":"handle-post.d.mts","names":[],"sources":["../../../src/internal/route/handle-post.ts"],"mappings":";;AAqBA;;;;;;;;;;iBAAsB,UAAA,CAAW,OAAA,EAAS,OAAA,GAAU,OAAA,CAAQ,QAAA"}
@@ -1,31 +1 @@
1
- import { log } from "../logger.mjs";
2
- import { extractSubPath, formatProxyError, forwardToCollector, notConfiguredResponse, resolveAuthenticatedEnv } from "./proxy.mjs";
3
- //#region src/internal/route/handle-post.ts
4
- /**
5
- * Generic POST proxy. SDK 10.x routes everything through here:
6
- *
7
- * - `/v2/sink` (OTLP traces / metrics / logs)
8
- * - `/v2/replay/upload/:sessionId`
9
- * - `/v1/session*` (session sync + identify)
10
- *
11
- * No envelope-aware special-casing — that endpoint (`/v1/ingest`) was
12
- * 9.x-only and is not produced by 10.x. Customers on 9.x post directly
13
- * to the collector through the same proxy without touching this file.
14
- */
15
- async function handlePost(request) {
16
- const env = resolveAuthenticatedEnv();
17
- if (!env) return notConfiguredResponse();
18
- const subPath = extractSubPath(request);
19
- try {
20
- return await forwardToCollector(request, env, subPath);
21
- } catch (error) {
22
- const detail = formatProxyError(error);
23
- log.error(`Proxy ${request.method} ${subPath} failed`, detail.lines);
24
- return Response.json({
25
- code: "INTERFERE_PROXY_ERROR",
26
- message: detail.message
27
- }, { status: 502 });
28
- }
29
- }
30
- //#endregion
31
- export { handlePost };
1
+ import{log}from"../logger.mjs";import{extractSubPath,formatProxyError,forwardToCollector,hasPublicKeyCredential,notConfiguredResponse,resolveAuthenticatedEnv}from"./proxy.mjs";async function handlePost(request){let env=resolveAuthenticatedEnv();if(!hasPublicKeyCredential(request,env.publicKey))return notConfiguredResponse();let subPath=extractSubPath(request);try{return await forwardToCollector(request,env,subPath)}catch(error){let detail=formatProxyError(error);return log.error(`Proxy ${request.method} ${subPath} failed`,detail.lines),Response.json({code:`INTERFERE_PROXY_ERROR`,message:detail.message},{status:502})}}export{handlePost};
@@ -1 +1 @@
1
- {"version":3,"file":"handle-post.mjs","names":[],"sources":["../../../src/internal/route/handle-post.ts"],"sourcesContent":["import { log } from \"../logger.js\";\nimport {\n extractSubPath,\n formatProxyError,\n forwardToCollector,\n notConfiguredResponse,\n resolveAuthenticatedEnv,\n} from \"./proxy.js\";\n\n/**\n * Generic POST proxy. SDK 10.x routes everything through here:\n *\n * - `/v2/sink` (OTLP traces / metrics / logs)\n * - `/v2/replay/upload/:sessionId`\n * - `/v1/session*` (session sync + identify)\n *\n * No envelope-aware special-casing — that endpoint (`/v1/ingest`) was\n * 9.x-only and is not produced by 10.x. Customers on 9.x post directly\n * to the collector through the same proxy without touching this file.\n */\nexport async function handlePost(request: Request): Promise<Response> {\n const env = resolveAuthenticatedEnv();\n if (!env) {\n return notConfiguredResponse();\n }\n const subPath = extractSubPath(request);\n try {\n return await forwardToCollector(request, env, subPath);\n } catch (error) {\n const detail = formatProxyError(error);\n log.error(`Proxy ${request.method} ${subPath} failed`, detail.lines);\n return Response.json(\n { code: \"INTERFERE_PROXY_ERROR\", message: detail.message },\n { status: 502 }\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAoBA,eAAsB,WAAW,SAAqC;CACpE,MAAM,MAAM,yBAAyB;CACrC,IAAI,CAAC,KACH,OAAO,uBAAuB;CAEhC,MAAM,UAAU,eAAe,QAAQ;CACvC,IAAI;EACF,OAAO,MAAM,mBAAmB,SAAS,KAAK,QAAQ;UAC/C,OAAO;EACd,MAAM,SAAS,iBAAiB,MAAM;EACtC,IAAI,MAAM,SAAS,QAAQ,OAAO,GAAG,QAAQ,UAAU,OAAO,MAAM;EACpE,OAAO,SAAS,KACd;GAAE,MAAM;GAAyB,SAAS,OAAO;GAAS,EAC1D,EAAE,QAAQ,KAAK,CAChB"}
1
+ {"version":3,"file":"handle-post.mjs","names":[],"sources":["../../../src/internal/route/handle-post.ts"],"sourcesContent":["import { log } from \"../logger.js\";\nimport {\n extractSubPath,\n formatProxyError,\n forwardToCollector,\n hasPublicKeyCredential,\n notConfiguredResponse,\n resolveAuthenticatedEnv,\n} from \"./proxy.js\";\n\n/**\n * Generic POST proxy. SDK 10.x routes everything through here:\n *\n * - `/v2/sink` (OTLP traces / metrics / logs)\n * - `/v2/replay/upload/:sessionId`\n * - `/v1/session*` (session sync + identify)\n *\n * No envelope-aware special-casing — that endpoint (`/v1/ingest`) was\n * 9.x-only and is not produced by 10.x. Customers on 9.x post directly\n * to the collector through the same proxy without touching this file.\n */\nexport async function handlePost(request: Request): Promise<Response> {\n const env = resolveAuthenticatedEnv();\n if (!hasPublicKeyCredential(request, env.publicKey)) {\n return notConfiguredResponse();\n }\n const subPath = extractSubPath(request);\n try {\n return await forwardToCollector(request, env, subPath);\n } catch (error) {\n const detail = formatProxyError(error);\n log.error(`Proxy ${request.method} ${subPath} failed`, detail.lines);\n return Response.json(\n { code: \"INTERFERE_PROXY_ERROR\", message: detail.message },\n { status: 502 }\n );\n }\n}\n"],"mappings":"gLAqBA,eAAsB,WAAW,QAAqC,CACpE,IAAM,IAAM,wBAAwB,EACpC,GAAI,CAAC,uBAAuB,QAAS,IAAI,SAAS,EAChD,OAAO,sBAAsB,EAE/B,IAAM,QAAU,eAAe,OAAO,EACtC,GAAI,CACF,OAAO,MAAM,mBAAmB,QAAS,IAAK,OAAO,CACvD,OAAS,MAAO,CACd,IAAM,OAAS,iBAAiB,KAAK,EAErC,OADA,IAAI,MAAM,SAAS,QAAQ,OAAO,GAAG,QAAQ,SAAU,OAAO,KAAK,EAC5D,SAAS,KACd,CAAE,KAAM,wBAAyB,QAAS,OAAO,OAAQ,EACzD,CAAE,OAAQ,GAAI,CAChB,CACF,CACF"}