diff --git a/packages/astro/.eslintrc.cjs b/packages/astro/.eslintrc.cjs index 29b78099e7c6..3be941649fcf 100644 --- a/packages/astro/.eslintrc.cjs +++ b/packages/astro/.eslintrc.cjs @@ -8,7 +8,7 @@ module.exports = { { files: ['vite.config.ts'], parserOptions: { - project: ['tsconfig.test.json'], + project: ['tsconfig.vite.json'], }, }, ], diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index 1a9eeaff8cd4..29dcc15ade0c 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -27,8 +27,13 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { clientInitPath, serverInitPath, autoInstrumentation, + // eslint-disable-next-line deprecation/deprecation sourceMapsUploadOptions, + sourcemaps, + // todo(v11): Extract `release` build time option here - cannot be done currently, because it conflicts with the `DeprecatedRuntimeOptions` type + // release, bundleSizeOptimizations, + unstable_sentryVitePluginOptions, debug, ...otherOptions } = options; @@ -48,8 +53,21 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { }; const sourceMapsNeeded = sdkEnabled.client || sdkEnabled.server; - const { unstable_sentryVitePluginOptions, ...uploadOptions } = sourceMapsUploadOptions || {}; - const shouldUploadSourcemaps = (sourceMapsNeeded && uploadOptions?.enabled) ?? true; + // eslint-disable-next-line deprecation/deprecation + const { unstable_sentryVitePluginOptions: deprecatedVitePluginOptions, ...uploadOptions } = + sourceMapsUploadOptions || {}; + + const unstableMerged_sentryVitePluginOptions = { + ...deprecatedVitePluginOptions, + ...unstable_sentryVitePluginOptions, + }; + + const shouldUploadSourcemaps = + (sourceMapsNeeded && + sourcemaps?.disable !== true && + // eslint-disable-next-line deprecation/deprecation + uploadOptions?.enabled) ?? + true; // We don't need to check for AUTH_TOKEN here, because the plugin will pick it up from the env if (shouldUploadSourcemaps && command !== 'dev') { @@ -58,7 +76,9 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { let updatedFilesToDeleteAfterUpload: string[] | undefined = undefined; if ( + // eslint-disable-next-line deprecation/deprecation typeof uploadOptions?.filesToDeleteAfterUpload === 'undefined' && + typeof sourcemaps?.filesToDeleteAfterUpload === 'undefined' && computedSourceMapSettings.previousUserSourceMapSetting === 'unset' ) { // This also works for adapters, as the source maps are also copied to e.g. the .vercel folder @@ -79,26 +99,40 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { }, plugins: [ sentryVitePlugin({ - org: uploadOptions.org ?? env.SENTRY_ORG, - project: uploadOptions.project ?? env.SENTRY_PROJECT, - authToken: uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN, - telemetry: uploadOptions.telemetry ?? true, + // Priority: top-level options > deprecated options > env vars + // eslint-disable-next-line deprecation/deprecation + org: options.org ?? uploadOptions.org ?? env.SENTRY_ORG, + // eslint-disable-next-line deprecation/deprecation + project: options.project ?? uploadOptions.project ?? env.SENTRY_PROJECT, + // eslint-disable-next-line deprecation/deprecation + authToken: options.authToken ?? uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN, + url: options.sentryUrl ?? env.SENTRY_URL, + headers: options.headers, + // eslint-disable-next-line deprecation/deprecation + telemetry: options.telemetry ?? uploadOptions.telemetry ?? true, + silent: options.silent ?? false, + errorHandler: options.errorHandler, _metaOptions: { telemetry: { metaFramework: 'astro', }, }, - ...unstable_sentryVitePluginOptions, - debug: debug ?? false, + ...unstableMerged_sentryVitePluginOptions, + debug: options.debug ?? false, sourcemaps: { - assets: uploadOptions.assets ?? [getSourcemapsAssetsGlob(config)], + ...options.sourcemaps, + // eslint-disable-next-line deprecation/deprecation + assets: sourcemaps?.assets ?? uploadOptions.assets ?? [getSourcemapsAssetsGlob(config)], filesToDeleteAfterUpload: - uploadOptions?.filesToDeleteAfterUpload ?? updatedFilesToDeleteAfterUpload, - ...unstable_sentryVitePluginOptions?.sourcemaps, + sourcemaps?.filesToDeleteAfterUpload ?? + // eslint-disable-next-line deprecation/deprecation + uploadOptions?.filesToDeleteAfterUpload ?? + updatedFilesToDeleteAfterUpload, + ...unstableMerged_sentryVitePluginOptions?.sourcemaps, }, bundleSizeOptimizations: { ...bundleSizeOptimizations, - ...unstable_sentryVitePluginOptions?.bundleSizeOptimizations, + ...unstableMerged_sentryVitePluginOptions?.bundleSizeOptimizations, }, }), ], diff --git a/packages/astro/src/integration/types.ts b/packages/astro/src/integration/types.ts index aed2b7e1d193..ec9996cba134 100644 --- a/packages/astro/src/integration/types.ts +++ b/packages/astro/src/integration/types.ts @@ -1,3 +1,4 @@ +import type { BuildTimeOptionsBase, UnstableVitePluginOptions } from '@sentry/core'; import type { SentryVitePluginOptions } from '@sentry/vite-plugin'; import type { RouteData } from 'astro'; @@ -23,12 +24,16 @@ type SdkInitPaths = { serverInitPath?: string; }; +/** + * @deprecated Move these options to the top-level of your Sentry configuration. + */ type SourceMapsOptions = { /** * If this flag is `true`, and an auth token is detected, the Sentry integration will * automatically generate and upload source maps to Sentry during a production build. * * @default true + * @deprecated Use `sourcemaps.disable` instead (with inverted logic) */ enabled?: boolean; @@ -39,18 +44,24 @@ type SourceMapsOptions = { * * To create an auth token, follow this guide: * @see https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens + * + * @deprecated Use top-level `authToken` option instead */ authToken?: string; /** * The organization slug of your Sentry organization. * Instead of specifying this option, you can also set the `SENTRY_ORG` environment variable. + * + * @deprecated Use top-level `org` option instead */ org?: string; /** * The project slug of your Sentry project. * Instead of specifying this option, you can also set the `SENTRY_PROJECT` environment variable. + * + * @deprecated Use top-level `project` option instead */ project?: string; @@ -59,6 +70,7 @@ type SourceMapsOptions = { * It will not collect any sensitive or user-specific data. * * @default true + * @deprecated Use top-level `telemetry` option instead */ telemetry?: boolean; @@ -71,6 +83,8 @@ type SourceMapsOptions = { * * The globbing patterns must follow the implementation of the `glob` package. * @see https://www.npmjs.com/package/glob#glob-primer + * + * @deprecated Use `sourcemaps.assets` instead */ assets?: string | Array; @@ -81,6 +95,8 @@ type SourceMapsOptions = { * @default [] - By default no files are deleted. * * The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob) + * + * @deprecated Use `sourcemaps.filesToDeleteAfterUpload` instead */ filesToDeleteAfterUpload?: string | Array; @@ -95,49 +111,10 @@ type SourceMapsOptions = { * changes can occur at any time within a major SDK version. * * Furthermore, some options are untested with Astro specifically. Use with caution. - */ - unstable_sentryVitePluginOptions?: Partial; -}; - -type BundleSizeOptimizationOptions = { - /** - * If set to `true`, the plugin will attempt to tree-shake (remove) any debugging code within the Sentry SDK. - * Note that the success of this depends on tree shaking being enabled in your build tooling. - * - * Setting this option to `true` will disable features like the SDK's `debug` option. - */ - excludeDebugStatements?: boolean; - - /** - * If set to true, the plugin will try to tree-shake performance monitoring statements out. - * Note that the success of this depends on tree shaking generally being enabled in your build. - * Attention: DO NOT enable this when you're using any performance monitoring-related SDK features (e.g. Sentry.startSpan()). - */ - excludeTracing?: boolean; - - /** - * If set to `true`, the plugin will attempt to tree-shake (remove) code related to the Sentry SDK's Session Replay Shadow DOM recording functionality. - * Note that the success of this depends on tree shaking being enabled in your build tooling. * - * This option is safe to be used when you do not want to capture any Shadow DOM activity via Sentry Session Replay. + * @deprecated Use top-level `unstable_sentryVitePluginOptions` instead */ - excludeReplayShadowDom?: boolean; - - /** - * If set to `true`, the plugin will attempt to tree-shake (remove) code related to the Sentry SDK's Session Replay `iframe` recording functionality. - * Note that the success of this depends on tree shaking being enabled in your build tooling. - * - * You can safely do this when you do not want to capture any `iframe` activity via Sentry Session Replay. - */ - excludeReplayIframe?: boolean; - - /** - * If set to `true`, the plugin will attempt to tree-shake (remove) code related to the Sentry SDK's Session Replay's Compression Web Worker. - * Note that the success of this depends on tree shaking being enabled in your build tooling. - * - * **Notice:** You should only do use this option if you manually host a compression worker and configure it in your Sentry Session Replay integration config via the `workerUrl` option. - */ - excludeReplayWorker?: boolean; + unstable_sentryVitePluginOptions?: Partial; }; type InstrumentationOptions = { @@ -202,7 +179,10 @@ type DeprecatedRuntimeOptions = Record; * * If you specify a dedicated init file, the SDK options passed to `sentryAstro` will be ignored. */ -export type SentryOptions = SdkInitPaths & +export type SentryOptions = Omit & + // todo(v11): `release` and `debug` need to be removed from BuildTimeOptionsBase as it is currently conflicting with `DeprecatedRuntimeOptions` + UnstableVitePluginOptions & + SdkInitPaths & InstrumentationOptions & SdkEnabledOptions & { /** @@ -210,19 +190,12 @@ export type SentryOptions = SdkInitPaths & * * These options are always read from the `sentryAstro` integration. * Do not define them in the `sentry.client.config.(js|ts)` or `sentry.server.config.(js|ts)` files. - */ - sourceMapsUploadOptions?: SourceMapsOptions; - /** - * Options for the Sentry Vite plugin to customize bundle size optimizations. * - * These options are always read from the `sentryAstro` integration. - * Do not define them in the `sentry.client.config.(js|ts)` or `sentry.server.config.(js|ts)` files. + * @deprecated This option was deprecated. Please move the options to the top-level configuration. + * See the migration guide in the SourceMapsOptions type documentation. */ - bundleSizeOptimizations?: BundleSizeOptimizationOptions; - /** - * If enabled, prints debug logs during the build process. - */ - debug?: boolean; + // eslint-disable-next-line deprecation/deprecation + sourceMapsUploadOptions?: SourceMapsOptions; // eslint-disable-next-line deprecation/deprecation } & DeprecatedRuntimeOptions; diff --git a/packages/astro/test/buildOptions.test-d.ts b/packages/astro/test/buildOptions.test-d.ts new file mode 100644 index 000000000000..ec4c9c5330f7 --- /dev/null +++ b/packages/astro/test/buildOptions.test-d.ts @@ -0,0 +1,190 @@ +import { describe, expectTypeOf, it } from 'vitest'; +import type { SentryOptions } from '../src/integration/types'; + +describe('Sentry Astro build-time options type', () => { + it('includes all options based on type BuildTimeOptionsBase', () => { + const completeOptions: SentryOptions = { + // --- BuildTimeOptionsBase options --- + org: 'test-org', + project: 'test-project', + authToken: 'test-auth-token', + sentryUrl: 'https://sentry.io', + headers: { Authorization: ' Bearer test-auth-token' }, + telemetry: true, + silent: false, + // eslint-disable-next-line no-console + errorHandler: (err: Error) => console.warn(err), + debug: false, + sourcemaps: { + disable: false, + assets: ['./dist/**/*'], + ignore: ['./dist/*.map'], + filesToDeleteAfterUpload: ['./dist/*.map'], + }, + release: { + name: 'test-release-1.0.0', + create: true, + finalize: true, + dist: 'test-dist', + vcsRemote: 'origin', + setCommits: { + auto: false, + repo: 'test/repo', + commit: 'abc123', + previousCommit: 'def456', + ignoreMissing: false, + ignoreEmpty: false, + }, + deploy: { + env: 'production', + started: 1234567890, + finished: 1234567900, + time: 10, + name: 'deployment-name', + url: 'https://example.com', + }, + }, + bundleSizeOptimizations: { + excludeDebugStatements: true, + excludeTracing: false, + excludeReplayShadowDom: true, + excludeReplayIframe: true, + excludeReplayWorker: true, + }, + + // --- UnstableVitePluginOptions --- + unstable_sentryVitePluginOptions: { + sourcemaps: { + assets: './dist/**/*', + }, + bundleSizeOptimizations: { + excludeDebugStatements: true, + }, + }, + + // --- SentryOptions specific options --- + enabled: true, + clientInitPath: './src/sentry.client.config.ts', + serverInitPath: './src/sentry.server.config.ts', + autoInstrumentation: { + requestHandler: true, + }, + + // Deprecated runtime options + environment: 'test', + dsn: 'https://test@sentry.io/123', + sampleRate: 1.0, + tracesSampleRate: 1.0, + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1.0, + }; + + expectTypeOf(completeOptions).toEqualTypeOf(); + }); + + it('includes all deprecated options', () => { + const completeOptions: SentryOptions = { + // SentryOptions specific options + enabled: true, + debug: true, + clientInitPath: './src/sentry.client.config.ts', + serverInitPath: './src/sentry.server.config.ts', + autoInstrumentation: { + requestHandler: true, + }, + unstable_sentryVitePluginOptions: { + sourcemaps: { + assets: './dist/**/*', + }, + bundleSizeOptimizations: { + excludeDebugStatements: true, + }, + }, + + // Deprecated sourceMapsUploadOptions + sourceMapsUploadOptions: { + enabled: true, + authToken: 'deprecated-token', + org: 'deprecated-org', + project: 'deprecated-project', + telemetry: false, + assets: './build/**/*', + filesToDeleteAfterUpload: ['./build/*.map'], + unstable_sentryVitePluginOptions: { + sourcemaps: { + ignore: ['./build/*.spec.js'], + }, + }, + }, + }; + + expectTypeOf(completeOptions).toEqualTypeOf(); + }); + + it('allows partial configuration', () => { + const minimalOptions: SentryOptions = { enabled: true }; + + expectTypeOf(minimalOptions).toEqualTypeOf(); + + const partialOptions: SentryOptions = { + enabled: true, + debug: false, + org: 'my-org', + project: 'my-project', + }; + + expectTypeOf(partialOptions).toEqualTypeOf(); + }); + + it('supports BuildTimeOptionsBase options at top level', () => { + const baseOptions: SentryOptions = { + // Test that all BuildTimeOptionsBase options are available at top level + org: 'test-org', + project: 'test-project', + authToken: 'test-token', + sentryUrl: 'https://custom.sentry.io', + headers: { 'Custom-Header': 'value' }, + telemetry: false, + silent: true, + debug: true, + sourcemaps: { + disable: false, + assets: ['./dist/**/*.js'], + ignore: ['./dist/test/**/*'], + filesToDeleteAfterUpload: ['./dist/**/*.map'], + }, + release: { + name: '1.0.0', + create: true, + finalize: false, + }, + bundleSizeOptimizations: { + excludeDebugStatements: true, + excludeTracing: true, + }, + }; + + expectTypeOf(baseOptions).toEqualTypeOf(); + }); + + it('supports UnstableVitePluginOptions at top level', () => { + const viteOptions: SentryOptions = { + unstable_sentryVitePluginOptions: { + org: 'override-org', + project: 'override-project', + sourcemaps: { + assets: './custom-dist/**/*', + ignore: ['./custom-dist/ignore/**/*'], + }, + bundleSizeOptimizations: { + excludeDebugStatements: true, + excludeTracing: false, + }, + debug: true, + silent: false, + }, + }; + + expectTypeOf(viteOptions).toEqualTypeOf(); + }); +}); diff --git a/packages/astro/test/integration/index.test.ts b/packages/astro/test/integration/index.test.ts index f7c0f2ec9e14..abb3f48dcf72 100644 --- a/packages/astro/test/integration/index.test.ts +++ b/packages/astro/test/integration/index.test.ts @@ -20,6 +20,10 @@ const injectScript = vi.fn(); const config = { root: new URL('file://path/to/project'), outDir: new URL('file://path/to/project/out'), +} as AstroConfig; + +const baseConfigHookObject = { + logger: { warn: vi.fn(), info: vi.fn() }, }; describe('sentryAstro integration', () => { @@ -39,7 +43,7 @@ describe('sentryAstro integration', () => { expect(integration.hooks['astro:config:setup']).toBeDefined(); // @ts-expect-error - the hook exists and we only need to pass what we actually use - await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config }); + await integration.hooks['astro:config:setup']({ ...baseConfigHookObject, updateConfig, injectScript, config }); expect(updateConfig).toHaveBeenCalledTimes(1); expect(updateConfig).toHaveBeenCalledWith({ @@ -52,23 +56,25 @@ describe('sentryAstro integration', () => { }); expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); - expect(sentryVitePluginSpy).toHaveBeenCalledWith({ - authToken: 'my-token', - org: 'my-org', - project: 'my-project', - telemetry: false, - debug: false, - bundleSizeOptimizations: {}, - sourcemaps: { - assets: ['out/**/*'], - filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], - }, - _metaOptions: { - telemetry: { - metaFramework: 'astro', + expect(sentryVitePluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: false, + debug: false, + bundleSizeOptimizations: {}, + sourcemaps: { + assets: ['out/**/*'], + filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], }, - }, - }); + _metaOptions: { + telemetry: { + metaFramework: 'astro', + }, + }, + }), + ); }); it('falls back to default output dir, if out and root dir are not available', async () => { @@ -76,26 +82,28 @@ describe('sentryAstro integration', () => { sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false }, }); // @ts-expect-error - the hook exists and we only need to pass what we actually use - await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config: {} }); + await integration.hooks['astro:config:setup']({ ...baseConfigHookObject, updateConfig, injectScript, config: {} }); expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); - expect(sentryVitePluginSpy).toHaveBeenCalledWith({ - authToken: 'my-token', - org: 'my-org', - project: 'my-project', - telemetry: false, - debug: false, - bundleSizeOptimizations: {}, - sourcemaps: { - assets: ['dist/**/*'], - filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], - }, - _metaOptions: { - telemetry: { - metaFramework: 'astro', + expect(sentryVitePluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: false, + debug: false, + bundleSizeOptimizations: {}, + sourcemaps: { + assets: ['dist/**/*'], + filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], }, - }, - }); + _metaOptions: { + telemetry: { + metaFramework: 'astro', + }, + }, + }), + ); }); it('sets the correct assets glob for vercel if the Vercel adapter is used', async () => { @@ -104,6 +112,7 @@ describe('sentryAstro integration', () => { }); // @ts-expect-error - the hook exists and we only need to pass what we actually use await integration.hooks['astro:config:setup']({ + ...baseConfigHookObject, updateConfig, injectScript, config: { @@ -113,23 +122,25 @@ describe('sentryAstro integration', () => { }); expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); - expect(sentryVitePluginSpy).toHaveBeenCalledWith({ - authToken: 'my-token', - org: 'my-org', - project: 'my-project', - telemetry: false, - debug: false, - bundleSizeOptimizations: {}, - sourcemaps: { - assets: ['{.vercel,dist}/**/*'], - filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], - }, - _metaOptions: { - telemetry: { - metaFramework: 'astro', + expect(sentryVitePluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: false, + debug: false, + bundleSizeOptimizations: {}, + sourcemaps: { + assets: ['{.vercel,dist}/**/*'], + filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], }, - }, - }); + _metaOptions: { + telemetry: { + metaFramework: 'astro', + }, + }, + }), + ); }); it('prefers user-specified assets-globs over the default values', async () => { @@ -143,6 +154,7 @@ describe('sentryAstro integration', () => { }); // @ts-expect-error - the hook exists and we only need to pass what we actually use await integration.hooks['astro:config:setup']({ + ...baseConfigHookObject, updateConfig, injectScript, // @ts-expect-error - only passing in partial config @@ -152,23 +164,25 @@ describe('sentryAstro integration', () => { }); expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); - expect(sentryVitePluginSpy).toHaveBeenCalledWith({ - authToken: 'my-token', - org: 'my-org', - project: 'my-project', - telemetry: true, - debug: false, - bundleSizeOptimizations: {}, - sourcemaps: { - assets: ['dist/server/**/*, dist/client/**/*'], - filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], - }, - _metaOptions: { - telemetry: { - metaFramework: 'astro', + expect(sentryVitePluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: true, + debug: false, + bundleSizeOptimizations: {}, + sourcemaps: { + assets: ['dist/server/**/*, dist/client/**/*'], + filesToDeleteAfterUpload: ['./dist/**/client/**/*.map', './dist/**/server/**/*.map'], }, - }, - }); + _metaOptions: { + telemetry: { + metaFramework: 'astro', + }, + }, + }), + ); }); it('prefers user-specified filesToDeleteAfterUpload over the default values', async () => { @@ -182,6 +196,7 @@ describe('sentryAstro integration', () => { }); // @ts-expect-error - the hook exists, and we only need to pass what we actually use await integration.hooks['astro:config:setup']({ + ...baseConfigHookObject, updateConfig, injectScript, // @ts-expect-error - only passing in partial config @@ -226,6 +241,7 @@ describe('sentryAstro integration', () => { }); // @ts-expect-error - the hook exists, and we only need to pass what we actually use await integration.hooks['astro:config:setup']({ + ...baseConfigHookObject, updateConfig, injectScript, // @ts-expect-error - only passing in partial config @@ -260,12 +276,36 @@ describe('sentryAstro integration', () => { expect(integration.hooks['astro:config:setup']).toBeDefined(); // @ts-expect-error - the hook exists and we only need to pass what we actually use - await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config }); + await integration.hooks['astro:config:setup']({ ...baseConfigHookObject, updateConfig, injectScript, config }); expect(updateConfig).toHaveBeenCalledTimes(0); expect(sentryVitePluginSpy).toHaveBeenCalledTimes(0); }); + it("doesn't enable source maps if `sourcemaps.disable` is `true`", async () => { + const integration = sentryAstro({ + sourcemaps: { disable: true }, + }); + + expect(integration.hooks['astro:config:setup']).toBeDefined(); + // @ts-expect-error - the hook exists and we only need to pass what we actually use + await integration.hooks['astro:config:setup']({ ...baseConfigHookObject, updateConfig, injectScript, config }); + + expect(updateConfig).toHaveBeenCalledTimes(0); + expect(sentryVitePluginSpy).toHaveBeenCalledTimes(0); + }); + + it('enables source maps if `sourcemaps.disable` is not defined', async () => { + const integration = sentryAstro({}); + + expect(integration.hooks['astro:config:setup']).toBeDefined(); + // @ts-expect-error - the hook exists and we only need to pass what we actually use + await integration.hooks['astro:config:setup']({ ...baseConfigHookObject, updateConfig, injectScript, config }); + + expect(updateConfig).toHaveBeenCalledTimes(1); + expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); + }); + it("doesn't add the Vite plugin in dev mode", async () => { const integration = sentryAstro({ sourceMapsUploadOptions: { enabled: true }, @@ -273,7 +313,13 @@ describe('sentryAstro integration', () => { expect(integration.hooks['astro:config:setup']).toBeDefined(); // @ts-expect-error - the hook exists and we only need to pass what we actually use - await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config, command: 'dev' }); + await integration.hooks['astro:config:setup']({ + ...baseConfigHookObject, + updateConfig, + injectScript, + config, + command: 'dev', + }); expect(updateConfig).toHaveBeenCalledTimes(0); expect(sentryVitePluginSpy).toHaveBeenCalledTimes(0); diff --git a/packages/astro/test/integration/snippets.test.ts b/packages/astro/test/integration/snippets.test.ts index edc8338906ab..4c3f1a88d25d 100644 --- a/packages/astro/test/integration/snippets.test.ts +++ b/packages/astro/test/integration/snippets.test.ts @@ -1,7 +1,8 @@ import { describe, expect, it } from 'vitest'; import { buildClientSnippet, buildSdkInitFileImportSnippet, buildServerSnippet } from '../../src/integration/snippets'; +import type { SentryOptions } from '../../src/integration/types'; -const allSdkOptions = { +const allSdkOptions: SentryOptions = { dsn: 'my-dsn', release: '1.0.0', environment: 'staging', diff --git a/packages/astro/tsconfig.test.json b/packages/astro/tsconfig.test.json index c41efeacd92f..da5a816712e3 100644 --- a/packages/astro/tsconfig.test.json +++ b/packages/astro/tsconfig.test.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", - "include": ["test/**/*", "vite.config.ts"], + "include": ["test/**/*"], "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used diff --git a/packages/astro/tsconfig.vite.json b/packages/astro/tsconfig.vite.json new file mode 100644 index 000000000000..a3d6e59b1bfe --- /dev/null +++ b/packages/astro/tsconfig.vite.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + + "include": ["vite.config.ts"], + + "compilerOptions": { + // should include all types from `./tsconfig.json` plus types for all test frameworks used + "types": ["node"] + } +} diff --git a/packages/astro/vite.config.ts b/packages/astro/vite.config.ts index f18ec92095bc..5f83f34483c3 100644 --- a/packages/astro/vite.config.ts +++ b/packages/astro/vite.config.ts @@ -4,5 +4,9 @@ export default { ...baseConfig, test: { ...baseConfig.test, + typecheck: { + enabled: true, + tsconfig: './tsconfig.test.json', + }, }, };