Added in fastify/formbody so I can...handle forms...in a webserver...in 2024...I guess that's why it's so 'small'.

main
Zed A. Shaw 9 months ago
parent 53d67f185b
commit 2d73c70186
  1. 44
      commands/app.js
  2. 15
      controllers/todo.js
  3. 10
      package-lock.json
  4. 1
      package.json
  5. 7
      templates/todo.html

@ -1,6 +1,7 @@
import Fastify from "fastify"; import Fastify from "fastify";
import { restartable } from "@fastify/restartable"; import { restartable } from "@fastify/restartable";
import FastifyStatic from "@fastify/static"; import FastifyStatic from "@fastify/static";
import Formbody from "@fastify/formbody";
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
import chokidar from "chokidar"; import chokidar from "chokidar";
@ -20,30 +21,30 @@ nunjucks.configure("templates", { watch: true });
const configure = async (fastify, opts) => { const configure = async (fastify, opts) => {
const app = fastify(opts); const app = fastify(opts);
// MAGIC: this is how you trick the importer to reload modules // forces reload of the modules
// that have changed. Since it uses a URL you can add a query
// to it, but that isn't parsed as the file. Using a date then
// tags the module as being "new" when it's still the same file
// TODO: maybe use fs timestamps instead?
// BUG: sometimes reload is too fast for vim and crashes
const control_mod = await import(`../controllers/todo.js?update=${new Date()}`); const control_mod = await import(`../controllers/todo.js?update=${new Date()}`);
// this is a sample that uses the handler we dynamic load // TODO: mappings are very simple for now
// to handle the /todo but not sure how to work the actual
// URL mappings for it. Also not sure about using classes
for(let [url, controller] of Object.entries(control_mod.default)) { for(let [url, controller] of Object.entries(control_mod.default)) {
const handler = new controller(); const handler = new controller();
app.get(`/${url}`, async (req, rep) => { // this goes through all the allowed verbs
try { for(let verb of ["get", "post", "put", "delete"]) {
await handler.get(req, rep); if(verb in handler) {
} catch(error) { app[verb](`/${url}`, async (req, rep) => {
console.error(error); try {
console.error(error.stack); await handler[verb](req, rep);
console.error(error.source); } catch(error) {
console.error(error);
console.error(error.stack);
console.error(error.source);
}
});
} }
}); }
} }
app.register(Formbody);
app.register(FastifyStatic, { app.register(FastifyStatic, {
root: path.join(path.resolve("."), 'static'), root: path.join(path.resolve("."), 'static'),
prefix: '/', // optional: default '/' prefix: '/', // optional: default '/'
@ -51,15 +52,6 @@ const configure = async (fastify, opts) => {
index: "index.html" index: "index.html"
}); });
// this is from fastify/restartable
app.addHook('onClose', async () => {
if(!app.closingRestartable) {
console.log('closing the app because of restart')
} else{
console.log('closing the app because server is stopping')
}
})
return app; return app;
} }

@ -2,9 +2,6 @@ import { ToDo } from "../lib/models.js";
import nunjucks from "nunjucks"; import nunjucks from "nunjucks";
export class Todo { export class Todo {
constructor() {
}
async get(req, rep) { async get(req, rep) {
const todo_list = await ToDo.all({}); const todo_list = await ToDo.all({});
@ -13,6 +10,18 @@ export class Todo {
rep.code(200).type("text/html").send(result); rep.code(200).type("text/html").send(result);
} }
async post(req, rep) {
if(req.query.todo_id !== undefined) {
await ToDo.delete({id: req.query.todo_id});
} else {
console.log("ADDING TASK", req.body.task);
await ToDo.insert({task: req.body.task});
}
// this is how you can prevent the annoying double submit
rep.redirect("/todo");
}
} }
// you use the export default to set the route URL? // you use the export default to set the route URL?

10
package-lock.json generated

@ -9,6 +9,7 @@
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@fastify/cors": "^9.0.1", "@fastify/cors": "^9.0.1",
"@fastify/formbody": "^7.4.0",
"@fastify/helmet": "^11.1.1", "@fastify/helmet": "^11.1.1",
"@fastify/static": "^7.0.0", "@fastify/static": "^7.0.0",
"commander": "^12.0.0", "commander": "^12.0.0",
@ -72,6 +73,15 @@
"fast-json-stringify": "^5.7.0" "fast-json-stringify": "^5.7.0"
} }
}, },
"node_modules/@fastify/formbody": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/@fastify/formbody/-/formbody-7.4.0.tgz",
"integrity": "sha512-H3C6h1GN56/SMrZS8N2vCT2cZr7mIHzBHzOBa5OPpjfB/D6FzP9mMpE02ZzrFX0ANeh0BAJdoXKOF2e7IbV+Og==",
"dependencies": {
"fast-querystring": "^1.0.0",
"fastify-plugin": "^4.0.0"
}
},
"node_modules/@fastify/helmet": { "node_modules/@fastify/helmet": {
"version": "11.1.1", "version": "11.1.1",
"resolved": "https://registry.npmjs.org/@fastify/helmet/-/helmet-11.1.1.tgz", "resolved": "https://registry.npmjs.org/@fastify/helmet/-/helmet-11.1.1.tgz",

@ -9,6 +9,7 @@
"scripts": {}, "scripts": {},
"dependencies": { "dependencies": {
"@fastify/cors": "^9.0.1", "@fastify/cors": "^9.0.1",
"@fastify/formbody": "^7.4.0",
"@fastify/helmet": "^11.1.1", "@fastify/helmet": "^11.1.1",
"@fastify/static": "^7.0.0", "@fastify/static": "^7.0.0",
"commander": "^12.0.0", "commander": "^12.0.0",

@ -19,11 +19,16 @@
<ol> <ol>
{% for todo in todo_list %} {% for todo in todo_list %}
<li>{{ todo.task }}</li> <li style="display: flex; gap: 1rem;"><form action="/todo?todo_id={{ todo.id }}" method="POST"><button>X</button></form> {{ todo.task }}</li>
{% else %} {% else %}
<li>No TODO Items</li> <li>No TODO Items</li>
{% endfor %} {% endfor %}
</ol> </ol>
<h4>Add a New TODO</h4>
<form action="/todo" method="POST">
<label for="task">Task</label>
<input name="task"></input>
</form>
{% include "./footer.html" %} {% include "./footer.html" %}

Loading…
Cancel
Save