allow additional arguments to be passed to handler functions
[squeep-api-dingus] / lib / dingus.js
index 1cbfd72b8c95ad1d3fe3de38f7a1840349887a15..343283974d7c723a6cbb8eb85fc3e3b942230fff 100644 (file)
@@ -105,8 +105,8 @@ class Dingus {
    * @param {string} urlPath 
    * @param {fn} handler 
    */
-  on(method, urlPath, handler) {
-    this.router.on(method, urlPath, handler);
+  on(method, urlPath, handler, ...handlerArgs) {
+    this.router.on(method, urlPath, handler, handlerArgs);
   }
 
 
@@ -259,9 +259,9 @@ class Dingus {
     const { pathPart, queryParams } = this._splitUrl(req.url);
     ctx.queryParams = queryParams;
 
-    let handler;
+    let handler, handlerArgs = [];
     try {
-      handler = this.router.lookup(req.method, pathPart, ctx);
+      ({ handler, handlerArgs } = this.router.lookup(req.method, pathPart, ctx));
     } catch (e) {
       if (e instanceof DingusError) {
         switch (e.message) {
@@ -274,7 +274,7 @@ class Dingus {
           default:
             this.logger.error(_scope, 'unknown dingus error', { error: e });
             handler = this.handlerInternalServerError.bind(this);
-          }
+        }
       } else if (e instanceof URIError) {
         handler = this.handlerBadRequest.bind(this);
       } else {
@@ -285,7 +285,7 @@ class Dingus {
 
     try {
       await this.preHandler(req, res, ctx);
-      return await handler(req, res, ctx);
+      return await handler(req, res, ctx, ...handlerArgs);
     } catch (e) {
       ctx.error = e;
       this.sendErrorResponse(e, req, res, ctx);
@@ -624,6 +624,37 @@ class Dingus {
   }
 
 
+  /**
+   * @param {http.ClientRequest} req
+   * @param {http.ServerResponse} res
+   * @param {object} ctx
+   * @param {String} file - override ctx.params.file
+   */
+  async handlerGetStaticFile(req, res, ctx, file) {
+    Dingus.setHeadHandler(req, res, ctx);
+
+    // Set a default response type to handle any errors; will be re-set to serve actual static content type.
+    this.setResponseType(this.responseTypes, req, res, ctx);
+
+    await this.serveFile(req, res, ctx, this.staticPath, file || ctx.params.file);
+  }
+
+
+  /**
+   * @param {http.ClientRequest} req
+   * @param {http.ServerResponse} res
+   * @param {Object} ctx
+   * @param {String} newPath
+   * @param {Number} statusCode
+  */
+  async handlerRedirect(req, res, ctx, newPath, statusCode = 307) {
+    this.setResponseType(this.responseTypes, req, res, ctx);
+    res.setHeader(Enum.Header.Location, newPath);
+    res.statusCode = statusCode;
+    res.end();
+  }
+
+
   /**
    * @param {http.ClientRequest} req
    * @param {http.ServerResponse} res
@@ -651,7 +682,7 @@ class Dingus {
    * @param {http.ServerResponse} res
    * @param {object} ctx
    */
-   async handlerBadRequest(req, res, ctx) {
+  async handlerBadRequest(req, res, ctx) {
     this.setResponseType(this.responseTypes, req, res, ctx);
     throw new ResponseError(Enum.ErrorResponse.BadRequest);
   }
@@ -662,7 +693,7 @@ class Dingus {
    * @param {http.ServerResponse} res
    * @param {object} ctx
    */
-   async handlerInternalServerError(req, res, ctx) {
+  async handlerInternalServerError(req, res, ctx) {
     this.setResponseType(this.responseTypes, req, res, ctx);
     throw new ResponseError(Enum.ErrorResponse.InternalServerError);
   }