Fix: Add TypeScript backend compilation for deployment
This commit is contained in:
parent
3592df6a5d
commit
7956762b7e
4 changed files with 194 additions and 5 deletions
156
backend/api/pages.js
Normal file
156
backend/api/pages.js
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import express from 'express';
|
||||
// BOSA SDK instance (initialized in server.js)
|
||||
let bosa = null;
|
||||
export const initPagesAPI = (bosaInstance) => {
|
||||
bosa = bosaInstance;
|
||||
};
|
||||
export const createPagesRouter = () => {
|
||||
const router = express.Router();
|
||||
router.post('/', async (req, res) => {
|
||||
try {
|
||||
const { app_name, route_path, page_config } = req.body;
|
||||
if (!app_name || !route_path || !page_config) {
|
||||
bosa?.log?.warn('CreatePage: Missing required fields');
|
||||
return res.status(400).json({ error: 'Missing required fields' });
|
||||
}
|
||||
if (!bosa) {
|
||||
return res.status(500).json({ error: 'BOSA SDK not initialized' });
|
||||
}
|
||||
// Check if page already exists
|
||||
const existing = await bosa.db
|
||||
.query('wb_pages')
|
||||
.where('app_name', '=', app_name)
|
||||
.where('route_path', '=', route_path)
|
||||
.first();
|
||||
if (existing) {
|
||||
bosa.log?.warn(`CreatePage: Page already exists | App: ${app_name} | Route: ${route_path}`);
|
||||
return res.status(409).json({ error: 'Page already exists' });
|
||||
}
|
||||
// Insert using BOSA SDK
|
||||
const id = await bosa.db.query('wb_pages').insert({
|
||||
app_name,
|
||||
route_path,
|
||||
page_config: JSON.stringify(page_config),
|
||||
version: 1,
|
||||
});
|
||||
bosa.log?.info(`CreatePage: Page created | ID: ${id} | App: ${app_name}`);
|
||||
res.status(201).json({
|
||||
id,
|
||||
app_name,
|
||||
route_path,
|
||||
page_config,
|
||||
version: 1,
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
bosa?.log?.error(`CreatePage: Failed | Error: ${error.message} | App: ${req.body.app_name}`);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
router.get('/:id', async (req, res) => {
|
||||
try {
|
||||
if (!bosa) {
|
||||
return res.status(500).json({ error: 'BOSA SDK not initialized' });
|
||||
}
|
||||
const page = await bosa.db
|
||||
.query('wb_pages')
|
||||
.where('id', '=', Number(req.params.id))
|
||||
.first();
|
||||
if (!page) {
|
||||
bosa.log?.warn(`GetPage: Page not found | ID: ${req.params.id}`);
|
||||
return res.status(404).json({ error: 'Page not found' });
|
||||
}
|
||||
const result = page;
|
||||
res.json({
|
||||
...result,
|
||||
page_config: JSON.parse(result.page_config),
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
bosa?.log?.error(`GetPage: Failed | ID: ${req.params.id} | Error: ${error.message}`);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
router.put('/:id', async (req, res) => {
|
||||
try {
|
||||
if (!bosa) {
|
||||
return res.status(500).json({ error: 'BOSA SDK not initialized' });
|
||||
}
|
||||
const { page_config } = req.body;
|
||||
if (!page_config) {
|
||||
bosa.log?.warn(`UpdatePage: Missing page_config | ID: ${req.params.id}`);
|
||||
return res.status(400).json({ error: 'Missing page_config' });
|
||||
}
|
||||
const existing = await bosa.db
|
||||
.query('wb_pages')
|
||||
.where('id', '=', Number(req.params.id))
|
||||
.first();
|
||||
if (!existing) {
|
||||
bosa.log?.warn(`UpdatePage: Page not found | ID: ${req.params.id}`);
|
||||
return res.status(404).json({ error: 'Page not found' });
|
||||
}
|
||||
const newVersion = (existing.version || 1) + 1;
|
||||
await bosa.db
|
||||
.query('wb_pages')
|
||||
.where('id', '=', Number(req.params.id))
|
||||
.update({
|
||||
page_config: JSON.stringify(page_config),
|
||||
version: newVersion,
|
||||
});
|
||||
bosa.log?.info(`UpdatePage: Page updated | ID: ${req.params.id} | Version: ${newVersion}`);
|
||||
res.json({
|
||||
id: Number(req.params.id),
|
||||
page_config,
|
||||
version: newVersion,
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
bosa?.log?.error(`UpdatePage: Failed | ID: ${req.params.id} | Error: ${error.message}`);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
router.delete('/:id', async (req, res) => {
|
||||
try {
|
||||
if (!bosa) {
|
||||
return res.status(500).json({ error: 'BOSA SDK not initialized' });
|
||||
}
|
||||
const deleted = await bosa.db
|
||||
.query('wb_pages')
|
||||
.where('id', '=', Number(req.params.id))
|
||||
.delete();
|
||||
if (deleted === 0) {
|
||||
bosa.log?.warn(`DeletePage: Page not found | ID: ${req.params.id}`);
|
||||
return res.status(404).json({ error: 'Page not found' });
|
||||
}
|
||||
bosa.log?.info(`DeletePage: Page deleted | ID: ${req.params.id}`);
|
||||
res.status(204).send();
|
||||
}
|
||||
catch (error) {
|
||||
bosa?.log?.error(`DeletePage: Failed | ID: ${req.params.id} | Error: ${error.message}`);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
if (!bosa) {
|
||||
return res.status(500).json({ error: 'BOSA SDK not initialized' });
|
||||
}
|
||||
const appName = req.query.app_name;
|
||||
let query = bosa.db.query('wb_pages');
|
||||
if (appName) {
|
||||
query = query.where('app_name', '=', appName);
|
||||
}
|
||||
const pages = await query.get();
|
||||
const results = pages.map((page) => ({
|
||||
...page,
|
||||
page_config: JSON.parse(page.page_config),
|
||||
}));
|
||||
res.json(results);
|
||||
}
|
||||
catch (error) {
|
||||
bosa?.log?.error(`ListPages: Failed | App: ${req.query.app_name} | Error: ${error.message}`);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
return router;
|
||||
};
|
||||
|
|
@ -9,7 +9,8 @@
|
|||
"dev:frontend": "vite",
|
||||
"dev:all": "concurrently \"npm run dev\" \"npm run dev:frontend\"",
|
||||
"start": "node server.js",
|
||||
"build": "tsc && vite build",
|
||||
"build": "npm run build:backend && npm run build:frontend",
|
||||
"build:backend": "tsc -p tsconfig.backend.json",
|
||||
"build:frontend": "vite build",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
||||
|
|
|
|||
|
|
@ -48,9 +48,19 @@ echo [INFO] Source: %SOURCE_DIR%
|
|||
echo [INFO] Target: %TARGET_DIR%
|
||||
echo.
|
||||
|
||||
REM Build the frontend first
|
||||
echo [INFO] Building frontend...
|
||||
REM Build backend and frontend
|
||||
echo [INFO] Building backend (TypeScript)...
|
||||
cd /d "%SOURCE_DIR%"
|
||||
call npm run build:backend
|
||||
if errorlevel 1 (
|
||||
echo [ERROR] Backend build failed!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo [OK] Backend build completed
|
||||
echo.
|
||||
|
||||
echo [INFO] Building frontend...
|
||||
call npm run build:frontend
|
||||
if errorlevel 1 (
|
||||
echo [ERROR] Frontend build failed!
|
||||
|
|
@ -82,10 +92,14 @@ if exist "%SOURCE_DIR%\package.json" (
|
|||
echo [OK] Copied package.json
|
||||
)
|
||||
|
||||
REM Copy backend directory
|
||||
REM Copy backend directory (compiled JS files only, exclude .ts files)
|
||||
if exist "%SOURCE_DIR%\backend" (
|
||||
xcopy /E /I /Y "%SOURCE_DIR%\backend" "%TARGET_DIR%\backend" >nul
|
||||
echo [OK] Copied backend directory
|
||||
REM Remove TypeScript source files from target
|
||||
for /r "%TARGET_DIR%\backend" %%f in (*.ts) do (
|
||||
if not "%%~nxf"=="*.test.ts" del "%%f"
|
||||
)
|
||||
echo [OK] Copied backend directory (JS files)
|
||||
)
|
||||
|
||||
REM Copy migrations directory
|
||||
|
|
|
|||
18
tsconfig.backend.json
Normal file
18
tsconfig.backend.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"outDir": "./backend",
|
||||
"rootDir": "./backend",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"allowImportingTsExtensions": false,
|
||||
"jsx": "preserve",
|
||||
"lib": ["ES2020"],
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false
|
||||
},
|
||||
"include": ["backend/**/*"],
|
||||
"exclude": ["node_modules", "dist", "backend/**/*.test.ts"]
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue