All files / server/plugins/parser index.js

82.85% Statements 29/35
56.25% Branches 9/16
100% Functions 10/10
100% Lines 28/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107      27x 27x   27x                                                                 103x             104x 104x 416x         104x 104x 104x         104x 104x 104x         104x 104x 104x         104x 104x 104x         104x 104x       104x         104x         104x 104x   1x 1x         27x  
// Parser plugin
// Get the raw request and transform it into something usable
// Examples: ctx.body, ctx.files, etc
const join = require('../../src/join');
const modern = require('../../src/modern');
 
const plugin = {
  name: 'parser',
  options: {
    body: {
      type: [Object, Boolean],
      default: { extended: true },
      extend: true
    },
    json: {
      type: [Object, Boolean],
      default: {}
    },
    text: {
      type: Object,
      default: {}
    },
    data: {
      type: Object,
      default: {}
    },
    cookie: {
      type: Object,
      default: {}
    },
    method: {
      type: [Object, String, Boolean],
      default: [
        'X-HTTP-Method',
        'X-HTTP-Method-Override',
        'X-Method-Override',
        '_method'
      ],
      // Coerce it into an Array if it is not already
      clean: value => typeof value === 'string' ? [value] : value
    }
  },
 
  // It is populated in "init()" right now:
  before: [
    ctx => {
      Iif (!ctx.options.parser.method) return;
      return join(ctx.options.parser.method.map(one => {
        return modern(require('method-override')(one));
      }))(ctx);
    },
 
    ctx => {
      Iif (!ctx.options.parser.body) return;
      const body = require('body-parser').urlencoded(ctx.options.parser.body);
      return modern(body)(ctx);
    },
 
    // JSON parser
    ctx => {
      Iif (!ctx.options.parser.json) return;
      const json = require('body-parser').json(ctx.options.parser.json);
      return modern(json)(ctx);
    },
 
    // Text parser
    ctx => {
      Iif (!ctx.options.parser.text) return;
      const text = require('body-parser').text(ctx.options.parser.text);
      return modern(text)(ctx);
    },
 
    // Data parser
    ctx => {
      Iif (!ctx.options.parser.data) return;
      const data = require('upload-files-express')(ctx.options.parser.data);
      return modern(data)(ctx);
    },
 
    // Cookie parser
    ctx => {
      Iif (!ctx.options.parser.cookie) return;
      const cookie = require('cookie-parser')(
        ctx.options.secret,
        ctx.options.parser.cookie
      );
      return modern(cookie)(ctx);
    },
 
    // Add a reference from ctx.req.body to the ctx.data and an alias
    ctx => {
      ctx.data = ctx.body;
    },
 
    // Fix the IP for heroku and similars
    ctx => {
      const forwarded = ctx.headers['x-forwarded-for'];
      if (!forwarded) return;
 
      const ip = forwarded.trim().split(/,\s?/g).shift();
      Object.defineProperty(ctx, 'ip', { enumerable: true, value: ip });
    },
  ]
};
 
module.exports = plugin;