{"version":3,"file":"index.cjs","names":["randomString","THIRTY_MB_IN_BYTES","resolveGitHash","ROLLUP_PLUGIN_NAME","MagicString","faroGitHashSnippet","faroBundleIdSnippet","shouldProcessFile","consoleInfoOrange","uploadCompressedSourceMaps","uploadSourceMap"],"sources":["../../src/index.ts"],"sourcesContent":["import type { Plugin, OutputOptions, OutputBundle } from \"rollup\";\nimport MagicString from \"magic-string\";\nimport {\n  ROLLUP_PLUGIN_NAME,\n  FaroSourceMapUploaderPluginOptions,\n  faroBundleIdSnippet,\n  faroGitHashSnippet,\n  resolveGitHash,\n  randomString,\n  consoleInfoOrange,\n  uploadSourceMap,\n  uploadCompressedSourceMaps,\n  THIRTY_MB_IN_BYTES,\n  exportBundleIdToFile,\n  shouldProcessFile,\n  modifySourceMapFileProperty,\n} from \"@grafana/faro-bundlers-shared\";\n\nimport fs from \"fs\";\nimport path from \"path\";\n\nexport default function faroUploader(\n  pluginOptions: FaroSourceMapUploaderPluginOptions\n): Plugin {\n  const {\n    endpoint,\n    appId,\n    apiKey,\n    stackId,\n    appName,\n    outputFiles,\n    keepSourcemaps,\n    gzipContents,\n    verbose,\n    skipUpload,\n    proxy,\n    prefixPath,\n    prefixPathBasenameOnly,\n  } = pluginOptions;\n  const bundleId =\n    pluginOptions.bundleId ?? String(Date.now() + randomString(5));\n  const uploadEndpoint = `${endpoint}/app/${appId}/sourcemaps/`;\n  const maxSize = pluginOptions.maxUploadSize && pluginOptions.maxUploadSize > 0\n    ? pluginOptions.maxUploadSize\n    : THIRTY_MB_IN_BYTES;\n  const gitHash = resolveGitHash(pluginOptions.gitHash);\n  if (!gitHash) {\n    consoleInfoOrange(`Git hash could not be resolved. window.__faroGitHash_${appName} will not be injected.`);\n  }\n\n  // Export bundleId to environment variable if skipUpload is true\n  if (skipUpload) {\n    exportBundleIdToFile(bundleId, appName, verbose);\n  }\n\n  return {\n    name: ROLLUP_PLUGIN_NAME,\n    /**\n     * Renders a chunk of code and generates a source map with a bundleId code snippet injected at the end.\n     * @param code The original code of the chunk.\n     * @param chunk The chunk object containing information about the file.\n     * @returns An object with the rendered code and the generated source map, or null if the chunk's file extension does not match the patterns.\n     */\n    renderChunk(code, chunk) {\n      if (chunk.fileName.match(/\\.(js|ts|jsx|tsx|mjs|cjs)$/)) {\n        const newCode = new MagicString(code);\n\n        newCode.prepend((gitHash ? faroGitHashSnippet(gitHash, appName) : '') + faroBundleIdSnippet(bundleId, appName));\n\n        const map = newCode.generateMap({\n          source: chunk.fileName,\n          file: `${chunk.fileName}.map`,\n        });\n\n        return {\n          code: newCode.toString(),\n          map,\n        };\n      }\n\n      return null;\n    },\n    async writeBundle(options: OutputOptions, bundle: OutputBundle) {\n      // handle both dir and file output modes\n      const outputPath = options.dir || (options.file ? path.dirname(options.file) : process.cwd());\n\n      // modify source map file properties if prefixPath is provided (do this regardless of skipUpload)\n      // NOTE: we scan the output directory directly rather than iterating the bundle object because\n      // Vite (and some Rollup configurations) write source maps to subdirectories (e.g. assets/)\n      // and those files may not appear as separate entries in the OutputBundle.\n      if (prefixPath) {\n        try {\n          const filenames = fs.readdirSync(outputPath, { recursive: true });\n          for (const filename of filenames) {\n            const filenameStr = filename.toString();\n            // Only include JavaScript-related source maps or match the outputFiles regex\n            if (!shouldProcessFile(filenameStr, outputFiles)) {\n              continue;\n            }\n            const filePath = path.join(outputPath, filenameStr);\n            if (fs.existsSync(filePath)) {\n              modifySourceMapFileProperty(filePath, prefixPath, verbose, prefixPathBasenameOnly);\n            }\n          }\n        } catch (e) {\n          console.error('Error modifying source maps:', e);\n        }\n      }\n\n      // Skip uploading if skipUpload is true\n      if (skipUpload) {\n        verbose && consoleInfoOrange(`Skipping sourcemap upload as skipUpload is set to true`);\n        return;\n      }\n\n      const uploadedSourcemaps = [];\n\n      try {\n        const sourcemapEndpoint = uploadEndpoint + bundleId;\n        const filesToUpload = [];\n        let totalSize = 0;\n\n        for (let filename in bundle) {\n          // Only include JavaScript-related source maps or match the outputFiles regex\n          if (!shouldProcessFile(filename, outputFiles)) {\n            continue;\n          }\n\n          // if we are tar/gzipping contents, collect N files and upload them all at once\n          // total size of all files uploaded at once must be less than the configured max size (uncompressed)\n          if (gzipContents) {\n            const file = path.join(outputPath, filename);\n            const { size } = fs.statSync(file);\n\n            filesToUpload.push(file);\n            totalSize += size;\n\n            if (totalSize > maxSize) {\n              filesToUpload.pop();\n              const result = await uploadCompressedSourceMaps({\n                sourcemapEndpoint,\n                apiKey,\n                stackId,\n                outputPath,\n                files: filesToUpload,\n                keepSourcemaps: !!keepSourcemaps,\n                verbose: verbose,\n                proxy: proxy,\n              });\n\n              if (result) {\n                uploadedSourcemaps.push(...filesToUpload);\n              }\n\n              filesToUpload.length = 0;\n              filesToUpload.push(file);\n              totalSize = size;\n            }\n          }\n\n          // if we are not compressing, upload each file individually\n          if (!gzipContents) {\n            const result = await uploadSourceMap({\n              sourcemapEndpoint,\n              apiKey,\n              stackId,\n              filename,\n              filePath: path.join(outputPath, filename),\n              keepSourcemaps: !!keepSourcemaps,\n              verbose: verbose,\n              proxy: proxy,\n            });\n\n            if (result) {\n              uploadedSourcemaps.push(filename);\n            }\n          }\n        }\n\n        // upload any remaining files\n        if (filesToUpload.length) {\n          const result = await uploadCompressedSourceMaps({\n            sourcemapEndpoint,\n            apiKey,\n            stackId,\n            outputPath,\n            files: filesToUpload,\n            keepSourcemaps: !!keepSourcemaps,\n            verbose: verbose,\n            proxy: proxy,\n          });\n\n          if (result) {\n            uploadedSourcemaps.push(...filesToUpload);\n          }\n        }\n      } catch (e) {\n        console.error(e);\n      }\n\n      if (verbose) {\n        consoleInfoOrange(\n          uploadedSourcemaps.length\n            ? `Uploaded sourcemaps: ${uploadedSourcemaps.map(map => map.split('/').pop()).join(\", \")}`\n            : \"No sourcemaps uploaded\"\n        );\n      }\n    },\n  };\n}\n"],"mappings":"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"}