@dargmuesli/nuxt-vio 23.1.2 → 23.1.4

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.
@@ -5,7 +5,7 @@ export const useSharedSentryConfig = () => {
5
5
  const runtimeConfig = useRuntimeConfig()
6
6
 
7
7
  return getSharedSentryConfig({
8
- enableLogs: runtimeConfig.public.sentry.logs.enable,
8
+ dataCollection: runtimeConfig.public.sentry.dataCollection,
9
9
  environment: runtimeConfig.public.sentry.environment,
10
10
  host: runtimeConfig.public.sentry.host,
11
11
  isInProduction: runtimeConfig.public.vio.isInProduction,
@@ -10,6 +10,37 @@ export const getHost = (event: { headers: Headers }) => {
10
10
  return host
11
11
  }
12
12
 
13
+ // derives the origins this project itself talks to, so Sentry's trace context is only propagated
14
+ // to its own services and never to third parties
15
+ export const getTracePropagationTargets = ({
16
+ baseUrl,
17
+ services = SERVICES,
18
+ }: {
19
+ baseUrl?: string
20
+ services?: Record<string, Service>
21
+ }): string[] => {
22
+ if (!baseUrl) return []
23
+
24
+ let base: URL
25
+ try {
26
+ base = new URL(baseUrl)
27
+ } catch {
28
+ return []
29
+ }
30
+
31
+ const targets = [base.origin]
32
+
33
+ for (const [name, service] of Object.entries(services)) {
34
+ if (!service.hasSubdomain) continue
35
+
36
+ targets.push(
37
+ `${base.protocol}//${name.replaceAll('_', '-')}.${getRootHost(base.hostname)}`,
38
+ )
39
+ }
40
+
41
+ return targets
42
+ }
43
+
13
44
  export const getRootHost = (host: string) => {
14
45
  const hostParts = host.split('.')
15
46
  const hostPartsLast = hostParts[hostParts.length - 1]
@@ -16,5 +16,4 @@ if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
16
16
  process.env.NITRO_SSL_KEY = fs.readFileSync(keyPath, 'utf8')
17
17
  }
18
18
 
19
- // await import(path.join(root, '.output/server/sentry.server.config.mjs'))
20
19
  await import(path.join(root, 'playground/.output/server/index.mjs'))
@@ -5,14 +5,40 @@ export const NUXT_PUBLIC_SENTRY_ENVIRONMENT =
5
5
  export const NUXT_PUBLIC_SENTRY_HOST = process.env.NUXT_PUBLIC_SENTRY_HOST || ''
6
6
  export const NUXT_PUBLIC_SENTRY_LOGS_ENABLE =
7
7
  process.env.NUXT_PUBLIC_SENTRY_LOGS_ENABLE !== 'false'
8
+ export const NUXT_PUBLIC_SENTRY_PROFILE_SESSION_SAMPLE_RATE = Number.parseFloat(
9
+ process.env.NUXT_PUBLIC_SENTRY_PROFILE_SESSION_SAMPLE_RATE ?? '0.1',
10
+ )
11
+ export const NUXT_PUBLIC_SENTRY_PROFILING_ENABLE =
12
+ process.env.NUXT_PUBLIC_SENTRY_PROFILING_ENABLE !== 'false'
8
13
  export const NUXT_PUBLIC_SENTRY_PROJECT_ID =
9
14
  process.env.NUXT_PUBLIC_SENTRY_PROJECT_ID || ''
10
15
  export const NUXT_PUBLIC_SENTRY_PROJECT_PUBLIC_KEY =
11
16
  process.env.NUXT_PUBLIC_SENTRY_PROJECT_PUBLIC_KEY || ''
12
17
  export const NUXT_PUBLIC_SENTRY_RELEASE = process.env.RELEASE_NAME
13
18
 
19
+ // v11's `dataCollection` collects more personal data by default than v10 did. This floor restores
20
+ // the previous, restrictive behavior for the categories v11 started to collect, without redefining
21
+ // Sentry's other defaults. Extending projects can relax or tighten any category through
22
+ // `runtimeConfig.public.sentry.dataCollection`, which is merged over this floor.
23
+ const SENTRY_DATA_COLLECTION_FLOOR: NonNullable<
24
+ Parameters<typeof Sentry.init>[0]['dataCollection']
25
+ > = {
26
+ cookies: false,
27
+ databaseQueryData: false,
28
+ genAI: {
29
+ inputs: false,
30
+ outputs: false,
31
+ },
32
+ graphQL: {
33
+ document: false,
34
+ variables: false,
35
+ },
36
+ httpBodies: [],
37
+ userInfo: false,
38
+ }
39
+
14
40
  export const getSharedSentryConfig = ({
15
- enableLogs,
41
+ dataCollection,
16
42
  environment,
17
43
  host,
18
44
  isInProduction,
@@ -21,7 +47,7 @@ export const getSharedSentryConfig = ({
21
47
  projectPublicKey,
22
48
  release,
23
49
  }: {
24
- enableLogs?: boolean
50
+ dataCollection?: Parameters<typeof Sentry.init>[0]['dataCollection']
25
51
  environment?: string
26
52
  host?: string
27
53
  isInProduction: boolean
@@ -30,12 +56,23 @@ export const getSharedSentryConfig = ({
30
56
  projectPublicKey?: string
31
57
  release?: string
32
58
  }): Parameters<typeof Sentry.init>[0] => ({
59
+ dataCollection: {
60
+ ...SENTRY_DATA_COLLECTION_FLOOR,
61
+ ...dataCollection,
62
+ genAI: {
63
+ ...SENTRY_DATA_COLLECTION_FLOOR.genAI,
64
+ ...dataCollection?.genAI,
65
+ },
66
+ graphQL: {
67
+ ...SENTRY_DATA_COLLECTION_FLOOR.graphQL,
68
+ ...dataCollection?.graphQL,
69
+ },
70
+ },
33
71
  dsn:
34
72
  projectPublicKey && host && projectId
35
73
  ? `https://${projectPublicKey}@${host}/${projectId}`
36
74
  : undefined,
37
75
  enabled: isInProduction && !isTesting,
38
- enableLogs,
39
76
  environment,
40
77
  release,
41
78
  tracesSampleRate: 1.0,
package/nuxt.config.ts CHANGED
@@ -154,15 +154,27 @@ export default defineNuxtConfig(
154
154
  asyncContext: true,
155
155
  },
156
156
  },
157
+ routeRules: {
158
+ '/**': {
159
+ headers: {
160
+ 'Document-Policy': 'js-profiling', // required by Sentry's browser profiling (Chromium-based browsers)
161
+ },
162
+ },
163
+ },
157
164
  runtimeConfig: {
158
165
  public: {
159
166
  i18n: {
160
167
  baseUrl: SITE_URL,
161
168
  },
162
169
  sentry: {
170
+ // merged over this layer's data collection floor, so extending projects can relax or
171
+ // tighten individual categories of collected data
172
+ dataCollection: {},
163
173
  environment: NUXT_PUBLIC_SENTRY_ENVIRONMENT,
164
174
  features: {
165
175
  consoleCapture: true,
176
+ // not every extending project uses GraphQL, so this is opt-in
177
+ graphqlClient: false,
166
178
  pinia: true,
167
179
  profiling: true,
168
180
  replay: true,
package/package.json CHANGED
@@ -15,11 +15,12 @@
15
15
  "@nuxtjs/seo": "6.0.1",
16
16
  "@nuxtjs/turnstile": "1.1.3",
17
17
  "@pinia/nuxt": "1.0.3",
18
- "@sentry/nuxt": "10.76.2",
18
+ "@sentry/nuxt": "11.8.0",
19
+ "@sentry/profiling-node": "11.8.0",
19
20
  "@tailwindcss/forms": "0.5.11",
20
21
  "@tailwindcss/typography": "0.5.20",
21
22
  "@tailwindcss/vite": "4.3.3",
22
- "@takumi-rs/core": "2.16.3",
23
+ "@takumi-rs/core": "2.17.0",
23
24
  "@types/lodash-es": "4.17.12",
24
25
  "@types/nodemailer": "8.0.2",
25
26
  "@urql/core": "6.0.3",
@@ -104,7 +105,7 @@
104
105
  "url": "git+https://github.com/dargmuesli/vio.git"
105
106
  },
106
107
  "type": "module",
107
- "version": "23.1.2",
108
+ "version": "23.1.4",
108
109
  "scripts": {
109
110
  "build": "pnpm run build:node",
110
111
  "build:node": "NUXT_PUBLIC_I18N_BASE_URL=https://app.localhost:3001 nuxt build playground",
@@ -1,5 +1,7 @@
1
1
  import * as Sentry from '@sentry/nuxt'
2
2
 
3
+ import { getTracePropagationTargets } from './node/networking'
4
+
3
5
  const runtimeConfig = useRuntimeConfig()
4
6
  const sharedSentryConfig = useSharedSentryConfig()
5
7
 
@@ -10,26 +12,42 @@ if (sharedSentryConfig.dsn) {
10
12
  ...sharedSentryConfig,
11
13
  integrations: [
12
14
  ...(features.profiling ? [Sentry.browserProfilingIntegration()] : []),
13
- ...(features.consoleCapture
14
- ? [
15
- Sentry.captureConsoleIntegration(),
16
- Sentry.consoleLoggingIntegration(),
17
- ]
15
+ ...(features.consoleCapture ? [Sentry.captureConsoleIntegration()] : []),
16
+ ...(runtimeConfig.public.sentry.logs.enable
17
+ ? [Sentry.consoleLoggingIntegration()]
18
18
  : []),
19
19
  Sentry.httpClientIntegration(),
20
+ ...(features.graphqlClient
21
+ ? [Sentry.graphqlClientIntegration({ endpoints: [/\/graphql$/] })]
22
+ : []),
20
23
  ...(features.pinia ? [Sentry.piniaIntegration(usePinia())] : []),
21
- ...(features.replay ? [Sentry.replayIntegration()] : []),
24
+ ...(features.replay
25
+ ? [
26
+ // replays are personal data, so everything is masked by default (GDPR)
27
+ Sentry.replayIntegration({
28
+ maskAllInputs: true,
29
+ maskAllText: true,
30
+ }),
31
+ ]
32
+ : []),
22
33
  Sentry.zodErrorsIntegration(),
23
34
  ],
24
- profilesSampleRate: features.profiling
35
+ // v11 replaced `profilesSampleRate` with `profileSessionSampleRate` (defaulting to `0`) and
36
+ // `profileLifecycle` (defaulting to `'manual'`); both are required to keep the v10 behavior
37
+ profileLifecycle: 'trace',
38
+ profileSessionSampleRate: features.profiling
25
39
  ? runtimeConfig.public.sentry.profiles.sampleRate
26
- : undefined,
40
+ : 0,
27
41
  replaysOnErrorSampleRate: features.replay
28
42
  ? runtimeConfig.public.sentry.replays.onError.sampleRate
29
43
  : undefined,
30
44
  replaysSessionSampleRate: features.replay
31
45
  ? runtimeConfig.public.sentry.replays.session.sampleRate
32
46
  : undefined,
47
+ tracePropagationTargets: getTracePropagationTargets({
48
+ baseUrl: runtimeConfig.public.i18n.baseUrl,
49
+ services: runtimeConfig.public.vio.services,
50
+ }),
33
51
  })
34
52
  } else {
35
53
  console.warn(
@@ -1,4 +1,5 @@
1
1
  import * as Sentry from '@sentry/nuxt'
2
+ import { nodeProfilingIntegration } from '@sentry/profiling-node'
2
3
 
3
4
  import {
4
5
  getSharedSentryConfig,
@@ -6,13 +7,14 @@ import {
6
7
  NUXT_PUBLIC_SENTRY_ENVIRONMENT,
7
8
  NUXT_PUBLIC_SENTRY_HOST,
8
9
  NUXT_PUBLIC_SENTRY_LOGS_ENABLE,
10
+ NUXT_PUBLIC_SENTRY_PROFILE_SESSION_SAMPLE_RATE,
11
+ NUXT_PUBLIC_SENTRY_PROFILING_ENABLE,
9
12
  NUXT_PUBLIC_SENTRY_PROJECT_ID,
10
13
  NUXT_PUBLIC_SENTRY_PROJECT_PUBLIC_KEY,
11
14
  NUXT_PUBLIC_SENTRY_RELEASE,
12
15
  } from './node/static'
13
16
 
14
17
  const sharedSentryConfig = getSharedSentryConfig({
15
- enableLogs: NUXT_PUBLIC_SENTRY_LOGS_ENABLE,
16
18
  environment: NUXT_PUBLIC_SENTRY_ENVIRONMENT,
17
19
  host: NUXT_PUBLIC_SENTRY_HOST,
18
20
  isInProduction: IS_IN_PRODUCTION,
@@ -25,9 +27,19 @@ const sharedSentryConfig = getSharedSentryConfig({
25
27
  if (sharedSentryConfig.dsn) {
26
28
  Sentry.init({
27
29
  ...sharedSentryConfig,
28
- integrations: NUXT_PUBLIC_SENTRY_LOGS_ENABLE
29
- ? [Sentry.consoleLoggingIntegration()]
30
- : [],
30
+ integrations: [
31
+ ...(NUXT_PUBLIC_SENTRY_LOGS_ENABLE
32
+ ? [Sentry.consoleLoggingIntegration()]
33
+ : []),
34
+ // v11 moved node profiling into the standalone `@sentry/profiling-node` package
35
+ ...(NUXT_PUBLIC_SENTRY_PROFILING_ENABLE
36
+ ? [nodeProfilingIntegration()]
37
+ : []),
38
+ ],
39
+ profileLifecycle: 'trace',
40
+ profileSessionSampleRate: NUXT_PUBLIC_SENTRY_PROFILING_ENABLE
41
+ ? NUXT_PUBLIC_SENTRY_PROFILE_SESSION_SAMPLE_RATE
42
+ : 0,
31
43
  })
32
44
  } else {
33
45
  console.warn(