flex-mock-server

    2.2.4 • Public • Published

    flex-mock-server

    NPM Version Build Status codecov License

    A static server, with easy extendability to become mock server, via flexible configuring of response from file, inline data, function and more.

    features

    • both CLI and API
    • multiple instances with different working directories
    • url to file path mapping
    • simple configuring for any http status code
    • full ability to manipulate request and response
    • support https

    cli

    install

    npm i -g flex-mock-server

    invoke

    • fms
    • flex-mock-server

    options

    • -d, --debug: Verbose information for debugging.
    • -p, --port [port]: Server port, default is 3000.
    • -c, --cwd [dir]: Current working directory, default to process.cwd(); mock folder and map file path are based on this.
    • -f, --folder [dir]: Mock files residing directory.
    • -m, --map [fileName]: Custom response map file path; see example below.
    • -i, --index [fileName]: Default html page file name for existing bare folder.
    • -h, --history [fileName]: Whether to support html5 history api, alike "historyApiFallback" of webpackDevServer. if string, it is a path relative to cwd, to which the requested file resorts when directory non-exists; if true, then the resorting file path is set to index.
    • -C, --cors: Allow cors
    • -k, --cors-cookie: Allow cors credential. When set, cors is implied to be true.
    • -o, --auto-preflight: Handle "OPTIONS" method automatically, bypassing checking map configs. default is true.
    • -r, --root [dir]: Virtual root directory where this app is mounted in the domain, alike webpack "publicPath", which will be removed when match file.
    • -H, --https: Whether to apply https.
    • -h, --help: Output usage information.

    api

    install

    npm i -D flex-mock-server

    usage

    import Server from 'flex-mock-server';
    // const Server = require('flex-mock-server').default;
    const params = {};
    const server = new Server(params);
    server.onError((error) => console.error(error));
    server.start();
    ...
    server.stop();
    

    Multiple instances could be created with different cwd.

    parameters

    • debug {bool}
    • port {Number}
    • cwd {string}
    • folder {string}
    • map {string|Object}
    • index {string}
    • history {string}
    • cors {bool}
    • corsCookie {bool}
    • autoPreflight {bool}
    • root {string}

    Refer to cli options.

    standard code-handler

    Utility function for before and data handlers to response with default status code behavior.

    usage

    import { StandardCodeHander } from 'flex-mock-server';
    // const StandardCodeHander = require('flex-mock-server').StandardCodeHander;
    module.exports = {
      'dir/file.html': function customHandler(req, res, passedThroughData, logger){
        return StandardCodeHander(req, res, 302, {location: 'http://a.com'}, logger);
      }
    }
    

    map file

    format

    {
      pattern: response
      ...
    }
    

    pattern

    A string to construct RexExp for url testing and replacing with file path.

    [Notes]

    • The url being matched against is whatever left after removing domain and root directory (if supplied). e.g. /dir1/dir2/abc.ext in https://domain.com:123/dir1/dir2/abc.ext
    • Backslash should be escaped if you hope it take effects in constructed RegExp: file\\.html

    response

    Allowed types are:

    • {Number}: Treated as http code, being handled automatically; returns intermediately.

    • {Array}: An array, http code along with corresponding data: [301, 'http://abc.com']

    • {object}: a json of complex type, fields are:

      • before {function(req, res, logger)}: Execute before processing, to modify request or whatever.

      • after {function(req, res, responseData, logger)}: Called after response data is got and before sent.
        if binary data, fs.ReadStream is passed instead of file content.

      • data {*}: (match for any type of METHOD)

        • non-function Inline respone data for any method; This data is sent instead of from file.
        • function(req, res, passedThroughData, logger) Custom handler. returns
          1. the response data;
          2. a promise that resolves the response data (polyfill was already applied).

        don't call respone.end()/write() yourself.

      • path {string | function}: file path.

        • {string} - mapped file path string, internally it is called with String.replace(), so special replacement patterns are supported, such as $&, $', $1.
        • {function(req, res, logger)} - custom replacer.
      • passThrough {bool}: whether to check left items for more matches and pass this data on. default is false.

      • get/post/... {*}: method respective version of 'data'. }

    • {string}: shorthand for string version of path: {path:''}

    • {function}: shorthand for function version of data: { data: func }

    This map is walked through twice. The first time matched "before" handlers are executed. The second time to retrieve response data. However if the first time encounters a standard code handler, e.g. type of config is Number/Array, traversing stops, returns immediately.

    logger

    Passed in parameter logger in custom handlers is used to output information for debugging when debug flag is turned on. Three methods are supplied.

    • error(...args): red color
    • info(...args): blue color
    • log(...args): white color

    notes

    • babel-polyfill v6.26.0 is applied, New es6/7 features could be used in this map file.
    • A sample map file exists with path of lib/sample.map.js, contents are:

    sample

    const url = require('url');
    
    module.exports = {
      // standard code
      '/code/401/file\\.htm': 401,
      // standard code with arguments
      '/code/301/.*': [301, { url: 'http://abc.def.com' }],
      // custom data for any methods.
      '/data/null': { data: null },
      '/data/empty-string\\.htm': { data: '' },
      '/data/string': { data: 'hello world' },
      '/data/number': { data: 1 },
      '/data/json': { data: { customData: '123' } },
      // custom handler returning plain data.
      '/data/func/plain': {
        data(req, res, logger) {
          const parsedUrl = url.parse(req.url, true);
          const params = parsedUrl.query;
          if (params.id == 1) { // eslint-disable-line eqeqeq
            return { success: false };
          }
          return { success: true };
        },
      },
      // custom handler returning plain promise.
      '/data/func/promise': function handle(req, res, logger) {
        return new Promise((resolve, reject) => {
          resolve({ data: 'abc' });
        });
      },
      // shorthand for { data: func }
      '/func/file\\.htm': function handle(req, res, logger) {
        return { success: true };
      },
      // explicit method handler prioritized over 'data'.
      '/post/file\\.htm': {
        post: { customData: '456' },
      },
    
      // pre-processing handler to redirect to another path defined before.
      '/before/.*': {
        before(req, res, logger) {
          req.url = '/data/json';
        },
      },
    
      // don't pass through to 'compound/.*' by default.
      '/compound/no-through': {
        data(req, res, data, logger) {
          return { value: 0, success: false };
        },
      },
      // pass through to next two items by setting 'passThrough' to true.
      '/compound/through/file\\.htm': {
        data(req, res, data, logger) {
          return { value: 1 };
        },
        passThrough: true,
      },
      '/compound/through/.*': {
        data(req, res, data, logger) {
          data.value++;
          return data;
        },
        passThrough: true,
      },
      // "after" handler to modify response data
      '/compound/.*': {
        after(req, res, data, logger) {
          if (typeof data === 'string') { // read from file
            data = JSON.parse(data);
          }
          data.success = true;
          return data;
        },
      },
    
      // direct file path mapping
      '/path/article/(\\d+)/comment/(\\d+)': {
        path: 'article_$2_comment_$1.json',
      },
      // custom file path mapping
      '/path/custom/article/(\\d+)/comment/(\\d+)': {
        path(req, res, logger) {
          return req.url.replace(
            new RegExp('path/custom/article/(\\d+)/comment/(\\d+)'),
            'article_$2_comment_$1.json',
          );
        },
      },
      // shorthand for { path }
      '/path/short/article/(\\d+)/comment/(\\d+)': 'article_$2_comment_$1.json',
    };
    

    License

    MIT.

    Install

    npm i flex-mock-server

    DownloadsWeekly Downloads

    14

    Version

    2.2.4

    License

    MIT

    Unpacked Size

    110 kB

    Total Files

    29

    Last publish

    Collaborators

    • avatar