@sentry/nuxt 8.16.0 → 8.18.0

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/README.md CHANGED
@@ -28,6 +28,31 @@ The minimum supported version of Nuxt is `3.0.0`.
28
28
  This package is a wrapper around `@sentry/node` for the server and `@sentry/vue` for the client side, with added
29
29
  functionality related to Nuxt.
30
30
 
31
+ **What is working:**
32
+
33
+ - Error Reporting
34
+ - Vue
35
+ - Node
36
+ - Nitro
37
+
38
+ **What is partly working:**
39
+
40
+ - Tracing by setting `tracesSampleRate`
41
+ - UI (Vue) traces
42
+ - HTTP (Node) traces
43
+
44
+ **What is not yet(!) included:**
45
+
46
+ - Source Maps
47
+ - Nuxt-specific traces and connecting frontend & backend traces
48
+
49
+ **Known Issues:**
50
+
51
+ - When adding `sentry.server.config.(ts/js)`, you get this error: "Failed to register ESM hook", but the application
52
+ will still work
53
+ - When initializing Sentry on the server with `instrument.server.(js|ts)`, you get an `'import-in-the-middle'` error,
54
+ and the application won't work
55
+
31
56
  ## Automatic Setup
32
57
 
33
58
  todo: add wizard instructions
@@ -83,10 +108,38 @@ Add a `sentry.server.config.(js|ts)` file to the root of your project:
83
108
  import * as Sentry from '@sentry/nuxt';
84
109
 
85
110
  Sentry.init({
86
- dsn: env.DSN,
111
+ dsn: process.env.DSN,
87
112
  });
88
113
  ```
89
114
 
115
+ **Alternative Setup (ESM-compatible)**
116
+
117
+ This setup makes sure Sentry is imported on the server before any other imports. As of now, this however leads to an
118
+ import-in-the-middle error ([related reproduction](https://github.com/getsentry/sentry-javascript-examples/pull/38)).
119
+
120
+ Add an `instrument.server.mjs` file to your `public` folder:
121
+
122
+ ```javascript
123
+ import * as Sentry from '@sentry/nuxt';
124
+
125
+ // Only run `init` when DSN is available
126
+ if (process.env.SENTRY_DSN) {
127
+ Sentry.init({
128
+ dsn: process.env.DSN,
129
+ });
130
+ }
131
+ ```
132
+
133
+ Add an import flag to the node options, so the file loads before any other imports:
134
+
135
+ ```json
136
+ {
137
+ "scripts": {
138
+ "preview": "NODE_OPTIONS='--import ./public/instrument.server.mjs' nuxt preview"
139
+ }
140
+ }
141
+ ```
142
+
90
143
  ### 5. Vite Setup
91
144
 
92
145
  todo: add vite setup
@@ -0,0 +1,5 @@
1
+ module.exports = function(...args) {
2
+ return import('./module.mjs').then(m => m.default.call(this, ...args))
3
+ }
4
+ const _meta = module.exports.meta = require('./module.json')
5
+ module.exports.getMeta = () => Promise.resolve(_meta)
@@ -0,0 +1,9 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { init } from '@sentry/vue';
3
+
4
+ type SentryNuxtOptions = Omit<Parameters<typeof init>[0] & object, 'app'>;
5
+
6
+ type ModuleOptions = SentryNuxtOptions;
7
+ declare const _default: _nuxt_schema.NuxtModule<SentryNuxtOptions>;
8
+
9
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,9 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { init } from '@sentry/vue';
3
+
4
+ type SentryNuxtOptions = Omit<Parameters<typeof init>[0] & object, 'app'>;
5
+
6
+ type ModuleOptions = SentryNuxtOptions;
7
+ declare const _default: _nuxt_schema.NuxtModule<SentryNuxtOptions>;
8
+
9
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@sentry/nuxt/module",
3
+ "configKey": "sentry",
4
+ "compatibility": {
5
+ "nuxt": "^3.0.0"
6
+ },
7
+ "version": "8.18.0",
8
+ "builder": {
9
+ "@nuxt/module-builder": "0.8.0",
10
+ "unbuild": "2.0.0"
11
+ }
12
+ }
@@ -0,0 +1,46 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { defineNuxtModule, createResolver, addPluginTemplate, addPlugin, addServerPlugin } from '@nuxt/kit';
4
+
5
+ const module = defineNuxtModule({
6
+ meta: {
7
+ name: "@sentry/nuxt/module",
8
+ configKey: "sentry",
9
+ compatibility: {
10
+ nuxt: "^3.0.0"
11
+ }
12
+ },
13
+ defaults: {},
14
+ setup(_moduleOptions, nuxt) {
15
+ const moduleDirResolver = createResolver(import.meta.url);
16
+ const buildDirResolver = createResolver(nuxt.options.buildDir);
17
+ const clientConfigFile = findDefaultSdkInitFile("client");
18
+ if (clientConfigFile) {
19
+ addPluginTemplate({
20
+ mode: "client",
21
+ filename: "sentry-client-config.mjs",
22
+ getContents: () => `import "${buildDirResolver.resolve(`/${clientConfigFile}`)}"
23
+ export default defineNuxtPlugin(() => {})`
24
+ });
25
+ addPlugin({ src: moduleDirResolver.resolve("./runtime/plugins/sentry.client"), mode: "client" });
26
+ }
27
+ const serverConfigFile = findDefaultSdkInitFile("server");
28
+ if (serverConfigFile) {
29
+ addPluginTemplate({
30
+ mode: "server",
31
+ filename: "sentry-server-config.mjs",
32
+ getContents: () => `import "${buildDirResolver.resolve(`/${serverConfigFile}`)}"
33
+ export default defineNuxtPlugin(() => {})`
34
+ });
35
+ addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/sentry.server"));
36
+ }
37
+ }
38
+ });
39
+ function findDefaultSdkInitFile(type) {
40
+ const possibleFileExtensions = ["ts", "js", "mjs", "cjs", "mts", "cts"];
41
+ const cwd = process.cwd();
42
+ const filePath = possibleFileExtensions.map((e) => path.resolve(path.join(cwd, `sentry.${type}.config.${e}`))).find((filename) => fs.existsSync(filename));
43
+ return filePath ? path.basename(filePath) : void 0;
44
+ }
45
+
46
+ export { module as default };
@@ -0,0 +1,11 @@
1
+ import { getClient } from "@sentry/core";
2
+ import { vueIntegration } from "@sentry/vue";
3
+ import { defineNuxtPlugin } from "nuxt/app";
4
+ export default defineNuxtPlugin((nuxtApp) => {
5
+ nuxtApp.hook("app:created", (vueApp) => {
6
+ const sentryClient = getClient();
7
+ if (sentryClient) {
8
+ sentryClient.addIntegration(vueIntegration({ app: vueApp }));
9
+ }
10
+ });
11
+ });
@@ -0,0 +1,18 @@
1
+ import { captureException } from "@sentry/node";
2
+ import { H3Error } from "h3";
3
+ import { defineNitroPlugin } from "nitropack/runtime";
4
+ import { extractErrorContext } from "../utils.js";
5
+ export default defineNitroPlugin((nitroApp) => {
6
+ nitroApp.hooks.hook("error", (error, errorContext) => {
7
+ if (error instanceof H3Error) {
8
+ if (error.statusCode >= 300 && error.statusCode < 500) {
9
+ return;
10
+ }
11
+ }
12
+ const structuredContext = extractErrorContext(errorContext);
13
+ captureException(error, {
14
+ captureContext: { contexts: { nuxt: structuredContext } },
15
+ mechanism: { handled: false }
16
+ });
17
+ });
18
+ });
File without changes
@@ -0,0 +1,18 @@
1
+ import { dropUndefinedKeys } from "@sentry/utils";
2
+ export function extractErrorContext(errorContext) {
3
+ const structuredContext = {
4
+ method: void 0,
5
+ path: void 0,
6
+ tags: void 0
7
+ };
8
+ if (errorContext) {
9
+ if (errorContext.event) {
10
+ structuredContext.method = errorContext.event._method || void 0;
11
+ structuredContext.path = errorContext.event._path || void 0;
12
+ }
13
+ if (Array.isArray(errorContext.tags)) {
14
+ structuredContext.tags = errorContext.tags || void 0;
15
+ }
16
+ }
17
+ return dropUndefinedKeys(structuredContext);
18
+ }
@@ -0,0 +1 @@
1
+ export { type ModuleOptions, default } from './module.js'
@@ -0,0 +1 @@
1
+ export { type ModuleOptions, default } from './module'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/nuxt",
3
- "version": "8.16.0",
3
+ "version": "8.18.0",
4
4
  "description": "Official Sentry SDK for Nuxt (EXPERIMENTAL)",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nuxt",
@@ -43,24 +43,24 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@nuxt/kit": "^3.12.2",
46
- "@sentry/browser": "8.16.0",
47
- "@sentry/core": "8.16.0",
48
- "@sentry/node": "8.16.0",
49
- "@sentry/opentelemetry": "8.16.0",
50
- "@sentry/types": "8.16.0",
51
- "@sentry/utils": "8.16.0",
46
+ "@sentry/browser": "8.18.0",
47
+ "@sentry/core": "8.18.0",
48
+ "@sentry/node": "8.18.0",
49
+ "@sentry/opentelemetry": "8.18.0",
50
+ "@sentry/types": "8.18.0",
51
+ "@sentry/utils": "8.18.0",
52
52
  "@sentry/vite-plugin": "2.20.1",
53
- "@sentry/vue": "8.16.0"
53
+ "@sentry/vue": "8.18.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@nuxt/module-builder": "0.8.0",
57
57
  "nuxt": "^3.12.2"
58
58
  },
59
59
  "scripts": {
60
- "build": "run-p build:transpile build:types build:nuxt-module",
60
+ "build": "run-s build:types build:transpile",
61
61
  "build:dev": "yarn build",
62
62
  "build:nuxt-module": "nuxt-module-build build --outDir build/module",
63
- "build:transpile": "rollup -c rollup.npm.config.mjs",
63
+ "build:transpile": "rollup -c rollup.npm.config.mjs && yarn build:nuxt-module",
64
64
  "build:types": "tsc -p tsconfig.types.json",
65
65
  "build:watch": "run-p build:transpile:watch build:types:watch",
66
66
  "build:dev:watch": "yarn build:watch",
@@ -84,10 +84,12 @@
84
84
  "build:transpile": {
85
85
  "dependsOn": [
86
86
  "^build:transpile",
87
- "^build:types"
87
+ "^build:types",
88
+ "build:types"
88
89
  ],
89
90
  "outputs": [
90
- "{projectRoot}/build",
91
+ "{projectRoot}/build/cjs",
92
+ "{projectRoot}/build/esm",
91
93
  "{projectRoot}/build/module"
92
94
  ]
93
95
  }