Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default defineNuxtModule<ModuleOptions>({
const moduleDirResolver = createResolver(import.meta.url);
const buildDirResolver = createResolver(nuxt.options.buildDir);

const clientConfigFile = findDefaultSdkInitFile('client');
const clientConfigFile = findDefaultSdkInitFile('client', nuxt);

if (clientConfigFile) {
// Inject the client-side Sentry config file with a side effect import
Expand All @@ -59,7 +59,7 @@ export default defineNuxtModule<ModuleOptions>({
addPlugin({ src: moduleDirResolver.resolve('./runtime/plugins/sentry.client'), mode: 'client' });
}

const serverConfigFile = findDefaultSdkInitFile('server');
const serverConfigFile = findDefaultSdkInitFile('server', nuxt);

if (serverConfigFile) {
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));
Expand Down
36 changes: 28 additions & 8 deletions packages/nuxt/src/vite/utils.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,49 @@
import { consoleSandbox } from '@sentry/core';
import * as fs from 'fs';
import type { Nuxt } from 'nuxt/schema';
import * as path from 'path';

/**
* Find the default SDK init file for the given type (client or server).
* The sentry.server.config file is prioritized over the instrument.server file.
*/
export function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
export function findDefaultSdkInitFile(type: 'server' | 'client', nuxt?: Nuxt): string | undefined {
const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];
const cwd = process.cwd();
const relativePaths: string[] = [];

const filePaths: string[] = [];
if (type === 'server') {
for (const ext of possibleFileExtensions) {
// order is important here - we want to prioritize the server.config file
filePaths.push(path.join(cwd, `sentry.${type}.config.${ext}`));
filePaths.push(path.join(cwd, 'public', `instrument.${type}.${ext}`));
relativePaths.push(`sentry.${type}.config.${ext}`);
relativePaths.push(path.join('public', `instrument.${type}.${ext}`));
}
} else {
for (const ext of possibleFileExtensions) {
filePaths.push(path.join(cwd, `sentry.${type}.config.${ext}`));
relativePaths.push(`sentry.${type}.config.${ext}`);
}
}

// Get layers from highest priority to lowest
const layers = [...nuxt?.options._layers ?? []].reverse();

for (const layer of layers) {
for (const relativePath of relativePaths) {
const fullPath = path.resolve(layer.cwd, relativePath);
if (fs.existsSync(fullPath)) {
return fullPath;
}
}
}

// As a fallback, also check CWD (left for pure compatibility)
const cwd = process.cwd();
for (const relativePath of relativePaths) {
const fullPath = path.resolve(cwd, relativePath);
if (fs.existsSync(fullPath)) {
return fullPath;
}
}

return filePaths.find(filename => fs.existsSync(filename));
return undefined;
}

/**
Expand Down
73 changes: 73 additions & 0 deletions packages/nuxt/test/vite/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as fs from 'fs';
import type { Nuxt } from 'nuxt/schema';
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
constructFunctionReExport,
Expand Down Expand Up @@ -69,8 +70,80 @@ describe('findDefaultSdkInitFile', () => {
const result = findDefaultSdkInitFile('server');
expect(result).toMatch('packages/nuxt/sentry.server.config.js');
});

it('should return the latest layer config file path if client config exists', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return !(filePath instanceof URL) && filePath.includes('sentry.client.config.ts');
});

const nuxtMock = {
options: {
_layers: [
{
cwd: 'packages/nuxt/module'
},
{
cwd: 'packages/nuxt'
}
]
}
} as Nuxt


const result = findDefaultSdkInitFile('client', nuxtMock);
expect(result).toMatch('packages/nuxt/sentry.client.config.ts');
});

it('should return the latest layer config file path if server config exists', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return (
!(filePath instanceof URL) &&
(filePath.includes('sentry.server.config.ts') || filePath.includes('instrument.server.ts'))
);
});

const nuxtMock = {
options: {
_layers: [
{
cwd: 'packages/nuxt/module'
},
{
cwd: 'packages/nuxt'
}
]
}
} as Nuxt

const result = findDefaultSdkInitFile('server', nuxtMock);
expect(result).toMatch('packages/nuxt/sentry.server.config.ts');
});

it('should return the latest layer config file path if client config exists in former layer', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return !(filePath instanceof URL) && filePath.includes('nuxt/sentry.client.config.ts');
});

const nuxtMock = {
options: {
_layers: [
{
cwd: 'packages/nuxt/module'
},
{
cwd: 'packages/nuxt'
}
]
}
} as Nuxt


const result = findDefaultSdkInitFile('client', nuxtMock);
expect(result).toMatch('packages/nuxt/sentry.client.config.ts');
});
});


describe('getFilenameFromPath', () => {
it('should return the filename from a simple path', () => {
const path = 'node ./server/index.mjs';
Expand Down
Loading