@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.
- package/app/composables/sentry.ts +1 -1
- package/node/networking.ts +31 -0
- package/node/server/node.mjs +0 -1
- package/node/static/sentry.ts +40 -3
- package/nuxt.config.ts +12 -0
- package/package.json +4 -3
- package/sentry.client.config.ts +26 -8
- package/sentry.server.config.ts +16 -4
|
@@ -5,7 +5,7 @@ export const useSharedSentryConfig = () => {
|
|
|
5
5
|
const runtimeConfig = useRuntimeConfig()
|
|
6
6
|
|
|
7
7
|
return getSharedSentryConfig({
|
|
8
|
-
|
|
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,
|
package/node/networking.ts
CHANGED
|
@@ -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]
|
package/node/server/node.mjs
CHANGED
|
@@ -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'))
|
package/node/static/sentry.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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": "
|
|
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.
|
|
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.
|
|
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",
|
package/sentry.client.config.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|
-
:
|
|
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(
|
package/sentry.server.config.ts
CHANGED
|
@@ -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:
|
|
29
|
-
|
|
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(
|