npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

flex-mock-server

v2.2.4

Published

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

Downloads

5

Readme

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.