Skip to content

Commit 7ae305c

Browse files
committed
refactor(rsc-mf): enforce single-module object import arrays
1 parent 442271f commit 7ae305c

2 files changed

Lines changed: 30 additions & 35 deletions

File tree

tests/integration/rsc-mf/remote/src/runtime/createRscExposeDefinitions.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,19 @@ const normalizeExposeImportPaths = (
7878
exposeImport.length > 0 &&
7979
exposeImport.every(item => typeof item === 'string')
8080
) {
81+
const normalizedImportPaths = normalizeImportPaths(exposeKey, exposeImport);
82+
if (normalizedImportPaths.includes(CALLBACK_BOOTSTRAP_IMPORT)) {
83+
throw new Error(
84+
`Callback bootstrap module (${CALLBACK_BOOTSTRAP_IMPORT}) must remain internal-only and cannot be exposed. Invalid entries: ${exposeKey}`,
85+
);
86+
}
87+
if (normalizedImportPaths.length > 1) {
88+
throw new Error(
89+
`Remote expose import arrays must normalize to a single userland module path. Invalid entry: ${exposeKey}`,
90+
);
91+
}
8192
return {
82-
importPaths: normalizeImportPaths(exposeKey, exposeImport),
93+
importPaths: normalizedImportPaths,
8394
exposeOverrides,
8495
} satisfies NormalizedExposeDefinition;
8596
}

tests/integration/rsc-mf/tests/createRscExposeDefinitions.test.ts

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -145,28 +145,20 @@ describe('createRscExposeDefinitions', () => {
145145
});
146146
});
147147

148-
it('supports object expose definitions with import arrays', () => {
149-
const { createRscExposeDefinitions, CALLBACK_BOOTSTRAP_MODULE } =
150-
loadCreateRscExposeDefinitions();
151-
const exposeDefinitions = createRscExposeDefinitions({
152-
'./infoBundle': {
153-
import: [
154-
'./src/components/infoBundle.ts',
155-
'./src/components/remoteMeta.ts',
156-
],
157-
},
158-
});
159-
160-
expect(exposeDefinitions).toEqual({
161-
'./infoBundle': {
162-
import: [
163-
CALLBACK_BOOTSTRAP_MODULE,
164-
'./src/components/infoBundle.ts',
165-
'./src/components/remoteMeta.ts',
166-
],
167-
layer: 'react-server-components',
168-
},
169-
});
148+
it('rejects multi-module import arrays in object expose definitions', () => {
149+
const { createRscExposeDefinitions } = loadCreateRscExposeDefinitions();
150+
expect(() =>
151+
createRscExposeDefinitions({
152+
'./infoBundle': {
153+
import: [
154+
'./src/components/infoBundle.ts',
155+
'./src/components/remoteMeta.ts',
156+
],
157+
},
158+
}),
159+
).toThrow(
160+
'Remote expose import arrays must normalize to a single userland module path.',
161+
);
170162
});
171163

172164
it('deduplicates repeated entries in object expose import arrays', () => {
@@ -177,18 +169,14 @@ describe('createRscExposeDefinitions', () => {
177169
import: [
178170
'./src/components/infoBundle.ts',
179171
'./src/components/infoBundle.ts',
180-
'./src/components/remoteMeta.ts',
172+
'./src/components/infoBundle.ts',
181173
],
182174
},
183175
});
184176

185177
expect(exposeDefinitions).toEqual({
186178
'./infoBundle': {
187-
import: [
188-
CALLBACK_BOOTSTRAP_MODULE,
189-
'./src/components/infoBundle.ts',
190-
'./src/components/remoteMeta.ts',
191-
],
179+
import: [CALLBACK_BOOTSTRAP_MODULE, './src/components/infoBundle.ts'],
192180
layer: 'react-server-components',
193181
},
194182
});
@@ -202,18 +190,14 @@ describe('createRscExposeDefinitions', () => {
202190
import: [
203191
' ./src/components/infoBundle.ts ',
204192
'./src/components/infoBundle.ts',
205-
' ./src/components/remoteMeta.ts ',
193+
' ./src/components/infoBundle.ts ',
206194
],
207195
},
208196
});
209197

210198
expect(exposeDefinitions).toEqual({
211199
'./infoBundle': {
212-
import: [
213-
CALLBACK_BOOTSTRAP_MODULE,
214-
'./src/components/infoBundle.ts',
215-
'./src/components/remoteMeta.ts',
216-
],
200+
import: [CALLBACK_BOOTSTRAP_MODULE, './src/components/infoBundle.ts'],
217201
layer: 'react-server-components',
218202
},
219203
});

0 commit comments

Comments
 (0)