### Install Dependencies for Building from Source Source: https://github.com/tulios/mappersmith/blob/master/README.md Install project dependencies using yarn before building from source. ```sh yarn ``` -------------------------------- ### Installing Optional Peer Dependencies for Richer Debug Output Source: https://github.com/tulios/mappersmith/blob/master/README.md Instructions for installing `diff` and `tty-table` to enhance the debug output with bordered tables and character-level diffs. ```sh npm install --save-dev diff tty-table # or yarn add --dev diff tty-table ``` -------------------------------- ### Run Integration Tests Source: https://github.com/tulios/mappersmith/blob/master/README.md Start the integration server and run browser integration tests. ```sh yarn integration-server & yarn test:browser:integration ``` -------------------------------- ### Install Optional Peer Dependencies Source: https://github.com/tulios/mappersmith/blob/master/CHANGELOG.md Install optional packages for enhanced mock error output, including character-level diffs and bordered tables. Mappersmith falls back to plain text if these are not installed. ```sh npm install --save-dev diff tty-table ``` -------------------------------- ### Enabling Enhanced Debugging with richMockErrors Source: https://github.com/tulios/mappersmith/blob/master/README.md Shows how to enable `richMockErrors` during `install` to get detailed debug tables on mock mismatches. ```javascript import { install, uninstall } from 'mappersmith/test' beforeEach(() => install({ richMockErrors: true })) afterEach(() => uninstall()) ``` -------------------------------- ### Basic Mocking with Jasmine Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates how to set up a mock client using Jasmine for testing. It mocks a GET request to retrieve all users and asserts the response data. ```javascript import { forge } from 'mappersmith' import { install, uninstall, mockClient } from 'mappersmith/test' describe('Feature', () => { beforeEach(() => install()) afterEach(() => uninstall()) it('works', (done) => { const myManifest = {} // Let's assume I have my manifest here const client = forge(myManifest) mockClient(client) .resource('User') .method('all') .response({ allUsers: [{id: 1}] }) // now if I call my resource method, it should return my mock response client.User .all() .then((response) => expect(response.data()).toEqual({ allUsers: [{id: 1}] })) .then(done) }) }) ``` -------------------------------- ### Using Match Functions with mockClient Source: https://github.com/tulios/mappersmith/blob/master/README.md Example of using a match function for the request body with `mockClient`. Note that `mockClient` only accepts match functions for body and params. ```javascript mockClient(client) .with({ id: 'abc', headers: { 'x-special': 'value'}, body: (body) => body === 'something' }) ``` -------------------------------- ### Mocking API Requests with mockRequest (POST Example) Source: https://github.com/tulios/mappersmith/blob/master/README.md A more complete example of using mockRequest to simulate a POST request with a specific status, body, and headers in the response. ```javascript // ... mockRequest({ method: 'post', url: 'http://example.org/blogs', body: 'param1=A¶m2=B', // request body response: { status: 503, body: { error: true }, headers: { 'x-header': 'nope' } } }) // ... ``` -------------------------------- ### Install Mappersmith with npm Source: https://github.com/tulios/mappersmith/blob/master/README.md Use npm to install the Mappersmith library as a project dependency. ```sh npm install mappersmith --save ``` -------------------------------- ### Install and Uninstall Mappersmith Test Utilities (Jasmine) Source: https://github.com/tulios/mappersmith/blob/master/README.md Set up and tear down the Mappersmith test environment using `install` and `uninstall`. This is essential for mocking Mappersmith clients and requests within your test suite. ```javascript import { install, uninstall } from 'mappersmith/test' describe('Feature', () => { beforeEach(() => install()) afterEach(() => uninstall()) }) ``` -------------------------------- ### Mocking API Requests with mockRequest (Jasmine Example) Source: https://github.com/tulios/mappersmith/blob/master/README.md Use mockRequest to simulate API responses within your tests. This example demonstrates setting up a mock for a GET request and asserting the response data. ```javascript import { forge } from 'mappersmith' import { install, uninstall, mockRequest } from 'mappersmith/test' describe('Feature', () => { beforeEach(() => install()) afterEach(() => uninstall()) it('works', (done) => { mockRequest({ method: 'get', url: 'https://my.api.com/users?someParam=true', response: { body: { allUsers: [{id: 1}] } } }) const myManifest = {} // Let's assume I have my manifest here const client = forge(myManifest) client.User .all() .then((response) => expect(response.data()).toEqual({ allUsers: [{id: 1}] })) .then(done) }) }) ``` -------------------------------- ### Creating Middleware with Optional Arguments Source: https://github.com/tulios/mappersmith/blob/master/README.md Middleware can optionally receive resourceName, resourceMethod, context, clientId, and mockRequest. This example shows the basic structure. ```javascript const MyMiddleware = ({ resourceName, resourceMethod, context, clientId, mockRequest }) => ({ /* ... */ }) client.User.all() // resourceName: 'User' // resourceMethod: 'all' // clientId: 'myClient' // context: {} // mockRequest: false ``` -------------------------------- ### HTTP Gateway Event Callbacks for Timing Source: https://github.com/tulios/mappersmith/blob/master/README.md Utilize HTTP gateway callbacks like `onRequestWillStart` and `onResponseReadable` to hook into the request lifecycle. This example measures the time to the first byte. ```javascript let startTime configs.gatewayConfigs.HTTP = { onRequestWillStart() { startTime = Date.now() }, onResponseReadable() { console.log('Time to first byte', Date.now() - startTime) } } ``` -------------------------------- ### Use Default Parameters for API Method Source: https://github.com/tulios/mappersmith/blob/master/README.md Example of calling a method (`byGroup`) that has a default parameter (`group: 'general'`) configured, which is used when no parameter is explicitly provided. ```javascript client.User.byGroup() // https://my.api.com/users/groups/general ``` -------------------------------- ### Install Mappersmith with yarn Source: https://github.com/tulios/mappersmith/blob/master/README.md Use yarn to add Mappersmith to your project. ```sh yarn add mappersmith ``` -------------------------------- ### Configure HTTP Gateway with Custom Agent Source: https://github.com/tulios/mappersmith/blob/master/README.md Customize the Node.js HTTP/HTTPS module by providing a `configure` callback to `configs.gatewayConfigs.HTTP`. This example shows how to set a custom HTTPS agent with certificates. ```javascript import fs from 'fs' import https from 'https' import { configs } from 'mappersmith' const key = fs.readFileSync('/path/to/my-key.pem') const cert = fs.readFileSync('/path/to/my-cert.pem') configs.gatewayConfigs.HTTP = { configure() { return { agent: new https.Agent({ key, cert }) } } } ``` -------------------------------- ### Enable Rich Mock Errors Per Install Source: https://github.com/tulios/mappersmith/blob/master/CHANGELOG.md Configure Mappersmith to display detailed mock error output for a specific test installation. This overrides the global configuration. ```javascript import { install } from 'mappersmith/test' beforeEach(() => install({ richMockErrors: true })) ``` -------------------------------- ### Asserting Mocked Requests with assertObject Source: https://github.com/tulios/mappersmith/blob/master/README.md Shows how to use `assertObject()` to retrieve and inspect requests made to the mock client. It exposes methods to get all calls, the most recent call, and the total count of calls. ```javascript const mock = mockClient(client) .resource('User') .method('all') .response({ allUsers: [{id: 1}] }) .assertObject() console.log(mock.mostRecentCall()) console.log(mock.callsCount()) console.log(mock.calls()) ``` -------------------------------- ### Disabling Global Middleware for a Client Source: https://github.com/tulios/mappersmith/blob/master/README.md Example of how to disable global middleware for a specific client instance by setting `ignoreGlobalMiddleware` to true. ```javascript forge({ ignoreGlobalMiddleware: true, // + the usual configurations }) ``` -------------------------------- ### Create a Mappersmith Client for GitHub API Source: https://github.com/tulios/mappersmith/blob/master/README.md Example of creating a Mappersmith client to interact with the GitHub Status API. It configures the gateway to use Fetch and defines resources for status, summary, and components. ```typescript import forge, { configs } from "mappersmith" import { Fetch } from "mappersmith/gateway/fetch" configs.gateway = Fetch; const github = forge({ clientId: "github", host: "https://www.githubstatus.com", resources: { Status: { current: { path: "/api/v2/status.json" }, summary: { path: "/api/v2/summary.json" }, components: { path: "/api/v2/components.json" }, }, }, }); github.Status.current().then((response) => { console.log(`summary`, response.data()); }); ``` -------------------------------- ### Custom Promise Implementation Source: https://github.com/tulios/mappersmith/blob/master/README.md Define a custom Promise implementation for Mappersmith when the global Promise is unavailable. This example uses RSVP.js. ```javascript import RSVP from 'rsvp' import { configs } from 'mappersmith' configs.Promise = RSVP.Promise ``` -------------------------------- ### Call API Method Without Parameters Source: https://github.com/tulios/mappersmith/blob/master/README.md Example of calling a Mappersmith API method that does not require any parameters. Handles both successful responses and errors. ```javascript client.User .all() // https://my.api.com/users .then((response) => console.log(response.data())) .catch((response) => console.error(response.data())) ``` -------------------------------- ### Configure Automatic Request Retries Source: https://github.com/tulios/mappersmith/blob/master/README.md Automatically retries GET requests with exponential backoff and randomization. Configurable retry count, time, and retry validation logic. Includes retry count and time in response headers. ```javascript import { RetryMiddleware } from 'mappersmith/middleware' const retryConfigs = { headerRetryCount: 'X-Mappersmith-Retry-Count', headerRetryTime: 'X-Mappersmith-Retry-Time', maxRetryTimeInSecs: 5, initialRetryTimeInSecs: 0.1, factor: 0.2, // randomization factor multiplier: 2, // exponential factor retries: 5, // max retries validateRetry: (response) => response.responseStatus >= 500 // a function that returns true if the request should be retried } const client = forge({ middleware: [ Retry(retryConfigs) ], /* ... */ }) ``` -------------------------------- ### Prepare Project for Packaging Source: https://github.com/tulios/mappersmith/blob/master/README.md Build the project and prepare the dist/ folder for local linking. ```sh yarn publish:prepare ``` -------------------------------- ### Run All Tests Source: https://github.com/tulios/mappersmith/blob/master/README.md Execute all unit and integration tests for the project. ```sh yarn test ``` -------------------------------- ### Configure Basic Authentication Source: https://github.com/tulios/mappersmith/blob/master/README.md Use the `auth` parameter with `username` and `password` to set up basic authentication. This automatically adds an `Authorization` header. ```javascript client.User.all({ auth: { username: 'bob', password: 'bob' } }) ``` -------------------------------- ### Configure Alternative Host for Resource Source: https://github.com/tulios/mappersmith/blob/master/README.md Use the 'host' key to configure a new host for a resource method. This is useful when a resource method resides in another host. ```javascript // ... { all: { path: '/users', host: 'http://old-api.com' } } // ... ``` -------------------------------- ### Publish to npm Source: https://github.com/tulios/mappersmith/blob/master/README.md Navigate to the dist directory, remove any tarballs, and publish to npm. ```sh cd dist/ rm *.tgz # do not accidentally publish any tarball npm publish ``` -------------------------------- ### Run Browser Unit Tests Source: https://github.com/tulios/mappersmith/blob/master/README.md Execute unit tests in a browser environment. ```sh yarn test:browser ``` -------------------------------- ### Global Middleware Configuration Source: https://github.com/tulios/mappersmith/blob/master/README.md Configure middleware to apply to all clients created subsequently. This middleware is applied last. ```javascript import { forge, configs } from 'mappersmith' configs.middleware = [MyMiddleware] // all clients defined from now on will include MyMiddleware ``` -------------------------------- ### Mocking with Request Arguments and Headers Source: https://github.com/tulios/mappersmith/blob/master/README.md Illustrates how to mock a request that includes specific arguments (like ID) and custom headers. The `with` method is used to define these parameters. ```javascript mockClient(client) .with({ id: 'abc', headers: { 'x-special': 'value'}, body: { payload: 1 } }) ``` -------------------------------- ### Using Match Functions with mockRequest Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates using match functions with mockRequest to assert request URL and body. `m.stringMatching` and `m.anything` are used here. ```javascript import { m } from 'mappersmith/test' mockRequest({ method: 'post', url: m.stringMatching(/example\.org/), body: m.anything(), response: { body: { allUsers: [{id: 1}] } } }) ``` -------------------------------- ### Build Mappersmith from Source Source: https://github.com/tulios/mappersmith/blob/master/README.md Build the Mappersmith library from source code. Use 'yarn release' for a minified version. ```sh yarn build yarn release # for minified version ``` -------------------------------- ### Configure Fetch Gateway Source: https://github.com/tulios/mappersmith/blob/master/README.md Set `configs.gateway` to `FetchGateway` to enable the Fetch API as the transport. Additional configurations like `credentials` can be set in `configs.gatewayConfigs.Fetch`. ```javascript import { FetchGateway } from 'mappersmith/gateway' import { configs } from 'mappersmith' configs.gateway = FetchGateway // Extra configurations, if needed configs.gatewayConfigs.Fetch = { credentials: 'same-origin' } ``` -------------------------------- ### Client Level Middleware Configuration Source: https://github.com/tulios/mappersmith/blob/master/README.md Configure middleware to apply to all resources within a specific client. This middleware is applied after resource-level middleware. ```javascript const client = forge({ clientId: 'myClient', // all resources in this client will include MyMiddleware: middleware: [ MyMiddleware ], resources: { User: { all: { path: '/users' } } } }) ``` -------------------------------- ### Run Node Integration Tests Source: https://github.com/tulios/mappersmith/blob/master/README.md Execute integration tests in a Node.js environment. ```sh yarn test:node:integration ``` -------------------------------- ### Run Node Unit Tests Source: https://github.com/tulios/mappersmith/blob/master/README.md Execute unit tests in a Node.js environment. ```sh yarn test:node ``` -------------------------------- ### Configure XHR Gateway for Browser Source: https://github.com/tulios/mappersmith/blob/master/README.md Customize the XMLHttpRequest object when running in the browser. Set `withCredentials` to true and provide a `configure` callback to handle events like `ontimeout`. ```javascript import { configs } from 'mappersmith' configs.gatewayConfigs.XHR = { withCredentials: true, configure(xhr) { xhr.ontimeout = () => console.error('timeout!') } } ``` -------------------------------- ### Send Query Parameters to API Method Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates how to send parameters to an API method, which will be appended as query string parameters if they do not match a path segment pattern. ```javascript client.User.all({ active: true }) // https://my.api.com/users?active=true ``` -------------------------------- ### Configure Custom Gateway Source: https://github.com/tulios/mappersmith/blob/master/README.md Import the configs object and assign your custom gateway to `configs.gateway`. This is useful for creating or using alternative transport mechanisms. ```javascript import { configs } from 'mappersmith' configs.gateway = MyGateway ``` -------------------------------- ### Configure Host via Custom Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If 'host' is not a suitable parameter, configure it using 'hostAttr' and a custom attribute name. The value of this attribute will be used as the host. ```javascript // ... { all: { path: '/users', hostAttr: 'baseUrl' } } // ... client.User.all({ baseUrl: 'http://very-old-api.com' }) // http://very-old-api.com/users ``` -------------------------------- ### Middleware with Context Passing (Part 1) Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates passing data between middleware using request context. This middleware adds a message to the request context. ```javascript const MyMiddlewareOne = () => ({ async prepareRequest(next) { const request = await next().then(request => request.enhance({}, { message: 'hello from mw1' })) } }) ``` -------------------------------- ### Handle Binary Data Response Source: https://github.com/tulios/mappersmith/blob/master/README.md Add the 'binary: true' key to a resource configuration when the data is in binary form. The response will be a Buffer (NodeJS) or Blob (browser). ```javascript // ... { report: { path: '/report.pdf', binary: true } } // ... ``` -------------------------------- ### Configure Basic Authentication Source: https://github.com/tulios/mappersmith/blob/master/README.md Automatically configures requests with basic authentication. The default can be overridden with an explicit auth parameter. ```javascript import { BasicAuthMiddleware } from 'mappersmith/middleware' const BasicAuth = BasicAuthMiddleware({ username: 'bob', password: 'bob' }) const client = forge({ middleware: [ BasicAuth ], /* ... */ }) client.User.all() // => header: "Authorization: Basic Ym9iOmJvYg==" ``` ```javascript client.User.all({ auth: { username: 'bill', password: 'bill' } }) // auth will be { username: 'bill', password: 'bill' } instead of { username: 'bob', password: 'bob' } ``` -------------------------------- ### Version and Changelog Update Source: https://github.com/tulios/mappersmith/blob/master/README.md Update the package version and generate an updated CHANGELOG.md. ```sh yarn changeset version yarn copy:version:src ``` -------------------------------- ### Dynamic Response Generation with Functions Source: https://github.com/tulios/mappersmith/blob/master/README.md Illustrates how `response` and `status` can accept functions to dynamically generate responses or status codes based on request details or call count. This is useful for simulating varying responses over multiple calls. ```javascript const generateResponse = () => { return (request, mock) => mock.callsCount() === 0 ? {} : { user: { id: 1 } } } const mock = mockClient(client) .resource('User') .method('create') .response(generateResponse()) ``` -------------------------------- ### Log Requests and Responses Source: https://github.com/tulios/mappersmith/blob/master/README.md Logs all requests and responses, which can be useful in development mode. ```javascript import { LogMiddleware } from 'mappersmith/middleware' const client = forge({ middleware: [ LogMiddleware ], /* ... */ }) ``` -------------------------------- ### Middleware with Context Passing (Part 2) Source: https://github.com/tulios/mappersmith/blob/master/README.md This middleware retrieves data from the request context set by a previous middleware. It logs the 'message' passed from `MyMiddlewareOne`. ```javascript const MyMiddlewareTwo = () => ({ async prepareRequest(next) { const request = await next() const { message } = request.getContext() // Logs: "hello from mw1" console.log(message) return request } }) ``` -------------------------------- ### Mocking with Matchers for Arguments and Body Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates using matchers from `mappersmith/test` to assert request arguments and body content. This allows for flexible matching of request details. ```javascript import { m } from 'mappersmith/test' mockClient(client) .with({ id: 'abc', name: m.stringContaining('john'), headers: { 'x-special': 'value'}, body: m.stringMatching(/token=[^&]+&other=true$/) }) ``` -------------------------------- ### Require Mappersmith in CommonJS Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates how to import Mappersmith and its configurations using `require` for CommonJS environments. ```javascript const forge = require("mappersmith").default; const { configs } = require("mappersmith"); const FetchGateway = require("mappersmith/gateway/fetch").default; ``` -------------------------------- ### Available Match Functions in Mappersmith Source: https://github.com/tulios/mappersmith/blob/master/README.md Lists the built-in match functions available for use with `mockClient` and `mockRequest`. These functions help in asserting request details. ```javascript import { m } from 'mappersmith/test' m.stringMatching(/something/) // accepts a regexp m.stringContaining('some-string') // accepts a string m.anything() m.uuid4() ``` -------------------------------- ### Tag and Push Release Source: https://github.com/tulios/mappersmith/blob/master/README.md Tag the current commit with the release version and push the tags to the remote repository. ```sh git tag 2.43.0 git push --tags ``` -------------------------------- ### Configure Path via Custom Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If 'path' is not a suitable parameter, configure it using 'pathAttr' and a custom attribute name. The value of this attribute will be used as the path. ```javascript // ... { all: { path: '/users', pathAttr: '__path' } } // ... client.User.all({ __path: '/people' }) ``` -------------------------------- ### Link Local Package Source: https://github.com/tulios/mappersmith/blob/master/README.md Link the local mappersmith dist/ folder into another project for testing. ```sh yarn link ../mappersmith/dist ``` -------------------------------- ### Configure Custom Parameter Encoding Source: https://github.com/tulios/mappersmith/blob/master/README.md Shows how to set a custom `parameterEncoder` function when initializing the Mappersmith client to handle specific encoding requirements for query parameters. ```javascript const client = forge({ host: 'https://custom-host.com', parameterEncoder: yourEncodingFunction, resources: { ... } }) ``` -------------------------------- ### Resource Level Middleware Configuration Source: https://github.com/tulios/mappersmith/blob/master/README.md Configure middleware to apply only to a specific resource's operations. This middleware is applied first. ```javascript const client = forge({ clientId: 'myClient', resources: { User: { all: { // only the `all` resource will include MyMiddleware: middleware: [ MyMiddleware ], path: '/users' } } } }) ``` -------------------------------- ### Assign Custom Fetch Implementation Source: https://github.com/tulios/mappersmith/blob/master/README.md Assign a custom fetch function to `configs.fetch` if Mappersmith needs to use a specific or polyfilled fetch implementation. ```javascript import { configs } from 'mappersmith' configs.fetch = fetchFunction ``` -------------------------------- ### Add Response Headers for Duration Source: https://github.com/tulios/mappersmith/blob/master/README.md Automatically adds `X-Started-At`, `X-Ended-At`, and `X-Duration` headers to the response. ```javascript import { DurationMiddleware } from 'mappersmith/middleware' const client = forge({ middleware: [ DurationMiddleware ], /* ... */ }) client.User.all({ body: { name: 'bob' } }) // => headers: "X-Started-At=1492529128453;X-Ended-At=1492529128473;X-Duration=20" ``` -------------------------------- ### Implement Global Error Handling Source: https://github.com/tulios/mappersmith/blob/master/README.md Provides a catch-all function for all requests. If the handler returns `true`, it prevents the original promise from continuing. The default error handler can be set globally. ```javascript import { GlobalErrorHandlerMiddleware, setErrorHandler } from 'mappersmith/middleware' setErrorHandler((response) => { console.log('global error handler') return response.status() === 500 }) const client = forge({ middleware: [ GlobalErrorHandlerMiddleware ], /* ... */ }) client.User .all() .catch((response) => console.error('my error')) // If status != 500 // output: // -> global error handler // -> my error // IF status == 500 // output: // -> global error handler ``` -------------------------------- ### Create an Asynchronous Mappersmith Middleware Request Source: https://github.com/tulios/mappersmith/blob/master/README.md This middleware demonstrates how to handle asynchronous operations in the `request` method. It returns a Promise that resolves with an enhanced request, allowing for operations like fetching tokens before sending the request. ```javascript const MyMiddleware = () => ({ request(request) { return Promise.resolve( request.enhance({ headers: { 'x-special-token': 'abc123' } }) ) } }) ``` -------------------------------- ### Mocking a Failure Response Source: https://github.com/tulios/mappersmith/blob/master/README.md Shows how to mock a failed API request by specifying an error status code and response body. This is useful for testing error handling. ```javascript mockClient(client) .resource('User') .method('byId') .with({ id: 'ABC' }) .status(422) .response({ error: 'invalid ID' }) ``` -------------------------------- ### Configuring Max Middleware Stack Execution Source: https://github.com/tulios/mappersmith/blob/master/README.md Configure the maximum number of times the middleware stack can be executed to prevent infinite loops. The default is 2. ```javascript import { configs } from 'mappersmith' configs.maxMiddlewareStackExecutionAllowed = 3 ``` -------------------------------- ### Using abort in Middleware Source: https://github.com/tulios/mappersmith/blob/master/README.md The abort function can be used in the prepareRequest phase to stop middleware execution early and throw a custom error. ```javascript const MyMiddleware = () => { prepareRequest(next, abort) { return next().then(request => request.header('x-special') ? response : abort(new Error('"x-special" must be set!')) ) } } ``` -------------------------------- ### Accessing Mock Call Information Source: https://github.com/tulios/mappersmith/blob/master/README.md Shows how to use the assert object returned by mockRequest to inspect call details like the most recent call, call count, and all calls. ```javascript const mock = mockRequest({ method: 'get', url: 'https://my.api.com/users?someParam=true', response: { body: { allUsers: [{id: 1}] } } }) console.log(mock.mostRecentCall()) console.log(mock.callsCount()) console.log(mock.calls()) ``` -------------------------------- ### Asserting Mocked Requests with assertObjectAsync Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates using `assertObjectAsync()` for mocking scenarios involving asynchronous middleware. It provides the same assertion methods as `assertObject()` but handles asynchronous operations. ```javascript const mock = await mockClient(client) .resource('User') .method('all') .response({ allUsers: [{id: 1}] }) .assertObjectAsync() console.log(mock.mostRecentCall()) console.log(mock.callsCount()) console.log(mock.calls()) ``` -------------------------------- ### Override Default Parameters for API Method Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates how to override a default parameter (`group`) when calling an API method by providing a new value. ```javascript client.User.byGroup({ group: 'cool' }) // https://my.api.com/users/groups/cool ``` -------------------------------- ### Configure Custom Auth Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If `auth` is not a valid parameter name, use `authAttr` to specify a custom attribute for authentication credentials. ```javascript // ... { all: { path: '/users', authAttr: 'secret' } } // ... client.User.all({ secret: { username: 'bob', password: 'bob' } }) ``` -------------------------------- ### Define Request Headers Source: https://github.com/tulios/mappersmith/blob/master/README.md Use the `headers` parameter to include custom headers in your request. This is useful for authentication tokens or content types. ```javascript client.User.all({ headers: { Authorization: 'token 1d1435k' } }) ``` -------------------------------- ### Create Response Middleware Source: https://github.com/tulios/mappersmith/blob/master/README.md Define a middleware to modify incoming responses. Use `response.enhance` to add headers or other properties. This middleware adds a custom header 'x-special-response'. ```javascript const MyMiddleware = () => ({ response(next) { return next().then((response) => response.enhance({ headers: { 'x-special-response': '<-' } })) } }) ``` -------------------------------- ### Configure Request Timeout Source: https://github.com/tulios/mappersmith/blob/master/README.md Automatically configures requests with a default timeout. The default timeout can be overridden with an explicit timeout parameter. ```javascript import { TimeoutMiddleware } from 'mappersmith/middleware' const Timeout = TimeoutMiddleware(500) const client = forge({ middleware: [ Timeout ], /* ... */ }) client.User.all() ``` ```javascript client.User.all({ timeout: 100 }) // timeout will be 100 instead of 500 ``` -------------------------------- ### Configure API Resources with Dynamic Paths and Methods Source: https://github.com/tulios/mappersmith/blob/master/README.md Defines Mappersmith resources with various configurations including dynamic path segments, default parameters, custom HTTP methods, and query parameter aliasing. ```javascript const client = forge({ resources: { User: { all: { path: '/users' }, // {id} is a dynamic segment and will be replaced by the parameter "id" // when called byId: { path: '/users/{id}' }, // {group} is also a dynamic segment but it has default value "general" byGroup: { path: '/users/groups/{group}', params: { group: 'general' } }, // {market?} is an optional dynamic segment. If called without a value // for the "market" parameter, {market?} will be removed from the path // including any prefixing "/". // This example: '/{market?}/users' => '/users' count: { path: '/{market?}/users' } } }, Blog: { // The HTTP method can be configured through the `method` key, and a default // header "X-Special-Header" has been configured for this resource create: { method: 'post', path: '/blogs', headers: { 'X-Special-Header': 'value' } }, // There are no restrictions for dynamic segments and HTTP methods addComment: { method: 'put', path: '/blogs/{id}/comment' }, // `queryParamAlias` will map parameter names to their alias when // constructing the query string bySubject: { path: '/blogs', queryParamAlias: { subjectId: 'subject_id' } }, // `path` is a function to map passed params to a custom path byDate: { path: ({date}) => `${date.getYear()}/${date.getMonth()}/${date.getDate()}` } } } }) ``` -------------------------------- ### Checking for Unused Mocks in Tests Source: https://github.com/tulios/mappersmith/blob/master/README.md Demonstrates how to use `unusedMocks` within test teardown to ensure all mocks are consumed, failing the test if any remain unused. ```javascript import { install, uninstall, unusedMocks } from 'mappersmith/test' describe('Feature', () => { beforeEach(() => install()) afterEach(() => { const unusedMocksCount = unusedMocks() uninstall() if (unusedMocksCount > 0) { throw new Error(`There are ${unusedMocksCount} unused mocks`) // fail the test } }) }) ``` -------------------------------- ### Create a Mappersmith Middleware with Request and Response Enhancements Source: https://github.com/tulios/mappersmith/blob/master/README.md Use this middleware to add custom headers to both outgoing requests and incoming responses. The `request` method modifies the outgoing request, and the `response` method modifies the incoming response. ```javascript const MyMiddleware = () => ({ request(request) { return request.enhance({ headers: { 'x-special-request': '->' } }) }, response(next) { return next().then((response) => response.enhance({ headers: { 'x-special-response': '<-' } })) } }) ``` -------------------------------- ### Configure CSRF Protection Source: https://github.com/tulios/mappersmith/blob/master/README.md Automatically configures requests by adding a header with the value of a cookie if it exists. The cookie and header names can be customized. ```javascript import { CsrfMiddleware } from 'mappersmith/middleware' const client = forge({ middleware: [ CsrfMiddleware('csrfToken', 'x-csrf-token') ], /* ... */ }) client.User.all() ``` -------------------------------- ### Enable Host Override with allowResourceHostOverride Source: https://github.com/tulios/mappersmith/blob/master/README.md Since version 2.34.0, enable host overrides by setting 'allowResourceHostOverride: true' in the forge configuration. This is required when using 'host' for resource-specific hosts. ```javascript const client = forge({ host: 'https://new-host.com', allowResourceHostOverride: true, resources: { User: { all: { path: '/users', host: 'https://old-host.com' } } } }) ``` -------------------------------- ### Use Mappersmith mockRequest with TypeScript Source: https://github.com/tulios/mappersmith/blob/master/README.md Configure a mock request using `mockRequest` with TypeScript. This allows for precise definition of request methods, URLs, and expected responses, including status codes and bodies. ```typescript const mock = mockRequest({ method: 'get', url: 'https://status.github.com/api/status.json', response: { status: 503, body: { error: true }, } }) console.log(mock.mostRecentCall()) console.log(mock.callsCount()) console.log(mock.calls()) ``` -------------------------------- ### Handle Missing Required Parameters Source: https://github.com/tulios/mappersmith/blob/master/README.md Illustrates the error raised by Mappersmith when a required parameter for a method is not provided during the call. ```javascript client.User.byId(/* missing id */) // throw '[Mappersmith] required parameter missing (id), "/users/{id}" cannot be resolved' ``` -------------------------------- ### Set Request Timeout Source: https://github.com/tulios/mappersmith/blob/master/README.md Use the `timeout` parameter to specify the request timeout in milliseconds. This prevents requests from hanging indefinitely. ```javascript client.User.all({ timeout: 1000 }) ``` -------------------------------- ### Alias Query Parameters Source: https://github.com/tulios/mappersmith/blob/master/README.md Use `queryParamAlias` to map code's camelCase parameters to API's snake_case parameters. This mapping is not applied to URL path parameters. ```javascript client.Blog.all({ subjectId: 10 }) // https://my.api.com/blogs?subject_id=10 ``` -------------------------------- ### Overwrite Host for Specific Call Source: https://github.com/tulios/mappersmith/blob/master/README.md Overwrite the host for a specific API call using the 'host' parameter. This allows for dynamic host configuration per request. ```javascript // ... { all: { path: '/users', host: 'http://old-api.com' } } // ... client.User.all({ host: 'http://very-old-api.com' }) // http://very-old-api.com/users ``` -------------------------------- ### Add Support for Abort Signals Source: https://github.com/tulios/mappersmith/blob/master/CHANGELOG.md Integrate AbortSignal with Mappersmith gateway APIs (Fetch, HTTP, XHR) to cancel asynchronous operations. Use an AbortController to manage the signal. ```javascript const abortController = new AbortController() // Start a long running task... client.Bitcoin.mine({ signal: abortController.signal }) // This takes too long, abort! abortController.abort() ``` -------------------------------- ### Configure Custom Body Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If `body` is not a valid parameter name, use `bodyAttr` to specify a custom attribute for the request body. ```javascript // ... { create: { method: 'post', path: '/blogs', bodyAttr: 'payload' } } // ... client.Blog.create({ payload: { title: 'Title', tags: ['party', 'launch'] } }) ``` -------------------------------- ### Using mockRequest in Middleware Source: https://github.com/tulios/mappersmith/blob/master/README.md The mockRequest flag is truthy when middleware is executed during mock definition matching. Use it to prevent middleware from being called multiple times unnecessarily. ```javascript const MyMiddleware = ({ mockRequest }) => { prepareRequest(next) { if (mockRequest) { ... // executed once for each mocked client that utilises the middleware } if (!mockRequest) { ... // executed once for the matching mock definition } return next().then(request => request) } } ``` -------------------------------- ### Configure Custom Headers Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If `headers` is not a valid parameter name, use `headersAttr` to specify a custom attribute for request headers. ```javascript // ... { all: { path: '/users', headersAttr: 'h' } } // ... client.User.all({ h: { Authorization: 'token 1d1435k' } }) ``` -------------------------------- ### Create Request Middleware Source: https://github.com/tulios/mappersmith/blob/master/README.md Define a middleware to modify outgoing requests. Use `request.enhance` to add headers or other properties. This middleware adds a custom header 'x-special-request'. ```javascript const MyMiddleware = () => ({ prepareRequest(next) { return next().then(request => request.enhance({ headers: { 'x-special-request': '->' } })) } }) ``` -------------------------------- ### Create a Mappersmith Middleware with TypeScript Source: https://github.com/tulios/mappersmith/blob/master/README.md Define a custom middleware for Mappersmith by implementing the `Middleware` interface. This middleware adds custom headers to requests and responses. ```typescript import type { 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': '<-' } })) } }) ``` -------------------------------- ### Configure Custom Abort Signal Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If `signal` is not a valid parameter name, use `signalAttr` to specify a custom attribute for the `AbortSignal` object. ```javascript // ... { all: { path: '/users', signalAttr: 'abortSignal' } } // ... const abortController = new AbortController() client.User.all({ abortSignal: abortController.signal }) // abort! abortController.abort() ``` -------------------------------- ### Use AbortSignal for Request Cancellation Source: https://github.com/tulios/mappersmith/blob/master/README.md Pass an `AbortSignal` object via the `signal` parameter to allow cancellation of asynchronous requests. Call `abortController.abort()` to cancel. ```javascript const abortController = new AbortController() client.User.all({ signal: abortController.signal }) // abort! abortController.abort() ``` -------------------------------- ### Send Request Body Source: https://github.com/tulios/mappersmith/blob/master/README.md Use the `body` parameter to send data in the request body for POST, PUT, or PATCH methods. By default, it creates a URL-encoded string. ```javascript client.Blog.create({ body: { title: 'Title', tags: ['party', 'launch'] } }) ``` -------------------------------- ### Using renew in Middleware for Token Refresh Source: https://github.com/tulios/mappersmith/blob/master/README.md The renew function in the response phase allows rerunning the middleware stack, useful for actions like refreshing an expired access token. ```javascript const AccessTokenMiddleware = () => { // maybe this is stored elsewhere, here for simplicity let accessToken = null return () => ({ request(request) { return Promise .resolve(accessToken) .then((token) => token || fetchAccessToken()) .then((token) => { accessToken = token return request.enhance({ headers: { 'Authorization': `Token ${token}` } }) }) }, response(next, renew) { return next().catch(response => { if (response.status() === 401) { // token expired accessToken = null return renew() } return next() }) } }) } ``` ```javascript const AccessToken = AccessTokenMiddleware() const client = forge({ // ... middleware: [ AccessToken ], // ... }) ``` -------------------------------- ### Enable Rich Mock Errors Globally Source: https://github.com/tulios/mappersmith/blob/master/CHANGELOG.md Configure Mappersmith to display detailed mock error output globally for all tests. This helps in debugging by showing outgoing requests and ranked mocks. ```javascript import { configs } from 'mappersmith' configs.test.richMockErrors = true ``` -------------------------------- ### Overwrite Path for Specific Call Source: https://github.com/tulios/mappersmith/blob/master/README.md Overwrite the path for a specific API call using the 'path' parameter. This allows for dynamic path configuration per request. ```javascript // ... { all: { path: '/users' } } // ... client.User.all({ path: '/people' }) ``` -------------------------------- ### Configure Custom Timeout Attribute Source: https://github.com/tulios/mappersmith/blob/master/README.md If `timeout` is not a valid parameter name, use `timeoutAttr` to specify a custom attribute for the timeout value. ```javascript // ... { all: { path: '/users', timeoutAttr: 'maxWait' } } // ... client.User.all({ maxWait: 500 }) ``` -------------------------------- ### Using request Argument in Response Phase Source: https://github.com/tulios/mappersmith/blob/master/README.md The request argument in the response phase provides access to the final request object after all middleware has been executed. This is useful for accessing request details like timeout. ```javascript const CircuitBreakerMiddleware = () => { return () => ({ response(next, renew, request) { // Creating the breaker required some information available only on `request`: const breaker = createBreaker({ ..., timeout: request.timeout }) // Note: `next` is still wrapped: return breaker.invoke(createExecutor(next)) } }) } ``` -------------------------------- ### Encode Request Body as JSON Source: https://github.com/tulios/mappersmith/blob/master/README.md Automatically encodes request bodies as JSON and sets the `Content-Type` header to `application/json;charset=utf-8`. ```javascript import { EncodeJsonMiddleware } from 'mappersmith/middleware' const client = forge({ middleware: [ EncodeJsonMiddleware ], /* ... */ }) client.User.all({ body: { name: 'bob' } }) // => body: {"name":"bob"} // => header: "Content-Type=application/json;charset=utf-8" ``` -------------------------------- ### Use Mappersmith mockClient with TypeScript Source: https://github.com/tulios/mappersmith/blob/master/README.md Utilize the `mockClient` function with TypeScript by passing the client's type as a generic parameter. This ensures type safety when mocking client interactions. ```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(github) .resource('Status') .method('current') .with({ id: 'abc' }) .response({ allUsers: [] }) .assertObject() console.log(mock.mostRecentCall()) console.log(mock.callsCount()) console.log(mock.calls()) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.