@mandujs/core 0.25.0 → 0.25.2
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/package.json +7 -1
- package/src/bundler/__tests__/build-runner.ts +101 -0
- package/src/bundler/__tests__/fast-refresh.test.ts +40 -30
- package/src/bundler/build.test.ts +84 -36
- package/src/bundler/safe-build.test.ts +22 -4
- package/src/db/migrations/__tests__/runner.test.ts +665 -661
- package/src/runtime/server.ts +49 -2
package/src/runtime/server.ts
CHANGED
|
@@ -1547,7 +1547,27 @@ async function loadPageData(
|
|
|
1547
1547
|
const exportedObj = exported as Record<string, unknown> | null;
|
|
1548
1548
|
const component = typeof exported === "function"
|
|
1549
1549
|
? (exported as RouteComponent)
|
|
1550
|
-
: (exportedObj?.component ??
|
|
1550
|
+
: (exportedObj?.component ?? undefined);
|
|
1551
|
+
// DX-1: pageLoader 경로에서 malformed default export를 silent 404 로
|
|
1552
|
+
//보내지 않고 명시적 에러로 즉시 실패시킨다. 이전에는
|
|
1553
|
+
// `export default "hello"` / `export default undefined` / named-only
|
|
1554
|
+
// 같은 실수가 registerRouteComponent(undefined) → defaultCreateApp
|
|
1555
|
+
// 에서 404로 렌더되어 사용자가 원인을 추적하기 어려웠음. 여기서 throw
|
|
1556
|
+
// 하면 try/catch(아래) 의 createPageLoadErrorResponse 가 500 응답과
|
|
1557
|
+
// 함께 route.id + pattern 을 출력해주므로 개발자가 바로 인지한다.
|
|
1558
|
+
if (typeof component !== "function") {
|
|
1559
|
+
const defaultSummary =
|
|
1560
|
+
exported === undefined
|
|
1561
|
+
? "undefined (missing `export default`)"
|
|
1562
|
+
: exported === null
|
|
1563
|
+
? "null"
|
|
1564
|
+
: `type ${typeof exported}`;
|
|
1565
|
+
throw new Error(
|
|
1566
|
+
`[Mandu] Page module for '${route.id}' (pattern ${route.pattern}) has an invalid default export: ${defaultSummary}. ` +
|
|
1567
|
+
"Expected `export default function Page() {…}` or `export default { component, filling }`. " +
|
|
1568
|
+
"If the page file is empty or only has named exports, add a default-exported React component."
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1551
1571
|
registry.registerRouteComponent(route.id, component as RouteComponent);
|
|
1552
1572
|
|
|
1553
1573
|
// #186: page 모듈에서 metadata / generateMetadata export 캐싱
|
|
@@ -2201,8 +2221,22 @@ async function handlePageRoute(
|
|
|
2201
2221
|
const cache = settings.cacheStore;
|
|
2202
2222
|
// Only call ensurePageRouteMetadata when a pageHandler exists;
|
|
2203
2223
|
// routes registered via registerPageLoader are handled by loadPageData instead.
|
|
2224
|
+
// DX-1: if the pageHandler returns a malformed registration (component is
|
|
2225
|
+
// not a function), ensurePageRouteMetadata now throws with a descriptive
|
|
2226
|
+
// message. Catch it here so the request becomes a loud 500 instead of
|
|
2227
|
+
// bubbling up as an opaque "Internal Server Error".
|
|
2204
2228
|
if (registry.pageHandlers.has(route.id)) {
|
|
2205
|
-
|
|
2229
|
+
try {
|
|
2230
|
+
await ensurePageRouteMetadata(route.id, registry);
|
|
2231
|
+
} catch (error) {
|
|
2232
|
+
const pageError = createPageLoadErrorResponse(
|
|
2233
|
+
route.id,
|
|
2234
|
+
route.pattern,
|
|
2235
|
+
error instanceof Error ? error : new Error(String(error))
|
|
2236
|
+
);
|
|
2237
|
+
console.error(`[Mandu] ${pageError.errorType}:`, pageError.message);
|
|
2238
|
+
return err(pageError);
|
|
2239
|
+
}
|
|
2206
2240
|
}
|
|
2207
2241
|
const renderMode = getRenderModeForRoute(route.id, registry);
|
|
2208
2242
|
|
|
@@ -2467,6 +2501,19 @@ async function ensurePageRouteMetadata(
|
|
|
2467
2501
|
}
|
|
2468
2502
|
|
|
2469
2503
|
const registration = await handler();
|
|
2504
|
+
// DX-1: pageHandler가 malformed registration을 반환해도 silent 404 대신
|
|
2505
|
+
// 명시적 에러로 실패. handlers.ts 의 auto-promote 블록이 function 기본값을
|
|
2506
|
+
// { component } 로 감싸주지만, 직접 registerPageHandler 를 쓰는 경우나
|
|
2507
|
+
// 사용자 코드가 이상한 값을 반환하는 경우를 방어한다.
|
|
2508
|
+
if (typeof registration?.component !== "function") {
|
|
2509
|
+
const t = registration === null || registration === undefined
|
|
2510
|
+
? String(registration)
|
|
2511
|
+
: typeof registration.component;
|
|
2512
|
+
throw new Error(
|
|
2513
|
+
`[Mandu] Page handler for '${routeId}' returned an invalid registration: component is ${t}. ` +
|
|
2514
|
+
"Expected `{ component: ReactComponent, filling? }` from the page module's default export."
|
|
2515
|
+
);
|
|
2516
|
+
}
|
|
2470
2517
|
const component = registration.component as RouteComponent;
|
|
2471
2518
|
registry.registerRouteComponent(routeId, component);
|
|
2472
2519
|
|