UNPKG

request-mocking-protocol

Version:
130 lines 4.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResponseBuilder = void 0; /** * Response builder class. */ const node_http_1 = require("node:http"); const utils_1 = require("./utils"); const placeholders_1 = require("./placeholders"); const request_patcher_1 = require("../request-patcher"); class ResponseBuilder { matchResult; callbacks; status = 200; statusText = 'OK'; headers = new Headers(); body = null; constructor(matchResult, callbacks) { this.matchResult = matchResult; this.callbacks = callbacks; } get resSchema() { return this.matchResult.mockSchema.resSchema; } get params() { return this.matchResult.params; } get req() { return this.matchResult.req; } async build() { if (this.needsRealRequest()) { await this.setPatchedResponse(); } else { this.setStaticResponse(); } await this.wait(); return { status: this.status, statusText: this.statusText, headers: this.headers, body: this.body, }; } needsRealRequest() { return this.resSchema.request || this.resSchema.bodyPatch; } async setPatchedResponse() { const res = await this.sendRealRequest(); this.setStatus(res.status, res.statusText); this.setHeaders(res.headers); // remove content-encoding header, otherwise error: Decompression failed this.headers.delete('content-encoding'); await this.setPatchedBody(res); } setStaticResponse() { if (this.resSchema.status) this.setStatus(this.resSchema.status); this.setHeaders(); this.setStaticBody(); } setStatus(status, statusText) { this.status = status; this.statusText = statusText || node_http_1.STATUS_CODES[status] || 'Unknown'; } async sendRealRequest() { const { request: requestOverrides } = this.resSchema; const req = requestOverrides ? await new request_patcher_1.RequestPatcher(this.req, requestOverrides, this.params).patch() : this.req; return this.callbacks.bypass(req); } setHeaders(origHeaders) { // Important to use Object.fromEntries(), otherwise headers become empty inside msw. // See: https://github.com/mswjs/msw/blob/main/src/core/utils/HttpResponse/decorators.ts#L20 this.headers = new Headers(Object.fromEntries(origHeaders || [])); Object.entries(this.resSchema.headers || {}).forEach(([key, value]) => { if (value) { value = (0, placeholders_1.replacePlaceholders)(value, this.params); this.headers.set(key, value); } else { this.headers.delete(key); } }); } async setPatchedBody(res) { const { bodyPatch } = this.resSchema; if (bodyPatch) { // todo: match status? If response status is not 200, should we patch it? // todo: handle parse error const actualBody = await res.json(); const bodyPatchFinal = (0, placeholders_1.cloneWithPlaceholders)(bodyPatch, this.params); (0, utils_1.patchObject)(actualBody, bodyPatchFinal); this.setBodyAsString(JSON.stringify(actualBody), 'application/json'); } else { this.body = await res.arrayBuffer(); } } setStaticBody() { const { body } = this.resSchema; if (!body) return; if (typeof body === 'string') { const newBody = (0, placeholders_1.replacePlaceholders)(body, this.params); this.setBodyAsString(newBody, 'text/plain'); } else { const newBody = (0, placeholders_1.stringifyWithPlaceholders)(body, this.params); this.setBodyAsString(newBody, 'application/json'); } } setBodyAsString(body, contentType) { this.body = body; if (!this.headers.has('content-type')) { this.headers.set('content-type', contentType); } const contentLength = body ? new Blob([body]).size.toString() : '0'; this.headers.set('content-length', contentLength); } async wait() { const { delay } = this.resSchema; if (delay) await (0, utils_1.wait)(delay); } } exports.ResponseBuilder = ResponseBuilder; //# sourceMappingURL=index.js.map