Skip to content

Commit 7feed8e

Browse files
committed
Filter invalid identifier exports and add typeof guard in RSC utils
1 parent 2cf00d2 commit 7feed8e

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

packages/react-router/src/server/rsc/responseUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function isNotFoundResponse(error: unknown): boolean {
3939
return true;
4040
}
4141

42-
if (errorObj.status === 404) {
42+
if (typeof errorObj.status === 'number' && errorObj.status === 404) {
4343
return true;
4444
}
4545
}

packages/react-router/src/vite/makeAutoInstrumentRSCPlugin.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { AutoInstrumentRSCOptions } from './types';
77
import t = recast.types.namedTypes;
88

99
const JS_EXTENSIONS_RE = /\.(ts|tsx|js|jsx|mjs|mts)$/;
10+
const JS_IDENTIFIER_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1011
const WRAPPED_MODULE_SUFFIX = '?sentry-rsc-wrap';
1112

1213
// Prevents the Sentry bundler plugin from transforming this import path
@@ -291,7 +292,9 @@ export function makeAutoInstrumentRSCPlugin(options: AutoInstrumentRSCOptions =
291292
return null;
292293
}
293294

294-
const exportNames = analysis.namedExports;
295+
// Skip string literal export names (e.g. `export { fn as "my-action" }`) that
296+
// can't be used in `export const name = ...` generated code.
297+
const exportNames = analysis.namedExports.filter(name => JS_IDENTIFIER_RE.test(name));
295298
const includeDefault = analysis.hasDefaultExport;
296299
if (exportNames.length === 0 && !includeDefault) {
297300
// eslint-disable-next-line no-console

packages/react-router/test/vite/makeAutoInstrumentRSCPlugin.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,16 @@ describe('makeAutoInstrumentRSCPlugin', () => {
294294
expect(result!.code).toContain('wrapServerFunction');
295295
});
296296

297+
it('skips string literal export names that are not valid identifiers', () => {
298+
const plugin = createPluginWithRSCDetected();
299+
const code = '\'use server\';\nfunction a() {}\nfunction b() {}\nexport { a as "my-action", b }';
300+
const result = plugin.transform(code, 'app/routes/rsc/actions.ts');
301+
302+
expect(result).not.toBeNull();
303+
expect(result!.code).toContain('export const b = wrapServerFunction("b"');
304+
expect(result!.code).not.toContain('my-action');
305+
});
306+
297307
it('does not log when debug is disabled', () => {
298308
const plugin = createPluginWithRSCDetected({ debug: false });
299309

0 commit comments

Comments
 (0)