Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
mock-config-server
Advanced tools
Tool that easily and quickly imitates server operation, create full fake api in few steps
tool that easily and quickly imitates server operation, create full fake api in few steps
$ npm i mock-config-server --save --dev
# or
$ yarn add mock-config-server --dev
🎉 Mock Config Server it is a tool that, easily, quickly simulates the work of a server. The main difference from solutions such as json-server and mock-service-worker is the ease of filling in data and flexible emulation of any and usual cases. Our goal is to create a simple and flexible system for users, with the help of which they can create, test, and support their products.
Install 🎉 Mock Config Server with npm or yarn
$ npm i mock-config-server --save --dev
# or
$ yarn add mock-config-server --dev
Create a mock-server.config.js
file with server configuration
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [{ data: { emoji: '🦁', name: 'Nursultan' } }]
}
]
}
};
export default mockServerConfig;
Start 🎉 Mock Config Server
$ npx mock-config-server
If the package is already installed you can use short command
mcs
rest?
Rest configs for mock requests
graphql?
GraphQL configs for mock requests
database?
Database config for mock requests read
data
{Object | string} initial data for databaseroutes?
{Object | string} map of custom routes for databasestaticPath?
{StaticPath} entity for working with static files, readinterceptors?
{Interceptors} functions to change request or response parameters, readcors?
{Cors} CORS settings object (default: CORS is turn off
), readport?
{number} server port (default: 31299
)baseUrl?
{string} part of the url that will be substituted at the beginning of the request url (default: '/'
)Configs are the fundamental part of the mock server. These configs are easy to fill and maintain. Config entities is an object with which you can emulate various application behaviors. You can specify headers
| cookies
| query
| params
| body
for Rest request or headers
| cookies
| query
| variables
for GraphQL request to define what contract data you need to get. Using this mechanism, you can easily simulate the operation of the server and emulate various cases
Every route must be configured to handle response content in one of three ways: data or queue or file.
path
{string | RegExp} request pathmethod
{get | post | delete | put | patch | options} rest api methodroutes
{RestRouteConfig[]} request routes
data?
{any} mock data of requestqueue?
{Array<{ time?: number; data: any}>} queue for polling with opportunity to set time for each responsefile?
{string} path to file for return in responsesettings?
{Settings} settings for route (polling on/off, etc.)entities?
Object<headers | cookies | query | params | body> object that helps in data retrievalinterceptors?
{Interceptors} functions to change request or response parameters, readinterceptors?
{Interceptors} functions to change request or response parameters, readEvery route must be configured to handle response content in one of two ways: data or queue.
operationType
{query | mutation} graphql operation typeoperationName?
{string | RegExp} graphql operation namequery?
: {string} graphql query as stringroutes
{GraphQLRouteConfig[]} request routes
data?
{any} mock data of requestqueue?
{Array<{ time?: number; data: any}>} queue for polling with opportunity to set time for each responsesettings?
{Settings} settings for route (polling on/off, etc.)entities?
Object<headers | cookies | query | variables> object that helps in data retrievalinterceptors?
{Interceptors} functions to change request or response parameters, readinterceptors?
{Interceptors} functions to change request or response parameters, readEvery graphql config should contain
operationName
orquery
or both of them
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [
{
entities: {
headers: { 'name-header': 'Nursultan' }
},
data: { emoji: '🦁', name: 'Nursultan' }
},
{
entities: {
headers: { 'name-header': 'Dmitriy' }
},
data: { emoji: '☄', name: 'Dmitriy' }
}
]
}
]
}
};
module.exports = mockServerConfig;
Now you can make a request with an additional header and get the desired result
fetch('http://localhost:31299/api/user', {
headers: {
'name-header': 'Nursultan',
'Content-Type': 'application/json'
}
})
.then((response) => response.json())
.then((data) => console.log(data)); // { emoji: '🦁', name: 'Nursultan' }
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
graphql: {
baseUrl: '/graphql',
configs: [
{
operationType: 'query',
operationName: 'GetUser',
routes: [
{
entities: {
headers: { 'name-header': 'Nursultan' }
},
data: { emoji: '🦁', name: 'Nursultan' }
},
{
entities: {
headers: { 'name-header': 'Dmitriy' }
},
data: { emoji: '☄', name: 'Dmitriy' }
}
]
}
]
}
};
module.exports = mockServerConfig;
Now you can make a request with an additional header and get the desired result
const body = JSON.stringify({
query: 'query GetUser { name }'
});
fetch('http://localhost:31299/graphql', {
method: 'POST',
headers: {
'name-header': 'Nursultan',
'Content-Type': 'application/json'
},
body
})
.then((response) => response.json())
.then((data) => console.log(data)); // { emoji: '🦁', name: 'Nursultan' }
If you need more complex logic for matching entities, you can use entity descriptors.
Descriptor is an object with checkMode
and value
fields that describe how the correctness of the actual entity is calculated.
Allowed checkModes
Value for checkMode
except function
| exists
| notExists
can be array, so you can write even more complex logic. For example "does not contain these values" or "must be match to one of these regExp".
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [
{
entities: {
headers: {
// 'name-header' is 'Dmitriy' or 'Nursultan'
'name-header': {
checkMode: 'equals',
value: ['Dmitriy', 'Nursultan']
},
// check for 'equals' if descriptor not provided
role: 'developer'
},
cookies: {
// any 'token' cookie
token: {
checkMode: 'exists'
},
// 'someSecretToken' cookie can be '123-abc' or 'abc-999' for example
someSecretToken: {
checkMode: 'regExp',
value: [/^\d\d\d-abc$/, /^abc-\d\d\d$/]
}
}
},
data: 'Some user data for Dmitriy and Nursultan'
}
]
}
]
}
};
module.exports = mockServerConfig;
Also you can use array as value for REST body and GraphQL variables entities: in this case mock-config-server will iterate
over array until checkMode=equals
finds a match or return 404
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'post',
routes: [
{
entities: {
// if body equals to { key1: 'value1' } or ['value1'] then mock-config-server return data
body: [{ key1: 'value1' }, ['value1']]
},
data: 'Some user data'
}
]
}
]
}
};
module.exports = mockServerConfig;
function checkMode
is the most powerful way to describe your entities
logic, but in most cases you will be fine using other checkModes
.
Function value
has the following signature (actualValue, checkFunction) => boolean
.
Return true
if actualValue
matches your logic or false
otherwise.
You can use the checkFunction
from second argument if you want to describe your logic in a more declarative way.
checkFunction
has the following signature (checkMode, actualValue, descriptorValue?) => boolean
.
If you want to check a certain field of your body or variables, you can use descriptors in flatten object style. In this case server will check every field in entity with corresponding actual field. You can use descriptors for array body elements as well.
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/users',
method: 'post',
routes: [
{
entities: {
body: {
'user.name': 'Sergey'
}
},
data: 'user.name in body is "Sergey"'
}
]
},
{
path: '/posts',
method: 'post',
routes: [
{
entities: {
body: {
title: {
checkMode: 'startsWith',
value: 'A'
}
}
},
data: 'title in body starts with "A"'
}
]
},
{
path: '/posts',
method: 'post',
routes: [
{
entities: {
body: [
{
checkMode: 'startsWith',
value: 1
},
2
]
},
data: 'array[0] starts with "1" and array[1] equals "2"'
}
]
}
]
}
};
module.exports = mockServerConfig;
To enable whole body/variables checking as plain object you should use descriptor for entire body/variables.
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/users',
method: 'post',
routes: [
{
entities: {
body: {
checkMode: 'equals',
value: {
user: {
name: 'Sergey',
emoji: '🐘',
roles: ['developer', 'moderator']
}
}
}
},
data: 'your body is strictly equals object from body entity value'
}
]
}
]
}
};
module.exports = mockServerConfig;
Routes support polling for data. To add polling for data, you must specify the polling setting
and change data
property to queue
.
After receiving the last value from polling, the queue is reset and the next request will return the first value from the queue.
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [
{
settings: { polling: true },
queue: [
{ data: { emoji: '🦁', name: 'Nursultan' } },
{ data: { emoji: '☄', name: 'Dmitriy' } }
]
}
]
}
]
}
};
export default mockServerConfig;
Using the additional time
properties in milliseconds, you can specify how much time certain data should be returned
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [
{
settings: { polling: true },
queue: [
{ time: 5000, data: { emoji: '🦁', name: 'Nursultan' } },
{ data: { emoji: '☄', name: 'Dmitriy' } }
]
}
]
}
]
}
};
export default mockServerConfig;
Rest routes support paths to files. If a route is matched, the server will send data from the file. If the file is not found, the server will return 404.
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/files/settings',
method: 'get',
routes: [
{
file: './settings.json'
}
]
}
]
}
};
export default mockServerConfig;
If the file path is absolute, then this path will be used as is. If the file path is relative, it will be appended to the current working directory.
If the file exists, response interceptors will receive null as the data argument.
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/files/settings',
method: 'get',
routes: [
{
file: './settings.json',
interceptors: {
response: (data) => {
console.log(data); // null
return data;
}
}
}
]
}
]
}
};
export default mockServerConfig;
Any changes to the data will not affect the file (and the response, respectively).
Entity for connecting statics to the server, like HTML, JSON, PNG, etc.
string
path to your static filesObject<{prefix, path}
prefix
{string} path prefix for requestpath
{string} path to your static filesArray<string | Object<{prefix, path}>>
Object with settings for CORS. You can flexibly configure the required origin, methods, headers, credentials, maxAge for the entire server. If you do not specify CORS
settings, then it will be disabled.
origin
{string | RegExp | Array<string | RegExp> | Function | Promise } available origins from which requests can be mademethods?
{Array<GET | POST | DELETE | PUT | PATCH>} available methods (default: GET,OPTIONS,PUT,PATCH,POST,DELETE
)allowedHeaders?
{Array} allowed headers (default: *
)exposedHeaders?
{Array} exposed headers (default: *
)credentials?
{boolean} param tells browsers whether to expose the response to the frontend JavaScript code (default: true
)maxAge?
{number} how long the results can be cached (default: 3600
)Functions to change request or response parameters
request?
(params) => voidresponse?
(data, params) => anyrequest interceptors (except interceptor for route) are called regardless of whether the server found a route match or not. So changes in request interceptors can affect whether the server finds the route or not
params
request
request objectsetDelay
(delay) => Promise
delay
{number} milliseconds of delay timegetHeader
(field) => string | number | string[] | undefined
field
{string} name of response headergetHeaders
() => Record<string | number | string[] | undefined>getCookie
(name) => string | undefined
name
{string} name of cookiedata
{any} mock data of requestparams
request
request objectresponse
response objectsetDelay
(delay) => Promise
delay
{number} milliseconds of delay timesetStatusCode
(statusCode) => void
statusCode
{number} status code for responsesetHeader
(field, value) => void
field
{string} name of response headervalue
{string | string[] | undefined} value of response headerappendHeader
(field, value) => void
field
{string} name of response headervalue
{string | string[] | undefined} value of response headergetHeader
(field) => string | number | string[] | undefined
field
{string} name of response headergetHeaders
() => Record<string | number | string[] | undefined>setCookie
(name, value, options) => void
name
{string} name of cookievalue
{string} value of cookieoptions
{CookieOptions | undefined} cookie options (like path, expires, etc.)getCookie
(name) => string | undefined
name
{string} name of cookieclearCookie
(name, options) => void
name
{string} name of cookieoptions
{CookieOptions | undefined} cookie options (like path, expires, etc.)attachment
(filename) => void
filename
{string} name of file in 'Content-Disposition' headerWith mock-config-server
you can create your own mock database with all CRUD operations
data
{Object | string} initial data for databaseroutes?
{Object | string} map of custom routes for databaseconst mockServerConfig = {
database: {
data: {
users: [{ id: 1, name: 'John' }],
settings: {
blocked: false
}
}
}
};
Now you have the following routes for requests
GET /users
POST /users
GET /users/1
PUT /users/1
PATCH /users/1
DELETE /users/1
GET /settings
POST /settings
PUT /settings
PATCH /settings
Collection routes created from arrays which all elements have unique(!) id. Other database parts become single routes.
Also, there are additional routes: /__db
and /__routes
__db -> return data from database config
__routes -> return routes from database config
const mockServerConfig = {
database: {
data: {
users: [{ id: 1, name: 'John' }],
settings: {
blocked: false
}
},
routes: {
'/api/users/:id': '/users/:id',
'/*/my-settings': '/settings'
}
}
};
Now following routes will work correctly
/api/users/1 -> return data for /users/1
/some/custom/url/my-settings -> return data for /settings
Note some things:
:id
templatewildcard
only for custom route, not for real routeUse . to access deep properties
GET /users?name=siberiacancode
GET /users?id=1&id=2
GET /users?author.name=siberiacancode
Use _page and optionally _limit to paginate returned data.
GET /users?_page=1
GET /users?_page=1&_limit=5
_limit is 10 by default
The returned data has the format:
{
_link: Link,
results: Data[]
}
In the Link header you'll get count, pages, next and prev links.
count
{number} total count of elementspages
{number} count of pagesnext
{string | null} query string for next linkprev
{string | null} query string for prev linkUse _sort and _order, use . to access deep properties
GET /users?_sort=name
GET /users/1/transfers?_sort=id&_order=asc
GET /users?_sort=address.city&_order=desc
_order is 'asc' by default
For multiple fields:
GET /users?_sort=id&_order=desc&_sort=name&_order=asc
X-Total-Count header is included in the response
GET /users?_begin=20
GET /users?_begin=20&_end=30
Works exactly as slice, _begin and _end are optional
Add _q parameter for search data, search can be done by strings and numbers
GET /users?_q=siberia
For multiple search
GET /users?_q=siberia&_q=24
const mockServerConfig = {
database: {
data: './data.json',
routes: './routes.json'
}
};
Instead of objects you can use paths to JSON files which contain needed data or routes
mcs [options]
Options:
--baseUrl, -b Set base url (default: '/')
--port, -p Set port (default: 31299)
--staticPath, -s Set static path
--config, -c Set path to config file (default: './mock-server.config.(?:ts|mts|cts|js|mjs|cjs)')
--watch, -w Enables server restart after config file changes (default: false)
--version, -v Show version number
--help, -h Show help
Examples:
mcs --baseurl /base/url --port 3000 --config ./path/to/config.ts -w
mcs --help
The init command is used to initialize a new project or set up the initial configuration for a tool. It helps users get started with a new project by providing a streamlined setup process.
mcs init
Examples:
mcs init
mcs init --baseurl /base/url --port 3000
☄️ debabin |
👹 MiaInturi |
🐘 RiceWithMeat |
🎱️ anv296 |
🌵 kvelian |
FAQs
Tool that easily and quickly imitates server operation, create full fake api in few steps
The npm package mock-config-server receives a total of 66 weekly downloads. As such, mock-config-server popularity was classified as not popular.
We found that mock-config-server demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.