|
1 | | -import express from 'express'; |
2 | | -import * as path from "node:path"; |
3 | | -import * as fs from "node:fs"; |
4 | | -import cors from 'cors'; |
5 | | -import { FrontController } from './controller/FrontController'; |
6 | | -import { MapController } from './controller/MapController'; |
7 | | -import { UploaderController } from './controller/UploaderController'; |
| 1 | +import core from '@workadventure/map-starter-kit-core/dist/server.js'; |
8 | 2 |
|
9 | | -const app = express(); |
10 | | - |
11 | | -const corsOptions = { |
12 | | - credentials: true, // Allow sending cookies |
13 | | - methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], |
14 | | - allowedHeaders: [ |
15 | | - 'Content-Type', |
16 | | - 'Authorization', |
17 | | - 'X-Requested-With', |
18 | | - 'Accept', |
19 | | - 'Origin', |
20 | | - 'Access-Control-Request-Method', |
21 | | - 'Access-Control-Request-Headers' |
22 | | - ], |
23 | | - exposedHeaders: ['Content-Length', 'Content-Type'], |
24 | | - maxAge: 86400, // Cache the OPTIONS requests for 24 hours |
25 | | -}; |
26 | | - |
27 | | -// Apply the CORS middleware |
28 | | -// The CORS middleware automatically handles the OPTIONS requests (preflight) |
29 | | -app.use(cors(corsOptions)); |
30 | | - |
31 | | -// Parse JSON bodies |
32 | | -app.use(express.json()); |
33 | | - |
34 | | -// Configure the static assets for Express |
35 | | -const staticOptions = { |
36 | | - maxAge: '1d', // Cache the files for 1 day |
37 | | - etag: true, // Enable ETag for cache validation |
38 | | - lastModified: true, // Enable Last-Modified header |
39 | | -}; |
40 | | - |
41 | | -// Serve dist/assets FIRST with explicit MIME type configuration |
42 | | -// This ensures compiled JavaScript files from getMapsScripts are served correctly |
43 | | -// This route must be before express.static('.') to take precedence |
44 | | -app.use('/assets', express.static(path.join(process.cwd(), 'dist', 'assets'), staticOptions)); |
45 | | -// Serve the public folder with a custom path |
46 | | -app.use('/public', express.static(path.join(process.cwd(), 'public'), staticOptions)); |
47 | | -// Serve the tilesets folder with a longer cache (rarely modified) |
48 | | -app.use('/tilesets', express.static(path.join(process.cwd(), 'tilesets'), { |
49 | | - maxAge: '7d', |
50 | | - etag: true, |
51 | | - lastModified: true, |
52 | | -})); |
53 | | - |
54 | | -// Middleware to exclude /src from express.static - let Vite handle TypeScript transformation |
55 | | -// VitePluginNode will automatically add Vite middleware that transforms TypeScript files |
56 | | -const staticMiddleware = express.static('.', staticOptions); |
57 | | - |
58 | | -// Middleware to transform and serve TypeScript files as JavaScript |
59 | | -// This bundles the file with its dependencies to resolve npm imports |
60 | | -app.use('/src', async (req, res, next) => { |
61 | | - // Only handle .ts and .tsx files - transform them to JavaScript |
62 | | - if (req.path.endsWith('.ts') || req.path.endsWith('.tsx')) { |
63 | | - try { |
64 | | - // req.path includes /src/, so we need to join it correctly |
65 | | - const filePath = path.join(process.cwd(), 'src', req.path.startsWith('/') ? req.path.slice(1) : req.path); |
66 | | - |
67 | | - // Check if file exists |
68 | | - if (!fs.existsSync(filePath)) { |
69 | | - return res.status(404).send('File not found'); |
70 | | - } |
71 | | - |
72 | | - // Use dynamic import to get esbuild (available via Vite) |
73 | | - const esbuild = await import('esbuild'); |
74 | | - |
75 | | - // Bundle the TypeScript file with its dependencies |
76 | | - // This resolves npm imports like @workadventure/scripting-api-extra |
77 | | - const result = await esbuild.build({ |
78 | | - entryPoints: [filePath], |
79 | | - bundle: true, |
80 | | - format: 'esm', |
81 | | - target: 'esnext', |
82 | | - write: false, |
83 | | - platform: 'browser', |
84 | | - sourcemap: false, |
85 | | - // Externalize WorkAdventure global API (available in the browser) |
86 | | - external: ['WA'], |
87 | | - }); |
88 | | - |
89 | | - res.setHeader('Content-Type', 'application/javascript; charset=utf-8'); |
90 | | - return res.send(result.outputFiles[0].text); |
91 | | - } catch (error) { |
92 | | - console.error('Error transforming TypeScript file:', error); |
93 | | - return next(error); |
94 | | - } |
95 | | - } |
96 | | - // For non-TypeScript files in /src, pass to next middleware |
97 | | - next(); |
98 | | -}); |
99 | | - |
100 | | -// Serve static files, but skip /src (handled above) |
101 | | -app.use((req, res, next) => { |
102 | | - // Skip /src requests - they are handled by the transformation middleware above |
103 | | - if (req.path.startsWith('/src/')) { |
104 | | - return next(); // Let the transformation middleware handle it or pass to Vite |
105 | | - } |
106 | | - // For other files, use express.static |
107 | | - staticMiddleware(req, res, next); |
108 | | -}); |
109 | | - |
110 | | -const controllers = [ |
111 | | - new MapController(app), |
112 | | - new FrontController(app), |
113 | | - new UploaderController(app), |
114 | | -]; |
115 | | - |
116 | | -// Verify and log all controllers created |
117 | | -controllers.forEach(controller => { |
118 | | - console.info(`Controller started: ${controller.constructor.name}`); |
119 | | -}); |
120 | | - |
121 | | -export default app; |
122 | | -// Export for VitePluginNode compatibility |
123 | | -export const viteNodeApp = app; |
| 3 | +export default core.default; |
| 4 | +export const viteNodeApp = core.viteNodeApp; |
0 commit comments