@mantajs/host-nitro 0.2.0-beta.1 → 0.2.0-beta.10
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/dist/build.d.ts +5 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +157 -20
- package/dist/build.js.map +1 -1
- package/dist/dev.d.ts +2 -0
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +29 -10
- package/dist/dev.js.map +1 -1
- package/package.json +1 -1
- package/templates/server/manta-bootstrap.ts +1 -1
- package/templates/server/routes/[...].ts +31 -5
package/dist/build.d.ts
CHANGED
|
@@ -27,4 +27,9 @@ export interface BuildResult {
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export declare function buildForProduction(options: BuildOptions): Promise<BuildResult>;
|
|
30
|
+
export declare function generateProductionBootstrap(options: {
|
|
31
|
+
deploymentPreset: string;
|
|
32
|
+
hasManifest: boolean;
|
|
33
|
+
}): string;
|
|
34
|
+
export declare function generateNodeProductionCatchAllRoute(): string;
|
|
30
35
|
//# sourceMappingURL=build.d.ts.map
|
package/dist/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAyEpF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CA8F/G;AAED,wBAAgB,mCAAmC,IAAI,MAAM,CA0F5D"}
|
package/dist/build.js
CHANGED
|
@@ -33,7 +33,16 @@ export async function buildForProduction(options) {
|
|
|
33
33
|
mkdirSync(targetDir, { recursive: true });
|
|
34
34
|
if (!existsSync(routesDir))
|
|
35
35
|
mkdirSync(routesDir, { recursive: true });
|
|
36
|
-
|
|
36
|
+
const spaManifestPath = resolve(targetDir, 'spa-manifest.ts');
|
|
37
|
+
if (!existsSync(spaManifestPath)) {
|
|
38
|
+
writeFileSync(spaManifestPath, `// Auto-generated by @mantajs/host-nitro — do not edit\nexport const spaFallbacks = [] as const\n`);
|
|
39
|
+
}
|
|
40
|
+
if (preset === 'node') {
|
|
41
|
+
writeFileSync(resolve(routesDir, '[...].ts'), generateNodeProductionCatchAllRoute());
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
copyFileSync(resolve(templatesDir, 'routes', '[...].ts'), resolve(routesDir, '[...].ts'));
|
|
45
|
+
}
|
|
37
46
|
// Copy manta.config.ts
|
|
38
47
|
const configSrc = resolve(cwd, 'manta.config.ts');
|
|
39
48
|
if (existsSync(configSrc)) {
|
|
@@ -48,7 +57,30 @@ export async function buildForProduction(options) {
|
|
|
48
57
|
const manifestPath = resolve(targetDir, 'manifest.ts');
|
|
49
58
|
if (existsSync(manifestPath)) {
|
|
50
59
|
const deploymentPreset = preset === 'cloudflare' ? 'cloudflare' : preset === 'vercel' ? 'vercel' : '';
|
|
51
|
-
const prodBootstrap =
|
|
60
|
+
const prodBootstrap = generateProductionBootstrap({ deploymentPreset, hasManifest: true });
|
|
61
|
+
writeFileSync(resolve(targetDir, 'manta-bootstrap.ts'), prodBootstrap);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
writeFileSync(resolve(targetDir, 'manta-bootstrap.ts'), generateProductionBootstrap({ deploymentPreset: '', hasManifest: false }));
|
|
65
|
+
}
|
|
66
|
+
const presetArg = preset === 'node' ? 'node-server' : preset === 'cloudflare' ? 'cloudflare_module' : preset;
|
|
67
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
68
|
+
const nitroPkgPath = nodeRequire.resolve('nitro/package.json');
|
|
69
|
+
const nitroCliPath = resolve(dirname(nitroPkgPath), 'dist', 'cli', 'index.mjs');
|
|
70
|
+
execFileSync(process.execPath, [nitroCliPath, 'build', '--preset', presetArg], {
|
|
71
|
+
cwd,
|
|
72
|
+
stdio: 'inherit',
|
|
73
|
+
env: { ...process.env, NODE_ENV: 'production' },
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
outputDir: resolve(cwd, outputDir),
|
|
77
|
+
preset,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function generateProductionBootstrap(options) {
|
|
81
|
+
const { deploymentPreset, hasManifest } = options;
|
|
82
|
+
if (hasManifest) {
|
|
83
|
+
return `// @ts-nocheck — Auto-generated PRODUCTION bootstrap (manifest with lazy imports)
|
|
52
84
|
import { bootstrapApp } from '@mantajs/cli/bootstrap'
|
|
53
85
|
import { moduleImports, preloadedResources, preloadedPluginResources } from './manifest.js'
|
|
54
86
|
|
|
@@ -89,7 +121,7 @@ ${deploymentPreset === 'cloudflare' ? " const cfEnv = (globalThis as any).__env
|
|
|
89
121
|
_bootstrapped = await bootstrapApp({
|
|
90
122
|
config,
|
|
91
123
|
cwd,
|
|
92
|
-
mode: '
|
|
124
|
+
mode: 'prod',
|
|
93
125
|
preloadedResources: preloadedResources as any,
|
|
94
126
|
preloadedPluginResources: preloadedPluginResources as any,
|
|
95
127
|
importFn,
|
|
@@ -105,24 +137,129 @@ function bootPromise() {
|
|
|
105
137
|
export async function getMantaAdapter() { const { adapter } = await bootPromise(); return adapter }
|
|
106
138
|
export async function getMantaApp() { const { app } = await bootPromise(); return app }
|
|
107
139
|
`;
|
|
108
|
-
writeFileSync(resolve(targetDir, 'manta-bootstrap.ts'), prodBootstrap);
|
|
109
140
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
141
|
+
return `// @ts-nocheck — Auto-generated PRODUCTION bootstrap (runtime discovery)
|
|
142
|
+
import { bootstrapApp } from '@mantajs/cli/bootstrap'
|
|
143
|
+
import { loadEnv } from '@mantajs/cli/env'
|
|
144
|
+
import mantaConfigModule from './manta.config.js'
|
|
145
|
+
|
|
146
|
+
let _bootstrapped: any = null
|
|
147
|
+
let _promise: Promise<any> | null = null
|
|
148
|
+
|
|
149
|
+
async function bootstrap() {
|
|
150
|
+
if (_bootstrapped) return _bootstrapped
|
|
151
|
+
const cwd = typeof process.cwd === 'function' ? process.cwd() : '/'
|
|
152
|
+
loadEnv(cwd)
|
|
153
|
+
|
|
154
|
+
const rawConfig = mantaConfigModule.default ?? mantaConfigModule
|
|
155
|
+
const config = rawConfig
|
|
156
|
+
|
|
157
|
+
const { createJiti } = await import('@mantajs/cli/jiti')
|
|
158
|
+
const jiti = createJiti(cwd)
|
|
159
|
+
const importFn = (path: string) => jiti.import(path) as Promise<any>
|
|
160
|
+
|
|
161
|
+
_bootstrapped = await bootstrapApp({ config, cwd, mode: 'prod', importFn })
|
|
162
|
+
return _bootstrapped
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function bootPromise() {
|
|
166
|
+
if (!_promise) _promise = bootstrap()
|
|
167
|
+
return _promise
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export async function getMantaAdapter() { const { adapter } = await bootPromise(); return adapter }
|
|
171
|
+
export async function getMantaApp() { const { app } = await bootPromise(); return app }
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
export function generateNodeProductionCatchAllRoute() {
|
|
175
|
+
return `// @ts-nocheck — Auto-generated by @mantajs/host-nitro
|
|
176
|
+
// Node production catch-all: Manta API first, then local SPA fallbacks.
|
|
177
|
+
|
|
178
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
179
|
+
import { join } from 'node:path'
|
|
180
|
+
import { defineEventHandler, getRequestHeaders, getRequestURL, readRawBody } from '@mantajs/adapter-h3'
|
|
181
|
+
import { getMantaAdapter } from '../manta-bootstrap.js'
|
|
182
|
+
import { spaFallbacks } from '../spa-manifest.js'
|
|
183
|
+
|
|
184
|
+
export default defineEventHandler(async (event) => {
|
|
185
|
+
const adapter = await getMantaAdapter()
|
|
186
|
+
|
|
187
|
+
const url = getRequestURL(event)
|
|
188
|
+
const method = event.method ?? 'GET'
|
|
189
|
+
const headers = getRequestHeaders(event)
|
|
190
|
+
|
|
191
|
+
let body
|
|
192
|
+
if (method !== 'GET' && method !== 'HEAD') {
|
|
193
|
+
body = (await readRawBody(event, false)) ?? undefined
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const request = new Request(url.toString(), {
|
|
197
|
+
method,
|
|
198
|
+
headers,
|
|
199
|
+
body: body || undefined,
|
|
200
|
+
})
|
|
201
|
+
const response = await adapter.handleRequest(request)
|
|
202
|
+
if (response.status !== 404 || method !== 'GET') return response
|
|
203
|
+
|
|
204
|
+
const fallback = resolveSpaFallback(url.pathname)
|
|
205
|
+
if (!fallback) return response
|
|
206
|
+
|
|
207
|
+
const indexHtml = readSpaIndex(fallback.indexPath)
|
|
208
|
+
if (!indexHtml) return response
|
|
209
|
+
|
|
210
|
+
if (fallback.redirectTo) {
|
|
211
|
+
return new Response(null, {
|
|
212
|
+
status: 307,
|
|
213
|
+
headers: { location: fallback.redirectTo },
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return new Response(indexHtml, {
|
|
218
|
+
status: 200,
|
|
219
|
+
headers: { 'content-type': 'text/html; charset=utf-8' },
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
function resolveSpaFallback(pathname) {
|
|
224
|
+
if (pathname.startsWith('/api/')) return null
|
|
225
|
+
if (hasFileExtension(pathname)) return null
|
|
226
|
+
if (!Array.isArray(spaFallbacks) || spaFallbacks.length === 0) return null
|
|
227
|
+
|
|
228
|
+
if (spaFallbacks.length === 1) {
|
|
229
|
+
const spa = spaFallbacks[0]
|
|
230
|
+
if (pathname === '/' && spa.mountPath !== '/') {
|
|
231
|
+
return { ...spa, redirectTo: spa.mountPath }
|
|
113
232
|
}
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
233
|
+
for (const authPath of ['/login', '/reset-password', '/accept-invite']) {
|
|
234
|
+
if (pathname === authPath && spa.mountPath !== '/') {
|
|
235
|
+
return { ...spa, redirectTo: spa.mountPath + authPath }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
for (const spa of spaFallbacks) {
|
|
241
|
+
if (spa.mountPath === '/') return { ...spa }
|
|
242
|
+
if (pathname === spa.mountPath || pathname.startsWith(spa.mountPath + '/')) return { ...spa }
|
|
243
|
+
}
|
|
244
|
+
return null
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function hasFileExtension(pathname) {
|
|
248
|
+
const lastSegment = pathname.split('/').pop() || ''
|
|
249
|
+
return lastSegment.includes('.') && lastSegment.split('.').pop().length >= 2
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function readSpaIndex(indexPath) {
|
|
253
|
+
const relativeIndex = indexPath.startsWith('/') ? indexPath.slice(1) : indexPath
|
|
254
|
+
const candidates = [
|
|
255
|
+
join(process.cwd(), 'public', relativeIndex),
|
|
256
|
+
join(process.cwd(), '.output', 'public', relativeIndex),
|
|
257
|
+
]
|
|
258
|
+
for (const candidate of candidates) {
|
|
259
|
+
if (existsSync(candidate)) return readFileSync(candidate, 'utf-8')
|
|
260
|
+
}
|
|
261
|
+
return null
|
|
262
|
+
}
|
|
263
|
+
`;
|
|
127
264
|
}
|
|
128
265
|
//# sourceMappingURL=build.js.map
|
package/dist/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,qEAAqE;AAkBrE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAqB;IAC5D,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,OAAO,CAAA;IACtD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;IACtD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC3D,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;IACtF,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;IACrD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;IAElD,gFAAgF;IAChF,8EAA8E;IAC9E,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACzD,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IAE9C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACrE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAErE,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface SpaEntry {
|
|
2
2
|
/** SPA name (e.g. 'admin', 'vendor') — served on /{name} */
|
|
3
3
|
name: string;
|
|
4
|
+
/** Public mount path. Defaults to /{name}; "/" mounts the SPA at the domain root. */
|
|
5
|
+
mountPath?: string;
|
|
4
6
|
/** Vite config path for this SPA */
|
|
5
7
|
viteConfigPath: string;
|
|
6
8
|
/** Vite dev server port */
|
package/dist/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,QAAQ;IACvB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,QAAQ;IACvB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6JxF"}
|
package/dist/dev.js
CHANGED
|
@@ -17,7 +17,7 @@ export async function startDevServer(options) {
|
|
|
17
17
|
// Collect all SPA entries (legacy viteConfigPath + V2 spas)
|
|
18
18
|
const allSpas = [...spas];
|
|
19
19
|
if (viteConfigPath && !allSpas.some((s) => s.name === 'admin')) {
|
|
20
|
-
allSpas.push({ name: 'admin', viteConfigPath, vitePort });
|
|
20
|
+
allSpas.push({ name: 'admin', mountPath: '/admin', viteConfigPath, vitePort });
|
|
21
21
|
}
|
|
22
22
|
// Start Vite dev servers for each SPA
|
|
23
23
|
// biome-ignore lint/suspicious/noExplicitAny: child process handles
|
|
@@ -39,9 +39,16 @@ export async function startDevServer(options) {
|
|
|
39
39
|
const devProxy = {};
|
|
40
40
|
for (const spa of allSpas) {
|
|
41
41
|
const target = `http://localhost:${spa.vitePort}`;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const mountPath = normalizeMountPath(spa);
|
|
43
|
+
if (mountPath === '/') {
|
|
44
|
+
// Root-mounted SPAs are proxied by the raw request hook below so /api/*
|
|
45
|
+
// remains owned by Nitro. A broad Nitro devProxy here would steal API calls.
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
devProxy[`${mountPath}/**`] = { target, ws: true };
|
|
49
|
+
devProxy[`${mountPath}/`] = { target, ws: true };
|
|
50
|
+
devProxy[mountPath] = { target, ws: true };
|
|
51
|
+
}
|
|
45
52
|
}
|
|
46
53
|
if (allSpas.length > 0) {
|
|
47
54
|
const target = `http://localhost:${allSpas[0].vitePort}`;
|
|
@@ -70,16 +77,15 @@ export async function startDevServer(options) {
|
|
|
70
77
|
// biome-ignore lint/suspicious/noExplicitAny: listhen internal
|
|
71
78
|
const httpServer = listener?.node?.server;
|
|
72
79
|
if (httpServer && allSpas.length > 0) {
|
|
73
|
-
const spaNames = allSpas.map((s) => s.name);
|
|
74
80
|
const originalListeners = httpServer.listeners('request').slice();
|
|
75
81
|
httpServer.removeAllListeners('request');
|
|
76
82
|
httpServer.on('request', async (req, res) => {
|
|
77
83
|
const url = req.url ?? '';
|
|
78
|
-
const matchedSpa =
|
|
84
|
+
const matchedSpa = allSpas.find((spa) => pathMatchesMount(url, normalizeMountPath(spa)));
|
|
79
85
|
// Proxy ALL SPA requests to Vite (HTML pages, .tsx, .js, .css, assets)
|
|
80
86
|
// Only skip /api/* routes which are handled by Nitro
|
|
81
87
|
if (matchedSpa && !url.startsWith('/api/') && req.method === 'GET') {
|
|
82
|
-
const spaVitePort =
|
|
88
|
+
const spaVitePort = matchedSpa.vitePort;
|
|
83
89
|
if (spaVitePort) {
|
|
84
90
|
try {
|
|
85
91
|
const isHtmlRoute = !url.match(/\.\w+(\?|$)/);
|
|
@@ -133,7 +139,7 @@ export async function startDevServer(options) {
|
|
|
133
139
|
const wsProxy = createProxyServer({ ws: true });
|
|
134
140
|
wsProxy.on('error', () => { }); // swallow — Vite reconnects
|
|
135
141
|
httpServer.on('upgrade', (req, socket, head) => {
|
|
136
|
-
const spa = allSpas.find((s) => req.url
|
|
142
|
+
const spa = allSpas.find((s) => pathMatchesMount(req.url ?? '', normalizeMountPath(s)));
|
|
137
143
|
const target = `http://localhost:${(spa ?? allSpas[0]).vitePort}`;
|
|
138
144
|
// httpxy signature: (req, socket, opts, head?) — target goes in opts.
|
|
139
145
|
// Cast socket: Node's http 'upgrade' event yields a Duplex subtype; net.Socket is the expected type.
|
|
@@ -200,9 +206,9 @@ async function startViteDev(cwd, viteConfigPath, vitePort) {
|
|
|
200
206
|
for (let i = 0; i < 20; i++) {
|
|
201
207
|
await new Promise((r) => setTimeout(r, 500));
|
|
202
208
|
try {
|
|
203
|
-
const res = await fetch(`http://localhost:${vitePort}
|
|
209
|
+
const res = await fetch(`http://localhost:${vitePort}/`);
|
|
204
210
|
if (res.ok) {
|
|
205
|
-
console.log(`
|
|
211
|
+
console.log(` Vite dashboard: http://localhost:${vitePort}/`);
|
|
206
212
|
break;
|
|
207
213
|
}
|
|
208
214
|
}
|
|
@@ -212,4 +218,17 @@ async function startViteDev(cwd, viteConfigPath, vitePort) {
|
|
|
212
218
|
}
|
|
213
219
|
return child;
|
|
214
220
|
}
|
|
221
|
+
function normalizeMountPath(spa) {
|
|
222
|
+
const raw = spa.mountPath?.trim() || `/${spa.name}`;
|
|
223
|
+
if (raw === '/')
|
|
224
|
+
return '/';
|
|
225
|
+
return (raw.startsWith('/') ? raw : `/${raw}`).replace(/\/+$/g, '') || '/';
|
|
226
|
+
}
|
|
227
|
+
function pathMatchesMount(url, mountPath) {
|
|
228
|
+
if (url.startsWith('/api/'))
|
|
229
|
+
return false;
|
|
230
|
+
if (mountPath === '/')
|
|
231
|
+
return url.startsWith('/');
|
|
232
|
+
return url === mountPath || url.startsWith(`${mountPath}/`);
|
|
233
|
+
}
|
|
215
234
|
//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,4DAA4D;AAC5D,4CAA4C;AAE5C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -43,7 +43,7 @@ async function bootstrap() {
|
|
|
43
43
|
_bootstrapped = await bootstrapApp({
|
|
44
44
|
config,
|
|
45
45
|
cwd,
|
|
46
|
-
mode: '
|
|
46
|
+
mode: 'prod',
|
|
47
47
|
preloadedResources: manifest.preloadedResources as any,
|
|
48
48
|
preloadedImports: manifest.moduleExports as Record<string, Record<string, unknown>>,
|
|
49
49
|
})
|
|
@@ -6,8 +6,29 @@
|
|
|
6
6
|
import { defineEventHandler, getRequestHeaders, getRequestURL, readRawBody } from '@mantajs/adapter-h3'
|
|
7
7
|
import { getMantaAdapter } from '../manta-bootstrap.js'
|
|
8
8
|
|
|
9
|
+
function nowMs() {
|
|
10
|
+
return typeof performance !== 'undefined' ? performance.now() : Date.now()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function withServerTiming(response: Response, timings: Record<string, number>) {
|
|
14
|
+
const headers = new Headers(response.headers)
|
|
15
|
+
const existing = headers.get('server-timing')
|
|
16
|
+
const value = Object.entries(timings)
|
|
17
|
+
.map(([name, dur]) => `${name};dur=${dur.toFixed(1)}`)
|
|
18
|
+
.join(', ')
|
|
19
|
+
headers.set('server-timing', existing ? `${existing}, ${value}` : value)
|
|
20
|
+
return new Response(response.body, {
|
|
21
|
+
status: response.status,
|
|
22
|
+
statusText: response.statusText,
|
|
23
|
+
headers,
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
9
27
|
export default defineEventHandler(async (event) => {
|
|
28
|
+
const startedAt = nowMs()
|
|
29
|
+
const bootStartedAt = nowMs()
|
|
10
30
|
const adapter = await getMantaAdapter()
|
|
31
|
+
const bootMs = nowMs() - bootStartedAt
|
|
11
32
|
|
|
12
33
|
const url = getRequestURL(event)
|
|
13
34
|
const method = event.method ?? 'GET'
|
|
@@ -23,7 +44,9 @@ export default defineEventHandler(async (event) => {
|
|
|
23
44
|
headers,
|
|
24
45
|
body: (body || undefined) as BodyInit | undefined,
|
|
25
46
|
})
|
|
47
|
+
const dispatchStartedAt = nowMs()
|
|
26
48
|
const response = await adapter.handleRequest(request)
|
|
49
|
+
const dispatchMs = nowMs() - dispatchStartedAt
|
|
27
50
|
|
|
28
51
|
// SPA fallback for dev mode: if the adapter returned 404 for a GET on a SPA path,
|
|
29
52
|
// fetch the SPA index.html from Vite. In prod, Vercel rewrites handle this.
|
|
@@ -33,13 +56,16 @@ export default defineEventHandler(async (event) => {
|
|
|
33
56
|
if (vitePort && pathname.startsWith('/admin') && !pathname.startsWith('/api/') && !pathname.match(/\.\w+$/)) {
|
|
34
57
|
const viteRes = await fetch(`http://localhost:${vitePort}/admin/`)
|
|
35
58
|
if (viteRes.ok) {
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
return withServerTiming(
|
|
60
|
+
new Response(viteRes.body, {
|
|
61
|
+
status: 200,
|
|
62
|
+
headers: { 'content-type': 'text/html; charset=utf-8' },
|
|
63
|
+
}),
|
|
64
|
+
{ manta: nowMs() - startedAt, bootstrap: bootMs, dispatch: dispatchMs },
|
|
65
|
+
)
|
|
40
66
|
}
|
|
41
67
|
}
|
|
42
68
|
}
|
|
43
69
|
|
|
44
|
-
return response
|
|
70
|
+
return withServerTiming(response, { manta: nowMs() - startedAt, bootstrap: bootMs, dispatch: dispatchMs })
|
|
45
71
|
})
|