UNPKG

rprcli

Version:

Reaper.js is a powerful TypeScript-based framework designed to streamline backend development. It offers built-in database migrations, seeders, and SQL query utilities, making it easy to manage data efficiently. With native support for TSX and JSX renderi

156 lines (145 loc) 5.26 kB
const path = require("path"); const ReaperRequest = require('./reaperRequest'); const ReaperResponse = require('./reaperResponse'); module.exports = (app,server)=>async function(req,res,next){ const routes = app.routes; const build = {}; const middleware = {}; const Get = (name,url,callback)=>{ build[name] = { method:"GET", url, callback } } const Post = (name,url,callback)=>{ build[name] = { method:"POST", url, callback } } const Middleware =(main_url,ReaperCallback,input)=>{ middleware[main_url] = ReaperCallback; input({ Get, Post, Middleware, Group, }); } const Group =(main_url,input)=>{ input({ Get:(name,url,ReaperCallback)=>Get(name,path.join(main_url,url),ReaperCallback), Post:(name,url,ReaperCallback)=>Post(name,path.join(main_url,url),ReaperCallback), Middleware:(s_url,ReaperCallback,input)=>Middleware(path.join(main_url,s_url),ReaperCallback,input), Group, }); } routes({ Get, Post, Middleware, Group, }); const renderTemplate =async (name,data={})=>{ const apis = []; Object.keys(build).forEach(key=>{ apis.push({ name:key, method:build[key].method, url:build[key].url }) }) res.render("index",{ script:`${name}View`, clientSideProps:data.props?data.props:{}, clientSideNames:{ listeners:Object.keys(app.listeners), apis }, metadata:{ title: 'Reaper website', description: 'A website made with the reaper framework', author: 'Damian Mostert', keywords: '', ogTitle: '', ogDescription: '', ogImage: '', ogUrl: '', twitterCard: '', twitterTitle: '', twitterDescription: '', twitterImage: '', favicon: '/reaper.webp', ...data.metadata?data.metadata:{} } }); } var Params = {}; for(let url of Object.keys(middleware)){ const {isValid,params} = isValidUrl(req.url,`${url}/[...middlewareRoute]`); Params = {...Params,...params} if(isValid){ const middlewareName = middleware[url]; var allow = false; var next = ()=>{ allow = true; } app.middleware[`${middlewareName}.js`](new ReaperRequest(req,params),new ReaperResponse(res,renderTemplate),next) if(!allow)return; } } const CALLBACK = Object.keys(build).find(name=>{ const item = build[name]; const {isValid,params} = isValidUrl(req.url,item.url); Params = {...Params,...params}; switch(item.method == req.method && isValid){ case true: return true; case false: return false; } }); if(CALLBACK){ const params = Params; const routstr = build[CALLBACK].callback; const controllerName = routstr.split("@")[1].split(".")[0]; const controllerSubName = routstr.split("@")[1].split(".")[1]; var pass = false; app.controllers[`${controllerName}.js`][controllerSubName](new ReaperRequest(req,params),new ReaperResponse(res,renderTemplate),()=>pass = true) if(!pass){ return; } }; next(); } const isValidUrl = (url_in, base_url) => { if (!url_in || !base_url) return { isValid: false, params: {} }; try { const cleanUrl = new URL(url_in, "http://localhost").pathname; const cleanBase = new URL(base_url, "http://localhost").pathname; // Convert paths to segments const urlSegments = cleanUrl.split("/").filter(Boolean); const baseSegments = cleanBase.split("/").filter(Boolean); let params = {}; for (let i = 0; i < baseSegments.length; i++) { if (baseSegments[i].startsWith("[...")) { // Wildcard parameter - capture everything after this segment const paramName = baseSegments[i].slice(4, -1); // Extract parameter name params[paramName] = urlSegments.slice(i).join("/"); return { isValid: true, params }; } if (baseSegments[i].startsWith("[") && baseSegments[i].endsWith("]")) { // Single dynamic parameter - extract value const paramName = baseSegments[i].slice(1, -1); params[paramName] = urlSegments[i]; } else if (urlSegments[i] !== baseSegments[i]) { return { isValid: false, params: {} }; } } return urlSegments.length === baseSegments.length ? { isValid: true, params } : { isValid: false, params: {} }; } catch (err) { return { isValid: false, params: {} }; } };