importdbJsonfrom'./fixtures/db.json';importexpressfrom'express';import{json}from'milliparsec';importcryptofrom'crypto';importchalkfrom'chalk';import{Eta}from'eta';import{fileURLToPath}from'url';import{dirname,join}from'path';constPORT=3001;constapp=newexpress();const__filename=fileURLToPath(import.meta.url);const__dirname=dirname(__filename);consteta=newEta({views: join(__dirname,'views'),cache: true,});app.use(json());constkaomojis=['(˶ᵔ ᵕ ᵔ˶)','(˶ˆᗜˆ˵)','(˶˃ ᵕ ˂˶)','( ∩´͈ ᐜ `͈∩)'];functionrandomEmoji() {returnkaomojis[Math.floor(Math.random()*kaomojis.length)];}constroutes=[];constbaseUrl=`http://localhost:${PORT}`;console.log(chalk.bold(`JSON Server started on port ${PORT}`));console.log(chalk.magenta(randomEmoji()));for(constkeyindbJson){routes.push(`${key}`);app.get(`/${key}`,(_,res)=>{res.json(dbJson[key]);});app.get(`/${key}/:id`,(req,res)=>{const{id}=req.params;letfindById=[];if(Array.isArray(dbJson[key])){findById=res.json(dbJson[key].find((item)=>item.id===id));}res.json(findById);});app.post(`/${key}`,(req,res)=>{const{body}=req;if(!body.id){body.id=crypto.randomUUID();}if(Array.isArray(dbJson[key])){dbJson[key].push(body);}else{dbJson[key]=body;}res.json(body);});app.put(`/${key}/:id`,(req,res)=>{const{id}=req.params;const{body}=req;constindex=dbJson[key].findIndex((item)=>item.id===id);if(index!==-1){dbJson[key][index]=body;res.json(body);}else{res.status(404).json({error:'Not found'});}});app.delete(`/${key}/:id`,(req,res)=>{const{id}=req.params;constindex=dbJson[key].findIndex((item)=>item.id===id);if(index!==-1){dbJson[key].splice(index,1);res.json({message:'Deleted'});}else{res.status(404).json({error:'Not found'});}});}app.get('/',(_,res)=>{constrenderedData={data: dbJson,};constrenderedTemplate=eta.render('index.html',renderedData);res.send(renderedTemplate);});console.log('\n');console.log(chalk.bold('Endpoints:'));console.log(routes.map((route)=>`${chalk.gray(baseUrl)}/${chalk.blue(route)}`).join('\n'));app.listen(PORT);
{// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version":"0.2.0","configurations":[{"type":"node","request":"launch","name":"tsx","program":"${workspaceFolder}/src/bin.ts","runtimeExecutable":"tsx","console":"integratedTerminal","internalConsoleOptions":"neverOpen","args":["${workspaceFolder}/fixtures/db.json"],// Files to exclude from debugger (e.g. call stack)
"skipFiles":[// Node.js internal core modules
"<node_internals>/**",// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**"]}]}
// Set up database
letadapter: Adapter<Data>;if(extname(file)==='.json5'){adapter=newDataFile<Data>(file,{parse: JSON5.parse,stringify: JSON5.stringify,});}else{adapter=newJSONFile<Data>(file);}constobserver=newObserver(adapter);constdb=newLow<Data>(observer,{});awaitdb.read();// ...
letwriting=false;// true if the file is being written to by the app
letprevEndpoints='';observer.onWriteStart=()=>{writing=true;};observer.onWriteEnd=()=>{writing=false;};observer.onReadStart=()=>{prevEndpoints=JSON.stringify(Object.keys(db.data).sort());};observer.onReadEnd=(data)=>{if(data===null){return;}constnextEndpoints=JSON.stringify(Object.keys(data).sort());if(prevEndpoints!==nextEndpoints){console.log();logRoutes(data);}};
watch(file).on('change',()=>{// Do no reload if the file is being written to by the app
if(!writing){db.read().catch((e)=>{if(einstanceofSyntaxError){returnconsole.log(chalk.red(['',`Error parsing ${file}`,e.message].join('\n')));}console.log(e);});}});