const express = require('express'); const app = express.Router(); const sqlite = require('better-sqlite3'); const db = new sqlite('the_big_db.db', { verbose: console.log }); const { loginRequired } = require('../authStuff.js'); const showdown = require('showdown'); const converter = new showdown.Converter(); const { JSDOM } = require("jsdom"); const hljs = require('highlight.js/lib/core'); hljs.registerLanguage('lua', require('highlight.js/lib/languages/lua')); const { interpret } = require('../interpreter.js'); const pageListQuery = db.prepare(` select p.number, p.title, p.time from pages p where time >= ( select max(s.time) from pages s where s.number = p.number ) order by p.time desc `); app.get('/pages', (req, res) => { try { const pages = pageListQuery.all(); res.status(200).json(pages); } catch (error) { res.status(500).json({"error": error}); } }); app.post('/page/new', loginRequired, (req, res) => { try { let maxPage = db.prepare('select max(number) as maximum from pages').get() let newPageNumber = maxPage.maximum + 1; let newPage = db.prepare('insert into pages (number, title, description, author) values (?, ?, ?, ?) returning number') .get(newPageNumber, "new page", "this page is new!", req.session.characterId); let newAttributes = db.prepare('insert into attributes (number, contents) values (?, ?)') .run(newPageNumber, JSON.stringify({"parent": 3})); res.status(200).json(newPageNumber); } catch (error) { res.status(500).json({"error": error}); } }); const getPageQuery = db.prepare('select * from pages where number=? order by time desc'); app.get('/page/:number', async (req, res) => { try { const page = getPageQuery.get(req.params.number); if (!page) { res.status(404).json({"error": "page not found"}); return; } let char = req.session?.characterId || process.env.GHOST_CHARACTER_OBJECT; console.log("getting page ", req.params.number); const jd = new JSDOM(page.html); for (const executable of jd.window.document.querySelectorAll(".execute-me")) { const result = await interpret(req.params.number, char, executable.innerHTML); executable.innerHTML = result; } page.html = jd.serialize() res.status(200).json(page); } catch (error) { res.status(500).json({"error": error}); } }); const getAttributesQuery = db.prepare('select * from attributes where number=?'); app.get('/page/:number/attributes', (req, res) => { try { const page = getPageQuery.get(req.params.number); if (!page) { res.status(404).json({"error": "page not found"}); return; } const attributes = getAttributesQuery.get(req.params.number); if (!attributes) res.status(200).json({}); else if (attributes.contents) res.status(200).json(JSON.parse(attributes.contents)); else res.status(200).json({}); } catch (error) { res.status(500).json({"error": error}); } }); const pageInsertQuery = db.prepare('insert into pages (number, title, description, html, lua, author, type) values (?, ?, ?, ?, ?, ?, ?)') app.post('/page/:number', loginRequired, (req, res) => { try { const html = converter.makeHtml(req.body.description); const lua = hljs.highlight(req.body.description, {language: 'lua'}).value; const changes = pageInsertQuery.run(req.params.number, req.body.title, req.body.description, html, lua, req.session.characterId, req.body.type ? 1 : 0); res.status(200).json(changes); } catch (error) { console.log(error); res.status(500).json({"error": error}); } }); const attributesUpdateQuery = db.prepare('update attributes set contents=? where number=?') app.post('/page/:number/attributes', loginRequired, (req, res) => { try { const changes = attributesUpdateQuery.run(req.body, req.params.number); res.status(200).json(changes); } catch (error) { res.status(500).json({"error": error}); } }) app.delete('/page/:number', loginRequired, (req, res) => { try { db.prepare('delete from pages where number = ?').run(req.params.number); db.prepare('delete from attributes where number = ?').run(req.params.number); res.status(200).json({id: req.params.id}); } catch (error) { res.status(500).json({"error": error}); } }); app.get('/page/:number/history', (req, res) => { try { const all = db.prepare('select * from pages where number=:number order by time desc').all(req.params); res.status(200).json(all); } catch (error) { res.status(500).json({"error": error}); } }); app.get('/page/:number/:id', (req, res) => { try { const page = db.prepare('select * from pages where number=:number and id=:id').get(req.params); if (page === undefined) res.status(404).json({"error": "page not found"}); else res.status(200).json(page); } catch (error) { res.status(500).json({"error": error}); } }); module.exports = app;