Socket
Socket
Sign inDemoInstall

mappersmith

Package Overview
Dependencies
Maintainers
1
Versions
120
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mappersmith - npm Package Compare versions

Comparing version 2.28.0 to 2.29.0

typings/gateway/fetch.d.ts

2

gateway/http.js

@@ -50,3 +50,3 @@ "use strict";

var headers = {};
var headers = {}; // eslint-disable-next-line node/no-deprecated-api

@@ -53,0 +53,0 @@ var defaults = _url.default.parse(this.request.url());

@@ -130,3 +130,9 @@ "use strict";

return this.middleware.map(createInstance);
var name = args.resourceName,
method = args.resourceMethod;
var resourceMiddleware = this.createMethodDescriptor(name, method).middleware;
var middlewares = _toConsumableArray(resourceMiddleware).concat(_toConsumableArray(this.middleware));
return middlewares.map(createInstance);
}

@@ -133,0 +139,0 @@ };

@@ -16,3 +16,3 @@ "use strict";

/* global VERSION */
var version = "2.28.0";
var version = "2.29.0";
exports.version = version;

@@ -19,0 +19,0 @@ var configs = {

@@ -34,2 +34,4 @@ "use strict";

this.timeoutAttr = obj.timeoutAttr || 'timeout';
var resourceMiddleware = obj.middleware || obj.middlewares || [];
this.middleware = resourceMiddleware;
}
{
"name": "mappersmith",
"version": "2.28.0",
"version": "2.29.0",
"description": "It is a lightweight rest client for node.js and the browser",

@@ -12,2 +12,3 @@ "author": "Tulio Ornelas <ornelas.tulio@gmail.com>",

"main": "index.js",
"types": "typings/index.d.ts",
"scripts": {

@@ -21,2 +22,3 @@ "integration-server": "node spec/integration/server.js",

"test:node:watch": "./node_modules/.bin/jest --config jestSetup/configs/config.node.json --watchAll",
"test:typings": "./node_modules/.bin/tsc",
"test": "concurrently --success first --names \"test,server\" --kill-others \"node scripts/ci.js\" \"yarn integration-server\"",

@@ -68,8 +70,8 @@ "build:node": "rm -rf lib/* && ./node_modules/.bin/babel src -d lib",

"cross-env": "^5.1.1",
"eslint": "^3.19.0",
"eslint-config-standard": "^10.2.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-node": "^4.2.2",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
"eslint": "^6.0.1",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"express": "^4.15.4",

@@ -81,18 +83,19 @@ "faux-jax-tulios": "^5.0.8",

"js-md5": "^0.6.1",
"karma": "^1.7.0",
"karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-ie-launcher": "^1.0.0",
"karma-jasmine": "^1.1.0",
"karma-jasmine": "^1.1.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "^0.0.31",
"karma-webpack": "^2.0.4",
"karma-webpack": "^4.0.2",
"mockdate": "^2.0.1",
"multer": "^1.2.0",
"puppeteer": "^0.12.0",
"puppeteer": "^1.18.1",
"typescript": "^3.5.2",
"uglifyjs-webpack-plugin": "^2.1.1",
"webpack": "^4.28.1",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.11",
"webpack": "^4.35.2",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2",
"whatwg-fetch": "^2.0.2"
}
}

@@ -25,4 +25,11 @@ [![npm version](https://badge.fury.io/js/mappersmith.svg)](http://badge.fury.io/js/mappersmith)

- [Middleware](#middleware)
- [Global middleware](#global-middleware)
- [Context](#context)
- [Creating middleware](#creating-middleware)
- [Context](#context)
- [Optional arguments](#creating-middleware-optional-arguments)
- [Abort](#creating-middleware-optional-arguments-abort)
- [Renew](#creating-middleware-optional-arguments-renew)
- [Configuring middleware](#configuring-middleware)
- [Resource level middleware](#resource-middleware)
- [Client level middleware](#client-middleware)
- [Global middleware](#global-middleware)
- [Built-in middleware](#built-in-middleware)

@@ -37,4 +44,6 @@ - [BasicAuth](#middleware-basic-auth)

- [Timeout](#middleware-timeout)
- [Middleware legacy notes](#middleware-legacy-notes)
- [Testing Mappersmith](#testing-mappersmith)
- [Gateways](#gateways)
- [TypeScript](#typescript)
- [Development](#development)

@@ -350,18 +359,14 @@

The `request` method receives an instance of the [Request](https://github.com/tulios/mappersmith/blob/master/src/request.js) object and it must return a Request. The method `enhance` can be used to generate a new request based on the previous one.
### <a name="creating-middleware"></a> Creating middleware
__NOTE__: Since version `2.27.0` a new method was introduced: `prepareRequest`. This method aims to replace the `request` method in future versions of mappersmith, it has a similar signature as the `response` method and it is always async. All previous middleware are backward compatible, the default implementation of `prepareRequest` will call the `request` method if it exists. The `prepareRequest` method receives a function which returns a `Promise` resolving the [Request](https://github.com/tulios/mappersmith/blob/master/src/request.js). This function must return a `Promise` resolving the request. The method `enhance` can be used to generate a new request based on the previous one.
The `prepareRequest` method receives a function which returns a `Promise` resolving the [Request](https://github.com/tulios/mappersmith/blob/master/src/request.js). This function must return a `Promise` resolving the request. The method `enhance` can be used to generate a new request based on the previous one.
The `response` method receives a function which returns a `Promise` resolving the [Response](https://github.com/tulios/mappersmith/blob/master/src/response.js). This function must return a `Promise` resolving the Response. The method `enhance` can be used to generate a new response based on the previous one.
You don't need to implement both methods, you can define only the phase you need.
Example:
```javascript
const MyMiddleware = () => ({
request(request) {
return request.enhance({
prepareRequest(next) {
return next().then(request => request.enhance({
headers: { 'x-special-request': '->' }
})
}))
},

@@ -377,37 +382,60 @@

__NOTE:__ If you are running mappersmith `2.27.0` or greater use the following instead:
#### <a name="context"></a> Context
Sometimes you may need to set data to be available to all your client's middleware. In this
case you can use the `setContext` helper, like so:
```javascript
const MyMiddleware = () => ({
prepareRequest(next) {
return next().then(request => request.enhance({
headers: { 'x-special-request': '->' }
}))
},
import { setContext } from 'mappersmith'
response(next) {
return next().then((response) => response.enhance({
headers: { 'x-special-response': '<-' }
}))
}
const MyMiddleware = ({ context }) => ({
/* ... */
})
setContext({ some: 'data'})
client.User.all()
// context: { some: 'data' }
```
The middleware can be configured using the key `middleware` in the manifest, example:
This is specially useful when using mappermith coupled with back-end services.
For instance you could define a globally available correlation id middleware
like this:
```javascript
const client = forge({
clientId: 'myClient',
middleware: [ MyMiddleware ],
resources: {
User: {
all: { path: '/users' }
}
import forge, { configs, setContext } from 'mappersmith'
import express from 'express'
const CorrelationIdMiddleware = ({ context }) => ({
request(request) {
return request.enhance({
headers: {
'correlation-id': context.correlationId
}
})
}
})
configs.middleware = [CorrelationIdMiddleware]
const api = forge({ ... })
const app = express()
app.use((req, res, next) => {
setContext({
correlationId: req.headers['correlation-id']
})
})
// Then, when calling `api.User.all()` in any handler it will include the
// `correlation-id` header automatically.
```
It can, optionally, receive `resourceName`, `resourceMethod`, [#context](`context`)
and `clientId`. Example:
Note that setContext will merge the object provided with the current context
instead of replacing it.
#### <a name="creating-middleware-optional-arguments"></a> Optional arguments
It can, optionally, receive `resourceName`, `resourceMethod`, [#context](`context`) and `clientId`. Example:
```javascript

@@ -425,22 +453,6 @@ const MyMiddleware = ({ resourceName, resourceMethod, context, clientId }) => ({

__NOTE__: The request phase can be asynchronous, just return a promise resolving a request. Example:
##### <a name="creating-middleware-optional-arguments-abort"></a> Abort
```javascript
const MyMiddleware = () => ({
request(request) {
return Promise.resolve(
request.enhance({
headers: { 'x-special-token': 'abc123' }
})
)
}
})
```
The `prepareRequest` phase can optionally receive a function called "abort". This function can be used to abort the middleware execution early-on and throw a custom error to the user. Example:
__NOTE 2__: If you are using mappersmith `2.27.0` or greater take a look at `prepareRequest`, which is always async.
The `prepareRequest` phase can optionally receive a function called "abort". This function can be used to abort the middleware execution early-on and throw a custom error to the user.
Example:
```javascript

@@ -458,6 +470,6 @@ const MyMiddleware = () => {

The `response` phase can optionally receive a function called "renew". This function can be used to rerun the
middleware stack. This feature is useful in some scenarios, for example, automatically refreshing an expired access token.
Example:
##### <a name="creating-middleware-optional-arguments-renew"></a> Renew
The `response` phase can optionally receive a function called "renew". This function can be used to rerun the middleware stack. This feature is useful in some scenarios, for example, automatically refreshing an expired access token. Example:
```javascript

@@ -505,6 +517,3 @@ const AccessTokenMiddleware = () => {

"renew" can only be invoked sometimes before it's considered an infinite loop, make sure your middleware
can distinguish an error from a "renew". By default, mappersmith will allow 2 calls to "renew". This can
be configured with `configs.maxMiddlewareStackExecutionAllowed`. It's advised to keep this number low.
Example:
"renew" can only be invoked sometimes before it's considered an infinite loop, make sure your middleware can distinguish an error from a "renew". By default, mappersmith will allow 2 calls to "renew". This can be configured with `configs.maxMiddlewareStackExecutionAllowed`. It's advised to keep this number low. Example:

@@ -518,79 +527,65 @@ ```javascript

### <a name="global-middleware"></a> Global middleware
### <a name="configuring-middleware"></a> Configuring middleware
Middleware can also be defined globally, so new clients will automatically
include the defined middleware:
Middleware scope can be Global, Client or on Resource level. The order will be applied in this order: Resource level applies first, then Client level, and finally Global level. The subsections below describes the differences and how to use them correctly.
```javascript
import forge, { configs } from 'mappersmith'
#### <a name="resource-middleware"></a> Resource level middleware
configs.middleware = [MyMiddleware]
// all clients defined from now on will automatically include MyMiddleware
```
Resource middleware are configured using the key `middleware` in the resource level of manifest, example:
* Global middleware can be disabled for specific clients with the option `ignoreGlobalMiddleware`, e.g:
```javascript
forge({
ignoreGlobalMiddleware: true,
// + the usual configurations
const client = forge({
clientId: 'myClient',
resources: {
User: {
all: {
// only the `all` resource will include MyMiddleware:
middleware: [ MyMiddleware ],
path: '/users'
}
}
}
})
```
### <a name="context"></a> Context
#### <a name="client-middleware"></a> Client level middleware
Sometimes you may need to set data to be available to all your client's middleware. In this
case you can use the `setContext` helper, like so:
Client middleware are configured using the key `middleware` in the root level of manifest, example:
```javascript
import { setContext } from 'mappersmith'
const MyMiddleware = ({ context }) => ({
/* ... */
const client = forge({
clientId: 'myClient',
// all resources in this client will include MyMiddleware:
middleware: [ MyMiddleware ],
resources: {
User: {
all: { path: '/users' }
}
}
})
```
setContext({ some: 'data'})
#### <a name="global-middleware"></a> Global middleware
client.User.all()
// context: { some: 'data' }
```
Global middleware are configured on a config level, and all new clients will automatically
include the defined middleware, example:
This is specially useful when using mappermith coupled with back-end services.
For instance you could define a globally available correlation id middleware
like this:
```javascript
import forge, { configs, setContext } from 'mappersmith'
import express from 'express'
import forge, { configs } from 'mappersmith'
const CorrelationIdMiddleware = ({ context }) => ({
request(request) {
return request.enhance({
headers: {
'correlation-id': context.correlationId
}
})
}
})
configs.middleware = [MyMiddleware]
// all clients defined from now on will include MyMiddleware
```
configs.middleware = [CorrelationIdMiddleware]
* Global middleware can be disabled for specific clients with the option `ignoreGlobalMiddleware`, e.g:
const api = forge({ ... })
const app = express()
app.use((req, res, next) => {
setContext({
correlationId: req.headers['correlation-id']
})
```javascript
forge({
ignoreGlobalMiddleware: true,
// + the usual configurations
})
// Then, when calling `api.User.all()` in any handler it will include the
// `correlation-id` header automatically.
```
Note that setContext will merge the object provided with the current context
instead of replacing it.
### <a name="built-in-middleware"></a> Built-in middleware
### Built-in middleware
#### <a name="middleware-basic-auth"></a> BasicAuth

@@ -797,2 +792,42 @@

### <a name="middleware-legacy-notes"></a> Middleware legacy notes
This section is only relevant for mappersmith versions older than but not including `2.27.0`, when the method `prepareRequest` did not exist. This section describes how to create a middleware using older versions.
Since version `2.27.0` a new method was introduced: `prepareRequest`. This method aims to replace the `request` method in future versions of mappersmith, it has a similar signature as the `response` method and it is always async. All previous middleware are backward compatible, the default implementation of `prepareRequest` will call the `request` method if it exists.
The `request` method receives an instance of the [Request](https://github.com/tulios/mappersmith/blob/master/src/request.js) object and it must return a Request. The method `enhance` can be used to generate a new request based on the previous one.
Example:
```javascript
const MyMiddleware = () => ({
request(request) {
return request.enhance({
headers: { 'x-special-request': '->' }
})
},
response(next) {
return next().then((response) => response.enhance({
headers: { 'x-special-response': '<-' }
}))
}
})
```
The request phase can be asynchronous, just return a promise resolving a request. Example:
```javascript
const MyMiddleware = () => ({
request(request) {
return Promise.resolve(
request.enhance({
headers: { 'x-special-token': 'abc123' }
})
)
}
})
```
## <a name="testing-mappersmith"></a> Testing Mappersmith

@@ -1092,7 +1127,7 @@

The HTTP gatewayConfigs also provides several callback functions that will be called when various events are emitted on the `request`, `socket`, and `response` EventEmitters. These callbacks can be used as a hook into the event cycle to execute any custom code.
The HTTP gatewayConfigs also provides several callback functions that will be called when various events are emitted on the `request`, `socket`, and `response` EventEmitters. These callbacks can be used as a hook into the event cycle to execute any custom code.
For example, you may want to time how long each stage of the request or response takes.
These callback functions will receive the `requestParams` as the first argument.
The following callbacks are supported:
The following callbacks are supported:
* `onRequestWillStart` - This callback is not based on a event emitted by Node but is called just before the `request` method is called.

@@ -1160,2 +1195,60 @@ * `onRequestSocketAssigned` - Called when the 'socket' event is emitted on the `request`

### <a name="typescript"></a> TypeScript
__Mappersmith__ also supports TypeScript (>=3.5). In the following sections there are some common examples for using TypeScript with Mappersmith where it is not too obvious how typings are properly applied.
#### Create a middleware with TypeScript
To create a middleware using TypeScript you just have to add the `Middleware` interface to your middleware object:
```typescript
import { Middleware } from 'mappersmith'
const MyMiddleware: Middleware = () => ({
prepareRequest(next) {
return next().then(request => request.enhance({
headers: { 'x-special-request': '->' }
}))
},
response(next) {
return next().then(response => response.enhance({
headers: { 'x-special-response': '<-' }
}))
}
})
```
#### Use the `mockClient` with TypeScript
To use the `mockClient` with proper types you need to pass a typeof your client as generic to the `mockClient` function:
```typescript
import forge from 'mappersmith'
import { mockClient } from 'mappersmith/test'
const github = forge({
clientId: 'github',
host: 'https://status.github.com',
resources: {
Status: {
current: { path: '/api/status.json' },
messages: { path: '/api/messages.json' },
lastMessage: { path: '/api/last-message.json' },
},
},
})
const mock = mockClient<typeof github>(github)
.resource('Status')
.method('current')
.with({ id: 'abc' })
.response({ allUsers: [] })
.assertObject()
console.log(mock.mostRecentCall())
console.log(mock.callsCount())
console.log(mock.calls())
```
## <a name="development"></a> Development

@@ -1162,0 +1255,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc