This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { paths } from '../config/paths.mjs';
|
||||
import {
|
||||
handleCreateArticle,
|
||||
handleDeleteArticle,
|
||||
handleListArticles,
|
||||
handleUpdateArticle,
|
||||
} from '../entities/article/articleHandlers.mjs';
|
||||
import { handleListAssets, handleUploadAsset } from '../entities/asset/assetHandlers.mjs';
|
||||
import { httpError } from '../shared/http/httpError.mjs';
|
||||
import { sendError } from '../shared/http/sendError.mjs';
|
||||
import { serveFile } from '../shared/static/serveFile.mjs';
|
||||
|
||||
export async function handleRequest(request, response) {
|
||||
try {
|
||||
return await routeRequest(request, response);
|
||||
} catch (error) {
|
||||
return sendError(response, error);
|
||||
}
|
||||
}
|
||||
|
||||
async function routeRequest(request, response) {
|
||||
const url = new URL(request.url || '/', `http://${request.headers.host || 'localhost'}`);
|
||||
|
||||
if (url.pathname === '/api/articles' && request.method === 'GET') {
|
||||
return await handleListArticles(request, response);
|
||||
}
|
||||
|
||||
if (url.pathname === '/api/articles' && request.method === 'POST') {
|
||||
return await handleCreateArticle(request, response);
|
||||
}
|
||||
|
||||
if (url.pathname === '/api/assets' && request.method === 'GET') {
|
||||
return await handleListAssets(request, response);
|
||||
}
|
||||
|
||||
if (url.pathname === '/api/assets' && request.method === 'POST') {
|
||||
return await handleUploadAsset(request, response);
|
||||
}
|
||||
|
||||
const articleRoute = url.pathname.match(/^\/api\/articles\/(.+)$/);
|
||||
if (articleRoute) {
|
||||
return await routeArticleBySlug(request, response, decodeURIComponent(articleRoute[1]));
|
||||
}
|
||||
|
||||
return await routeStaticFile(request, response, url.pathname);
|
||||
}
|
||||
|
||||
async function routeArticleBySlug(request, response, slug) {
|
||||
if (request.method === 'PUT') {
|
||||
return await handleUpdateArticle(request, response, slug);
|
||||
}
|
||||
|
||||
if (request.method === 'DELETE') {
|
||||
return await handleDeleteArticle(request, response, slug);
|
||||
}
|
||||
|
||||
throw httpError(405, 'Method not allowed');
|
||||
}
|
||||
|
||||
async function routeStaticFile(request, response, pathname) {
|
||||
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
||||
throw httpError(405, 'Method not allowed');
|
||||
}
|
||||
|
||||
if (pathname.startsWith('/assets/')) {
|
||||
return await serveFile(response, paths.webPublicRoot, pathname, request.method);
|
||||
}
|
||||
|
||||
const adminPath = pathname === '/' ? '/index.html' : pathname;
|
||||
return await serveFile(response, paths.adminPublicRoot, adminPath, request.method);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { createServer } from 'node:http';
|
||||
import { paths } from '../config/paths.mjs';
|
||||
import { serverConfig } from '../config/server.mjs';
|
||||
import { handleRequest } from './requestHandler.mjs';
|
||||
|
||||
export function startServer() {
|
||||
const server = createServer(handleRequest);
|
||||
|
||||
server.on('error', (error) => {
|
||||
if (error.code === 'EADDRINUSE') {
|
||||
console.error(`Port ${serverConfig.port} is already in use. Run with ADMIN_PORT=3334 npm run admin:posts.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
|
||||
server.listen(serverConfig.port, serverConfig.host, () => {
|
||||
console.log(`Local posts admin: http://${serverConfig.host}:${serverConfig.port}`);
|
||||
console.log(`Editing: ${paths.articlesFile}`);
|
||||
});
|
||||
|
||||
for (const signal of ['SIGINT', 'SIGTERM']) {
|
||||
process.on(signal, () => {
|
||||
server.close(() => process.exit(0));
|
||||
});
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
Reference in New Issue
Block a user