Gathering detailed insights and metrics for @betheweb/mockme
Gathering detailed insights and metrics for @betheweb/mockme
Gathering detailed insights and metrics for @betheweb/mockme
Gathering detailed insights and metrics for @betheweb/mockme
npm install @betheweb/mockme
Typescript
Module System
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
24
A mock service worker generator to intercept fetch calls in the browser and return mocks defined in custom files.
This package will add a CLI to allow the creation of a service worker implementation that uses the result of parsing any kind of mock file. This will be done using a plugin system, where each plugin should be able to create the mocks needed for a specific style of mocking.
There are some environments where you want to resolve your network (mainly API) calls, but you cannot reach the services or servers behind the scenes. Perhaps you need to benchmark the performance of your front-end solution, but you don't want the results to be affected by network response times, or you want to simulate what happens if a call takes 3 seconds to complete.
There are many scenarios where mocking responses using delays or different responses for different scenarios is a great tool to ensure you cover all edge cases. This is where mockme can help you.
Install with NPM
1$ npm i -D @betheweb/mockme
Install with Bun
1$ bun add -D @betheweb/mockme
Install with PNPM
1$ pnpm add -D @betheweb/mockme
The config file mockme.config.mjs
should be placed in the root of your project. Here is an example:
1import mockmeJsPlugin from '@betheweb/mockme-plugin-js'; 2 3export default { 4 output: 'demo/service-worker.js', 5 plugins: [ 6 mockmeJsPlugin({ 7 // plugin config 8 }), 9 ], 10};
In order to generate the service worker file from the command line, add the next script in your package.json file
1{ 2 "scripts": { 3 "mocks:sw": "mockme" 4 } 5}
If the config file is not in the root or you named it differently, just use the -c, --config
option.
1{ 2 "scripts": { 3 "mocks:sw": "mockme --config path/to/my/mockmeconfig.mjs" 4 } 5}
Once the service worker file is generated, it is time to use it in the code. In order to help in this task, mockme provides a manager to wire up all at once so you don't need to do it by yourself. Just import the ServiceWorkerManager and call the register function with the path where the service provider was generated.
1<html lang="en"> 2 <head> 3 <title>Mockme example</title> 4 <script type="module"> 5 import { ServiceWorkerManager } from '@betheweb/mockme/ServiceWorkerManager.js'; 6 7 ServiceWorkerManager.register('./sw.js'); 8 </script> 9 </head> 10</html>
A mockme plugin is an object with name property, and a handler function to generate the output as described below, and which follows our conventions. A plugin should be distributed as a package that exports a function that can be called with plugin-specific options and returns such an object.
mockme-plugin-
prefix.mockme-plugin
keyword in package.json
.fs.readFile
instead of fs.readFileSync
.string
The name of the plugin to be used when logging.
function(logger?: Logger): Promise<MockSchema[]>|MockSchema[]
The function which is going to use the config to generate the output.
1export function plugin(config) { 2 return { 3 name: 'mockme-plugin-test', 4 handler: () => [], // Returns an array of objects that have a mock schema 5 }; 6}
All plugins should return an array of objects that should be validated using the Mock Schema. This is the definition for the schema:
1type Request = { 2 method: 'GET' | 'POST' | 'PUT' | 'HEAD' | 'DELETE' | 'OPTIONS' | 'CONNECT'; 3 path: string; 4 body?: object | string; 5 queryParams?: Record<string, string>; 6 headers?: Record<string, string>; 7 cookies?: Record<string, string>; 8}; 9 10type Response = { 11 body?: object | string; 12 headers?: Record<string, string>; 13 status: number; 14}; 15 16type mockSchema = { 17 request: Request; 18 response: Response | (() => Response); 19 scenario?: string; 20 delay?: number; 21};
HTTP Verb used in the request. It is required and must have a value of GET
,POST
,PUT
,HEAD
,DELETE
,OPTIONS
or CONNECT
.
Pathname of the request. It is required accepts segments like express routes.
Example:
1{ 2 "request": { 3 "method": "GET", 4 "path": "/api/v1/books/:id" 5 } 6}
The body of the HTTP request. It is optional and should match
Example:
1{ 2 "request": { 3 "method": "POST", 4 "path": "/api/v1/books", 5 "body": { 6 "title": "Harry Potter" 7 } 8 } 9}
This object defines the conditions to match against the cookies included in the request. It is optional.
Example:
1{ 2 "request": { 3 "method": "GET", 4 "path": "/api/v1/books/:id", 5 "cookies": { 6 "user": "1" 7 } 8 } 9}
This object defines the conditions to match against the headers included in the request. It is optional.
Example:
1{ 2 "request": { 3 "method": "GET", 4 "path": "/api/v1/books/:id", 5 "headers": { 6 "Content-Type": "application/json" 7 } 8 } 9}
This object defines the conditions to match against url query parameters. It is optional.
Example:
1{ 2 "request": { 3 "method": "GET", 4 "path": "/api/v1/books?page=1", 5 "queryParams": { 6 "page": "1" 7 } 8 } 9}
All conditions are checked against the request and should pass. If there is a mismatch, no mock will be returned and the request will be passed to the network.
Here is a complex example where all conditions are combined:
1{ 2 "request": { 3 "method": "PUT", 4 "path": "/api/v1/books/:id?pages=100", 5 "queryParams": { "pages": "100" }, 6 "header": { "Authorization": "Bearer abcd" }, 7 "cookie": { "token": "12345" } 8 } 9}
To the service worker to match a request and return a mock data for it, the request should be like this:
1const myHeaders = new Headers(); 2myHeaders.append('Content-Type', 'application/json'); 3myHeaders.append('Authorization', 'Bearer abcd'); 4myHeaders.append('Cookie', 'token=12345'); 5 6const requestOptions = { 7 method: 'GET', 8 headers: myHeaders, 9 body: JSON.stringify({ 10 role: 'admin', 11 title: 'Harry Potter', 12 }), 13}; 14 15async function updateBook() { 16 try { 17 const response = await fetch('https://test.com/api/v1/books/1?pages=100', requestOptions); 18 const result = await response.json(); 19 } catch (error) { 20 console.log(error); 21 } 22}
The response can be either a function or an object. In case you need to perform any logic before returning the response, you may use a function which will receive an object with path, queryParams, pathParams, body, headers and cookies keys from the request.
Example:
1{ 2 response: ({ path, pathParams, queryParams, body, headers, cookies }) => { 3 if (pathParams.id === '1') { 4 return { 5 body: { 6 message: 'Book updated', 7 }, 8 status: 200, 9 delay: 3000, 10 }; 11 } else { 12 return { 13 body: { message: 'Book not found' }, 14 status: 404, 15 }; 16 } 17 }; 18}
The body to include in the response. This is optional and it is set to an empty object if not present.
Example:
1{ 2 "response": { 3 "body": { 4 "title": "Harry Potter", 5 "id": "1" 6 } 7 } 8}
The headers to include in the response. This is optional.
1{ 2 "response": { 3 "headers": { 4 "Content-Type": "application/json" 5 } 6 } 7}
The status of the response. This is optional and default value is 200
.
1{ 2 "response": { 3 "status": 404 4 } 5}
This will set the response to be delayed by the number of milliseconds specified. This is optional and default value is 0. If the response is set as a function and it returns a value for delay, it will take precendence over this one.
The scenario the mock is going to be in. This is optional. When using the service worker generated with mockme, the scenario can be set so we can have multiple mocks for the same endpoint but for different scenarios.
Example :
1[ 2 { 3 "request": { 4 "method": "GET", 5 "path": "/api/v1/books" 6 }, 7 "response": { 8 "body": [{ "id": "1", "title": "Harry Potter" }] 9 } 10 }, 11 { 12 "request": { 13 "method": "GET", 14 "path": "/api/v1/books" 15 }, 16 "response": { 17 "body": [ 18 { "id": "1", "title": "Harry Potter: Philosopher's stone" }, 19 { "id": "2", "title": "Harry Potter: Chamber of secrets" }, 20 { "id": "3", "title": "Harry Potter: Prisoner of Azkaban" } 21 ] 22 }, 23 "scenario": "3 books" 24 } 25]
If no scenario is set, the response will include one item, but if the scenario is set to '3 books'
, the response will include 3 items in the body.
No vulnerabilities found.
No security vulnerabilities found.