UNPKG

express-rendertype

Version:

Express middleware to (automatically) render content and errors to content-type

75 lines (61 loc) 2.69 kB
Errors = require "restify-errors" errify = require "errify" Fancy = require "./fancy" class RenderType @text: (path, obj) -> @send obj.toString() @html: (path, obj) -> @render path, obj @json: (path, obj) -> @json obj @yaml: (path, obj) -> @send (require "js-yaml").safeDump obj, skipInvalid: true @xml: (path, obj) -> @send (require "xml") obj, indent: ' ' @auto: (fallback = false, preference = ["yaml", "json", "html", "text"]) -> (req, res, next) => res.rendr = => type = req.accepts preference type or= fallback next new Errors.NotAcceptableError unless type res.type type @[type].apply res, arguments next() class RenderTypedErrors extends RenderType @Error404: (req, res, next) -> next new Errors.NotFoundError @log: -> @text: (err, req, res, next) -> super "", err.message @html: (err, req, res, next) -> super "error", err @json: (err, req, res, next) -> super "", err @yaml: (err, req, res, next) -> super "", err @xml: (err, req, res, next) -> super "", err @auto: (fallback = false, preference = ["yaml", "json", "html", "text"], log = @log) -> (err, req, res, next) => type = req.accepts preference type or= fallback err.statusCode = err.status if err.status and not err.statusCode if err.statusCode < 400 or not err.statusCode then err.statusCode = 500 if err.statusCode and not (err instanceof Error) {message} = err err = Errors.makeErrFromCode err.statusCode trimTo = 0 stack = (Fancy.stringify err).split "\n" trimTo = i for line, i in stack when line.match /at next/ err.stack = stack[trimTo..-1].join "\n" err.message = message if message log err return req.socket.destroy() if res._header res.status err.statusCode res.setHeader "X-Content-Type-Options", "nosniff" res.type type @[type].apply res, arguments class FancyErrors extends RenderTypedErrors @text: (err, req, res, next) -> super message: Fancy.stringify err @html: (err, req, res, next) -> ideally = errify next await Fancy.html err, ideally defer html res.type "html" res.send html @json: (err, req, res, next) -> super Fancy.json err @yaml: (err, req, res, next) -> super Fancy.json err @xml: (err, req, res, next) -> super Fancy.json err @auto: (fallback = false, preference = ["yaml", "json", "html", "text"], log = @log) -> super fallback, preference, Fancy.log log RenderType.error = Errors RenderType.error.fromCode = Errors.makeErrFromCode RenderType.Errors = RenderTypedErrors RenderType.FancyErrors = FancyErrors module.exports = RenderType