From 917945e82c2d14e6973088c43eccaa13720e5064 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Fri, 23 Dec 2022 11:45:16 +0700 Subject: [PATCH] lib/api.js now mostly documented. --- lib/api.js | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/lib/api.js b/lib/api.js index 3f45066..1b177ee 100644 --- a/lib/api.js +++ b/lib/api.js @@ -267,26 +267,69 @@ export class API { return this.res.redirect(status, url); } + /* + Returns an error status to the browser. The `err` parameter can either + be a plain `string` or an Object. Since this is an entirely JSON API + system the function does this: + + 1. If it's a string, it wraps it in `{message: err}`. + 2. If it's an object is sends it directly as JSON. + + + `status number` -- Status code for the error. + + `err (string|Object)` -- Either a string message that will be wrapped, or a raw object. + */ error(status, err) { if(typeof err === 'string') { return this.res.status(status).send({message: err}); } else { - return this.res.status(status).send(err); + return this.res.status(status).json(err); } } + /* + A `get accessor` that returns whether the current user is authenticated + or not. Normally you would tag your handler as requiring authentication + with `get.authenticated = true` but there's some instances when you need + to do your own auth inside a handler. + + + ___return___ boolean -- whether the user is authenticated + */ get user_authenticated() { return this.req.user !== undefined; } + /* + Another `get accessor` that tells you if this user is authenicated _and_ an + admin. An admin user is defined by having the `User.admin` field of the `user` + table in the database set to 1. + + + ___return___ boolean -- whether the user is authenticated and an admin. + */ get admin_authenticated() { return this.req.user !== undefined && this.req.user.admin === 1; } + /* + A `get accessor` that retuns the current user object if they're authenticated. + + + ___return___ User -- the currently authenticated user. + */ get user() { return this.req.user; } + /* + Validates the rules given using the Laravel rules system. You can combine + with with `Model.validation` to generate the rules based on the schema. You + can use `extra` to pass in a callback to do extra validation. The `extra(form)` + callback has access to the final result _after_ all validation has ran, so you + can alter the results how you want. + + ___WARNING___: This documentation needs to be improved to show exactly how to use it. + + + `rules Object` -- Uses the validtion rules system from Laravel. See this module's docs at the top for more information. + + `extra(form)` --- Callback that takes the validated form and does additional validation or cleaning. + */ validate(rules, extra) { const form = this.req.method === "GET" ? this.req.query : this.req.body; let validation = Validator.make(form, rules); @@ -312,10 +355,28 @@ export class API { return form; } + /* + Returns a properly formatted validation error to the browser. This can then be used by + the `client/components/FormField.svelte` to display validation errors, and since the + rules are included in the response you can do further validation in the browser. + + + `res Object` -- The response object from Express.js. + + `form Object` -- The failed form from `.validate()`. + */ validation_error(res, form) { return res.status(400).json(form); } + /* + Cleans a form you've received from the internet to have only fields + matching `rules`. You can also give an `extra` list of fields to + keep. You combine this with `Model.validation` to create a way to + remove bad inputs from submitted forms before validation. + + + `form Object` -- The form to clean before validation. + + `rules Object` -- The rules to base the cleaning on. + + `extra Array` -- A list of additional fields to keep. + */ clean_form(form, rules, extras=[]) { // what I wouldn't give for set operations for(let [key, rule] of Object.entries(form)) { @@ -330,6 +391,10 @@ export class API { } } +/* + BUG: This is a copy of the `defer()` in `client/helpers.js` but + really both of these should be in another library. + */ export const defer = () => { let res; let rej;