{"version":3,"sources":["../../src/trace/trace-uploader.ts"],"sourcesContent":["import findUp from 'next/dist/compiled/find-up'\nimport fsPromise from 'fs/promises'\nimport child_process from 'child_process'\nimport assert from 'assert'\nimport os from 'os'\nimport { createInterface } from 'readline'\nimport { createReadStream } from 'fs'\nimport path from 'path'\n\nconst COMMON_ALLOWED_EVENTS = ['memory-usage']\n\n// Predefined set of the event names to be included in the trace.\n// If the trace span's name matches to one of the event names in the set,\n// it'll up uploaded to the trace server.\nconst DEV_ALLOWED_EVENTS = new Set([\n  ...COMMON_ALLOWED_EVENTS,\n  'client-hmr-latency',\n  'render-path',\n  'hot-reloader',\n  'webpack-invalid-client',\n  'webpack-invalidated-server',\n  'navigation-to-hydration',\n  'start-dev-server',\n  'compile-path',\n  'memory-usage',\n  'server-restart-close-to-memory-threshold',\n])\n\nconst BUILD_ALLOWED_EVENTS = new Set([\n  ...COMMON_ALLOWED_EVENTS,\n  'next-build',\n  'run-turbopack',\n  'webpack-compilation',\n  'run-webpack-compiler',\n  'create-entrypoints',\n  'worker-main-edge-server',\n  'worker-main-client',\n  'worker-main-server',\n  'server',\n  'make',\n  'seal',\n  'chunk-graph',\n  'optimize-modules',\n  'optimize-chunks',\n  'optimize',\n  'optimize-tree',\n  'optimize-chunk-modules',\n  'module-hash',\n  'client',\n  'static-check',\n  'node-file-trace-build',\n  'static-generation',\n  'next-export',\n  'run-typescript',\n  'run-eslint',\n])\n\nconst {\n  NEXT_TRACE_UPLOAD_DEBUG,\n  // An external env to allow to upload full trace without picking up the relavant spans.\n  // This is mainly for the debugging purpose, to allow manual audit for full trace for the given build.\n  // [NOTE] This may fail if build is large and generated trace is excessively large.\n  NEXT_TRACE_UPLOAD_FULL,\n} = process.env\n\nconst isDebugEnabled = !!NEXT_TRACE_UPLOAD_DEBUG || !!NEXT_TRACE_UPLOAD_FULL\nconst shouldUploadFullTrace = !!NEXT_TRACE_UPLOAD_FULL\n\nconst [\n  ,\n  ,\n  traceUploadUrl,\n  mode,\n  projectDir,\n  distDir,\n  _isTurboSession,\n  traceId,\n  anonymousId,\n  sessionId,\n] = process.argv\nconst isTurboSession = _isTurboSession === 'true'\n\ntype TraceRequestBody = {\n  metadata: TraceMetadata\n  traces: TraceEvent[][]\n}\n\ninterface TraceEvent {\n  traceId: string\n  parentId?: number\n  name: string\n  id: number\n  startTime: number\n  timestamp: number\n  duration: number\n  tags: Record<string, unknown>\n}\n\ninterface TraceMetadata {\n  anonymousId: string\n  arch: string\n  branch: string\n  commit: string\n  cpus: number\n  isVercelEnvironment: boolean\n  isTurboSession: boolean\n  mode: string\n  nextVersion: string\n  pkgName: string\n  platform: string\n  sessionId: string\n  enabledFeatures: Record<string, unknown>\n}\n\n;(async function upload() {\n  const nextVersion = JSON.parse(\n    await fsPromise.readFile(\n      path.resolve(__dirname, '../../package.json'),\n      'utf8'\n    )\n  ).version\n\n  const projectPkgJsonPath = await findUp('package.json')\n  assert(projectPkgJsonPath)\n\n  const projectPkgJson = JSON.parse(\n    await fsPromise.readFile(projectPkgJsonPath, 'utf-8')\n  )\n  const pkgName = projectPkgJson.name\n\n  const git = os.platform() === 'win32' ? 'git.exe' : 'git'\n\n  const isVercelEnvironment = !!process.env.VERCEL\n\n  const commit =\n    process.env.VERCEL_GIT_COMMIT_SHA ||\n    child_process\n      .spawnSync(git, ['rev-parse', 'HEAD'])\n      .stdout.toString()\n      .trimEnd()\n\n  const branch =\n    process.env.VERCEL_GIT_COMMIT_REF ||\n    child_process\n      .spawnSync(git, ['rev-parse', '--abbrev-ref', 'HEAD'])\n      .stdout.toString()\n      .trimEnd()\n\n  const readLineInterface = createInterface({\n    input: createReadStream(path.join(projectDir, distDir, 'trace')),\n    crlfDelay: Infinity,\n  })\n\n  const sessionTrace = []\n  let sessionEnabledFeatures: Record<string, unknown> = {}\n  const spanEnabledFeatures = new Map<number, Record<string, unknown>>()\n\n  for await (const line of readLineInterface) {\n    const lineEvents: TraceEvent[] = JSON.parse(line)\n    for (const event of lineEvents) {\n      if (event.traceId !== traceId) {\n        // Only consider events for the current session\n        continue\n      }\n\n      // Extract enabled features from the root span (next-dev or next-build)\n      if (\n        event.parentId === undefined &&\n        event.tags &&\n        (event.name === 'next-dev' || event.name === 'next-build')\n      ) {\n        for (const [key, value] of Object.entries(event.tags)) {\n          if (key.startsWith('feature.')) {\n            sessionEnabledFeatures[key] = value\n          }\n        }\n      }\n\n      // Collect feature tags from all events for inheritance\n      if (event.tags) {\n        const enabledFeatures: Record<string, unknown> = {}\n        for (const [key, value] of Object.entries(event.tags)) {\n          if (key.startsWith('feature.')) {\n            enabledFeatures[key] = value\n          }\n        }\n        if (Object.keys(enabledFeatures).length > 0) {\n          spanEnabledFeatures.set(event.id, enabledFeatures)\n        }\n      }\n\n      if (\n        // Always include root spans\n        event.parentId === undefined ||\n        shouldUploadFullTrace ||\n        (mode === 'dev'\n          ? DEV_ALLOWED_EVENTS.has(event.name)\n          : BUILD_ALLOWED_EVENTS.has(event.name))\n      ) {\n        sessionTrace.push(event)\n      }\n    }\n  }\n\n  // Apply feature tag inheritance to session trace\n  const sessionTraceWithInheritance = sessionTrace.map((event) => {\n    if (event.parentId !== undefined) {\n      const parentFlags = spanEnabledFeatures.get(event.parentId)\n      if (parentFlags && Object.keys(parentFlags).length > 0) {\n        // Inherit parent flags, but child's own tags take precedence\n        return { ...event, tags: { ...parentFlags, ...event.tags } }\n      }\n    }\n    return event\n  })\n\n  const body: TraceRequestBody = {\n    metadata: {\n      anonymousId,\n      arch: os.arch(),\n      branch,\n      commit,\n      cpus: os.cpus().length,\n      isVercelEnvironment,\n      isTurboSession,\n      mode,\n      nextVersion,\n      pkgName,\n      platform: os.platform(),\n      sessionId,\n      enabledFeatures: sessionEnabledFeatures,\n    },\n    // The trace file can contain events spanning multiple sessions.\n    // Only submit traces for the current session, as the metadata we send is\n    // intended for this session only.\n    traces: [sessionTraceWithInheritance],\n  }\n\n  if (isDebugEnabled) {\n    console.log('Sending request with body', JSON.stringify(body, null, 2))\n  }\n\n  let res = await fetch(traceUploadUrl, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'x-trace-transfer-mode': shouldUploadFullTrace ? 'full' : 'default',\n    },\n    body: JSON.stringify(body),\n  })\n\n  if (isDebugEnabled) {\n    console.log('Received response', res.status, await res.json())\n  }\n})()\n"],"names":["COMMON_ALLOWED_EVENTS","DEV_ALLOWED_EVENTS","Set","BUILD_ALLOWED_EVENTS","NEXT_TRACE_UPLOAD_DEBUG","NEXT_TRACE_UPLOAD_FULL","process","env","isDebugEnabled","shouldUploadFullTrace","traceUploadUrl","mode","projectDir","distDir","_isTurboSession","traceId","anonymousId","sessionId","argv","isTurboSession","upload","nextVersion","JSON","parse","fsPromise","readFile","path","resolve","__dirname","version","projectPkgJsonPath","findUp","assert","projectPkgJson","pkgName","name","git","os","platform","isVercelEnvironment","VERCEL","commit","VERCEL_GIT_COMMIT_SHA","child_process","spawnSync","stdout","toString","trimEnd","branch","VERCEL_GIT_COMMIT_REF","readLineInterface","createInterface","input","createReadStream","join","crlfDelay","Infinity","sessionTrace","sessionEnabledFeatures","spanEnabledFeatures","Map","line","lineEvents","event","parentId","undefined","tags","key","value","Object","entries","startsWith","enabledFeatures","keys","length","set","id","has","push","sessionTraceWithInheritance","map","parentFlags","get","body","metadata","arch","cpus","traces","console","log","stringify","res","fetch","method","headers","status","json"],"mappings":"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","ignoreList":[0]}