@@ -15,7 +15,7 @@ import { createOriginMatcher, hasWildcardPattern } from '@objectstack/plugin-hon
1515import { getRequestListener } from '@hono/node-server' ;
1616import { ObjectKernel , createRestApiPlugin , createDispatcherPlugin , KernelManager } from '@objectstack/runtime' ;
1717import type { EnvironmentDriverRegistry } from '@objectstack/runtime' ;
18- import type { Hono } from 'hono' ;
18+ import { Hono } from 'hono' ;
1919import stackConfig from '../objectstack.config.js' ;
2020import { listTemplates } from './templates/registry.js' ;
2121
@@ -118,28 +118,38 @@ async function ensureApp(): Promise<Hono> {
118118 // envRegistry / kernelManager are resolved by HttpDispatcher from the
119119 // kernel's service registry (MultiProjectPlugin registered them during
120120 // bootKernel), so they do NOT need to be passed explicitly here.
121- _app = createHonoApp ( { kernel, prefix : '/api/v1' } ) ;
121+ const inner = createHonoApp ( { kernel, prefix : '/api/v1' } ) ;
122122
123123 // Vercel entrypoint does NOT load plugin-hono-server, so the
124124 // `http.server` service is never registered. The route plugins in
125125 // `multi-project-plugins.ts` early-return when that service is
126126 // missing, leaving `/studio/runtime-config` and `/cloud/templates`
127- // unmounted (404 / empty list). Mount them directly on the Hono
128- // instance here so multi-project deployments behave correctly.
127+ // unmounted (404 / empty list).
128+ //
129+ // We can't simply call `inner.get(...)` after createHonoApp() because
130+ // it has already registered an `app.all('${prefix}/*')` dispatcher
131+ // catch-all that wins on registration order. Instead wrap `inner` in
132+ // an outer Hono whose own routes are matched first, then fall
133+ // through to `inner.fetch()` for everything else.
129134 if ( envFlag ( 'OBJECTSTACK_MULTI_PROJECT' ) ) {
130135 const templatesPayload = listTemplates ( ) . map ( ( { id, label, description, category } ) => ( {
131136 id,
132137 label,
133138 description,
134139 category,
135140 } ) ) ;
136- _app . get ( '/api/v1/studio/runtime-config' , ( c ) =>
141+ const outer = new Hono ( ) ;
142+ outer . get ( '/api/v1/studio/runtime-config' , ( c ) =>
137143 c . json ( { singleProject : false } ) ) ;
138- _app . get ( '/api/v1/cloud/templates' , ( c ) =>
144+ outer . get ( '/api/v1/cloud/templates' , ( c ) =>
139145 c . json ( {
140146 success : true ,
141147 data : { templates : templatesPayload , total : templatesPayload . length } ,
142148 } ) ) ;
149+ outer . all ( '*' , ( c ) => inner . fetch ( c . req . raw ) ) ;
150+ _app = outer ;
151+ } else {
152+ _app = inner ;
143153 }
144154
145155 return _app ;
0 commit comments