@sentry/bundler-plugins 11.0.0-alpha.0 → 11.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/core/build-plugin-manager.js +43 -72
- package/build/cjs/core/build-plugin-manager.js.map +1 -1
- package/build/cjs/core/cli.js +134 -0
- package/build/cjs/core/cli.js.map +1 -0
- package/build/cjs/core/index.js +1 -23
- package/build/cjs/core/index.js.map +1 -1
- package/build/cjs/core/options-mapping.js.map +1 -1
- package/build/cjs/core/sentry/telemetry.js +3 -23
- package/build/cjs/core/sentry/telemetry.js.map +1 -1
- package/build/cjs/core/utils.js +0 -6
- package/build/cjs/core/utils.js.map +1 -1
- package/build/cjs/core/version.js +1 -1
- package/build/cjs/core/version.js.map +1 -1
- package/build/cjs/esbuild/index.js +0 -1
- package/build/cjs/esbuild/index.js.map +1 -1
- package/build/cjs/rollup/index.js +0 -1
- package/build/cjs/rollup/index.js.map +1 -1
- package/build/cjs/vite/index.js +2 -4
- package/build/cjs/vite/index.js.map +1 -1
- package/build/cjs/webpack/index.js +0 -2
- package/build/cjs/webpack/index.js.map +1 -1
- package/build/cjs/webpack/webpack5.js +0 -2
- package/build/cjs/webpack/webpack5.js.map +1 -1
- package/build/esm/core/build-plugin-manager.js +45 -71
- package/build/esm/core/build-plugin-manager.js.map +1 -1
- package/build/esm/core/cli.js +132 -0
- package/build/esm/core/cli.js.map +1 -0
- package/build/esm/core/index.js +2 -6
- package/build/esm/core/index.js.map +1 -1
- package/build/esm/core/options-mapping.js.map +1 -1
- package/build/esm/core/sentry/telemetry.js +3 -19
- package/build/esm/core/sentry/telemetry.js.map +1 -1
- package/build/esm/core/utils.js +1 -6
- package/build/esm/core/utils.js.map +1 -1
- package/build/esm/core/version.js +1 -1
- package/build/esm/core/version.js.map +1 -1
- package/build/esm/esbuild/index.js +0 -1
- package/build/esm/esbuild/index.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/rollup/index.js +0 -1
- package/build/esm/rollup/index.js.map +1 -1
- package/build/esm/vite/index.js +0 -1
- package/build/esm/vite/index.js.map +1 -1
- package/build/esm/webpack/index.js +0 -1
- package/build/esm/webpack/index.js.map +1 -1
- package/build/esm/webpack/webpack5.js +0 -1
- package/build/esm/webpack/webpack5.js.map +1 -1
- package/build/types/core/build-plugin-manager.d.ts.map +1 -1
- package/build/types/core/cli.d.ts +50 -0
- package/build/types/core/cli.d.ts.map +1 -0
- package/build/types/core/index.d.ts +0 -6
- package/build/types/core/index.d.ts.map +1 -1
- package/build/types/core/options-mapping.d.ts +1 -0
- package/build/types/core/options-mapping.d.ts.map +1 -1
- package/build/types/core/sentry/telemetry.d.ts.map +1 -1
- package/build/types/core/types.d.ts +17 -12
- package/build/types/core/types.d.ts.map +1 -1
- package/build/types/core/utils.d.ts +0 -6
- package/build/types/core/utils.d.ts.map +1 -1
- package/build/types/core/version.d.ts +1 -1
- package/build/types/esbuild/index.d.ts +0 -1
- package/build/types/esbuild/index.d.ts.map +1 -1
- package/build/types/rollup/index.d.ts +0 -1
- package/build/types/rollup/index.d.ts.map +1 -1
- package/build/types/vite/index.d.ts +0 -1
- package/build/types/vite/index.d.ts.map +1 -1
- package/build/types/webpack/index.d.ts +0 -1
- package/build/types/webpack/index.d.ts.map +1 -1
- package/build/types/webpack/webpack5.d.ts +0 -1
- package/build/types/webpack/webpack5.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-plugin-manager.js","sources":["../../../src/core/build-plugin-manager.ts"],"sourcesContent":["/* oxlint-disable max-lines */\nimport SentryCli from '@sentry/cli';\nimport { closeSession, DEFAULT_ENVIRONMENT, getTraceData, makeSession, setMeasurement, startSpan } from '@sentry/core';\nimport * as dotenv from 'dotenv';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport type { NormalizedOptions } from './options-mapping';\nimport { normalizeUserOptions, validateOptions } from './options-mapping';\nimport type { Logger } from './logger';\nimport { createLogger } from './logger';\nimport { allowedToSendTelemetry, createSentryInstance, safeFlushTelemetry } from './sentry/telemetry';\nimport type { Options, SentrySDKBuildFlags } from './types';\nimport {\n arrayify,\n getProjects,\n getTurborepoEnvPassthroughWarning,\n serializeIgnoreOptions,\n stripQueryAndHashFromPath,\n} from './utils';\nimport { defaultRewriteSourcesHook, prepareBundleForDebugIdUpload } from './debug-id-upload';\nimport { globFiles } from './glob';\nimport { LIB_VERSION } from './version';\n\n// Module-level guard to prevent duplicate deploy records when multiple bundler plugin\n// instances run in the same process (e.g. Next.js creates separate webpack compilers\n// for client, server, and edge). Keyed by release name.\nconst _deployedReleases = new Set<string>();\n\n/** @internal Exported for testing only. */\nexport function _resetDeployedReleasesForTesting(): void {\n _deployedReleases.clear();\n}\n\nexport type SentryBuildPluginManager = {\n /**\n * A logger instance that takes the options passed to the build plugin manager into account. (for silencing and log level etc.)\n */\n logger: Logger;\n\n /**\n * Options after normalization. Includes things like the inferred release name.\n */\n normalizedOptions: NormalizedOptions;\n /**\n * Magic strings and their replacement values that can be used for bundle size optimizations. This already takes\n * into account the options passed to the build plugin manager.\n */\n bundleSizeOptimizationReplacementValues: SentrySDKBuildFlags;\n /**\n * Metadata that should be injected into bundles if possible. Takes into account options passed to the build plugin manager.\n */\n // See `generateModuleMetadataInjectorCode` for how this should be used exactly\n bundleMetadata: Record<string, unknown>;\n\n /**\n * Contains utility functions for emitting telemetry via the build plugin manager.\n */\n telemetry: {\n /**\n * Emits a `Sentry Bundler Plugin execution` signal.\n */\n emitBundlerPluginExecutionSignal(): Promise<void>;\n };\n\n /**\n * Will potentially create a release based on the build plugin manager options.\n *\n * Also\n * - finalizes the release\n * - sets commits\n * - uploads legacy sourcemaps\n * - adds deploy information\n */\n createRelease(): Promise<void>;\n\n /**\n * Injects debug IDs into the build artifacts.\n *\n * This is a separate function from `uploadSourcemaps` because that needs to run before the sourcemaps are uploaded.\n * Usually the respective bundler-plugin will take care of this before the sourcemaps are uploaded.\n * Only use this if you need to manually inject debug IDs into the build artifacts.\n */\n injectDebugIds(buildArtifactPaths: string[]): Promise<void>;\n\n /**\n * Uploads sourcemaps using the \"Debug ID\" method. This function takes a list of build artifact paths that will be uploaded\n */\n uploadSourcemaps(buildArtifactPaths: string[], opts?: { prepareArtifacts?: boolean }): Promise<void>;\n\n /**\n * Will delete artifacts based on the passed `sourcemaps.filesToDeleteAfterUpload` option.\n */\n deleteArtifacts(): Promise<void>;\n\n createDependencyOnBuildArtifacts: () => () => void;\n};\n\nfunction createCliInstance(options: NormalizedOptions): SentryCli {\n return new SentryCli(null, {\n authToken: options.authToken,\n org: options.org,\n // Default to the first project if multiple projects are specified\n project: getProjects(options.project)?.[0],\n silent: options.silent,\n url: options.url,\n vcsRemote: options.release.vcsRemote,\n headers: {\n ...(options.telemetry ? getTraceData() : {}),\n ...options.headers,\n },\n });\n}\n\n/**\n * Creates a build plugin manager that exposes primitives for everything that a Sentry JavaScript SDK or build tooling may do during a build.\n *\n * The build plugin manager's behavior strongly depends on the options that are passed in.\n */\nexport function createSentryBuildPluginManager(\n userOptions: Options,\n bundlerPluginMetaContext: {\n /**\n * E.g. `webpack` or `nextjs` or `turbopack`\n */\n buildTool: string;\n /**\n * E.g. `5` for webpack v5 or `4` for Rollup v4\n */\n buildToolMajorVersion?: string;\n /**\n * E.g. `[sentry-webpack-plugin]` or `[@sentry/nextjs]`\n */\n loggerPrefix: string;\n },\n): SentryBuildPluginManager {\n const logger = createLogger({\n prefix: bundlerPluginMetaContext.loggerPrefix,\n silent: userOptions.silent ?? false,\n debug: userOptions.debug ?? false,\n });\n\n try {\n const dotenvFile = fs.readFileSync(path.join(process.cwd(), '.env.sentry-build-plugin'), 'utf-8');\n // NOTE: Do not use the dotenv.config API directly to read the dotenv file! For some ungodly reason, it falls back to reading `${process.cwd()}/.env` which is absolutely not what we want.\n const dotenvResult = dotenv.parse(dotenvFile);\n\n // Vite has a bug/behaviour where spreading into process.env will cause it to crash\n // https://github.com/vitest-dev/vitest/issues/1870#issuecomment-1501140251\n Object.assign(process.env, dotenvResult);\n\n logger.info('Using environment variables configured in \".env.sentry-build-plugin\".');\n } catch (e: unknown) {\n // Ignore \"file not found\" errors but throw all others\n if (typeof e === 'object' && e && 'code' in e && e.code !== 'ENOENT') {\n throw e;\n }\n }\n\n const options = normalizeUserOptions(userOptions);\n\n if (options.disable) {\n // Early-return a noop build plugin manager instance so that we\n // don't continue validating options, setting up Sentry, etc.\n // Otherwise we might create side-effects or log messages that\n // users don't expect from a disabled plugin.\n return {\n normalizedOptions: options,\n logger,\n bundleSizeOptimizationReplacementValues: {},\n telemetry: {\n emitBundlerPluginExecutionSignal: async () => {\n /* noop */\n },\n },\n bundleMetadata: {},\n createRelease: async () => {\n /* noop */\n },\n uploadSourcemaps: async () => {\n /* noop */\n },\n deleteArtifacts: async () => {\n /* noop */\n },\n createDependencyOnBuildArtifacts: () => () => {\n /* noop */\n },\n injectDebugIds: async () => {\n /* noop */\n },\n };\n }\n\n const shouldSendTelemetry = allowedToSendTelemetry(options);\n const { sentryScope, sentryClient } = createSentryInstance(\n options,\n shouldSendTelemetry,\n bundlerPluginMetaContext.buildTool,\n bundlerPluginMetaContext.buildToolMajorVersion,\n );\n\n const { release, environment = DEFAULT_ENVIRONMENT } = sentryClient.getOptions();\n\n const sentrySession = makeSession({ release, environment });\n sentryScope.setSession(sentrySession);\n // Send the start of the session\n sentryClient.captureSession(sentrySession);\n\n let sessionHasEnded = false; // Just to prevent infinite loops with beforeExit, which is called whenever the event loop empties out\n\n function endSession(): void {\n if (sessionHasEnded) {\n return;\n }\n\n closeSession(sentrySession);\n sentryClient.captureSession(sentrySession);\n sessionHasEnded = true;\n }\n\n // We also need to manually end sessions on errors because beforeExit is not called on crashes\n process.on('beforeExit', () => {\n endSession();\n });\n\n // Set the User-Agent that Sentry CLI will use when interacting with Sentry\n process.env['SENTRY_PIPELINE'] = `${bundlerPluginMetaContext.buildTool}-plugin/${LIB_VERSION}`;\n\n // Propagate debug flag to Sentry CLI via environment variable\n // Only set if not already defined to respect user's explicit configuration\n if (options.debug && !process.env['SENTRY_LOG_LEVEL']) {\n process.env['SENTRY_LOG_LEVEL'] = 'debug';\n }\n\n // Not a bulletproof check but should be good enough to at least sometimes determine\n // if the plugin is called in dev/watch mode or for a prod build. The important part\n // here is to avoid a false positive. False negatives are okay.\n const isDevMode = process.env['NODE_ENV'] === 'development';\n\n /**\n * Handles errors caught and emitted in various areas of the plugin.\n *\n * Also sets the sentry session status according to the error handling.\n *\n * If users specify their custom `errorHandler` we'll leave the decision to throw\n * or continue up to them. By default, @param throwByDefault controls if the plugin\n * should throw an error (which causes a build fail in most bundlers) or continue.\n */\n function handleRecoverableError(unknownError: unknown, throwByDefault: boolean): void {\n sentrySession.status = 'abnormal';\n try {\n if (options.errorHandler) {\n try {\n if (unknownError instanceof Error) {\n options.errorHandler(unknownError);\n } else {\n options.errorHandler(new Error('An unknown error occurred'));\n }\n } catch (e) {\n sentrySession.status = 'crashed';\n throw e;\n }\n } else {\n // setting the session to \"crashed\" b/c from a plugin perspective this run failed.\n // However, we're intentionally not rethrowing the error to avoid breaking the user build.\n sentrySession.status = 'crashed';\n if (throwByDefault) {\n throw unknownError;\n }\n logger.error(\"An error occurred. Couldn't finish all operations:\", unknownError);\n }\n } finally {\n endSession();\n }\n }\n\n if (!validateOptions(options, logger)) {\n // Throwing by default to avoid a misconfigured plugin going unnoticed.\n handleRecoverableError(new Error('Options were not set correctly. See output above for more details.'), true);\n }\n\n // We have multiple plugins depending on generated source map files. (debug ID upload, legacy upload)\n // Additionally, we also want to have the functionality to delete files after uploading sourcemaps.\n // All of these plugins and the delete functionality need to run in the same hook (`writeBundle`).\n // Since the plugins among themselves are not aware of when they run and finish, we need a system to\n // track their dependencies on the generated files, so that we can initiate the file deletion only after\n // nothing depends on the files anymore.\n const dependenciesOnBuildArtifacts = new Set<symbol>();\n const buildArtifactsDependencySubscribers: (() => void)[] = [];\n\n function notifyBuildArtifactDependencySubscribers(): void {\n buildArtifactsDependencySubscribers.forEach(subscriber => {\n subscriber();\n });\n }\n\n function createDependencyOnBuildArtifacts(): () => void {\n const dependencyIdentifier = Symbol();\n dependenciesOnBuildArtifacts.add(dependencyIdentifier);\n\n return function freeDependencyOnBuildArtifacts() {\n dependenciesOnBuildArtifacts.delete(dependencyIdentifier);\n notifyBuildArtifactDependencySubscribers();\n };\n }\n\n /**\n * Returns a Promise that resolves when all the currently active dependencies are freed again.\n *\n * It is very important that this function is called as late as possible before wanting to await the Promise to give\n * the dependency producers as much time as possible to register themselves.\n */\n function waitUntilBuildArtifactDependenciesAreFreed(): Promise<void> {\n return new Promise<void>(resolve => {\n buildArtifactsDependencySubscribers.push(() => {\n if (dependenciesOnBuildArtifacts.size === 0) {\n resolve();\n }\n });\n\n if (dependenciesOnBuildArtifacts.size === 0) {\n resolve();\n }\n });\n }\n\n const bundleSizeOptimizationReplacementValues: SentrySDKBuildFlags = {};\n if (options.bundleSizeOptimizations) {\n const { bundleSizeOptimizations } = options;\n\n if (bundleSizeOptimizations.excludeDebugStatements) {\n bundleSizeOptimizationReplacementValues['__SENTRY_DEBUG__'] = false;\n }\n if (bundleSizeOptimizations.excludeTracing) {\n bundleSizeOptimizationReplacementValues['__SENTRY_TRACING__'] = false;\n }\n if (bundleSizeOptimizations.excludeReplayCanvas) {\n bundleSizeOptimizationReplacementValues['__RRWEB_EXCLUDE_CANVAS__'] = true;\n }\n if (bundleSizeOptimizations.excludeReplayIframe) {\n bundleSizeOptimizationReplacementValues['__RRWEB_EXCLUDE_IFRAME__'] = true;\n }\n if (bundleSizeOptimizations.excludeReplayShadowDom) {\n bundleSizeOptimizationReplacementValues['__RRWEB_EXCLUDE_SHADOW_DOM__'] = true;\n }\n if (bundleSizeOptimizations.excludeReplayWorker) {\n bundleSizeOptimizationReplacementValues['__SENTRY_EXCLUDE_REPLAY_WORKER__'] = true;\n }\n }\n\n let bundleMetadata: Record<string, unknown> = {};\n if (options.moduleMetadata || options.applicationKey) {\n if (options.applicationKey) {\n // We use different keys so that if user-code receives multiple bundling passes, we will store the application keys of all the passes.\n // It is a bit unfortunate that we have to inject the metadata snippet at the top, because after multiple\n // injections, the first injection will always \"win\" because it comes last in the code. We would generally be\n // fine with making the last bundling pass win. But because it cannot win, we have to use a workaround of storing\n // the app keys in different object keys.\n // We can simply use the `_sentryBundlerPluginAppKey:` to filter for app keys in the SDK.\n bundleMetadata[`_sentryBundlerPluginAppKey:${options.applicationKey}`] = true;\n }\n\n if (typeof options.moduleMetadata === 'function') {\n const args = {\n org: options.org,\n project: getProjects(options.project)?.[0],\n projects: getProjects(options.project),\n release: options.release.name,\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n bundleMetadata = { ...bundleMetadata, ...options.moduleMetadata(args) };\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n bundleMetadata = { ...bundleMetadata, ...options.moduleMetadata };\n }\n }\n\n return {\n /**\n * A logger instance that takes the options passed to the build plugin manager into account. (for silencing and log level etc.)\n */\n logger,\n\n /**\n * Options after normalization. Includes things like the inferred release name.\n */\n normalizedOptions: options,\n\n /**\n * Magic strings and their replacement values that can be used for bundle size optimizations. This already takes\n * into account the options passed to the build plugin manager.\n */\n bundleSizeOptimizationReplacementValues,\n\n /**\n * Metadata that should be injected into bundles if possible. Takes into account options passed to the build plugin manager.\n */\n // See `generateModuleMetadataInjectorCode` for how this should be used exactly\n bundleMetadata,\n\n /**\n * Contains utility functions for emitting telemetry via the build plugin manager.\n */\n telemetry: {\n /**\n * Emits a `Sentry Bundler Plugin execution` signal.\n */\n async emitBundlerPluginExecutionSignal() {\n if (await shouldSendTelemetry) {\n logger.info(\n 'Sending telemetry data on issues and performance to Sentry. To disable telemetry, set `options.telemetry` to `false`.',\n );\n startSpan({ name: 'Sentry Bundler Plugin execution', scope: sentryScope }, () => {\n //\n });\n await safeFlushTelemetry(sentryClient);\n }\n },\n },\n\n /**\n * Will potentially create a release based on the build plugin manager options.\n *\n * Also\n * - finalizes the release\n * - sets commits\n * - uploads legacy sourcemaps\n * - adds deploy information\n */\n async createRelease() {\n if (!options.release.name) {\n logger.debug(\n 'No release name provided. Will not create release. Please set the `release.name` option to identify your release.',\n );\n return;\n } else if (isDevMode) {\n logger.debug('Running in development mode. Will not create release.');\n return;\n } else if (!options.authToken) {\n logger.warn(\n `No auth token provided. Will not create release. Please set the \\`authToken\\` option. You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/${getTurborepoEnvPassthroughWarning('SENTRY_AUTH_TOKEN')}`,\n );\n return;\n } else if (!options.org && !options.authToken.startsWith('sntrys_')) {\n logger.warn(\n `No organization slug provided. Will not create release. Please set the \\`org\\` option to your Sentry organization slug.${getTurborepoEnvPassthroughWarning('SENTRY_ORG')}`,\n );\n return;\n } else if (!options.project || (Array.isArray(options.project) && options.project.length === 0)) {\n logger.warn(\n `No project provided. Will not create release. Please set the \\`project\\` option to your Sentry project slug.${getTurborepoEnvPassthroughWarning('SENTRY_PROJECT')}`,\n );\n return;\n }\n\n // It is possible that this writeBundle hook is called multiple times in one build (for example when reusing the plugin, or when using build tooling like `@vitejs/plugin-legacy`)\n // Therefore we need to actually register the execution of this hook as dependency on the sourcemap files.\n const freeWriteBundleInvocationDependencyOnSourcemapFiles = createDependencyOnBuildArtifacts();\n\n try {\n const cliInstance = createCliInstance(options);\n\n if (options.release.create) {\n const releaseOutput = await cliInstance.releases.new(options.release.name);\n logger.debug('Release created:', releaseOutput);\n }\n\n if (options.release.uploadLegacySourcemaps) {\n const normalizedInclude = arrayify(options.release.uploadLegacySourcemaps)\n .map(includeItem => (typeof includeItem === 'string' ? { paths: [includeItem] } : includeItem))\n .map(includeEntry => ({\n ...includeEntry,\n validate: includeEntry.validate ?? false,\n ext: includeEntry.ext\n ? includeEntry.ext.map(extension => `.${extension.replace(/^\\./, '')}`)\n : ['.js', '.map', '.jsbundle', '.bundle'],\n ignore: includeEntry.ignore ? arrayify(includeEntry.ignore) : undefined,\n }));\n\n await cliInstance.releases.uploadSourceMaps(options.release.name, {\n include: normalizedInclude,\n dist: options.release.dist,\n projects: getProjects(options.project),\n // We want this promise to throw if the sourcemaps fail to upload so that we know about it.\n // see: https://github.com/getsentry/sentry-cli/pull/2605\n live: 'rejectOnError',\n });\n }\n\n if (options.release.setCommits !== false) {\n try {\n await cliInstance.releases.setCommits(\n options.release.name,\n // set commits always exists due to the normalize function\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n options.release.setCommits!,\n );\n } catch (e) {\n // shouldNotThrowOnFailure being present means that the plugin defaulted to `{ auto: true }` for the setCommitsOptions, meaning that wee should not throw when CLI throws because there is no repo\n if (\n options.release.setCommits &&\n 'shouldNotThrowOnFailure' in options.release.setCommits &&\n options.release.setCommits.shouldNotThrowOnFailure\n ) {\n logger.debug(\n 'An error occurred setting commits on release (this message can be ignored unless you commits on release are desired):',\n e,\n );\n } else {\n throw e;\n }\n }\n }\n\n if (options.release.finalize) {\n await cliInstance.releases.finalize(options.release.name);\n }\n\n if (options.release.deploy && !_deployedReleases.has(options.release.name)) {\n await cliInstance.releases.newDeploy(options.release.name, options.release.deploy);\n _deployedReleases.add(options.release.name);\n }\n } catch (e) {\n sentryScope.captureException('Error in \"releaseManagementPlugin\" writeBundle hook');\n await safeFlushTelemetry(sentryClient);\n handleRecoverableError(e, false);\n } finally {\n freeWriteBundleInvocationDependencyOnSourcemapFiles();\n }\n },\n\n /*\n Injects debug IDs into the build artifacts.\n\n This is a separate function from `uploadSourcemaps` because that needs to run before the sourcemaps are uploaded.\n Usually the respective bundler-plugin will take care of this before the sourcemaps are uploaded.\n Only use this if you need to manually inject debug IDs into the build artifacts.\n */\n async injectDebugIds(buildArtifactPaths: string[]) {\n await startSpan({ name: 'inject-debug-ids', scope: sentryScope, forceTransaction: true }, async () => {\n try {\n const cliInstance = createCliInstance(options);\n await cliInstance.execute(\n ['sourcemaps', 'inject', ...serializeIgnoreOptions(options.sourcemaps?.ignore), ...buildArtifactPaths],\n options.debug ? 'rejectOnError' : false,\n );\n } catch (e) {\n sentryScope.captureException('Error in \"debugIdInjectionPlugin\" writeBundle hook');\n handleRecoverableError(e, false);\n } finally {\n await safeFlushTelemetry(sentryClient);\n }\n });\n },\n\n /**\n * Uploads sourcemaps using the \"Debug ID\" method.\n *\n * By default, this prepares bundles in a temporary folder before uploading. You can opt into an\n * in-place, direct upload path by setting `prepareArtifacts` to `false`. If `prepareArtifacts` is set to\n * `false`, no preparation (e.g. adding `//# debugId=...` and writing adjusted source maps) is performed and no temp folder is used.\n *\n * @param buildArtifactPaths - The paths of the build artifacts to upload\n * @param opts - Optional flags to control temp folder usage and preparation\n */\n async uploadSourcemaps(buildArtifactPaths: string[], opts?: { prepareArtifacts?: boolean }) {\n if (!canUploadSourceMaps(options, logger, isDevMode)) {\n return;\n }\n\n // Early exit if assets is explicitly set to an empty array\n const assets = options.sourcemaps?.assets;\n if (Array.isArray(assets) && assets.length === 0) {\n logger.debug('Empty `sourcemaps.assets` option provided. Will not upload sourcemaps with debug ID.');\n return;\n }\n\n await startSpan(\n // This is `forceTransaction`ed because this span is used in dashboards in the form of indexed transactions.\n { name: 'debug-id-sourcemap-upload', scope: sentryScope, forceTransaction: true },\n async () => {\n // If we're not using a temp folder, we must not prepare artifacts in-place (to avoid mutating user files)\n const shouldPrepare = opts?.prepareArtifacts ?? true;\n\n let folderToCleanUp: string | undefined;\n\n // It is possible that this writeBundle hook (which calls this function) is called multiple times in one build (for example when reusing the plugin, or when using build tooling like `@vitejs/plugin-legacy`)\n // Therefore we need to actually register the execution of this hook as dependency on the sourcemap files.\n const freeUploadDependencyOnBuildArtifacts = createDependencyOnBuildArtifacts();\n\n try {\n if (!shouldPrepare) {\n // Direct CLI upload from existing artifact paths (no globbing, no preparation)\n let pathsToUpload: string[];\n\n if (assets) {\n pathsToUpload = Array.isArray(assets) ? assets : [assets];\n logger.debug(\n `Direct upload mode: passing user-provided assets directly to CLI: ${pathsToUpload.join(', ')}`,\n );\n } else {\n // Use original paths e.g. like ['.next/server'] directly –> preferred way when no globbing is done\n pathsToUpload = buildArtifactPaths;\n }\n\n const ignorePaths = options.sourcemaps?.ignore\n ? Array.isArray(options.sourcemaps?.ignore)\n ? options.sourcemaps?.ignore\n : [options.sourcemaps?.ignore]\n : [];\n await startSpan({ name: 'upload', scope: sentryScope }, async () => {\n const cliInstance = createCliInstance(options);\n await cliInstance.releases.uploadSourceMaps(options.release.name ?? 'undefined', {\n include: [\n {\n paths: pathsToUpload,\n rewrite: true,\n dist: options.release.dist,\n },\n ],\n ignore: ignorePaths,\n projects: getProjects(options.project),\n live: 'rejectOnError',\n });\n });\n\n logger.info('Successfully uploaded source maps to Sentry');\n } else {\n // Prepare artifacts in temp folder before uploading\n let globAssets: string | string[];\n if (assets) {\n globAssets = assets;\n } else {\n logger.debug(\n 'No `sourcemaps.assets` option provided, falling back to uploading detected build artifacts.',\n );\n globAssets = buildArtifactPaths;\n }\n\n const globResult = await startSpan({ name: 'glob', scope: sentryScope }, async () =>\n globFiles(globAssets, { ignore: options.sourcemaps?.ignore }),\n );\n\n const debugIdChunkFilePaths = globResult.filter(debugIdChunkFilePath => {\n return !!stripQueryAndHashFromPath(debugIdChunkFilePath).match(/\\.(js|mjs|cjs)$/);\n });\n\n // The order of the files output by glob() is not deterministic\n // Ensure order within the files so that {debug-id}-{chunkIndex} coupling is consistent\n debugIdChunkFilePaths.sort();\n\n if (debugIdChunkFilePaths.length === 0) {\n logger.warn(\n \"Didn't find any matching sources for debug ID upload. Please check the `sourcemaps.assets` option.\",\n );\n } else {\n const tmpUploadFolder = await startSpan({ name: 'mkdtemp', scope: sentryScope }, async () => {\n return (\n process.env?.['SENTRY_TEST_OVERRIDE_TEMP_DIR'] ||\n (await fs.promises.mkdtemp(path.join(os.tmpdir(), 'sentry-bundler-plugin-upload-')))\n );\n });\n folderToCleanUp = tmpUploadFolder;\n\n // Prepare into temp folder, then upload\n await startSpan({ name: 'prepare-bundles', scope: sentryScope }, async prepBundlesSpan => {\n // Preparing the bundles can be a lot of work and doing it all at once has the potential of nuking the heap so\n // instead we do it with a maximum of 16 concurrent workers\n const preparationTasks = debugIdChunkFilePaths.map((chunkFilePath, chunkIndex) => async () => {\n await prepareBundleForDebugIdUpload(\n chunkFilePath,\n tmpUploadFolder,\n chunkIndex,\n logger,\n options.sourcemaps?.rewriteSources ?? defaultRewriteSourcesHook,\n options.sourcemaps?.resolveSourceMap,\n );\n });\n const workers: Promise<void>[] = [];\n const worker = async (): Promise<void> => {\n while (preparationTasks.length > 0) {\n const task = preparationTasks.shift();\n if (task) {\n await task();\n }\n }\n };\n for (let workerIndex = 0; workerIndex < 16; workerIndex++) {\n workers.push(worker());\n }\n\n await Promise.all(workers);\n\n const files = await fs.promises.readdir(tmpUploadFolder);\n const stats = files.map(file => fs.promises.stat(path.join(tmpUploadFolder, file)));\n const uploadSize = (await Promise.all(stats)).reduce(\n (accumulator, { size }) => accumulator + size,\n 0,\n );\n\n setMeasurement('files', files.length, 'none', prepBundlesSpan);\n setMeasurement('upload_size', uploadSize, 'byte', prepBundlesSpan);\n\n // Preparation produced no artifacts, meaning none of the\n // matched bundles had an associated source map. This almost\n // always means source map generation is turned off in the\n // bundler, so warn instead of silently reporting success.\n if (files.length === 0) {\n logger.warn(\n `No source maps found for any of the ${debugIdChunkFilePaths.length} matched build ` +\n 'artifacts, so no source maps were uploaded to Sentry. This usually means source map ' +\n 'generation is not enabled in your bundler. Enable it so Sentry can un-minify your stack traces.',\n );\n return;\n }\n\n await startSpan({ name: 'upload', scope: sentryScope }, async () => {\n const cliInstance = createCliInstance(options);\n await cliInstance.releases.uploadSourceMaps(options.release.name ?? 'undefined', {\n include: [\n {\n paths: [tmpUploadFolder],\n rewrite: false,\n dist: options.release.dist,\n },\n ],\n projects: getProjects(options.project),\n live: 'rejectOnError',\n });\n });\n\n // this must be in the method so that the \"no sourcemaps\"\n // early return doesn't also log success.\n logger.info('Successfully uploaded source maps to Sentry');\n });\n }\n }\n } catch (e) {\n sentryScope.captureException('Error in \"debugIdUploadPlugin\" writeBundle hook');\n handleRecoverableError(e, false);\n } finally {\n if (folderToCleanUp && !process.env?.['SENTRY_TEST_OVERRIDE_TEMP_DIR']) {\n logger.debug('Cleaning up temporary files...');\n try {\n await startSpan({ name: 'cleanup', scope: sentryScope }, async () => {\n if (folderToCleanUp) {\n await fs.promises.rm(folderToCleanUp, { recursive: true, force: true });\n logger.debug(`Temporary folder deleted: ${folderToCleanUp}`);\n }\n });\n } catch (e) {\n // A failed cleanup must not skip the teardown steps below (freeing upload\n // dependencies, flushing telemetry), so swallow and log instead of rethrowing.\n logger.debug('Failed to clean up temporary folder:', e);\n }\n }\n logger.debug('Freeing upload dependencies...');\n freeUploadDependencyOnBuildArtifacts();\n logger.debug('Flushing telemetry data...');\n await safeFlushTelemetry(sentryClient);\n logger.debug('Telemetry flushed. Plugin upload process complete.');\n }\n },\n );\n },\n\n /**\n * Will delete artifacts based on the passed `sourcemaps.filesToDeleteAfterUpload` option.\n */\n async deleteArtifacts() {\n try {\n const filesToDelete = await options.sourcemaps?.filesToDeleteAfterUpload;\n if (filesToDelete !== undefined) {\n const filePathsToDelete = await globFiles(filesToDelete);\n\n logger.debug('Waiting for dependencies on generated files to be freed before deleting...');\n\n await waitUntilBuildArtifactDependenciesAreFreed();\n\n filePathsToDelete.forEach(filePathToDelete => {\n logger.debug(`Deleting asset after upload: ${filePathToDelete}`);\n });\n\n await Promise.all(\n filePathsToDelete.map(filePathToDelete =>\n fs.promises.rm(filePathToDelete, { force: true }).catch(e => {\n // This is allowed to fail - we just don't do anything\n logger.debug(`An error occurred while attempting to delete asset: ${filePathToDelete}`, e);\n }),\n ),\n );\n }\n } catch (e) {\n sentryScope.captureException('Error in \"sentry-file-deletion-plugin\" buildEnd hook');\n await safeFlushTelemetry(sentryClient);\n // We throw by default if we get here b/c not being able to delete\n // source maps could leak them to production\n handleRecoverableError(e, true);\n }\n },\n createDependencyOnBuildArtifacts,\n };\n}\n\nfunction canUploadSourceMaps(options: NormalizedOptions, logger: Logger, isDevMode: boolean): boolean {\n if (options.sourcemaps?.disable) {\n logger.debug('Source map upload was disabled. Will not upload sourcemaps using debug ID process.');\n return false;\n }\n if (isDevMode) {\n logger.debug('Running in development mode. Will not upload sourcemaps.');\n return false;\n }\n if (!options.authToken) {\n logger.warn(\n `No auth token provided. Will not upload source maps. Please set the \\`authToken\\` option. You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/${getTurborepoEnvPassthroughWarning('SENTRY_AUTH_TOKEN')}`,\n );\n return false;\n }\n if (!options.org && !options.authToken.startsWith('sntrys_')) {\n logger.warn(\n `No org provided. Will not upload source maps. Please set the \\`org\\` option to your Sentry organization slug.${getTurborepoEnvPassthroughWarning('SENTRY_ORG')}`,\n );\n return false;\n }\n if (!getProjects(options.project)?.[0]) {\n logger.warn(\n `No project provided. Will not upload source maps. Please set the \\`project\\` option to your Sentry project slug.${getTurborepoEnvPassthroughWarning('SENTRY_PROJECT')}`,\n );\n return false;\n }\n\n return true;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"build-plugin-manager.js","sources":["../../../src/core/build-plugin-manager.ts"],"sourcesContent":["/* oxlint-disable max-lines */\nimport { closeSession, DEFAULT_ENVIRONMENT, makeSession, setMeasurement, startSpan } from '@sentry/core';\nimport * as dotenv from 'dotenv';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { SentryCliAdapter } from './cli';\nimport type { NormalizedOptions } from './options-mapping';\nimport { normalizeUserOptions, validateOptions } from './options-mapping';\nimport type { Logger } from './logger';\nimport { createLogger } from './logger';\nimport { allowedToSendTelemetry, createSentryInstance, safeFlushTelemetry } from './sentry/telemetry';\nimport type { Options, SentrySDKBuildFlags } from './types';\nimport { arrayify, getProjects, getTurborepoEnvPassthroughWarning, stripQueryAndHashFromPath } from './utils';\nimport { defaultRewriteSourcesHook, prepareBundleForDebugIdUpload } from './debug-id-upload';\nimport { globFiles } from './glob';\nimport { LIB_VERSION } from './version';\n\n// Module-level guard to prevent duplicate deploy records when multiple bundler plugin\n// instances run in the same process (e.g. Next.js creates separate webpack compilers\n// for client, server, and edge). Keyed by release name.\nconst _deployedReleases = new Set<string>();\n\n/** @internal Exported for testing only. */\nexport function _resetDeployedReleasesForTesting(): void {\n _deployedReleases.clear();\n}\n\nexport type SentryBuildPluginManager = {\n /**\n * A logger instance that takes the options passed to the build plugin manager into account. (for silencing and log level etc.)\n */\n logger: Logger;\n\n /**\n * Options after normalization. Includes things like the inferred release name.\n */\n normalizedOptions: NormalizedOptions;\n /**\n * Magic strings and their replacement values that can be used for bundle size optimizations. This already takes\n * into account the options passed to the build plugin manager.\n */\n bundleSizeOptimizationReplacementValues: SentrySDKBuildFlags;\n /**\n * Metadata that should be injected into bundles if possible. Takes into account options passed to the build plugin manager.\n */\n // See `generateModuleMetadataInjectorCode` for how this should be used exactly\n bundleMetadata: Record<string, unknown>;\n\n /**\n * Contains utility functions for emitting telemetry via the build plugin manager.\n */\n telemetry: {\n /**\n * Emits a `Sentry Bundler Plugin execution` signal.\n */\n emitBundlerPluginExecutionSignal(): Promise<void>;\n };\n\n /**\n * Will potentially create a release based on the build plugin manager options.\n *\n * Also\n * - finalizes the release\n * - sets commits\n * - uploads legacy sourcemaps\n * - adds deploy information\n */\n createRelease(): Promise<void>;\n\n /**\n * Injects debug IDs into the build artifacts.\n *\n * This is a separate function from `uploadSourcemaps` because that needs to run before the sourcemaps are uploaded.\n * Usually the respective bundler-plugin will take care of this before the sourcemaps are uploaded.\n * Only use this if you need to manually inject debug IDs into the build artifacts.\n */\n injectDebugIds(buildArtifactPaths: string[]): Promise<void>;\n\n /**\n * Uploads sourcemaps using the \"Debug ID\" method. This function takes a list of build artifact paths that will be uploaded\n */\n uploadSourcemaps(buildArtifactPaths: string[], opts?: { prepareArtifacts?: boolean }): Promise<void>;\n\n /**\n * Will delete artifacts based on the passed `sourcemaps.filesToDeleteAfterUpload` option.\n */\n deleteArtifacts(): Promise<void>;\n\n createDependencyOnBuildArtifacts: () => () => void;\n};\n\n/**\n * Creates a build plugin manager that exposes primitives for everything that a Sentry JavaScript SDK or build tooling may do during a build.\n *\n * The build plugin manager's behavior strongly depends on the options that are passed in.\n */\nexport function createSentryBuildPluginManager(\n userOptions: Options,\n bundlerPluginMetaContext: {\n /**\n * E.g. `webpack` or `nextjs` or `turbopack`\n */\n buildTool: string;\n /**\n * E.g. `5` for webpack v5 or `4` for Rollup v4\n */\n buildToolMajorVersion?: string;\n /**\n * E.g. `[sentry-webpack-plugin]` or `[@sentry/nextjs]`\n */\n loggerPrefix: string;\n },\n): SentryBuildPluginManager {\n const logger = createLogger({\n prefix: bundlerPluginMetaContext.loggerPrefix,\n silent: userOptions.silent ?? false,\n debug: userOptions.debug ?? false,\n });\n\n try {\n const dotenvFile = fs.readFileSync(path.join(process.cwd(), '.env.sentry-build-plugin'), 'utf-8');\n // NOTE: Do not use the dotenv.config API directly to read the dotenv file! For some ungodly reason, it falls back to reading `${process.cwd()}/.env` which is absolutely not what we want.\n const dotenvResult = dotenv.parse(dotenvFile);\n\n // Vite has a bug/behaviour where spreading into process.env will cause it to crash\n // https://github.com/vitest-dev/vitest/issues/1870#issuecomment-1501140251\n Object.assign(process.env, dotenvResult);\n\n logger.info('Using environment variables configured in \".env.sentry-build-plugin\".');\n } catch (e: unknown) {\n // Ignore \"file not found\" errors but throw all others\n if (typeof e === 'object' && e && 'code' in e && e.code !== 'ENOENT') {\n throw e;\n }\n }\n\n const options = normalizeUserOptions(userOptions);\n\n if (options.disable) {\n // Early-return a noop build plugin manager instance so that we\n // don't continue validating options, setting up Sentry, etc.\n // Otherwise we might create side-effects or log messages that\n // users don't expect from a disabled plugin.\n return {\n normalizedOptions: options,\n logger,\n bundleSizeOptimizationReplacementValues: {},\n telemetry: {\n emitBundlerPluginExecutionSignal: async () => {\n /* noop */\n },\n },\n bundleMetadata: {},\n createRelease: async () => {\n /* noop */\n },\n uploadSourcemaps: async () => {\n /* noop */\n },\n deleteArtifacts: async () => {\n /* noop */\n },\n createDependencyOnBuildArtifacts: () => () => {\n /* noop */\n },\n injectDebugIds: async () => {\n /* noop */\n },\n };\n }\n\n const shouldSendTelemetry = allowedToSendTelemetry(options);\n const { sentryScope, sentryClient } = createSentryInstance(\n options,\n shouldSendTelemetry,\n bundlerPluginMetaContext.buildTool,\n bundlerPluginMetaContext.buildToolMajorVersion,\n );\n\n const { release, environment = DEFAULT_ENVIRONMENT } = sentryClient.getOptions();\n\n const sentrySession = makeSession({ release, environment });\n sentryScope.setSession(sentrySession);\n // Send the start of the session\n sentryClient.captureSession(sentrySession);\n\n let sessionHasEnded = false; // Just to prevent infinite loops with beforeExit, which is called whenever the event loop empties out\n\n function endSession(): void {\n if (sessionHasEnded) {\n return;\n }\n\n closeSession(sentrySession);\n sentryClient.captureSession(sentrySession);\n sessionHasEnded = true;\n }\n\n // We also need to manually end sessions on errors because beforeExit is not called on crashes\n process.on('beforeExit', () => {\n endSession();\n });\n\n // Set the User-Agent that Sentry CLI will use when interacting with Sentry\n process.env['SENTRY_PIPELINE'] = `${bundlerPluginMetaContext.buildTool}-plugin/${LIB_VERSION}`;\n\n // Propagate debug flag to Sentry CLI via environment variable\n // Only set if not already defined to respect user's explicit configuration\n if (options.debug && !process.env['SENTRY_LOG_LEVEL']) {\n process.env['SENTRY_LOG_LEVEL'] = 'debug';\n }\n\n // Not a bulletproof check but should be good enough to at least sometimes determine\n // if the plugin is called in dev/watch mode or for a prod build. The important part\n // here is to avoid a false positive. False negatives are okay.\n const isDevMode = process.env['NODE_ENV'] === 'development';\n\n /**\n * Handles errors caught and emitted in various areas of the plugin.\n *\n * Also sets the sentry session status according to the error handling.\n *\n * If users specify their custom `errorHandler` we'll leave the decision to throw\n * or continue up to them. By default, @param throwByDefault controls if the plugin\n * should throw an error (which causes a build fail in most bundlers) or continue.\n */\n function handleRecoverableError(unknownError: unknown, throwByDefault: boolean): void {\n sentrySession.status = 'abnormal';\n try {\n if (options.errorHandler) {\n try {\n if (unknownError instanceof Error) {\n options.errorHandler(unknownError);\n } else {\n options.errorHandler(new Error('An unknown error occurred'));\n }\n } catch (e) {\n sentrySession.status = 'crashed';\n throw e;\n }\n } else {\n // setting the session to \"crashed\" b/c from a plugin perspective this run failed.\n // However, we're intentionally not rethrowing the error to avoid breaking the user build.\n sentrySession.status = 'crashed';\n if (throwByDefault) {\n throw unknownError;\n }\n logger.error(\"An error occurred. Couldn't finish all operations:\", unknownError);\n }\n } finally {\n endSession();\n }\n }\n\n if (!validateOptions(options, logger)) {\n // Throwing by default to avoid a misconfigured plugin going unnoticed.\n handleRecoverableError(new Error('Options were not set correctly. See output above for more details.'), true);\n }\n\n // We have multiple plugins depending on generated source map files. (debug ID upload, legacy upload)\n // Additionally, we also want to have the functionality to delete files after uploading sourcemaps.\n // All of these plugins and the delete functionality need to run in the same hook (`writeBundle`).\n // Since the plugins among themselves are not aware of when they run and finish, we need a system to\n // track their dependencies on the generated files, so that we can initiate the file deletion only after\n // nothing depends on the files anymore.\n const dependenciesOnBuildArtifacts = new Set<symbol>();\n const buildArtifactsDependencySubscribers: (() => void)[] = [];\n\n function notifyBuildArtifactDependencySubscribers(): void {\n buildArtifactsDependencySubscribers.forEach(subscriber => {\n subscriber();\n });\n }\n\n function createDependencyOnBuildArtifacts(): () => void {\n const dependencyIdentifier = Symbol();\n dependenciesOnBuildArtifacts.add(dependencyIdentifier);\n\n return function freeDependencyOnBuildArtifacts() {\n dependenciesOnBuildArtifacts.delete(dependencyIdentifier);\n notifyBuildArtifactDependencySubscribers();\n };\n }\n\n /**\n * Returns a Promise that resolves when all the currently active dependencies are freed again.\n *\n * It is very important that this function is called as late as possible before wanting to await the Promise to give\n * the dependency producers as much time as possible to register themselves.\n */\n function waitUntilBuildArtifactDependenciesAreFreed(): Promise<void> {\n return new Promise<void>(resolve => {\n buildArtifactsDependencySubscribers.push(() => {\n if (dependenciesOnBuildArtifacts.size === 0) {\n resolve();\n }\n });\n\n if (dependenciesOnBuildArtifacts.size === 0) {\n resolve();\n }\n });\n }\n\n const bundleSizeOptimizationReplacementValues: SentrySDKBuildFlags = {};\n if (options.bundleSizeOptimizations) {\n const { bundleSizeOptimizations } = options;\n\n if (bundleSizeOptimizations.excludeDebugStatements) {\n bundleSizeOptimizationReplacementValues['__SENTRY_DEBUG__'] = false;\n }\n if (bundleSizeOptimizations.excludeTracing) {\n bundleSizeOptimizationReplacementValues['__SENTRY_TRACING__'] = false;\n }\n if (bundleSizeOptimizations.excludeChannelInjection) {\n bundleSizeOptimizationReplacementValues['__SENTRY_CHANNEL_INJECTION__'] = false;\n }\n if (bundleSizeOptimizations.excludeReplayCanvas) {\n bundleSizeOptimizationReplacementValues['__RRWEB_EXCLUDE_CANVAS__'] = true;\n }\n if (bundleSizeOptimizations.excludeReplayIframe) {\n bundleSizeOptimizationReplacementValues['__RRWEB_EXCLUDE_IFRAME__'] = true;\n }\n if (bundleSizeOptimizations.excludeReplayShadowDom) {\n bundleSizeOptimizationReplacementValues['__RRWEB_EXCLUDE_SHADOW_DOM__'] = true;\n }\n if (bundleSizeOptimizations.excludeReplayWorker) {\n bundleSizeOptimizationReplacementValues['__SENTRY_EXCLUDE_REPLAY_WORKER__'] = true;\n }\n }\n\n let bundleMetadata: Record<string, unknown> = {};\n if (options.moduleMetadata || options.applicationKey) {\n if (options.applicationKey) {\n // We use different keys so that if user-code receives multiple bundling passes, we will store the application keys of all the passes.\n // It is a bit unfortunate that we have to inject the metadata snippet at the top, because after multiple\n // injections, the first injection will always \"win\" because it comes last in the code. We would generally be\n // fine with making the last bundling pass win. But because it cannot win, we have to use a workaround of storing\n // the app keys in different object keys.\n // We can simply use the `_sentryBundlerPluginAppKey:` to filter for app keys in the SDK.\n bundleMetadata[`_sentryBundlerPluginAppKey:${options.applicationKey}`] = true;\n }\n\n if (typeof options.moduleMetadata === 'function') {\n const args = {\n org: options.org,\n project: getProjects(options.project)?.[0],\n projects: getProjects(options.project),\n release: options.release.name,\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n bundleMetadata = { ...bundleMetadata, ...options.moduleMetadata(args) };\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n bundleMetadata = { ...bundleMetadata, ...options.moduleMetadata };\n }\n }\n\n return {\n /**\n * A logger instance that takes the options passed to the build plugin manager into account. (for silencing and log level etc.)\n */\n logger,\n\n /**\n * Options after normalization. Includes things like the inferred release name.\n */\n normalizedOptions: options,\n\n /**\n * Magic strings and their replacement values that can be used for bundle size optimizations. This already takes\n * into account the options passed to the build plugin manager.\n */\n bundleSizeOptimizationReplacementValues,\n\n /**\n * Metadata that should be injected into bundles if possible. Takes into account options passed to the build plugin manager.\n */\n // See `generateModuleMetadataInjectorCode` for how this should be used exactly\n bundleMetadata,\n\n /**\n * Contains utility functions for emitting telemetry via the build plugin manager.\n */\n telemetry: {\n /**\n * Emits a `Sentry Bundler Plugin execution` signal.\n */\n async emitBundlerPluginExecutionSignal() {\n if (await shouldSendTelemetry) {\n logger.info(\n 'Sending telemetry data on issues and performance to Sentry. To disable telemetry, set `options.telemetry` to `false`.',\n );\n startSpan({ name: 'Sentry Bundler Plugin execution', scope: sentryScope }, () => {\n //\n });\n await safeFlushTelemetry(sentryClient);\n }\n },\n },\n\n /**\n * Will potentially create a release based on the build plugin manager options.\n *\n * Also\n * - finalizes the release\n * - sets commits\n * - uploads legacy sourcemaps\n * - adds deploy information\n */\n async createRelease() {\n if (!options.release.name) {\n logger.debug(\n 'No release name provided. Will not create release. Please set the `release.name` option to identify your release.',\n );\n return;\n } else if (isDevMode) {\n logger.debug('Running in development mode. Will not create release.');\n return;\n } else if (!options.authToken) {\n logger.warn(\n `No auth token provided. Will not create release. Please set the \\`authToken\\` option. You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/${getTurborepoEnvPassthroughWarning('SENTRY_AUTH_TOKEN')}`,\n );\n return;\n } else if (!options.org && !options.authToken.startsWith('sntrys_')) {\n logger.warn(\n `No organization slug provided. Will not create release. Please set the \\`org\\` option to your Sentry organization slug.${getTurborepoEnvPassthroughWarning('SENTRY_ORG')}`,\n );\n return;\n } else if (!options.project || (Array.isArray(options.project) && options.project.length === 0)) {\n logger.warn(\n `No project provided. Will not create release. Please set the \\`project\\` option to your Sentry project slug.${getTurborepoEnvPassthroughWarning('SENTRY_PROJECT')}`,\n );\n return;\n }\n\n // It is possible that this writeBundle hook is called multiple times in one build (for example when reusing the plugin, or when using build tooling like `@vitejs/plugin-legacy`)\n // Therefore we need to actually register the execution of this hook as dependency on the sourcemap files.\n const freeWriteBundleInvocationDependencyOnSourcemapFiles = createDependencyOnBuildArtifacts();\n\n // Guaranteed to be set by the guard clause above.\n const releaseName = options.release.name;\n\n try {\n const cliInstance = new SentryCliAdapter(options);\n\n if (options.release.create) {\n const releaseOutput = await cliInstance.createRelease(releaseName);\n logger.debug('Release created:', releaseOutput);\n }\n\n if (options.release.uploadLegacySourcemaps) {\n const uploadTargets = arrayify(options.release.uploadLegacySourcemaps)\n .map(includeItem => (typeof includeItem === 'string' ? { paths: [includeItem] } : includeItem))\n .flatMap(includeEntry =>\n includeEntry.paths.map(directory => ({\n directory,\n dist: options.release.dist,\n ext: includeEntry.ext\n ? includeEntry.ext.map(extension => `.${extension.replace(/^\\./, '')}`)\n : ['.js', '.map', '.jsbundle', '.bundle'],\n // The old CLI only skipped `node_modules` when neither ignore source was configured.\n ignore: includeEntry.ignore\n ? arrayify(includeEntry.ignore)\n : includeEntry.ignoreFile\n ? undefined\n : ['node_modules'],\n ignoreFile: includeEntry.ignoreFile,\n urlPrefix: includeEntry.urlPrefix,\n })),\n );\n\n await cliInstance.uploadSourcemaps(releaseName, uploadTargets);\n }\n\n if (options.release.setCommits !== false) {\n try {\n await cliInstance.setCommits(\n releaseName,\n // set commits always exists due to the normalize function\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n options.release.setCommits!,\n );\n } catch (e) {\n // shouldNotThrowOnFailure being present means that the plugin defaulted to `{ auto: true }` for the setCommitsOptions, meaning that wee should not throw when CLI throws because there is no repo\n if (\n options.release.setCommits &&\n 'shouldNotThrowOnFailure' in options.release.setCommits &&\n options.release.setCommits.shouldNotThrowOnFailure\n ) {\n logger.debug(\n 'An error occurred setting commits on release (this message can be ignored unless you commits on release are desired):',\n e,\n );\n } else {\n throw e;\n }\n }\n }\n\n if (options.release.finalize) {\n await cliInstance.finalizeRelease(releaseName);\n }\n\n if (options.release.deploy && !_deployedReleases.has(releaseName)) {\n await cliInstance.newDeploy(releaseName, options.release.deploy);\n _deployedReleases.add(releaseName);\n }\n } catch (e) {\n sentryScope.captureException('Error in \"releaseManagementPlugin\" writeBundle hook');\n await safeFlushTelemetry(sentryClient);\n handleRecoverableError(e, false);\n } finally {\n freeWriteBundleInvocationDependencyOnSourcemapFiles();\n }\n },\n\n /*\n Injects debug IDs into the build artifacts.\n\n This is a separate function from `uploadSourcemaps` because that needs to run before the sourcemaps are uploaded.\n Usually the respective bundler-plugin will take care of this before the sourcemaps are uploaded.\n Only use this if you need to manually inject debug IDs into the build artifacts.\n */\n async injectDebugIds(buildArtifactPaths: string[]) {\n await startSpan({ name: 'inject-debug-ids', scope: sentryScope, forceTransaction: true }, async () => {\n try {\n const cliInstance = new SentryCliAdapter(options);\n await cliInstance.injectDebugIds(buildArtifactPaths, options.sourcemaps?.ignore);\n } catch (e) {\n sentryScope.captureException('Error in \"debugIdInjectionPlugin\" writeBundle hook');\n handleRecoverableError(e, false);\n } finally {\n await safeFlushTelemetry(sentryClient);\n }\n });\n },\n\n /**\n * Uploads sourcemaps using the \"Debug ID\" method.\n *\n * By default, this prepares bundles in a temporary folder before uploading. You can opt into an\n * in-place, direct upload path by setting `prepareArtifacts` to `false`. If `prepareArtifacts` is set to\n * `false`, no preparation (e.g. adding `//# debugId=...` and writing adjusted source maps) is performed and no temp folder is used.\n *\n * @param buildArtifactPaths - The paths of the build artifacts to upload\n * @param opts - Optional flags to control temp folder usage and preparation\n */\n async uploadSourcemaps(buildArtifactPaths: string[], opts?: { prepareArtifacts?: boolean }) {\n if (!canUploadSourceMaps(options, logger, isDevMode)) {\n return;\n }\n\n // Early exit if assets is explicitly set to an empty array\n const assets = options.sourcemaps?.assets;\n if (Array.isArray(assets) && assets.length === 0) {\n logger.debug('Empty `sourcemaps.assets` option provided. Will not upload sourcemaps with debug ID.');\n return;\n }\n\n await startSpan(\n // This is `forceTransaction`ed because this span is used in dashboards in the form of indexed transactions.\n { name: 'debug-id-sourcemap-upload', scope: sentryScope, forceTransaction: true },\n async () => {\n // If we're not using a temp folder, we must not prepare artifacts in-place (to avoid mutating user files)\n const shouldPrepare = opts?.prepareArtifacts ?? true;\n\n let folderToCleanUp: string | undefined;\n\n // It is possible that this writeBundle hook (which calls this function) is called multiple times in one build (for example when reusing the plugin, or when using build tooling like `@vitejs/plugin-legacy`)\n // Therefore we need to actually register the execution of this hook as dependency on the sourcemap files.\n const freeUploadDependencyOnBuildArtifacts = createDependencyOnBuildArtifacts();\n\n try {\n if (!shouldPrepare) {\n // Direct CLI upload from existing artifact paths (no globbing, no preparation)\n let pathsToUpload: string[];\n\n if (assets) {\n pathsToUpload = Array.isArray(assets) ? assets : [assets];\n logger.debug(\n `Direct upload mode: passing user-provided assets directly to CLI: ${pathsToUpload.join(', ')}`,\n );\n } else {\n // Use original paths e.g. like ['.next/server'] directly –> preferred way when no globbing is done\n pathsToUpload = buildArtifactPaths;\n }\n\n await startSpan({ name: 'upload', scope: sentryScope }, async () => {\n const cliInstance = new SentryCliAdapter(options);\n await cliInstance.uploadSourcemaps(\n options.release.name ?? 'undefined',\n pathsToUpload.map(directory => ({\n directory,\n dist: options.release.dist,\n ignore: options.sourcemaps?.ignore,\n })),\n );\n });\n\n logger.info('Successfully uploaded source maps to Sentry');\n } else {\n // Prepare artifacts in temp folder before uploading\n let globAssets: string | string[];\n if (assets) {\n globAssets = assets;\n } else {\n logger.debug(\n 'No `sourcemaps.assets` option provided, falling back to uploading detected build artifacts.',\n );\n globAssets = buildArtifactPaths;\n }\n\n const globResult = await startSpan({ name: 'glob', scope: sentryScope }, async () =>\n globFiles(globAssets, { ignore: options.sourcemaps?.ignore }),\n );\n\n const debugIdChunkFilePaths = globResult.filter(debugIdChunkFilePath => {\n return !!stripQueryAndHashFromPath(debugIdChunkFilePath).match(/\\.(js|mjs|cjs)$/);\n });\n\n // The order of the files output by glob() is not deterministic\n // Ensure order within the files so that {debug-id}-{chunkIndex} coupling is consistent\n debugIdChunkFilePaths.sort();\n\n if (debugIdChunkFilePaths.length === 0) {\n logger.warn(\n \"Didn't find any matching sources for debug ID upload. Please check the `sourcemaps.assets` option.\",\n );\n } else {\n const tmpUploadFolder = await startSpan({ name: 'mkdtemp', scope: sentryScope }, async () => {\n return (\n process.env?.['SENTRY_TEST_OVERRIDE_TEMP_DIR'] ||\n (await fs.promises.mkdtemp(path.join(os.tmpdir(), 'sentry-bundler-plugin-upload-')))\n );\n });\n folderToCleanUp = tmpUploadFolder;\n\n // Prepare into temp folder, then upload\n await startSpan({ name: 'prepare-bundles', scope: sentryScope }, async prepBundlesSpan => {\n // Preparing the bundles can be a lot of work and doing it all at once has the potential of nuking the heap so\n // instead we do it with a maximum of 16 concurrent workers\n const preparationTasks = debugIdChunkFilePaths.map((chunkFilePath, chunkIndex) => async () => {\n await prepareBundleForDebugIdUpload(\n chunkFilePath,\n tmpUploadFolder,\n chunkIndex,\n logger,\n options.sourcemaps?.rewriteSources ?? defaultRewriteSourcesHook,\n options.sourcemaps?.resolveSourceMap,\n );\n });\n const workers: Promise<void>[] = [];\n const worker = async (): Promise<void> => {\n while (preparationTasks.length > 0) {\n const task = preparationTasks.shift();\n if (task) {\n await task();\n }\n }\n };\n for (let workerIndex = 0; workerIndex < 16; workerIndex++) {\n workers.push(worker());\n }\n\n await Promise.all(workers);\n\n const files = await fs.promises.readdir(tmpUploadFolder);\n const stats = files.map(file => fs.promises.stat(path.join(tmpUploadFolder, file)));\n const uploadSize = (await Promise.all(stats)).reduce(\n (accumulator, { size }) => accumulator + size,\n 0,\n );\n\n setMeasurement('files', files.length, 'none', prepBundlesSpan);\n setMeasurement('upload_size', uploadSize, 'byte', prepBundlesSpan);\n\n // Preparation produced no artifacts, meaning none of the\n // matched bundles had an associated source map. This almost\n // always means source map generation is turned off in the\n // bundler, so warn instead of silently reporting success.\n if (files.length === 0) {\n logger.warn(\n `No source maps found for any of the ${debugIdChunkFilePaths.length} matched build ` +\n 'artifacts, so no source maps were uploaded to Sentry. This usually means source map ' +\n 'generation is not enabled in your bundler. Enable it so Sentry can un-minify your stack traces.',\n );\n return;\n }\n\n await startSpan({ name: 'upload', scope: sentryScope }, async () => {\n const cliInstance = new SentryCliAdapter(options);\n await cliInstance.uploadSourcemaps(options.release.name ?? 'undefined', [\n {\n directory: tmpUploadFolder,\n dist: options.release.dist,\n },\n ]);\n });\n\n // this must be in the method so that the \"no sourcemaps\"\n // early return doesn't also log success.\n logger.info('Successfully uploaded source maps to Sentry');\n });\n }\n }\n } catch (e) {\n sentryScope.captureException('Error in \"debugIdUploadPlugin\" writeBundle hook');\n handleRecoverableError(e, false);\n } finally {\n if (folderToCleanUp && !process.env?.['SENTRY_TEST_OVERRIDE_TEMP_DIR']) {\n logger.debug('Cleaning up temporary files...');\n try {\n await startSpan({ name: 'cleanup', scope: sentryScope }, async () => {\n if (folderToCleanUp) {\n await fs.promises.rm(folderToCleanUp, { recursive: true, force: true });\n logger.debug(`Temporary folder deleted: ${folderToCleanUp}`);\n }\n });\n } catch (e) {\n // A failed cleanup must not skip the teardown steps below (freeing upload\n // dependencies, flushing telemetry), so swallow and log instead of rethrowing.\n logger.debug('Failed to clean up temporary folder:', e);\n }\n }\n logger.debug('Freeing upload dependencies...');\n freeUploadDependencyOnBuildArtifacts();\n logger.debug('Flushing telemetry data...');\n await safeFlushTelemetry(sentryClient);\n logger.debug('Telemetry flushed. Plugin upload process complete.');\n }\n },\n );\n },\n\n /**\n * Will delete artifacts based on the passed `sourcemaps.filesToDeleteAfterUpload` option.\n */\n async deleteArtifacts() {\n try {\n const filesToDelete = await options.sourcemaps?.filesToDeleteAfterUpload;\n if (filesToDelete !== undefined) {\n const filePathsToDelete = await globFiles(filesToDelete);\n\n logger.debug('Waiting for dependencies on generated files to be freed before deleting...');\n\n await waitUntilBuildArtifactDependenciesAreFreed();\n\n filePathsToDelete.forEach(filePathToDelete => {\n logger.debug(`Deleting asset after upload: ${filePathToDelete}`);\n });\n\n await Promise.all(\n filePathsToDelete.map(filePathToDelete =>\n fs.promises.rm(filePathToDelete, { force: true }).catch(e => {\n // This is allowed to fail - we just don't do anything\n logger.debug(`An error occurred while attempting to delete asset: ${filePathToDelete}`, e);\n }),\n ),\n );\n }\n } catch (e) {\n sentryScope.captureException('Error in \"sentry-file-deletion-plugin\" buildEnd hook');\n await safeFlushTelemetry(sentryClient);\n // We throw by default if we get here b/c not being able to delete\n // source maps could leak them to production\n handleRecoverableError(e, true);\n }\n },\n createDependencyOnBuildArtifacts,\n };\n}\n\nfunction canUploadSourceMaps(options: NormalizedOptions, logger: Logger, isDevMode: boolean): boolean {\n if (options.sourcemaps?.disable) {\n logger.debug('Source map upload was disabled. Will not upload sourcemaps using debug ID process.');\n return false;\n }\n if (isDevMode) {\n logger.debug('Running in development mode. Will not upload sourcemaps.');\n return false;\n }\n if (!options.authToken) {\n logger.warn(\n `No auth token provided. Will not upload source maps. Please set the \\`authToken\\` option. You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/${getTurborepoEnvPassthroughWarning('SENTRY_AUTH_TOKEN')}`,\n );\n return false;\n }\n if (!options.org && !options.authToken.startsWith('sntrys_')) {\n logger.warn(\n `No org provided. Will not upload source maps. Please set the \\`org\\` option to your Sentry organization slug.${getTurborepoEnvPassthroughWarning('SENTRY_ORG')}`,\n );\n return false;\n }\n if (!getProjects(options.project)?.[0]) {\n logger.warn(\n `No project provided. Will not upload source maps. Please set the \\`project\\` option to your Sentry project slug.${getTurborepoEnvPassthroughWarning('SENTRY_PROJECT')}`,\n );\n return false;\n }\n\n return true;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createSentrySDK } from 'sentry';
|
|
2
|
+
import { getProjects, arrayify } from './utils.js';
|
|
3
|
+
|
|
4
|
+
var __typeError = (msg) => {
|
|
5
|
+
throw TypeError(msg);
|
|
6
|
+
};
|
|
7
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
8
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
9
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
11
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
|
+
var _options, _sdk, _SentryCliAdapter_instances, createClient_fn;
|
|
13
|
+
function serializeIgnore(ignore) {
|
|
14
|
+
if (!ignore) {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
const patterns = arrayify(ignore);
|
|
18
|
+
return patterns.length > 0 ? patterns.join(",") : void 0;
|
|
19
|
+
}
|
|
20
|
+
class SentryCliAdapter {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
__privateAdd(this, _SentryCliAdapter_instances);
|
|
23
|
+
__privateAdd(this, _options);
|
|
24
|
+
/** Client for every command that is not scoped to a specific project. */
|
|
25
|
+
__privateAdd(this, _sdk);
|
|
26
|
+
__privateSet(this, _options, options);
|
|
27
|
+
__privateSet(this, _sdk, __privateMethod(this, _SentryCliAdapter_instances, createClient_fn).call(this));
|
|
28
|
+
}
|
|
29
|
+
/** Create a release and associate it with the configured project(s). */
|
|
30
|
+
async createRelease(name) {
|
|
31
|
+
return __privateGet(this, _sdk).release.create({ orgVersion: name, project: getProjects(__privateGet(this, _options).project)?.join(",") });
|
|
32
|
+
}
|
|
33
|
+
/** Finalize a release by stamping an end timestamp. */
|
|
34
|
+
async finalizeRelease(name) {
|
|
35
|
+
await __privateGet(this, _sdk).release.finalize({ orgVersion: name });
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Associate commits with a release. Translates the plugin's {@link SetCommitsOptions} `auto` /
|
|
39
|
+
* `repo`+`commit` union into the flags accepted by `sentry release set-commits`. The old CLI's
|
|
40
|
+
* `ignoreMissing`/`ignoreEmpty` toggles have no equivalent flag on the new CLI; the caller's
|
|
41
|
+
* `shouldNotThrowOnFailure` handling still swallows the "no repository" failure case.
|
|
42
|
+
*/
|
|
43
|
+
async setCommits(name, setCommitsOptions) {
|
|
44
|
+
const { auto, repo, commit, previousCommit } = setCommitsOptions;
|
|
45
|
+
const commitSpec = repo && commit ? `${repo}@${previousCommit ? `${previousCommit}..${commit}` : commit}` : void 0;
|
|
46
|
+
await __privateGet(this, _sdk).release["set-commits"]({
|
|
47
|
+
orgVersion: name,
|
|
48
|
+
auto: auto === true,
|
|
49
|
+
commit: commitSpec
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/** Create a deploy for a release. */
|
|
53
|
+
async newDeploy(name, deploy) {
|
|
54
|
+
if (deploy === false) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
await __privateGet(this, _sdk).release.deploy({
|
|
58
|
+
orgVersion: name,
|
|
59
|
+
environment: deploy.env,
|
|
60
|
+
name: deploy.name,
|
|
61
|
+
url: deploy.url,
|
|
62
|
+
started: deploy.started !== void 0 ? String(deploy.started) : void 0,
|
|
63
|
+
finished: deploy.finished !== void 0 ? String(deploy.finished) : void 0,
|
|
64
|
+
time: deploy.time !== void 0 ? String(deploy.time) : void 0
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Upload sourcemaps for one or more directories. The old CLI accepted a structured `include`
|
|
69
|
+
* array; the new `sourcemap upload` command takes a single directory, so we upload each target
|
|
70
|
+
* separately. A client is created per project because project selection is bound at client
|
|
71
|
+
* creation time.
|
|
72
|
+
*/
|
|
73
|
+
async uploadSourcemaps(name, targets) {
|
|
74
|
+
const projects = getProjects(__privateGet(this, _options).project) ?? [void 0];
|
|
75
|
+
for (const project of projects) {
|
|
76
|
+
const sdk = __privateMethod(this, _SentryCliAdapter_instances, createClient_fn).call(this, project);
|
|
77
|
+
for (const target of targets) {
|
|
78
|
+
await sdk.sourcemap.upload({
|
|
79
|
+
directory: target.directory,
|
|
80
|
+
release: name,
|
|
81
|
+
dist: target.dist ?? __privateGet(this, _options).release.dist,
|
|
82
|
+
ext: target.ext?.join(","),
|
|
83
|
+
ignore: serializeIgnore(target.ignore),
|
|
84
|
+
ignoreFile: target.ignoreFile,
|
|
85
|
+
urlPrefix: target.urlPrefix
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Inject debug IDs into the given build artifacts. */
|
|
91
|
+
async injectDebugIds(directories, ignore) {
|
|
92
|
+
const serializedIgnore = serializeIgnore(ignore) ?? "node_modules";
|
|
93
|
+
for (const directory of directories) {
|
|
94
|
+
await __privateGet(this, _sdk).sourcemap.inject({ directory, ignore: serializedIgnore });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Resolve the Sentry server URL the CLI is configured to talk to. Used by the telemetry guard
|
|
99
|
+
* to decide whether the current build targets Sentry SaaS. Returns `undefined` on error.
|
|
100
|
+
*/
|
|
101
|
+
async getServerUrl() {
|
|
102
|
+
try {
|
|
103
|
+
const info = await __privateGet(this, _sdk).run("info");
|
|
104
|
+
return info.config?.url;
|
|
105
|
+
} catch {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
_options = new WeakMap();
|
|
111
|
+
_sdk = new WeakMap();
|
|
112
|
+
_SentryCliAdapter_instances = new WeakSet();
|
|
113
|
+
/**
|
|
114
|
+
* The CLI binds `org`/`project`/`url` when the client is created rather than per call, so a
|
|
115
|
+
* client scoped to a different project needs to be a different client.
|
|
116
|
+
*
|
|
117
|
+
* Creating one is free: it reads no config and opens no connection, it only closes over these
|
|
118
|
+
* options. Everything happens when a command is actually invoked.
|
|
119
|
+
*/
|
|
120
|
+
createClient_fn = function(project) {
|
|
121
|
+
const options = {
|
|
122
|
+
token: __privateGet(this, _options).authToken,
|
|
123
|
+
org: __privateGet(this, _options).org,
|
|
124
|
+
project,
|
|
125
|
+
url: __privateGet(this, _options).url,
|
|
126
|
+
headers: __privateGet(this, _options).headers
|
|
127
|
+
};
|
|
128
|
+
return createSentrySDK(options);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export { SentryCliAdapter };
|
|
132
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../../../src/core/cli.ts"],"sourcesContent":["import { createSentrySDK } from 'sentry';\nimport type { NormalizedOptions } from './options-mapping';\nimport type { SetCommitsOptions } from './types';\nimport { arrayify, getProjects } from './utils';\n\ntype SentrySDK = ReturnType<typeof createSentrySDK>;\ntype SentryOptions = NonNullable<Parameters<typeof createSentrySDK>[0]>;\n\n/**\n * The CLI accepts `headers` since 0.44.0, but its bundled type declarations do not list the\n * option yet.\n * TODO: Drop once `SentryOptions` in the `sentry` package declares `headers`: https://github.com/getsentry/cli/pull/1500\n */\ntype SentryOptionsWithHeaders = SentryOptions & { headers?: Record<string, string> };\n\n/** Comma-joined list of ignore globs, or `undefined` when nothing should be ignored. */\nfunction serializeIgnore(ignore: string | string[] | undefined): string | undefined {\n if (!ignore) {\n return undefined;\n }\n const patterns = arrayify(ignore);\n return patterns.length > 0 ? patterns.join(',') : undefined;\n}\n\n/** A single sourcemap directory to upload plus the flags that apply to it. */\ninterface UploadTarget {\n directory: string;\n dist?: string;\n ext?: string[];\n ignore?: string | string[];\n ignoreFile?: string;\n urlPrefix?: string;\n}\n\n/**\n * Thin wrapper around the Sentry CLI's programmatic SDK. The bundler plugin used to drive the\n * old `@sentry/cli` binary through a `SentryCli` class; the new CLI exposes typed methods via\n * `createSentrySDK()` instead. This adapter maps the plugin's structured option shapes onto\n * those methods and keeps all translation logic in one place.\n */\nexport class SentryCliAdapter {\n readonly #options: NormalizedOptions;\n /** Client for every command that is not scoped to a specific project. */\n readonly #sdk: SentrySDK;\n\n public constructor(options: NormalizedOptions) {\n this.#options = options;\n this.#sdk = this.#createClient();\n }\n\n /**\n * The CLI binds `org`/`project`/`url` when the client is created rather than per call, so a\n * client scoped to a different project needs to be a different client.\n *\n * Creating one is free: it reads no config and opens no connection, it only closes over these\n * options. Everything happens when a command is actually invoked.\n */\n #createClient(project?: string): SentrySDK {\n const options: SentryOptionsWithHeaders = {\n token: this.#options.authToken,\n org: this.#options.org,\n project,\n url: this.#options.url,\n headers: this.#options.headers,\n };\n\n return createSentrySDK(options);\n }\n\n /** Create a release and associate it with the configured project(s). */\n public async createRelease(name: string): Promise<unknown> {\n // Sentry rejects a release without projects, and the unscoped client carries none.\n return this.#sdk.release.create({ orgVersion: name, project: getProjects(this.#options.project)?.join(',') });\n }\n\n /** Finalize a release by stamping an end timestamp. */\n public async finalizeRelease(name: string): Promise<void> {\n await this.#sdk.release.finalize({ orgVersion: name });\n }\n\n /**\n * Associate commits with a release. Translates the plugin's {@link SetCommitsOptions} `auto` /\n * `repo`+`commit` union into the flags accepted by `sentry release set-commits`. The old CLI's\n * `ignoreMissing`/`ignoreEmpty` toggles have no equivalent flag on the new CLI; the caller's\n * `shouldNotThrowOnFailure` handling still swallows the \"no repository\" failure case.\n */\n public async setCommits(name: string, setCommitsOptions: SetCommitsOptions): Promise<void> {\n const { auto, repo, commit, previousCommit } = setCommitsOptions;\n\n // Manual mode is expressed as `REPO@SHA` (optionally `REPO@PREV..SHA`).\n const commitSpec =\n repo && commit ? `${repo}@${previousCommit ? `${previousCommit}..${commit}` : commit}` : undefined;\n\n await this.#sdk.release['set-commits']({\n orgVersion: name,\n auto: auto === true,\n commit: commitSpec,\n });\n }\n\n /** Create a deploy for a release. */\n public async newDeploy(name: string, deploy: NonNullable<NormalizedOptions['release']['deploy']>): Promise<void> {\n if (deploy === false) {\n return;\n }\n\n await this.#sdk.release.deploy({\n orgVersion: name,\n environment: deploy.env,\n name: deploy.name,\n url: deploy.url,\n started: deploy.started !== undefined ? String(deploy.started) : undefined,\n finished: deploy.finished !== undefined ? String(deploy.finished) : undefined,\n time: deploy.time !== undefined ? String(deploy.time) : undefined,\n });\n }\n\n /**\n * Upload sourcemaps for one or more directories. The old CLI accepted a structured `include`\n * array; the new `sourcemap upload` command takes a single directory, so we upload each target\n * separately. A client is created per project because project selection is bound at client\n * creation time.\n */\n public async uploadSourcemaps(name: string, targets: UploadTarget[]): Promise<void> {\n const projects = getProjects(this.#options.project) ?? [undefined];\n\n for (const project of projects) {\n const sdk = this.#createClient(project);\n for (const target of targets) {\n await sdk.sourcemap.upload({\n directory: target.directory,\n release: name,\n dist: target.dist ?? this.#options.release.dist,\n ext: target.ext?.join(','),\n ignore: serializeIgnore(target.ignore),\n ignoreFile: target.ignoreFile,\n urlPrefix: target.urlPrefix,\n });\n }\n }\n }\n\n /** Inject debug IDs into the given build artifacts. */\n public async injectDebugIds(directories: string[], ignore: string | string[] | undefined): Promise<void> {\n // Preserve the previous CLI's default of ignoring `node_modules` when nothing else is configured.\n const serializedIgnore = serializeIgnore(ignore) ?? 'node_modules';\n for (const directory of directories) {\n await this.#sdk.sourcemap.inject({ directory, ignore: serializedIgnore });\n }\n }\n\n /**\n * Resolve the Sentry server URL the CLI is configured to talk to. Used by the telemetry guard\n * to decide whether the current build targets Sentry SaaS. Returns `undefined` on error.\n */\n public async getServerUrl(): Promise<string | undefined> {\n try {\n const info = (await this.#sdk.run('info')) as { config?: { url?: string } };\n return info.config?.url;\n } catch {\n return undefined;\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
package/build/esm/core/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import SentryCli from '@sentry/cli';
|
|
2
1
|
import { debug } from '@sentry/core';
|
|
3
|
-
import * as fs from 'fs';
|
|
4
2
|
import { stripQueryAndHashFromPath, CodeInjection, containsOnlyImports } from './utils.js';
|
|
5
3
|
export { generateModuleMetadataInjectorCode, generateReleaseInjectorCode, replaceBooleanFlagsInCode, stringToUUID } from './utils.js';
|
|
6
4
|
export { globFiles } from './glob.js';
|
|
@@ -22,9 +20,6 @@ function loadBabelAnnotationRuntime() {
|
|
|
22
20
|
}
|
|
23
21
|
return babelAnnotationRuntimePromise;
|
|
24
22
|
}
|
|
25
|
-
function sentryCliBinaryExists() {
|
|
26
|
-
return fs.existsSync(SentryCli.getPath());
|
|
27
|
-
}
|
|
28
23
|
const COMMENT_USE_STRICT_REGEX = (
|
|
29
24
|
// Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
|
|
30
25
|
/^(?:\s*|\/\*(?:.|\r|\n)*?\*\/|\/\/.*[\n\r])*(?:"[^"]*";|'[^']*';)?/
|
|
@@ -64,6 +59,7 @@ function createComponentNameAnnotateHooks(ignoredComponents, injectIntoHtml) {
|
|
|
64
59
|
const result = await transformAsync(code, {
|
|
65
60
|
plugins: [[plugin, { ignoredComponents }]],
|
|
66
61
|
filename: id,
|
|
62
|
+
sourceFileName: idWithoutQueryAndHash,
|
|
67
63
|
parserOpts: {
|
|
68
64
|
sourceType: "module",
|
|
69
65
|
allowAwaitOutsideFunction: true,
|
|
@@ -91,5 +87,5 @@ function getDebugIdSnippet(debugId) {
|
|
|
91
87
|
);
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
export { COMMENT_USE_STRICT_REGEX, CodeInjection, createComponentNameAnnotateHooks, getDebugIdSnippet, isJsFile,
|
|
90
|
+
export { COMMENT_USE_STRICT_REGEX, CodeInjection, createComponentNameAnnotateHooks, getDebugIdSnippet, isJsFile, shouldSkipCodeInjection };
|
|
95
91
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/core/index.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/core/index.ts"],"sourcesContent":["import { debug } from '@sentry/core';\nimport { CodeInjection, containsOnlyImports, stripQueryAndHashFromPath } from './utils';\nimport type { transformAsync as babelTransformAsync } from '@babel/core';\nimport type componentNameAnnotatePlugin from '../babel-plugin';\nimport type { experimentalComponentNameAnnotatePlugin } from '../babel-plugin';\n\ntype BabelTransformAsync = typeof babelTransformAsync;\ntype BabelParserPlugins = NonNullable<NonNullable<Parameters<BabelTransformAsync>[1]>['parserOpts']>['plugins'];\ntype BabelAnnotationRuntime = {\n transformAsync: BabelTransformAsync;\n componentNameAnnotatePlugin: typeof componentNameAnnotatePlugin;\n experimentalComponentNameAnnotatePlugin: typeof experimentalComponentNameAnnotatePlugin;\n};\n\nlet babelAnnotationRuntimePromise: Promise<BabelAnnotationRuntime> | undefined;\n\nfunction loadBabelAnnotationRuntime(): Promise<BabelAnnotationRuntime> {\n if (!babelAnnotationRuntimePromise) {\n babelAnnotationRuntimePromise = Promise.all([import('@babel/core'), import('../babel-plugin')]).then(\n ([babel, babelPlugin]) => {\n return {\n transformAsync: babel.transformAsync,\n componentNameAnnotatePlugin: babelPlugin.default,\n experimentalComponentNameAnnotatePlugin: babelPlugin.experimentalComponentNameAnnotatePlugin,\n };\n },\n );\n }\n\n return babelAnnotationRuntimePromise;\n}\n\n// We need to be careful not to inject the snippet before any `\"use strict\";`s.\n// As an additional complication `\"use strict\";`s may come after any number of comments.\nexport const COMMENT_USE_STRICT_REGEX =\n // Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.\n /^(?:\\s*|\\/\\*(?:.|\\r|\\n)*?\\*\\/|\\/\\/.*[\\n\\r])*(?:\"[^\"]*\";|'[^']*';)?/;\n\n/**\n * Checks if a file is a JavaScript file based on its extension.\n * Handles query strings and hashes in the filename.\n */\nexport function isJsFile(fileName: string): boolean {\n const cleanFileName = stripQueryAndHashFromPath(fileName);\n return ['.js', '.mjs', '.cjs'].some(ext => cleanFileName.endsWith(ext));\n}\n\n/**\n * Checks if a chunk should be skipped for code injection\n *\n * This is necessary to handle Vite's MPA (multi-page application) mode where\n * HTML entry points create \"facade\" chunks that should not contain injected code.\n * See: https://github.com/getsentry/sentry-javascript-bundler-plugins/issues/829\n *\n * However, in SPA mode, the main bundle also has an HTML facade but contains\n * substantial application code. We should NOT skip injection for these bundles.\n *\n * @param code - The chunk's code content\n * @param facadeModuleId - The facade module ID (if any) - HTML files create facade chunks\n * @returns true if the chunk should be skipped\n */\nexport function shouldSkipCodeInjection(code: string, facadeModuleId: string | null | undefined): boolean {\n // Skip empty chunks - these are placeholder chunks that should be optimized away\n if (code.trim().length === 0) {\n return true;\n }\n\n // For HTML facade chunks, only skip if they contain only import statements\n if (facadeModuleId && stripQueryAndHashFromPath(facadeModuleId).endsWith('.html')) {\n return containsOnlyImports(code);\n }\n\n return false;\n}\n\nexport { globFiles } from './glob';\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function createComponentNameAnnotateHooks(ignoredComponents: string[], injectIntoHtml: boolean) {\n return {\n async transform(this: void, code: string, id: string) {\n // id may contain query and hash which will trip up our file extension logic below\n const idWithoutQueryAndHash = stripQueryAndHashFromPath(id);\n\n if (idWithoutQueryAndHash.match(/\\\\node_modules\\\\|\\/node_modules\\//)) {\n return null;\n }\n\n // We will only apply this plugin on jsx and tsx files\n if (!['.jsx', '.tsx'].some(ending => idWithoutQueryAndHash.endsWith(ending))) {\n return null;\n }\n\n const parserPlugins: BabelParserPlugins = [];\n if (idWithoutQueryAndHash.endsWith('.jsx')) {\n parserPlugins.push('jsx');\n } else if (idWithoutQueryAndHash.endsWith('.tsx')) {\n parserPlugins.push('jsx', 'typescript');\n }\n\n const { transformAsync, componentNameAnnotatePlugin, experimentalComponentNameAnnotatePlugin } =\n await loadBabelAnnotationRuntime();\n const plugin = injectIntoHtml ? experimentalComponentNameAnnotatePlugin : componentNameAnnotatePlugin;\n\n try {\n const result = await transformAsync(code, {\n plugins: [[plugin, { ignoredComponents }]],\n filename: id,\n sourceFileName: idWithoutQueryAndHash,\n parserOpts: {\n sourceType: 'module',\n allowAwaitOutsideFunction: true,\n plugins: parserPlugins,\n },\n generatorOpts: {\n decoratorsBeforeExport: true,\n },\n sourceMaps: true,\n });\n\n return {\n code: result?.code ?? code,\n map: result?.map,\n };\n } catch (e) {\n debug.error(`Failed to apply react annotate plugin`, e);\n }\n\n return { code };\n },\n };\n}\n\nexport function getDebugIdSnippet(debugId: string): CodeInjection {\n return new CodeInjection(\n `var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\"${debugId}\",e._sentryDebugIdIdentifier=\"sentry-dbid-${debugId}\");`,\n );\n}\n\nexport type { Logger } from './logger';\nexport type { Options, SentrySDKBuildFlags } from './types';\nexport {\n CodeInjection,\n replaceBooleanFlagsInCode,\n stringToUUID,\n generateReleaseInjectorCode,\n generateModuleMetadataInjectorCode,\n} from './utils';\nexport { createSentryBuildPluginManager } from './build-plugin-manager';\nexport { createDebugIdUploadFunction } from './debug-id-upload';\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options-mapping.js","sources":["../../../src/core/options-mapping.ts"],"sourcesContent":["import type { Logger } from './logger';\nimport type {\n Options as UserOptions,\n SetCommitsOptions,\n RewriteSourcesHook,\n ResolveSourceMapHook,\n IncludeEntry,\n ModuleMetadata,\n ModuleMetadataCallback,\n} from './types';\nimport { determineReleaseName } from './utils';\n\nexport type NormalizedOptions = {\n org: string | undefined;\n project: string | string[] | undefined;\n authToken: string | undefined;\n url: string;\n headers: Record<string, string> | undefined;\n debug: boolean;\n silent: boolean;\n errorHandler: ((err: Error) => void) | undefined;\n telemetry: boolean;\n disable: boolean;\n sourcemaps:\n | {\n disable?: boolean | 'disable-upload';\n assets?: string | string[];\n ignore?: string | string[];\n rewriteSources?: RewriteSourcesHook;\n resolveSourceMap?: ResolveSourceMapHook;\n filesToDeleteAfterUpload?: string | string[] | Promise<string | string[] | undefined>;\n }\n | undefined;\n release: {\n name: string | undefined;\n inject: boolean;\n create: boolean;\n finalize: boolean;\n vcsRemote: string;\n setCommits:\n | (SetCommitsOptions & {\n shouldNotThrowOnFailure?: boolean;\n })\n | false\n | undefined;\n dist?: string;\n deploy?:\n | {\n env: string;\n started?: number | string;\n finished?: number | string;\n time?: number;\n name?: string;\n url?: string;\n }\n | false;\n uploadLegacySourcemaps?: string | IncludeEntry | Array<string | IncludeEntry>;\n };\n bundleSizeOptimizations:\n | {\n excludeDebugStatements?: boolean;\n excludeTracing?: boolean;\n excludeReplayCanvas?: boolean;\n excludeReplayShadowDom?: boolean;\n excludeReplayIframe?: boolean;\n excludeReplayWorker?: boolean;\n }\n | undefined;\n reactComponentAnnotation:\n | {\n enabled?: boolean;\n ignoredComponents?: string[];\n _experimentalInjectIntoHtml?: boolean;\n }\n | undefined;\n _metaOptions: {\n telemetry: {\n metaFramework: string | undefined;\n bundlerMajorVersion: string | undefined;\n };\n };\n applicationKey: string | undefined;\n moduleMetadata: ModuleMetadata | ModuleMetadataCallback | undefined;\n _experiments: {\n injectBuildInformation?: boolean;\n } & Record<string, unknown>;\n};\n\nexport const SENTRY_SAAS_URL = 'https://sentry.io';\n\n// oxlint-disable-next-line complexity\nexport function normalizeUserOptions(userOptions: UserOptions): NormalizedOptions {\n const options = {\n org: userOptions.org ?? process.env['SENTRY_ORG'],\n project:\n userOptions.project ??\n (process.env['SENTRY_PROJECT']?.includes(',')\n ? process.env['SENTRY_PROJECT'].split(',').map(p => p.trim())\n : process.env['SENTRY_PROJECT']),\n authToken: userOptions.authToken ?? process.env['SENTRY_AUTH_TOKEN'],\n url: userOptions.url ?? process.env['SENTRY_URL'] ?? SENTRY_SAAS_URL,\n headers: userOptions.headers,\n debug: userOptions.debug ?? false,\n silent: userOptions.silent ?? false,\n errorHandler: userOptions.errorHandler,\n telemetry: userOptions.telemetry ?? true,\n disable: userOptions.disable ?? false,\n sourcemaps: userOptions.sourcemaps,\n release: {\n ...userOptions.release,\n name: userOptions.release?.name ?? process.env['SENTRY_RELEASE'] ?? determineReleaseName(),\n inject: userOptions.release?.inject ?? true,\n create: userOptions.release?.create ?? true,\n finalize: userOptions.release?.finalize ?? true,\n vcsRemote: userOptions.release?.vcsRemote ?? process.env['SENTRY_VSC_REMOTE'] ?? 'origin',\n // oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- rule false positive: the cast carries the internal `shouldNotThrowOnFailure` field; tsc errors without it\n setCommits: userOptions.release?.setCommits as\n | (SetCommitsOptions & { shouldNotThrowOnFailure?: boolean })\n | false\n | undefined,\n },\n bundleSizeOptimizations: userOptions.bundleSizeOptimizations,\n reactComponentAnnotation: userOptions.reactComponentAnnotation,\n _metaOptions: {\n telemetry: {\n metaFramework: userOptions._metaOptions?.telemetry?.metaFramework,\n bundlerMajorVersion: userOptions._metaOptions?.telemetry?.bundlerMajorVersion,\n },\n },\n applicationKey: userOptions.applicationKey,\n moduleMetadata: userOptions.moduleMetadata,\n _experiments: userOptions._experiments ?? {},\n };\n\n if (options.release.setCommits === undefined) {\n if (\n process.env['VERCEL'] &&\n process.env['VERCEL_GIT_COMMIT_SHA'] &&\n process.env['VERCEL_GIT_REPO_SLUG'] &&\n process.env['VERCEL_GIT_REPO_OWNER'] &&\n // We only want to set commits for the production env because Sentry becomes extremely noisy (eg on slack) for\n // preview environments because the previous commit is always the \"stem\" commit of the preview/PR causing Sentry\n // to notify you for other people creating PRs.\n process.env['VERCEL_TARGET_ENV'] === 'production'\n ) {\n options.release.setCommits = {\n shouldNotThrowOnFailure: true,\n commit: process.env['VERCEL_GIT_COMMIT_SHA'],\n previousCommit: process.env['VERCEL_GIT_PREVIOUS_SHA'],\n repo: `${process.env['VERCEL_GIT_REPO_OWNER']}/${process.env['VERCEL_GIT_REPO_SLUG']}`,\n ignoreEmpty: true,\n ignoreMissing: true,\n };\n } else {\n options.release.setCommits = {\n shouldNotThrowOnFailure: true,\n auto: true,\n ignoreEmpty: true,\n ignoreMissing: true,\n };\n }\n }\n\n if (options.release.deploy === undefined && process.env['VERCEL'] && process.env['VERCEL_TARGET_ENV']) {\n options.release.deploy = {\n env: `vercel-${process.env['VERCEL_TARGET_ENV']}`,\n url: process.env['VERCEL_URL'] ? `https://${process.env['VERCEL_URL']}` : undefined,\n };\n }\n\n return options;\n}\n\n/**\n * Validates a few combinations of options that are not checked by Sentry CLI.\n *\n * For all other options, we can rely on Sentry CLI to validate them. In fact,\n * we can't validate them in the plugin because Sentry CLI might pick up options from\n * its config file.\n *\n * @param options the internal options\n * @param logger the logger\n *\n * @returns `true` if the options are valid, `false` otherwise\n */\nexport function validateOptions(options: NormalizedOptions, logger: Logger): boolean {\n const setCommits = options.release?.setCommits;\n if (setCommits) {\n if (!setCommits.auto && !(setCommits.repo && setCommits.commit)) {\n logger.error(\n 'The `setCommits` option was specified but is missing required properties.',\n 'Please set either `auto` or both, `repo` and `commit`.',\n );\n return false;\n }\n if (setCommits.auto && setCommits.repo && setCommits) {\n logger.warn(\n 'The `setCommits` options includes `auto` but also `repo` and `commit`.',\n 'Ignoring `repo` and `commit`.',\n 'Please only set either `auto` or both, `repo` and `commit`.',\n );\n }\n }\n\n if (options.release?.deploy && typeof options.release.deploy === 'object' && !options.release.deploy.env) {\n logger.error(\n 'The `deploy` option was specified but is missing the required `env` property.',\n 'Please set the `env` property.',\n );\n return false;\n }\n\n if (options.project && Array.isArray(options.project)) {\n if (options.project.length === 0) {\n logger.error(\n 'The `project` option was specified as an array but is empty.',\n 'Please provide at least one project slug.',\n );\n return false;\n }\n // Check each project is a non-empty string\n const invalidProjects = options.project.filter(p => typeof p !== 'string' || p.trim() === '');\n if (invalidProjects.length > 0) {\n logger.error('The `project` option contains invalid project slugs.', 'All projects must be non-empty strings.');\n return false;\n }\n }\n\n return true;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"options-mapping.js","sources":["../../../src/core/options-mapping.ts"],"sourcesContent":["import type { Logger } from './logger';\nimport type {\n Options as UserOptions,\n SetCommitsOptions,\n RewriteSourcesHook,\n ResolveSourceMapHook,\n IncludeEntry,\n ModuleMetadata,\n ModuleMetadataCallback,\n} from './types';\nimport { determineReleaseName } from './utils';\n\nexport type NormalizedOptions = {\n org: string | undefined;\n project: string | string[] | undefined;\n authToken: string | undefined;\n url: string;\n headers: Record<string, string> | undefined;\n debug: boolean;\n silent: boolean;\n errorHandler: ((err: Error) => void) | undefined;\n telemetry: boolean;\n disable: boolean;\n sourcemaps:\n | {\n disable?: boolean | 'disable-upload';\n assets?: string | string[];\n ignore?: string | string[];\n rewriteSources?: RewriteSourcesHook;\n resolveSourceMap?: ResolveSourceMapHook;\n filesToDeleteAfterUpload?: string | string[] | Promise<string | string[] | undefined>;\n }\n | undefined;\n release: {\n name: string | undefined;\n inject: boolean;\n create: boolean;\n finalize: boolean;\n vcsRemote: string;\n setCommits:\n | (SetCommitsOptions & {\n shouldNotThrowOnFailure?: boolean;\n })\n | false\n | undefined;\n dist?: string;\n deploy?:\n | {\n env: string;\n started?: number | string;\n finished?: number | string;\n time?: number;\n name?: string;\n url?: string;\n }\n | false;\n uploadLegacySourcemaps?: string | IncludeEntry | Array<string | IncludeEntry>;\n };\n bundleSizeOptimizations:\n | {\n excludeDebugStatements?: boolean;\n excludeTracing?: boolean;\n excludeChannelInjection?: boolean;\n excludeReplayCanvas?: boolean;\n excludeReplayShadowDom?: boolean;\n excludeReplayIframe?: boolean;\n excludeReplayWorker?: boolean;\n }\n | undefined;\n reactComponentAnnotation:\n | {\n enabled?: boolean;\n ignoredComponents?: string[];\n _experimentalInjectIntoHtml?: boolean;\n }\n | undefined;\n _metaOptions: {\n telemetry: {\n metaFramework: string | undefined;\n bundlerMajorVersion: string | undefined;\n };\n };\n applicationKey: string | undefined;\n moduleMetadata: ModuleMetadata | ModuleMetadataCallback | undefined;\n _experiments: {\n injectBuildInformation?: boolean;\n } & Record<string, unknown>;\n};\n\nexport const SENTRY_SAAS_URL = 'https://sentry.io';\n\n// oxlint-disable-next-line complexity\nexport function normalizeUserOptions(userOptions: UserOptions): NormalizedOptions {\n const options = {\n org: userOptions.org ?? process.env['SENTRY_ORG'],\n project:\n userOptions.project ??\n (process.env['SENTRY_PROJECT']?.includes(',')\n ? process.env['SENTRY_PROJECT'].split(',').map(p => p.trim())\n : process.env['SENTRY_PROJECT']),\n authToken: userOptions.authToken ?? process.env['SENTRY_AUTH_TOKEN'],\n url: userOptions.url ?? process.env['SENTRY_URL'] ?? SENTRY_SAAS_URL,\n headers: userOptions.headers,\n debug: userOptions.debug ?? false,\n silent: userOptions.silent ?? false,\n errorHandler: userOptions.errorHandler,\n telemetry: userOptions.telemetry ?? true,\n disable: userOptions.disable ?? false,\n sourcemaps: userOptions.sourcemaps,\n release: {\n ...userOptions.release,\n name: userOptions.release?.name ?? process.env['SENTRY_RELEASE'] ?? determineReleaseName(),\n inject: userOptions.release?.inject ?? true,\n create: userOptions.release?.create ?? true,\n finalize: userOptions.release?.finalize ?? true,\n vcsRemote: userOptions.release?.vcsRemote ?? process.env['SENTRY_VSC_REMOTE'] ?? 'origin',\n // oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- rule false positive: the cast carries the internal `shouldNotThrowOnFailure` field; tsc errors without it\n setCommits: userOptions.release?.setCommits as\n | (SetCommitsOptions & { shouldNotThrowOnFailure?: boolean })\n | false\n | undefined,\n },\n bundleSizeOptimizations: userOptions.bundleSizeOptimizations,\n reactComponentAnnotation: userOptions.reactComponentAnnotation,\n _metaOptions: {\n telemetry: {\n metaFramework: userOptions._metaOptions?.telemetry?.metaFramework,\n bundlerMajorVersion: userOptions._metaOptions?.telemetry?.bundlerMajorVersion,\n },\n },\n applicationKey: userOptions.applicationKey,\n moduleMetadata: userOptions.moduleMetadata,\n _experiments: userOptions._experiments ?? {},\n };\n\n if (options.release.setCommits === undefined) {\n if (\n process.env['VERCEL'] &&\n process.env['VERCEL_GIT_COMMIT_SHA'] &&\n process.env['VERCEL_GIT_REPO_SLUG'] &&\n process.env['VERCEL_GIT_REPO_OWNER'] &&\n // We only want to set commits for the production env because Sentry becomes extremely noisy (eg on slack) for\n // preview environments because the previous commit is always the \"stem\" commit of the preview/PR causing Sentry\n // to notify you for other people creating PRs.\n process.env['VERCEL_TARGET_ENV'] === 'production'\n ) {\n options.release.setCommits = {\n shouldNotThrowOnFailure: true,\n commit: process.env['VERCEL_GIT_COMMIT_SHA'],\n previousCommit: process.env['VERCEL_GIT_PREVIOUS_SHA'],\n repo: `${process.env['VERCEL_GIT_REPO_OWNER']}/${process.env['VERCEL_GIT_REPO_SLUG']}`,\n ignoreEmpty: true,\n ignoreMissing: true,\n };\n } else {\n options.release.setCommits = {\n shouldNotThrowOnFailure: true,\n auto: true,\n ignoreEmpty: true,\n ignoreMissing: true,\n };\n }\n }\n\n if (options.release.deploy === undefined && process.env['VERCEL'] && process.env['VERCEL_TARGET_ENV']) {\n options.release.deploy = {\n env: `vercel-${process.env['VERCEL_TARGET_ENV']}`,\n url: process.env['VERCEL_URL'] ? `https://${process.env['VERCEL_URL']}` : undefined,\n };\n }\n\n return options;\n}\n\n/**\n * Validates a few combinations of options that are not checked by Sentry CLI.\n *\n * For all other options, we can rely on Sentry CLI to validate them. In fact,\n * we can't validate them in the plugin because Sentry CLI might pick up options from\n * its config file.\n *\n * @param options the internal options\n * @param logger the logger\n *\n * @returns `true` if the options are valid, `false` otherwise\n */\nexport function validateOptions(options: NormalizedOptions, logger: Logger): boolean {\n const setCommits = options.release?.setCommits;\n if (setCommits) {\n if (!setCommits.auto && !(setCommits.repo && setCommits.commit)) {\n logger.error(\n 'The `setCommits` option was specified but is missing required properties.',\n 'Please set either `auto` or both, `repo` and `commit`.',\n );\n return false;\n }\n if (setCommits.auto && setCommits.repo && setCommits) {\n logger.warn(\n 'The `setCommits` options includes `auto` but also `repo` and `commit`.',\n 'Ignoring `repo` and `commit`.',\n 'Please only set either `auto` or both, `repo` and `commit`.',\n );\n }\n }\n\n if (options.release?.deploy && typeof options.release.deploy === 'object' && !options.release.deploy.env) {\n logger.error(\n 'The `deploy` option was specified but is missing the required `env` property.',\n 'Please set the `env` property.',\n );\n return false;\n }\n\n if (options.project && Array.isArray(options.project)) {\n if (options.project.length === 0) {\n logger.error(\n 'The `project` option was specified as an array but is empty.',\n 'Please provide at least one project slug.',\n );\n return false;\n }\n // Check each project is a non-empty string\n const invalidProjects = options.project.filter(p => typeof p !== 'string' || p.trim() === '');\n if (invalidProjects.length > 0) {\n logger.error('The `project` option contains invalid project slugs.', 'All projects must be non-empty strings.');\n return false;\n }\n }\n\n return true;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import SentryCli from '@sentry/cli';
|
|
2
1
|
import { createStackParser, nodeStackLineParser, applySdkMetadata, ServerRuntimeClient, Scope } from '@sentry/core';
|
|
3
2
|
import { SENTRY_SAAS_URL } from '../options-mapping.js';
|
|
4
3
|
import { makeOptionallyEnabledNodeTransport } from './transports.js';
|
|
5
|
-
import {
|
|
4
|
+
import { SentryCliAdapter } from '../cli.js';
|
|
6
5
|
import { LIB_VERSION } from '../version.js';
|
|
7
6
|
|
|
8
7
|
const SENTRY_SAAS_HOSTNAME = "sentry.io";
|
|
@@ -82,29 +81,14 @@ function setTelemetryDataOnScope(options, scope, buildTool, buildToolMajorVersio
|
|
|
82
81
|
scope.setUser({ id: org });
|
|
83
82
|
}
|
|
84
83
|
async function allowedToSendTelemetry(options) {
|
|
85
|
-
const {
|
|
84
|
+
const { telemetry, url } = options;
|
|
86
85
|
if (telemetry === false) {
|
|
87
86
|
return false;
|
|
88
87
|
}
|
|
89
88
|
if (url === SENTRY_SAAS_URL) {
|
|
90
89
|
return true;
|
|
91
90
|
}
|
|
92
|
-
const
|
|
93
|
-
url,
|
|
94
|
-
authToken,
|
|
95
|
-
org,
|
|
96
|
-
project: getProjects(project)?.[0],
|
|
97
|
-
vcsRemote: release.vcsRemote,
|
|
98
|
-
silent,
|
|
99
|
-
headers
|
|
100
|
-
});
|
|
101
|
-
let cliInfo;
|
|
102
|
-
try {
|
|
103
|
-
cliInfo = await cli.execute(["info"], false);
|
|
104
|
-
} catch {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
const cliInfoUrl = cliInfo.split(/(\r\n|\n|\r)/)[0]?.replace(/^Sentry Server: /, "")?.trim();
|
|
91
|
+
const cliInfoUrl = await new SentryCliAdapter(options).getServerUrl();
|
|
108
92
|
if (cliInfoUrl === void 0) {
|
|
109
93
|
return false;
|
|
110
94
|
}
|