From b74d7cce699538d60b3b6aacba2e711fa37cbaa4 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 10 Oct 2023 18:28:27 +0200 Subject: [PATCH 01/10] feat(astro): Add `sentryAstro` integration --- packages/astro/.eslintrc.js | 7 ++ packages/astro/.npmignore | 10 ++ packages/astro/README.md | 96 ++++++++++++++++++- packages/astro/package.json | 23 ++++- packages/astro/scripts/syncIntegration.ts | 20 ++++ packages/astro/src/integration/README.md | 4 + packages/astro/src/integration/index.ts | 69 +++++++++++++ packages/astro/src/integration/snippets.ts | 47 +++++++++ packages/astro/src/integration/types.ts | 32 +++++++ .../astro/test/integration/snippets.test.ts | 93 ++++++++++++++++++ packages/astro/tsconfig.dev.json | 14 +++ scripts/prepack.ts | 7 +- yarn.lock | 38 ++++++++ 13 files changed, 453 insertions(+), 7 deletions(-) create mode 100644 packages/astro/.npmignore create mode 100644 packages/astro/scripts/syncIntegration.ts create mode 100644 packages/astro/src/integration/README.md create mode 100644 packages/astro/src/integration/index.ts create mode 100644 packages/astro/src/integration/snippets.ts create mode 100644 packages/astro/src/integration/types.ts create mode 100644 packages/astro/test/integration/snippets.test.ts create mode 100644 packages/astro/tsconfig.dev.json diff --git a/packages/astro/.eslintrc.js b/packages/astro/.eslintrc.js index 29b78099e7c6..c706032aaf35 100644 --- a/packages/astro/.eslintrc.js +++ b/packages/astro/.eslintrc.js @@ -11,5 +11,12 @@ module.exports = { project: ['tsconfig.test.json'], }, }, + { + files: ['src/integration/**', 'src/server/**'], + rules: { + '@sentry-internal/sdk/no-optional-chaining': 'off', + '@sentry-internal/sdk/no-nullish-coalescing': 'off', + }, + }, ], }; diff --git a/packages/astro/.npmignore b/packages/astro/.npmignore new file mode 100644 index 000000000000..ded80d725803 --- /dev/null +++ b/packages/astro/.npmignore @@ -0,0 +1,10 @@ +# The paths in this file are specified so that they align with the file structure in `./build` after this file is copied +# into it by the prepack script `scripts/prepack.ts`. + +* + +!/cjs/**/* +!/esm/**/* +!/types/**/* +!/types-ts3.8/**/* +!/integration/**/* diff --git a/packages/astro/README.md b/packages/astro/README.md index 1ef88df544c3..497cba3b4202 100644 --- a/packages/astro/README.md +++ b/packages/astro/README.md @@ -28,4 +28,98 @@ This package is a wrapper around `@sentry/node` for the server and `@sentry/brow ## Installation and Setup -TODO +### 1. Registering the Sentry Astro integration: + +Add the `sentryAstro` integration to your `astro.config.mjs` file: + +```javascript +import { sentryAstro } from "@sentry/astro/integration"; + +export default defineConfig({ + // Rest of your Astro project config + integrations: [ + sentryAstro({ + dsn: '__DSN__', + }), + ], +}) +``` + +This is the easiest way to configure Sentry in an Astro project. +You can pass a few additional options to `sentryAstro` but the SDK comes preconfigured in an opinionated way. +If you want to fully customize your SDK setup, you can do so, too: + +### 2. [Optional] Uploading Source Maps + +To upload source maps to Sentry, simply add the `project`, `org` and `authToken` options to `sentryAstro`: + +```js +// astro.config.mjs +import { sentryAstro } from "@sentry/astro/integration"; + +export default defineConfig({ + // Rest of your Astro project config + integrations: [ + sentryAstro({ + dsn: '__DSN__', + org: 'your-org-slug', + project: 'your-project-slug', + authToken: import.meta.env('SENTRY_AUTH_TOKEN'), + }), + ], +}) +``` + +You can also define these values as environment variables in e.g. a `.env` file +or in you CI configuration: + +```sh +SENTRY_ORG="your-org-slug" +SENTRY_PROJECT="your-project" +SENTRY_AUTH_TOKEN="your-token" +``` + +### 3. [Optional] Advanced Configuration + +To fully customize and configure Sentry in an Astro project, follow step 1 and in addition, +add a `sentry.client.config.(js|ts)` and `sentry.server.config(js|ts)` file to the root directory of your project. +Inside these files, you can call `Sentry.init()` and get the full range of Sentry options. + +Configuring the client SDK: + +```js +// sentry.client.config.ts or sentry.server.config.ts +import * as Sentry from "@sentry/astro"; + +Sentry.init({ + dsn: "__DSN__", + beforeSend(event) { + console.log("Sending event on the client"); + return event; + }, + tracesSampler: () => {/* ... */} +}); +``` + +**Important**: Once you created a sentry config file, the SDK options passed to `sentryAstro` will be ignored for the respective runtime. You can also only define create of the two files. + +#### 3.1 Custom file location + +If you want to move the `sentry.*.config` files to another location, +you can specify the file path, relative to the project root, in `sentryAstro`: + +```js +// astro.config.mjs +import { sentryAstro } from "@sentry/astro/integration"; + +export default defineConfig({ + // Rest of your Astro project config + integrations: [ + sentryAstro({ + dsn: '__DSN__', + clientInitPath: '.config/sentry.client.init.js', + serverInitPath: '.config/sentry.server.init.js', + }), + ], +}) +``` diff --git a/packages/astro/package.json b/packages/astro/package.json index 96e8a48c0a8b..ce6b79f9cd57 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -9,22 +9,36 @@ "engines": { "node": ">=18.14.1" }, - "main": "build/cjs/index.server.js", + "type": "module", + "main": "build/cjs/index.client.js", "module": "build/esm/index.server.js", "browser": "build/esm/index.client.js", "types": "build/types/index.types.d.ts", + "exports": { + ".": { + "node": "./build/esm/index.server.js", + "browser": "./build/esm/index.client.js", + "import": "./build/esm/index.client.js", + "require": "./build/cjs/index.server.js", + "types": "./build/types/index.types.d.ts" + }, + "./integration": { + "default": "./build/integration/index.ts" + } + }, "publishConfig": { "access": "public" }, "peerDependencies": { - "astro": "1.x" + "astro": "3.x" }, "dependencies": { "@sentry/browser": "7.73.0", "@sentry/node": "7.73.0", "@sentry/core": "7.73.0", "@sentry/utils": "7.73.0", - "@sentry/types": "7.73.0" + "@sentry/types": "7.73.0", + "@sentry/vite-plugin": "^2.8.0" }, "devDependencies": { "astro": "^3.2.3", @@ -32,7 +46,7 @@ "vite": "4.0.5" }, "scripts": { - "build": "run-p build:transpile build:types", + "build": "run-p build:transpile build:types build:sync:integration", "build:dev": "yarn build", "build:transpile": "rollup -c rollup.npm.config.js --bundleConfigAsCjs", "build:types": "tsc -p tsconfig.types.json", @@ -41,6 +55,7 @@ "build:transpile:watch": "rollup -c rollup.npm.config.js --bundleConfigAsCjs --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:tarball": "ts-node ../../scripts/prepack.ts && npm pack ./build", + "build:sync:integration": "ts-node -P tsconfig.dev.json ./scripts/syncIntegration.ts", "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts", "clean": "rimraf build coverage sentry-astro-*.tgz", "fix": "run-s fix:eslint fix:prettier", diff --git a/packages/astro/scripts/syncIntegration.ts b/packages/astro/scripts/syncIntegration.ts new file mode 100644 index 000000000000..006d9b3237ac --- /dev/null +++ b/packages/astro/scripts/syncIntegration.ts @@ -0,0 +1,20 @@ +/* eslint-disable no-console */ + +import * as fse from 'fs-extra'; +import * as path from 'path'; + +const buildDir = path.resolve('build'); +const srcIntegrationDir = path.resolve(path.join('src', 'integration')); +const destIntegrationDir = path.resolve(path.join(buildDir, 'integration')); + +try { + fse.copySync(srcIntegrationDir, destIntegrationDir, { + filter: (src, _) => { + return !src.endsWith('.md'); + }, + }); + console.log('\nCopied Astro integration to ./build/integration\n'); +} catch (e) { + console.error('\nError while copying integration to build dir:'); + console.error(e); +} diff --git a/packages/astro/src/integration/README.md b/packages/astro/src/integration/README.md new file mode 100644 index 000000000000..b248906967d1 --- /dev/null +++ b/packages/astro/src/integration/README.md @@ -0,0 +1,4 @@ +Contents of this directory are _not_ bundled with rollup. +They're directly copied into `build/integration`. +Astro supports TypeScript in integration packages. +The integration files will simply be bundled by Vite when building the Astro project. diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts new file mode 100644 index 000000000000..18dac368edbc --- /dev/null +++ b/packages/astro/src/integration/index.ts @@ -0,0 +1,69 @@ +/* eslint-disable no-console */ +import { sentryVitePlugin } from '@sentry/vite-plugin'; +import type { AstroIntegration } from 'astro'; +import * as fs from 'fs'; +import * as path from 'path'; +import { loadEnv } from 'vite'; + +import { buildClientSnippet, buildSdkInitFileImportSnippet, buildServerSnippet } from './snippets'; +import type { SentryOptions } from './types'; + +const PKG_NAME = '@sentry/astro'; + +export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { + return { + name: PKG_NAME, + hooks: { + 'astro:config:setup': async ({ updateConfig, injectScript }) => { + // The third param here enables loading of all env vars, regardless of prefix + // see: https://main.vitejs.dev/config/#using-environment-variables-in-config + const env = loadEnv('production', process.cwd(), ''); + + if (options.authToken ?? env.SENTRY_AUTH_TOKEN) { + updateConfig({ + vite: { + build: { + sourcemap: true, + }, + plugins: [ + sentryVitePlugin({ + org: options.org ?? env.SENTRY_ORG, + project: options.project ?? env.SENTRY_PROJECT, + authToken: options.authToken ?? env.SENTRY_AUTH_TOKEN, + telemetry: options.telemetry, + }), + ], + }, + }); + } + + const pathToClientInit = options.clientInitPath ?? findSdkInitFile('client'); + const pathToServerInit = options.serverInitPath ?? findSdkInitFile('server'); + + if (pathToClientInit) { + options.debug && console.log(`[sentry-astro] Using ${pathToClientInit} for client init.`); + injectScript('page', buildSdkInitFileImportSnippet(pathToClientInit)); + } else { + options.debug && console.log('[sentry-astro] Using default client init.'); + injectScript('page', buildClientSnippet(options || {})); + } + + if (pathToServerInit) { + options.debug && console.log(`[sentry-astro] Using ${pathToServerInit} for server init.`); + // For whatever reason, we need to move one level up to import the server file correctly + injectScript('page-ssr', buildSdkInitFileImportSnippet(path.join('..', pathToServerInit))); + } else { + options.debug && console.log('[sentry-astro] Using default server init.'); + injectScript('page-ssr', buildServerSnippet(options || {})); + } + }, + }, + }; +}; + +function findSdkInitFile(type: 'server' | 'client'): string | undefined { + const fileExtensions = ['ts', 'js', 'tsx', 'jsx', 'mjs', 'cjs', 'mts']; + return fileExtensions + .map(ext => path.join(process.cwd(), `sentry.${type}.config.${ext}`)) + .find(filename => fs.existsSync(filename)); +} diff --git a/packages/astro/src/integration/snippets.ts b/packages/astro/src/integration/snippets.ts new file mode 100644 index 000000000000..66ed59b70da7 --- /dev/null +++ b/packages/astro/src/integration/snippets.ts @@ -0,0 +1,47 @@ +import type { SentryOptions } from './types'; + +/** + * Creates a snippet that imports a Sentry.init file. + */ +export function buildSdkInitFileImportSnippet(filePath: string): string { + return `import "${filePath}";`; +} + +/** + * Creates a snippet that initializes Sentry on the client by choosing + * default options. + */ +export function buildClientSnippet(options: SentryOptions): string { + return `import * as Sentry from "@sentry/astro"; + +Sentry.init({ + dsn: ${options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN'}, + debug: ${options.debug ? true : false}, + environment: ${options.environment ? JSON.stringify(options.environment) : 'import.meta.env.PUBLIC_VERCEL_ENV'}, + release: ${options.release ? JSON.stringify(options.release) : 'import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA'}, + integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], + tracesSampleRate: ${options.tracesSampleRate ?? 1.0}, + replaysSessionSampleRate: ${options.replaysSessionSampleRate ?? 0.1}, + replaysOnErrorSampleRate: ${options.replaysOnErrorSampleRate ?? 1.0},${ + options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : '' + } +});`; +} + +/** + * Creates a snippet that initializes Sentry on the server by choosing + * default options. + */ +export function buildServerSnippet(options: SentryOptions): string { + return `import * as Sentry from "@sentry/astro"; + +Sentry.init({ + dsn: ${options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN'}, + debug: ${options.debug ? true : false}, + environment: ${options.environment ? JSON.stringify(options.environment) : 'import.meta.env.PUBLIC_VERCEL_ENV'}, + release: ${options.release ? JSON.stringify(options.release) : 'import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA'}, + tracesSampleRate: ${options.tracesSampleRate ?? 1.0},${ + options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : '' + } +});`; +} diff --git a/packages/astro/src/integration/types.ts b/packages/astro/src/integration/types.ts new file mode 100644 index 000000000000..35cddb3e3e31 --- /dev/null +++ b/packages/astro/src/integration/types.ts @@ -0,0 +1,32 @@ +import type { BrowserOptions } from '@sentry/browser'; +import type { Options } from '@sentry/types'; +import type { SentryVitePluginOptions } from '@sentry/vite-plugin'; + +type SdkInitPaths = { + /** + * Path to a `sentry.client.config.(js|ts)` file that contains a `Sentry.init` call. + * If this option is not specified, the default location (`src/sentry.client.config.(js|ts)`) will be used. + * If there is no file at the default location, a default `Sentry.init` call will made. + */ + clientInitPath?: string; + /** + * Path to a `sentry.client.config.(js|ts)` file that contains a `Sentry.init` call. + * If this option is not specified, the default location (`src/sentry.client.config.(js|ts)`) will be used. + * If there is no file at the default location, a default `Sentry.init` call will made. + */ + serverInitPath?: string; +}; + +/** + * A subset of Sentry SDK options that can be set via the `sentryAstro` integration. + * Some options (e.g. integrations) are set by default and cannot be changed here. + * + * If you want a more fine-grained control over the SDK, with all options, + * you can call Sentry.init in `sentry.client.config.(js|ts)` or `sentry.server.config.(js|ts)` files. + * + * If you specify a dedicated init file, the SDK options passed to `sentryAstro` will be ignored. + */ +export type SentryOptions = SdkInitPaths & + Pick & + Pick & + Pick; diff --git a/packages/astro/test/integration/snippets.test.ts b/packages/astro/test/integration/snippets.test.ts new file mode 100644 index 000000000000..c2ce40c9c04d --- /dev/null +++ b/packages/astro/test/integration/snippets.test.ts @@ -0,0 +1,93 @@ +import { buildClientSnippet, buildSdkInitFileImportSnippet, buildServerSnippet } from '../../src/integration/snippets'; + +const allSdkOptions = { + dsn: 'my-dsn', + release: '1.0.0', + environment: 'staging', + sampleRate: 0.2, + tracesSampleRate: 0.3, + replaysOnErrorSampleRate: 0.4, + replaysSessionSampleRate: 0.5, + debug: true, +}; + +describe('buildClientSnippet', () => { + it('returns a basic Sentry init call with default options', () => { + const snippet = buildClientSnippet({}); + expect(snippet).toMatchInlineSnapshot(` + "import * as Sentry from \\"@sentry/astro\\"; + + Sentry.init({ + dsn: import.meta.env.PUBLIC_SENTRY_DSN, + debug: false, + environment: import.meta.env.PUBLIC_VERCEL_ENV, + release: import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA, + integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], + tracesSampleRate: 1, + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1, + });" + `); + }); + + it('returns a basic Sentry init call with custom options', () => { + const snippet = buildClientSnippet(allSdkOptions); + + expect(snippet).toMatchInlineSnapshot(` + "import * as Sentry from \\"@sentry/astro\\"; + + Sentry.init({ + dsn: \\"my-dsn\\", + debug: true, + environment: \\"staging\\", + release: \\"1.0.0\\", + integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], + tracesSampleRate: 0.3, + replaysSessionSampleRate: 0.5, + replaysOnErrorSampleRate: 0.4, + sampleRate: 0.2, + });" + `); + }); +}); + +describe('buildServerSnippet', () => { + it('returns a basic Sentry init call with default options', () => { + const snippet = buildServerSnippet({}); + expect(snippet).toMatchInlineSnapshot(` + "import * as Sentry from \\"@sentry/astro\\"; + + Sentry.init({ + dsn: import.meta.env.PUBLIC_SENTRY_DSN, + debug: false, + environment: import.meta.env.PUBLIC_VERCEL_ENV, + release: import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA, + tracesSampleRate: 1, + });" + `); + }); + + it('returns a basic Sentry init call with custom options', () => { + const snippet = buildServerSnippet(allSdkOptions); + + expect(snippet).toMatchInlineSnapshot(` + "import * as Sentry from \\"@sentry/astro\\"; + + Sentry.init({ + dsn: \\"my-dsn\\", + debug: true, + environment: \\"staging\\", + release: \\"1.0.0\\", + tracesSampleRate: 0.3, + sampleRate: 0.2, + });" + `); + }); +}); + +describe('buildSdkInitFileImportSnippet', () => { + it('returns a snippet that imports a file', () => { + const snippet = buildSdkInitFileImportSnippet('./my-file.ts'); + expect(snippet).toBe('import "./my-file.ts";'); + }); +}); diff --git a/packages/astro/tsconfig.dev.json b/packages/astro/tsconfig.dev.json new file mode 100644 index 000000000000..cc931d956044 --- /dev/null +++ b/packages/astro/tsconfig.dev.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.dev.json", + + "include": ["scripts/**/*"], + + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Node", + }, + + "ts-node": { + "esm": true + } +} diff --git a/scripts/prepack.ts b/scripts/prepack.ts index 0c810f3e9030..ed280c45d088 100644 --- a/scripts/prepack.ts +++ b/scripts/prepack.ts @@ -21,13 +21,13 @@ const TYPES_VERSIONS_ENTRY_POINT = 'typesVersions'; const packageWithBundles = process.argv.includes('--bundles'); const buildDir = packageWithBundles ? NPM_BUILD_DIR : BUILD_DIR; -type PackageJsonEntryPoints = Record; +type PackageJsonEntryPoints = Record<(typeof ENTRY_POINTS)[number], string>; interface TypeVersions { [key: string]: { [key: string]: string[]; }; -}; +} interface PackageJson extends Record, PackageJsonEntryPoints { [EXPORT_MAP_ENTRY_POINT]: { @@ -35,6 +35,9 @@ interface PackageJson extends Record, PackageJsonEntryPoints { import: string; require: string; types: string; + node: string; + browser: string; + default: string; }; }; [TYPES_VERSIONS_ENTRY_POINT]: TypeVersions; diff --git a/yarn.lock b/yarn.lock index 7dec17d9f84c..ceb462aa1dad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5024,6 +5024,20 @@ unplugin "1.0.1" webpack-sources "3.2.3" +"@sentry/bundler-plugin-core@2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.8.0.tgz#e01df24d7f909277f453844132b856ed997c182b" + integrity sha512-DsTUgeKPqck3DkGzKjRduhPpEn0pez+/THF3gpwQBEfbPnKGr0EYugDvfungZwBFenckIvQBDTOZw0STvbgChA== + dependencies: + "@sentry/cli" "^2.21.2" + "@sentry/node" "^7.60.0" + "@sentry/utils" "^7.60.0" + dotenv "^16.3.1" + find-up "5.0.0" + glob "9.3.2" + magic-string "0.27.0" + unplugin "1.0.1" + "@sentry/cli@2.20.5": version "2.20.5" resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.20.5.tgz#255a5388ca24c211a0eae01dcc4ad813a7ff335a" @@ -5059,6 +5073,17 @@ proxy-from-env "^1.1.0" which "^2.0.2" +"@sentry/cli@^2.21.2": + version "2.21.2" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.21.2.tgz#89e5633ff48a83d078c76c6997fffd4b68b2da1c" + integrity sha512-X1nye89zl+QV3FSuQDGItfM51tW9PQ7ce0TtV/12DgGgTVEgnVp5uvO3wX5XauHvulQzRPzwUL3ZK+yS5bAwCw== + dependencies: + https-proxy-agent "^5.0.0" + node-fetch "^2.6.7" + progress "^2.0.3" + proxy-from-env "^1.1.0" + which "^2.0.2" + "@sentry/vite-plugin@^0.6.1": version "0.6.1" resolved "https://registry.yarnpkg.com/@sentry/vite-plugin/-/vite-plugin-0.6.1.tgz#31eb744e8d87b1528eed8d41433647727a62e7c0" @@ -5066,6 +5091,14 @@ dependencies: "@sentry/bundler-plugin-core" "0.6.1" +"@sentry/vite-plugin@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@sentry/vite-plugin/-/vite-plugin-2.8.0.tgz#d19d2ebf07fcbf09bb585033d803b9967717e5a6" + integrity sha512-17++vXjfn0xEfE7W4FWdwoXdNNqGjXnuTvIgSLlhJvDCTcqWONDpA/TGXGLjbhQEmQ58wL4wQqmlyxoqMPlokQ== + dependencies: + "@sentry/bundler-plugin-core" "2.8.0" + unplugin "1.0.1" + "@sentry/webpack-plugin@1.19.0": version "1.19.0" resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.19.0.tgz#2b134318f1552ba7f3e3f9c83c71a202095f7a44" @@ -12617,6 +12650,11 @@ dotenv@16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== +dotenv@^16.3.1: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + dotenv@~10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" From f8bbf8f86807f88d994289e44eacb8eb3c9e4149 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 10 Oct 2023 22:35:57 +0200 Subject: [PATCH 02/10] lint --- packages/astro/{.eslintrc.js => .eslintrc.cjs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/astro/{.eslintrc.js => .eslintrc.cjs} (100%) diff --git a/packages/astro/.eslintrc.js b/packages/astro/.eslintrc.cjs similarity index 100% rename from packages/astro/.eslintrc.js rename to packages/astro/.eslintrc.cjs From 65c934ba20fee7985118846d631126c672b6259d Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Oct 2023 11:30:34 +0200 Subject: [PATCH 03/10] Update packages/astro/README.md Co-authored-by: Francesco Novy --- packages/astro/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro/README.md b/packages/astro/README.md index 497cba3b4202..98531db8b40a 100644 --- a/packages/astro/README.md +++ b/packages/astro/README.md @@ -83,7 +83,7 @@ SENTRY_AUTH_TOKEN="your-token" To fully customize and configure Sentry in an Astro project, follow step 1 and in addition, add a `sentry.client.config.(js|ts)` and `sentry.server.config(js|ts)` file to the root directory of your project. -Inside these files, you can call `Sentry.init()` and get the full range of Sentry options. +Inside these files, you can call `Sentry.init()` and use the full range of Sentry options. Configuring the client SDK: From 47e7385451c436544752834cf8a037496bfd53bb Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Oct 2023 11:34:34 +0200 Subject: [PATCH 04/10] extract common init options snippet builder --- packages/astro/src/integration/snippets.ts | 24 +++++++++---------- .../astro/test/integration/snippets.test.ts | 6 ++--- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/astro/src/integration/snippets.ts b/packages/astro/src/integration/snippets.ts index 66ed59b70da7..28d03ea443eb 100644 --- a/packages/astro/src/integration/snippets.ts +++ b/packages/astro/src/integration/snippets.ts @@ -15,16 +15,10 @@ export function buildClientSnippet(options: SentryOptions): string { return `import * as Sentry from "@sentry/astro"; Sentry.init({ - dsn: ${options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN'}, - debug: ${options.debug ? true : false}, - environment: ${options.environment ? JSON.stringify(options.environment) : 'import.meta.env.PUBLIC_VERCEL_ENV'}, - release: ${options.release ? JSON.stringify(options.release) : 'import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA'}, + ${buildCommonInitOptions(options)} integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], - tracesSampleRate: ${options.tracesSampleRate ?? 1.0}, replaysSessionSampleRate: ${options.replaysSessionSampleRate ?? 0.1}, - replaysOnErrorSampleRate: ${options.replaysOnErrorSampleRate ?? 1.0},${ - options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : '' - } + replaysOnErrorSampleRate: ${options.replaysOnErrorSampleRate ?? 1.0}, });`; } @@ -36,12 +30,16 @@ export function buildServerSnippet(options: SentryOptions): string { return `import * as Sentry from "@sentry/astro"; Sentry.init({ - dsn: ${options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN'}, + ${buildCommonInitOptions(options)} +});`; +} + +const buildCommonInitOptions = (options: SentryOptions): string => `dsn: ${ + options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN' +}, debug: ${options.debug ? true : false}, environment: ${options.environment ? JSON.stringify(options.environment) : 'import.meta.env.PUBLIC_VERCEL_ENV'}, release: ${options.release ? JSON.stringify(options.release) : 'import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA'}, tracesSampleRate: ${options.tracesSampleRate ?? 1.0},${ - options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : '' - } -});`; -} + options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : '' +}`; diff --git a/packages/astro/test/integration/snippets.test.ts b/packages/astro/test/integration/snippets.test.ts index c2ce40c9c04d..60406b652bf8 100644 --- a/packages/astro/test/integration/snippets.test.ts +++ b/packages/astro/test/integration/snippets.test.ts @@ -22,8 +22,8 @@ describe('buildClientSnippet', () => { debug: false, environment: import.meta.env.PUBLIC_VERCEL_ENV, release: import.meta.env.PUBLIC_VERCEL_GIT_COMMIT_SHA, - integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], tracesSampleRate: 1, + integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1, });" @@ -41,11 +41,11 @@ describe('buildClientSnippet', () => { debug: true, environment: \\"staging\\", release: \\"1.0.0\\", - integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], tracesSampleRate: 0.3, + sampleRate: 0.2, + integrations: [new Sentry.BrowserTracing(), new Sentry.Replay()], replaysSessionSampleRate: 0.5, replaysOnErrorSampleRate: 0.4, - sampleRate: 0.2, });" `); }); From 97581c8f75b17aafa016e37407807f40f14ee6da Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Oct 2023 11:41:43 +0200 Subject: [PATCH 05/10] remove org from readme (no need with org tokens) --- packages/astro/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/astro/README.md b/packages/astro/README.md index 98531db8b40a..a2738298a67c 100644 --- a/packages/astro/README.md +++ b/packages/astro/README.md @@ -51,7 +51,7 @@ If you want to fully customize your SDK setup, you can do so, too: ### 2. [Optional] Uploading Source Maps -To upload source maps to Sentry, simply add the `project`, `org` and `authToken` options to `sentryAstro`: +To upload source maps to Sentry, simply add the `project` and `authToken` options to `sentryAstro`: ```js // astro.config.mjs @@ -62,7 +62,6 @@ export default defineConfig({ integrations: [ sentryAstro({ dsn: '__DSN__', - org: 'your-org-slug', project: 'your-project-slug', authToken: import.meta.env('SENTRY_AUTH_TOKEN'), }), @@ -74,11 +73,12 @@ You can also define these values as environment variables in e.g. a `.env` file or in you CI configuration: ```sh -SENTRY_ORG="your-org-slug" SENTRY_PROJECT="your-project" SENTRY_AUTH_TOKEN="your-token" ``` +Follow [this guide](https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens) to create an auth token. + ### 3. [Optional] Advanced Configuration To fully customize and configure Sentry in an Astro project, follow step 1 and in addition, From b752a2b5d9b72255125cfa3265b10a0d82e24f41 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Oct 2023 12:11:43 +0200 Subject: [PATCH 06/10] new sourcemaps API --- packages/astro/src/integration/index.ts | 16 +++--- packages/astro/src/integration/types.ts | 68 ++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index 18dac368edbc..829594c9248d 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -19,7 +19,12 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { // see: https://main.vitejs.dev/config/#using-environment-variables-in-config const env = loadEnv('production', process.cwd(), ''); - if (options.authToken ?? env.SENTRY_AUTH_TOKEN) { + const uploadOptions = options.sourceMapsUploadOptions || {}; + + const shouldUploadSourcemaps = uploadOptions?.enabled ?? true; + const authToken = uploadOptions.authToken || env.SENTRY_AUTH_TOKEN; + + if (shouldUploadSourcemaps && authToken) { updateConfig({ vite: { build: { @@ -27,10 +32,10 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { }, plugins: [ sentryVitePlugin({ - org: options.org ?? env.SENTRY_ORG, - project: options.project ?? env.SENTRY_PROJECT, - authToken: options.authToken ?? env.SENTRY_AUTH_TOKEN, - telemetry: options.telemetry, + org: uploadOptions.org ?? env.SENTRY_ORG, + project: uploadOptions.project ?? env.SENTRY_PROJECT, + authToken: uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN, + telemetry: uploadOptions.telemetry ?? true, }), ], }, @@ -52,7 +57,6 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { options.debug && console.log(`[sentry-astro] Using ${pathToServerInit} for server init.`); // For whatever reason, we need to move one level up to import the server file correctly injectScript('page-ssr', buildSdkInitFileImportSnippet(path.join('..', pathToServerInit))); - } else { options.debug && console.log('[sentry-astro] Using default server init.'); injectScript('page-ssr', buildServerSnippet(options || {})); } diff --git a/packages/astro/src/integration/types.ts b/packages/astro/src/integration/types.ts index 35cddb3e3e31..d54c948401ca 100644 --- a/packages/astro/src/integration/types.ts +++ b/packages/astro/src/integration/types.ts @@ -1,22 +1,76 @@ import type { BrowserOptions } from '@sentry/browser'; import type { Options } from '@sentry/types'; -import type { SentryVitePluginOptions } from '@sentry/vite-plugin'; type SdkInitPaths = { /** * Path to a `sentry.client.config.(js|ts)` file that contains a `Sentry.init` call. - * If this option is not specified, the default location (`src/sentry.client.config.(js|ts)`) will be used. - * If there is no file at the default location, a default `Sentry.init` call will made. + * + * If this option is not specified, the default location (`/sentry.client.config.(js|ts)`) + * will be used to look up the config file. + * If there is no file at the default location either, the SDK will initalize with the options + * specified in the `sentryAstro` integration or with default options. */ clientInitPath?: string; + /** - * Path to a `sentry.client.config.(js|ts)` file that contains a `Sentry.init` call. - * If this option is not specified, the default location (`src/sentry.client.config.(js|ts)`) will be used. - * If there is no file at the default location, a default `Sentry.init` call will made. + * Path to a `sentry.server.config.(js|ts)` file that contains a `Sentry.init` call. + * + * If this option is not specified, the default location (`/sentry.server.config.(js|ts)`) + * will be used to look up the config file. + * If there is no file at the default location either, the SDK will initalize with the options + * specified in the `sentryAstro` integration or with default options. */ serverInitPath?: string; }; +type SourceMapsOptions = { + /** + * Options for the Sentry Vite plugin to customize the source maps upload process. + * + * 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?: { + /** + * 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 + */ + enabled?: boolean; + + /** + * The auth token to use when uploading source maps to Sentry. + * + * Instead of specifying this option, you can also set the `SENTRY_AUTH_TOKEN` environment variable. + * + * To create an auth token, follow this guide: + * @see https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens + */ + authToken?: string; + + /** + * The organization slug of your Sentry organization. + * Instead of specifying this option, you can also set the `SENTRY_ORG` environment variable. + */ + org?: string; + + /** + * The project slug of your Sentry project. + * Instead of specifying this option, you can also set the `SENTRY_PROJECT` environment variable. + */ + project?: string; + + /** + * If this flag is `true`, the Sentry plugin will collect some telemetry data and send it to Sentry. + * It will not collect any sensitive or user-specific data. + * + * @default true + */ + telemetry?: boolean; + }; +}; + /** * A subset of Sentry SDK options that can be set via the `sentryAstro` integration. * Some options (e.g. integrations) are set by default and cannot be changed here. @@ -29,4 +83,4 @@ type SdkInitPaths = { export type SentryOptions = SdkInitPaths & Pick & Pick & - Pick; + SourceMapsOptions; From fd29a6398d438e1f467bf3f868579a640b74d0e9 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Oct 2023 13:47:10 +0200 Subject: [PATCH 07/10] fix server file import --- packages/astro/src/integration/index.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index 829594c9248d..b33f02d11144 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -42,8 +42,12 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { }); } - const pathToClientInit = options.clientInitPath ?? findSdkInitFile('client'); - const pathToServerInit = options.serverInitPath ?? findSdkInitFile('server'); + const pathToClientInit = options.clientInitPath + ? path.resolve(options.clientInitPath) + : findDefaultSdkInitFile('client'); + const pathToServerInit = options.serverInitPath + ? path.resolve(options.serverInitPath) + : findDefaultSdkInitFile('server'); if (pathToClientInit) { options.debug && console.log(`[sentry-astro] Using ${pathToClientInit} for client init.`); @@ -55,8 +59,7 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { if (pathToServerInit) { options.debug && console.log(`[sentry-astro] Using ${pathToServerInit} for server init.`); - // For whatever reason, we need to move one level up to import the server file correctly - injectScript('page-ssr', buildSdkInitFileImportSnippet(path.join('..', pathToServerInit))); + injectScript('page-ssr', buildSdkInitFileImportSnippet(pathToServerInit)); options.debug && console.log('[sentry-astro] Using default server init.'); injectScript('page-ssr', buildServerSnippet(options || {})); } @@ -65,9 +68,9 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { }; }; -function findSdkInitFile(type: 'server' | 'client'): string | undefined { +function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined { const fileExtensions = ['ts', 'js', 'tsx', 'jsx', 'mjs', 'cjs', 'mts']; return fileExtensions - .map(ext => path.join(process.cwd(), `sentry.${type}.config.${ext}`)) + .map(ext => path.resolve(path.join(process.cwd(), `sentry.${type}.config.${ext}`))) .find(filename => fs.existsSync(filename)); } From 811fd0bb67ded68f544d0dddbef8d37fabc5b71d Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 12 Oct 2023 14:11:33 +0200 Subject: [PATCH 08/10] add tests --- packages/astro/src/integration/index.ts | 1 + packages/astro/test/integration/index.test.ts | 104 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 packages/astro/test/integration/index.test.ts diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index b33f02d11144..1db985eea6a1 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -60,6 +60,7 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { if (pathToServerInit) { options.debug && console.log(`[sentry-astro] Using ${pathToServerInit} for server init.`); injectScript('page-ssr', buildSdkInitFileImportSnippet(pathToServerInit)); + } else { options.debug && console.log('[sentry-astro] Using default server init.'); injectScript('page-ssr', buildServerSnippet(options || {})); } diff --git a/packages/astro/test/integration/index.test.ts b/packages/astro/test/integration/index.test.ts new file mode 100644 index 000000000000..651c28e379b5 --- /dev/null +++ b/packages/astro/test/integration/index.test.ts @@ -0,0 +1,104 @@ +import { vi } from 'vitest'; + +import { sentryAstro } from '../../src/integration'; + +const sentryVitePluginSpy = vi.fn(() => 'sentryVitePlugin'); + +vi.mock('@sentry/vite-plugin', () => ({ + // @ts-expect-error - just mocking around + sentryVitePlugin: vi.fn(args => sentryVitePluginSpy(args)), +})); + +vi.mock('vite', () => ({ + loadEnv: () => ({ + SENTRY_AUTH_TOKEN: 'my-token', + }), +})); + +describe('sentryAstro integration', () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + it('has a name', () => { + const integration = sentryAstro({}); + expect(integration.name).toBe('@sentry/astro'); + }); + + it('enables source maps and adds the sentry vite plugin if an auth token is detected', async () => { + const integration = sentryAstro({ + sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false }, + }); + const updateConfig = vi.fn(); + const injectScript = vi.fn(); + + 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 }); + + expect(updateConfig).toHaveBeenCalledTimes(1); + expect(updateConfig).toHaveBeenCalledWith({ + vite: { + build: { + sourcemap: true, + }, + plugins: ['sentryVitePlugin'], + }, + }); + + expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); + expect(sentryVitePluginSpy).toHaveBeenCalledWith({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: false, + }); + }); + + it("doesn't enable source maps if `sourceMapsUploadOptions.enabled` is `false`", async () => { + const integration = sentryAstro({ + sourceMapsUploadOptions: { enabled: false }, + }); + const updateConfig = vi.fn(); + const injectScript = vi.fn(); + + 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 }); + + expect(updateConfig).toHaveBeenCalledTimes(0); + expect(sentryVitePluginSpy).toHaveBeenCalledTimes(0); + }); + + it('injects client and server init scripts', async () => { + const integration = sentryAstro({}); + const updateConfig = vi.fn(); + const injectScript = vi.fn(); + + 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 }); + + expect(injectScript).toHaveBeenCalledTimes(2); + expect(injectScript).toHaveBeenCalledWith('page', expect.stringContaining('Sentry.init')); + expect(injectScript).toHaveBeenCalledWith('page-ssr', expect.stringContaining('Sentry.init')); + }); + + it('injects client and server init scripts from custom paths', async () => { + const integration = sentryAstro({ + clientInitPath: 'my-client-init-path.js', + serverInitPath: 'my-server-init-path.js', + }); + + const updateConfig = vi.fn(); + const injectScript = vi.fn(); + + 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 }); + + expect(injectScript).toHaveBeenCalledTimes(2); + expect(injectScript).toHaveBeenCalledWith('page', expect.stringContaining('my-client-init-path.js')); + expect(injectScript).toHaveBeenCalledWith('page-ssr', expect.stringContaining('my-server-init-path.js')); + }); +}); From 306c97efe0d38a26226ecf7675ba0412f17de12b Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 13 Oct 2023 10:14:55 +0200 Subject: [PATCH 09/10] build astro integration with server entry point --- packages/astro/package.json | 6 +----- packages/astro/rollup.npm.config.js | 7 ++++++- packages/astro/src/index.server.ts | 5 +++++ packages/astro/src/integration/README.md | 4 ---- packages/astro/src/integration/index.ts | 4 ++-- rollup/npmHelpers.js | 16 +++++++--------- rollup/plugins/npmPlugins.js | 3 ++- 7 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 packages/astro/src/integration/README.md diff --git a/packages/astro/package.json b/packages/astro/package.json index ce6b79f9cd57..60a2007a1553 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -21,9 +21,6 @@ "import": "./build/esm/index.client.js", "require": "./build/cjs/index.server.js", "types": "./build/types/index.types.d.ts" - }, - "./integration": { - "default": "./build/integration/index.ts" } }, "publishConfig": { @@ -46,7 +43,7 @@ "vite": "4.0.5" }, "scripts": { - "build": "run-p build:transpile build:types build:sync:integration", + "build": "run-p build:transpile build:types", "build:dev": "yarn build", "build:transpile": "rollup -c rollup.npm.config.js --bundleConfigAsCjs", "build:types": "tsc -p tsconfig.types.json", @@ -55,7 +52,6 @@ "build:transpile:watch": "rollup -c rollup.npm.config.js --bundleConfigAsCjs --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:tarball": "ts-node ../../scripts/prepack.ts && npm pack ./build", - "build:sync:integration": "ts-node -P tsconfig.dev.json ./scripts/syncIntegration.ts", "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts", "clean": "rimraf build coverage sentry-astro-*.tgz", "fix": "run-s fix:eslint fix:prettier", diff --git a/packages/astro/rollup.npm.config.js b/packages/astro/rollup.npm.config.js index 23b23ff7a8d7..06dd0b3e4ec1 100644 --- a/packages/astro/rollup.npm.config.js +++ b/packages/astro/rollup.npm.config.js @@ -1,12 +1,17 @@ import { makeBaseNPMConfig, makeNPMConfigVariants } from '../../rollup/index.js'; -export default makeNPMConfigVariants( +const variants = makeNPMConfigVariants( makeBaseNPMConfig({ entrypoints: ['src/index.server.ts', 'src/index.client.ts'], packageSpecificConfig: { output: { dynamicImportInCjs: true, + exports: 'named', }, }, + // Astro is Node 18+ no need to add polyfills + addPolyfills: false, }), ); + +export default variants; diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index 2e008583cbe8..7a28bf907d48 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -2,6 +2,9 @@ // Unfortunately, we cannot `export * from '@sentry/node'` because in prod builds, // Vite puts these exports into a `default` property (Sentry.default) rather than // on the top - level namespace. + +import { sentryAstro } from './integration'; + // Hence, we export everything from the Node SDK explicitly: export { addGlobalEventProcessor, @@ -58,3 +61,5 @@ export { export * from '@sentry/node'; export { init } from './server/sdk'; + +export default sentryAstro; diff --git a/packages/astro/src/integration/README.md b/packages/astro/src/integration/README.md deleted file mode 100644 index b248906967d1..000000000000 --- a/packages/astro/src/integration/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Contents of this directory are _not_ bundled with rollup. -They're directly copied into `build/integration`. -Astro supports TypeScript in integration packages. -The integration files will simply be bundled by Vite when building the Astro project. diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index 1db985eea6a1..f9df42194913 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -3,7 +3,6 @@ import { sentryVitePlugin } from '@sentry/vite-plugin'; import type { AstroIntegration } from 'astro'; import * as fs from 'fs'; import * as path from 'path'; -import { loadEnv } from 'vite'; import { buildClientSnippet, buildSdkInitFileImportSnippet, buildServerSnippet } from './snippets'; import type { SentryOptions } from './types'; @@ -17,7 +16,8 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { 'astro:config:setup': async ({ updateConfig, injectScript }) => { // The third param here enables loading of all env vars, regardless of prefix // see: https://main.vitejs.dev/config/#using-environment-variables-in-config - const env = loadEnv('production', process.cwd(), ''); + // const env = loadEnv('production', process.cwd(), ''); + const env = process.env; const uploadOptions = options.sourceMapsUploadOptions || {}; diff --git a/rollup/npmHelpers.js b/rollup/npmHelpers.js index be6a900b2115..fe2a55543e59 100644 --- a/rollup/npmHelpers.js +++ b/rollup/npmHelpers.js @@ -25,10 +25,11 @@ export function makeBaseNPMConfig(options = {}) { esModuleInterop = false, hasBundles = false, packageSpecificConfig = {}, + addPolyfills = true, } = options; const nodeResolvePlugin = makeNodeResolvePlugin(); - const sucrasePlugin = makeSucrasePlugin(); + const sucrasePlugin = makeSucrasePlugin({ disableESTransforms: !addPolyfills }); const debugBuildStatementReplacePlugin = makeDebugBuildStatementReplacePlugin(); const cleanupPlugin = makeCleanupPlugin(); const extractPolyfillsPlugin = makeExtractPolyfillsPlugin(); @@ -83,14 +84,7 @@ export function makeBaseNPMConfig(options = {}) { interop: esModuleInterop ? 'auto' : 'esModule', }, - plugins: [ - nodeResolvePlugin, - setSdkSourcePlugin, - sucrasePlugin, - debugBuildStatementReplacePlugin, - cleanupPlugin, - extractPolyfillsPlugin, - ], + plugins: [nodeResolvePlugin, setSdkSourcePlugin, sucrasePlugin, debugBuildStatementReplacePlugin, cleanupPlugin], // don't include imported modules from outside the package in the final output external: [ @@ -100,6 +94,10 @@ export function makeBaseNPMConfig(options = {}) { ], }; + if (addPolyfills) { + defaultBaseConfig.plugins.push(extractPolyfillsPlugin); + } + return deepMerge(defaultBaseConfig, packageSpecificConfig, { // Plugins have to be in the correct order or everything breaks, so when merging we have to manually re-order them customMerge: key => (key === 'plugins' ? mergePlugins : undefined), diff --git a/rollup/plugins/npmPlugins.js b/rollup/plugins/npmPlugins.js index ec162615623f..5265f5007755 100644 --- a/rollup/plugins/npmPlugins.js +++ b/rollup/plugins/npmPlugins.js @@ -16,9 +16,10 @@ import sucrase from '@rollup/plugin-sucrase'; * * @returns An instance of the `@rollup/plugin-sucrase` plugin */ -export function makeSucrasePlugin() { +export function makeSucrasePlugin(options = {}) { return sucrase({ transforms: ['typescript', 'jsx'], + ...options, }); } From c23cb6122598459f21de7b2432e5dcc6a4d48e6e Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 13 Oct 2023 10:22:40 +0200 Subject: [PATCH 10/10] adjust tests --- packages/astro/src/integration/index.ts | 4 ++++ packages/astro/test/index.client.test.ts | 5 ----- packages/astro/test/integration/index.test.ts | 9 ++++----- packages/astro/test/server/index.server.test.ts | 7 +++++++ 4 files changed, 15 insertions(+), 10 deletions(-) delete mode 100644 packages/astro/test/index.client.test.ts create mode 100644 packages/astro/test/server/index.server.test.ts diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index f9df42194913..0432fb8108d3 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -16,7 +16,11 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { 'astro:config:setup': async ({ updateConfig, injectScript }) => { // The third param here enables loading of all env vars, regardless of prefix // see: https://main.vitejs.dev/config/#using-environment-variables-in-config + + // TODO: Ideally, we want to load the environment with vite like this: // const env = loadEnv('production', process.cwd(), ''); + // However, this currently throws a build error. + // Will revisit this later. const env = process.env; const uploadOptions = options.sourceMapsUploadOptions || {}; diff --git a/packages/astro/test/index.client.test.ts b/packages/astro/test/index.client.test.ts deleted file mode 100644 index f4bf62c84f1d..000000000000 --- a/packages/astro/test/index.client.test.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('placeholder', () => { - it('holds a place', () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/astro/test/integration/index.test.ts b/packages/astro/test/integration/index.test.ts index 651c28e379b5..fe876023c9c4 100644 --- a/packages/astro/test/integration/index.test.ts +++ b/packages/astro/test/integration/index.test.ts @@ -9,11 +9,10 @@ vi.mock('@sentry/vite-plugin', () => ({ sentryVitePlugin: vi.fn(args => sentryVitePluginSpy(args)), })); -vi.mock('vite', () => ({ - loadEnv: () => ({ - SENTRY_AUTH_TOKEN: 'my-token', - }), -})); +process.env = { + ...process.env, + SENTRY_AUTH_TOKEN: 'my-token', +}; describe('sentryAstro integration', () => { afterEach(() => { diff --git a/packages/astro/test/server/index.server.test.ts b/packages/astro/test/server/index.server.test.ts new file mode 100644 index 000000000000..f319ef90eaad --- /dev/null +++ b/packages/astro/test/server/index.server.test.ts @@ -0,0 +1,7 @@ +import sentryAstro from '../../src/index.server'; +describe('server SDK', () => { + it('exports the astro integration as a default export', () => { + const integration = sentryAstro(); + expect(integration.name).toBe('@sentry/astro'); + }); +});