@pactflow/pact-msw-adapter
Advanced tools
Comparing version 0.11.1 to 1.1.0
@@ -5,2 +5,17 @@ # Changelog | ||
## [1.1.0](https://github.com/pactflow/pact-msw-adapter/compare/v0.11.1...v1.1.0) (2022-04-22) | ||
### Features | ||
* (release): 1.0.0 ([25292a9](https://github.com/pactflow/pact-msw-adapter/commit/25292a9bb8542e904090ada53e5d1d6e0beba863)) | ||
* Worker examples ([#39](https://github.com/pactflow/pact-msw-adapter/issues/39)) ([3a5d499](https://github.com/pactflow/pact-msw-adapter/commit/3a5d4993a291c4384d90dac54a90719fb295424d)) | ||
## [1.0.0](https://github.com/pactflow/pact-msw-adapter/compare/v0.11.1...v1.0.0) (2022-04-22) | ||
### Features | ||
* Worker examples ([#39](https://github.com/pactflow/pact-msw-adapter/issues/39)) ([3a5d499](https://github.com/pactflow/pact-msw-adapter/commit/3a5d4993a291c4384d90dac54a90719fb295424d)) | ||
### [0.11.1](https://github.com/pactflow/pact-msw-adapter/compare/v0.10.4...v0.11.1) (2022-03-10) | ||
@@ -7,0 +22,0 @@ |
@@ -1,3 +0,3 @@ | ||
import { PactFile, MswMatch } from './pactMswAdapter'; | ||
export declare const convertMswMatchToPact: ({ consumer, provider, matches, headers }: { | ||
import { PactFile, MswMatch } from "./pactMswAdapter"; | ||
export declare const convertMswMatchToPact: ({ consumer, provider, matches, headers, }: { | ||
consumer: string; | ||
@@ -4,0 +4,0 @@ provider: string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.convertMswMatchToPact = void 0; | ||
var lodash_1 = require("lodash"); | ||
var convertMswMatchToPact = function (_a) { | ||
var consumer = _a.consumer, provider = _a.provider, matches = _a.matches, headers = _a.headers; | ||
var pactFile = { | ||
const lodash_1 = require("lodash"); | ||
const convertMswMatchToPact = ({ consumer, provider, matches, headers, }) => { | ||
const pactFile = { | ||
consumer: { name: consumer }, | ||
provider: { name: provider }, | ||
interactions: matches.map(function (match) { | ||
interactions: matches.map((match) => { | ||
var _a; | ||
return ({ | ||
return { | ||
description: match.request.id, | ||
providerState: "", | ||
providerState: '', | ||
request: { | ||
method: match.request.method, | ||
path: match.request.url.pathname, | ||
headers: (headers === null || headers === void 0 ? void 0 : headers.excludeHeaders) ? (0, lodash_1.omit)(match.request.headers['_headers'], headers.excludeHeaders) : match.request.headers['_headers'], | ||
body: match.request.bodyUsed ? match.request.body : undefined, | ||
headers: (headers === null || headers === void 0 ? void 0 : headers.excludeHeaders) | ||
? (0, lodash_1.omit)(match.request.headers['_headers'], headers.excludeHeaders) | ||
: match.request.headers['_headers'], | ||
body: match.request.bodyUsed ? match.request.body : undefined | ||
}, | ||
response: { | ||
status: match.response.status, | ||
headers: (headers === null || headers === void 0 ? void 0 : headers.excludeHeaders) ? (0, lodash_1.omit)(match.response.headers['_headers'], headers.excludeHeaders) : match.response.headers['_headers'], | ||
body: match.response.body | ||
? ((_a = match.response.headers.get("content-type")) === null || _a === void 0 ? void 0 : _a.includes("json")) | ||
? (JSON.parse(match.response.body)) | ||
: match.response.body | ||
: undefined, | ||
}, | ||
}); | ||
headers: (headers === null || headers === void 0 ? void 0 : headers.excludeHeaders) | ||
? (0, lodash_1.omit)(Object.fromEntries(match.response.headers.entries()), headers.excludeHeaders) | ||
: Object.fromEntries(match.response.headers.entries()), | ||
body: match.body | ||
? ((_a = match.response.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json')) | ||
? JSON.parse(match.body) | ||
: match.body | ||
: undefined | ||
} | ||
}; | ||
}), | ||
metadata: { | ||
pactSpecification: { | ||
version: '2.0.0', | ||
version: "2.0.0", | ||
}, | ||
@@ -36,0 +39,0 @@ }, |
@@ -31,7 +31,3 @@ /// <reference types="node" /> | ||
} | ||
export declare const setupPactMswAdapter: ({ options: externalOptions, worker, server }: { | ||
options: PactMswAdapterOptions; | ||
worker?: SetupWorkerApi | undefined; | ||
server?: SetupServerApi | undefined; | ||
}) => { | ||
export interface PactMswAdapter { | ||
emitter: EventEmitter; | ||
@@ -42,3 +38,8 @@ newTest: () => void; | ||
clear: () => void; | ||
}; | ||
} | ||
export declare const setupPactMswAdapter: ({ options: externalOptions, worker, server }: { | ||
options: PactMswAdapterOptions; | ||
worker?: SetupWorkerApi | undefined; | ||
server?: SetupServerApi | undefined; | ||
}) => PactMswAdapter; | ||
export { convertMswMatchToPact }; | ||
@@ -81,3 +82,4 @@ export interface PactInteraction { | ||
request: MockedRequest; | ||
response: Response | IsomorphicResponse; | ||
response: IsomorphicResponse | Response; | ||
body: string | undefined; | ||
} | ||
@@ -84,0 +86,0 @@ export interface ExpiredRequest { |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.convertMswMatchToPact = exports.setupPactMswAdapter = void 0; | ||
var utils_1 = require("./utils/utils"); | ||
var convertMswMatchToPact_1 = require("./convertMswMatchToPact"); | ||
const utils_1 = require("./utils/utils"); | ||
const convertMswMatchToPact_1 = require("./convertMswMatchToPact"); | ||
Object.defineProperty(exports, "convertMswMatchToPact", { enumerable: true, get: function () { return convertMswMatchToPact_1.convertMswMatchToPact; } }); | ||
var events_1 = require("events"); | ||
var setupPactMswAdapter = function (_a) { | ||
var externalOptions = _a.options, worker = _a.worker, server = _a.server; | ||
const events_1 = require("events"); | ||
const setupPactMswAdapter = ({ options: externalOptions, worker, server }) => { | ||
if (!worker && !server) { | ||
throw new Error('Either a worker or server must be provided'); | ||
} | ||
var mswMocker = worker ? worker : server; | ||
const isWorker = worker ? !!worker : false; | ||
const mswMocker = worker ? worker : server; | ||
if (!mswMocker) { | ||
throw new Error('Could not setup either the worker or server'); | ||
} | ||
var emitter = new events_1.EventEmitter(); | ||
var options = __assign(__assign({}, externalOptions), { timeout: externalOptions.timeout || 200, debug: externalOptions.debug || false, pactOutDir: externalOptions.pactOutDir || './msw_generated_pacts/' }); | ||
(0, utils_1.logGroup)("Adapter enabled".concat(options.debug ? ' on debug mode' : '')); | ||
const emitter = new events_1.EventEmitter(); | ||
const options = { | ||
...externalOptions, | ||
timeout: externalOptions.timeout || 200, | ||
debug: externalOptions.debug || false, | ||
pactOutDir: externalOptions.pactOutDir || './msw_generated_pacts/' | ||
}; | ||
(0, utils_1.logGroup)(`Adapter enabled${options.debug ? ' on debug mode' : ''}`); | ||
if (options.debug) { | ||
@@ -74,11 +32,11 @@ (0, utils_1.logGroup)(['options:', options], { endGroup: true }); | ||
// This can include expired requests | ||
var pendingRequests = []; // Requests waiting for their responses | ||
var unhandledRequests = []; // Requests that need to be handled | ||
var expiredRequests = []; // Requests that have expired (timeout) | ||
var orphanResponses = []; // Responses from previous tests | ||
var oldRequestIds = []; // Pending requests from previous tests | ||
var activeRequestIds = []; // Pending requests which are still valid | ||
var matches = []; // Completed request-response pairs | ||
mswMocker.events.on('request:match', function (req) { | ||
var url = req.url.toString(); | ||
const pendingRequests = []; // Requests waiting for their responses | ||
const unhandledRequests = []; // Requests that need to be handled | ||
const expiredRequests = []; // Requests that have expired (timeout) | ||
const orphanResponses = []; // Responses from previous tests | ||
const oldRequestIds = []; // Pending requests from previous tests | ||
const activeRequestIds = []; // Pending requests which are still valid | ||
const matches = []; // Completed request-response pairs | ||
mswMocker.events.on('request:match', (req) => { | ||
const url = req.url.toString(); | ||
if (!(0, utils_1.checkUrlFilters)(url, options)) | ||
@@ -89,13 +47,14 @@ return; | ||
} | ||
var startTime = Date.now(); | ||
const startTime = Date.now(); | ||
pendingRequests.push(req); | ||
activeRequestIds.push(req.id); | ||
setTimeout(function () { | ||
var activeIdx = activeRequestIds.indexOf(req.id); | ||
setTimeout(() => { | ||
const activeIdx = activeRequestIds.indexOf(req.id); | ||
emitter.emit('pact-msw-adapter:expired', req); | ||
if (activeIdx >= 0) { // Could be removed if completed or the test ended | ||
if (activeIdx >= 0) { | ||
// Could be removed if completed or the test ended | ||
activeRequestIds.splice(activeIdx, 1); | ||
expiredRequests.push({ | ||
reqId: req.id, | ||
startTime: startTime | ||
startTime | ||
}); | ||
@@ -105,20 +64,33 @@ } | ||
}); | ||
mswMocker.events.on('response:mocked', function (response, reqId) { | ||
var reqIdx = pendingRequests.findIndex(function (req) { return req.id === reqId; }); | ||
mswMocker.events.on('response:mocked', async (response, reqId) => { | ||
// https://mswjs.io/docs/extensions/life-cycle-events#responsemocked | ||
// Note that the res instance differs between the browser and Node.js. | ||
// Take this difference into account when operating with it. | ||
const responseBody = isWorker | ||
? await response.text() | ||
: response.body; | ||
(0, utils_1.logGroup)(JSON.stringify(response), { endGroup: true }); | ||
const reqIdx = pendingRequests.findIndex((req) => req.id === reqId); | ||
if (reqIdx < 0) | ||
return; // Filtered and (expired and cleared) requests | ||
var endTime = Date.now(); | ||
var request = pendingRequests.splice(reqIdx, 1)[0]; | ||
var activeReqIdx = activeRequestIds.indexOf(reqId); | ||
const endTime = Date.now(); | ||
const request = pendingRequests.splice(reqIdx, 1)[0]; | ||
const activeReqIdx = activeRequestIds.indexOf(reqId); | ||
if (activeReqIdx < 0) { | ||
// Expired requests and responses from previous tests | ||
var oldReqId = oldRequestIds.find(function (id) { return id === reqId; }); | ||
var expiredReq = expiredRequests.find(function (expired) { return expired.reqId === reqId; }); | ||
const oldReqId = oldRequestIds.find((id) => id === reqId); | ||
const expiredReq = expiredRequests.find((expired) => expired.reqId === reqId); | ||
if (oldReqId) { | ||
orphanResponses.push(request.url.toString()); | ||
(0, utils_1.log)("Orphan response: ".concat(request.url), { mode: 'warning', group: expiredReq !== undefined }); | ||
(0, utils_1.log)(`Orphan response: ${request.url}`, { | ||
mode: 'warning', | ||
group: expiredReq !== undefined | ||
}); | ||
} | ||
if (expiredReq) { | ||
if (!oldReqId) { | ||
(0, utils_1.log)("Expired request to ".concat(request.url.pathname), { mode: 'warning', group: true }); | ||
(0, utils_1.log)(`Expired request to ${request.url.pathname}`, { | ||
mode: 'warning', | ||
group: true | ||
}); | ||
} | ||
@@ -137,80 +109,84 @@ expiredReq.duration = endTime - expiredReq.startTime; | ||
activeRequestIds.splice(activeReqIdx, 1); | ||
var match = { request: request, response: response }; | ||
const match = { | ||
request, | ||
response, | ||
body: responseBody | ||
}; | ||
emitter.emit('pact-msw-adapter:match', match); | ||
matches.push(match); | ||
}); | ||
mswMocker.events.on('request:unhandled', function (req) { | ||
var url = req.url.toString(); | ||
mswMocker.events.on('request:unhandled', (req) => { | ||
const url = req.url.toString(); | ||
if (!(0, utils_1.checkUrlFilters)(url, options)) | ||
return; | ||
unhandledRequests.push(url); | ||
(0, utils_1.warning)("Unhandled request: ".concat(url)); | ||
(0, utils_1.warning)(`Unhandled request: ${url}`); | ||
}); | ||
return { | ||
emitter: emitter, | ||
newTest: function () { | ||
oldRequestIds.push.apply(oldRequestIds, activeRequestIds); | ||
emitter, | ||
newTest: () => { | ||
oldRequestIds.push(...activeRequestIds); | ||
activeRequestIds.length = 0; | ||
emitter.emit('pact-msw-adapter:new-test'); | ||
}, | ||
verifyTest: function () { | ||
var errors = ''; | ||
verifyTest: () => { | ||
let errors = ''; | ||
if (unhandledRequests.length) { | ||
errors += "Requests with missing msw handlers:\n ".concat(unhandledRequests.join('\n'), "\n"); | ||
errors += `Requests with missing msw handlers:\n ${unhandledRequests.join('\n')}\n`; | ||
unhandledRequests.length = 0; | ||
} | ||
if (expiredRequests.length) { | ||
errors += "Expired requests:\n".concat(expiredRequests | ||
.map(function (expired) { return ({ expired: expired, req: pendingRequests.find(function (req) { return req.id === expired.reqId; }) }); }) | ||
.filter(function (_a) { | ||
var expired = _a.expired, req = _a.req; | ||
return expired && req; | ||
}) | ||
.map(function (_a) { | ||
var expired = _a.expired, req = _a.req; | ||
return "".concat(req.url.pathname).concat(expired.duration ? "took ".concat(expired.duration, "ms and") : '', " timed out after ").concat(options.timeout, "ms"); | ||
}) | ||
.join('\n'), "\n"); | ||
errors += `Expired requests:\n${expiredRequests | ||
.map((expired) => ({ | ||
expired, | ||
req: pendingRequests.find((req) => req.id === expired.reqId) | ||
})) | ||
.filter(({ expired, req }) => expired && req) | ||
.map(({ expired, req }) => `${req.url.pathname}${expired.duration ? `took ${expired.duration}ms and` : ''} timed out after ${options.timeout}ms`) | ||
.join('\n')}\n`; | ||
expiredRequests.length = 0; | ||
} | ||
if (orphanResponses.length) { | ||
errors += "Orphan responses:\n".concat(orphanResponses.join('\n'), "\n"); | ||
errors += `Orphan responses:\n${orphanResponses.join('\n')}\n`; | ||
orphanResponses.length = 0; | ||
} | ||
if (errors.length > 0) { | ||
throw new Error("Found errors on msw requests.\n".concat(errors)); | ||
throw new Error(`Found errors on msw requests.\n${errors}`); | ||
} | ||
}, | ||
writeToFile: function (writer) { | ||
if (writer === void 0) { writer = utils_1.writeData2File; } | ||
return __awaiter(void 0, void 0, void 0, function () { | ||
var pactFiles; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
// TODO - dedupe pactResults so we only have one file per consumer/provider pair | ||
// Note: There are scenarios such as feature flagging where you want more than one file per consumer/provider pair | ||
(0, utils_1.logGroup)(['Found the following number of matches to write to a file:- ' + matches.length]); | ||
return [4 /*yield*/, transformMswToPact(matches, activeRequestIds, options, emitter)]; | ||
case 1: | ||
pactFiles = _a.sent(); | ||
if (!pactFiles) { | ||
(0, utils_1.logGroup)(['writeToFile() was called but no pact files were generated, did you forget to await the writeToFile() method?', matches.length], { endGroup: true }); | ||
} | ||
pactFiles.forEach(function (pactFile) { | ||
var filePath = options.pactOutDir + '/' + | ||
[ | ||
pactFile.consumer.name, | ||
pactFile.provider.name, | ||
Date.now().toString(), | ||
].join('-') + | ||
'.json'; | ||
writer(filePath, pactFile); | ||
}); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
writeToFile: async (writer = utils_1.writeData2File) => { | ||
// TODO - dedupe pactResults so we only have one file per consumer/provider pair | ||
// Note: There are scenarios such as feature flagging where you want more than one file per consumer/provider pair | ||
(0, utils_1.logGroup)([ | ||
'Found the following number of matches to write to a file:- ' + | ||
matches.length | ||
], { endGroup: true }); | ||
(0, utils_1.logGroup)(JSON.stringify(matches), { endGroup: true }); | ||
let pactFiles; | ||
try { | ||
pactFiles = await transformMswToPact(matches, activeRequestIds, options, emitter); | ||
} | ||
catch (error) { | ||
(0, utils_1.logGroup)(['An error occurred parsing the JSON file', error]); | ||
throw new Error('error generating pact files'); | ||
} | ||
if (!pactFiles) { | ||
(0, utils_1.logGroup)([ | ||
'writeToFile() was called but no pact files were generated, did you forget to await the writeToFile() method?', | ||
matches.length | ||
], { endGroup: true }); | ||
} | ||
pactFiles.forEach((pactFile) => { | ||
const filePath = options.pactOutDir + | ||
'/' + | ||
[ | ||
pactFile.consumer.name, | ||
pactFile.provider.name, | ||
Date.now().toString() | ||
].join('-') + | ||
'.json'; | ||
writer(filePath, pactFile); | ||
}); | ||
}, | ||
clear: function () { | ||
clear: () => { | ||
pendingRequests.length = 0; | ||
@@ -225,65 +201,64 @@ unhandledRequests.length = 0; | ||
return; | ||
}, | ||
} | ||
}; | ||
}; | ||
exports.setupPactMswAdapter = setupPactMswAdapter; | ||
var transformMswToPact = function (matches, activeRequestIds, options, emitter) { return __awaiter(void 0, void 0, void 0, function () { | ||
var requestsCompleted, pactFiles, providers_1, matchesByProvider_1, _i, _a, _b, provider, providerMatches, pactFile, err_1; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
_c.trys.push([0, 2, , 3]); | ||
requestsCompleted = new Promise(function (resolve) { | ||
if (activeRequestIds.length === 0) { | ||
resolve(); | ||
return; | ||
} | ||
var events = ['pact-msw-adapter:expired ', 'pact-msw-adapter:match', 'pact-msw-adapter:new-test', 'pact-msw-adapter:clear']; | ||
var listener = function () { | ||
if (activeRequestIds.length === 0) { | ||
events.forEach(function (ev) { return emitter.off(ev, listener); }); | ||
resolve(); | ||
} | ||
}; | ||
events.forEach(function (ev) { return emitter.on(ev, listener); }); | ||
}); | ||
return [4 /*yield*/, (0, utils_1.addTimeout)(requestsCompleted, 'requests completed listener', options.timeout * 2)]; | ||
case 1: | ||
_c.sent(); | ||
pactFiles = []; | ||
providers_1 = Object.entries(options.providers); | ||
matchesByProvider_1 = {}; | ||
matches.forEach(function (match) { | ||
var _a; | ||
var url = match.request.url.toString(); | ||
var provider = ((_a = providers_1.find(function (_a) { | ||
var _ = _a[0], paths = _a[1]; | ||
return paths.some(function (path) { return url.includes(path); }); | ||
})) === null || _a === void 0 ? void 0 : _a[0]) || 'unknown'; | ||
if (!matchesByProvider_1[provider]) | ||
matchesByProvider_1[provider] = []; | ||
matchesByProvider_1[provider].push(match); | ||
}); | ||
for (_i = 0, _a = Object.entries(matchesByProvider_1); _i < _a.length; _i++) { | ||
_b = _a[_i], provider = _b[0], providerMatches = _b[1]; | ||
pactFile = (0, convertMswMatchToPact_1.convertMswMatchToPact)({ consumer: options.consumer, provider: provider, matches: providerMatches, headers: { excludeHeaders: options.excludeHeaders } }); | ||
if (pactFile) { | ||
pactFiles.push(pactFile); | ||
} | ||
const transformMswToPact = async (matches, activeRequestIds, options, emitter) => { | ||
try { | ||
// TODO: Lock new requests, error on clear/new-test if locked | ||
const requestsCompleted = new Promise((resolve) => { | ||
if (activeRequestIds.length === 0) { | ||
resolve(); | ||
return; | ||
} | ||
const events = [ | ||
'pact-msw-adapter:expired ', | ||
'pact-msw-adapter:match', | ||
'pact-msw-adapter:new-test', | ||
'pact-msw-adapter:clear' | ||
]; | ||
const listener = () => { | ||
if (activeRequestIds.length === 0) { | ||
events.forEach((ev) => emitter.off(ev, listener)); | ||
resolve(); | ||
} | ||
return [2 /*return*/, pactFiles]; | ||
case 2: | ||
err_1 = _c.sent(); | ||
if (err_1 instanceof Error) { | ||
throw err_1; | ||
} | ||
if (err_1 && typeof (err_1) === 'string') | ||
err_1 = new Error(err_1); | ||
console.groupCollapsed('%c[pact-msw-adapter] Unexpected error.', 'color:coral;font-weight:bold;'); | ||
console.log(err_1); | ||
console.groupEnd(); | ||
throw err_1; | ||
case 3: return [2 /*return*/]; | ||
}; | ||
events.forEach((ev) => emitter.on(ev, listener)); | ||
}); | ||
await (0, utils_1.addTimeout)(requestsCompleted, 'requests completed listener', options.timeout * 2); | ||
const pactFiles = []; | ||
const providers = Object.entries(options.providers); | ||
const matchesByProvider = {}; | ||
matches.forEach((match) => { | ||
var _a; | ||
const url = match.request.url.toString(); | ||
const provider = ((_a = providers.find(([_, paths]) => paths.some((path) => url.includes(path)))) === null || _a === void 0 ? void 0 : _a[0]) || 'unknown'; | ||
if (!matchesByProvider[provider]) | ||
matchesByProvider[provider] = []; | ||
matchesByProvider[provider].push(match); | ||
}); | ||
for (const [provider, providerMatches] of Object.entries(matchesByProvider)) { | ||
const pactFile = (0, convertMswMatchToPact_1.convertMswMatchToPact)({ | ||
consumer: options.consumer, | ||
provider, | ||
matches: providerMatches, | ||
headers: { excludeHeaders: options.excludeHeaders } | ||
}); | ||
if (pactFile) { | ||
pactFiles.push(pactFile); | ||
} | ||
} | ||
}); | ||
}); }; | ||
return pactFiles; | ||
} | ||
catch (err) { | ||
if (err instanceof Error) { | ||
throw err; | ||
} | ||
if (err && typeof err === 'string') | ||
err = new Error(err); | ||
console.groupCollapsed('%c[pact-msw-adapter] Unexpected error.', 'color:coral;font-weight:bold;'); | ||
console.log(err); | ||
console.groupEnd(); | ||
throw err; | ||
} | ||
}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.addTimeout = exports.checkUrlFilters = exports.writeData2File = exports.logGroup = exports.warning = exports.log = void 0; | ||
var path = require("path"); | ||
var fs; // dynamic import | ||
var logPrefix = '[pact-msw-adapter]'; | ||
var logColors = { | ||
let fs; // dynamic import | ||
const logPrefix = '[pact-msw-adapter]'; | ||
const logColors = { | ||
log: 'forestgreen', | ||
@@ -48,18 +12,18 @@ warning: 'gold', | ||
}; | ||
var log = function (message, options) { | ||
var group = (options === null || options === void 0 ? void 0 : options.group) || false; | ||
var mode = (options === null || options === void 0 ? void 0 : options.mode) || 'log'; | ||
var color = logColors[mode]; | ||
var logFunction = group ? console.groupCollapsed : console.log; | ||
logFunction("%c".concat(logPrefix, " %c").concat(message), "color:".concat(color), 'color:inherit'); | ||
const log = (message, options) => { | ||
const group = (options === null || options === void 0 ? void 0 : options.group) || false; | ||
const mode = (options === null || options === void 0 ? void 0 : options.mode) || 'log'; | ||
const color = logColors[mode]; | ||
const logFunction = group ? console.groupCollapsed : console.log; | ||
logFunction(`%c${logPrefix} %c${message}`, `color:${color}`, 'color:inherit'); | ||
}; | ||
exports.log = log; | ||
var warning = function (message) { return log(message, { mode: 'warning' }); }; | ||
const warning = (message) => log(message, { mode: 'warning' }); | ||
exports.warning = warning; | ||
var logGroup = function (message, options) { | ||
var isArray = message instanceof Array; | ||
const logGroup = (message, options) => { | ||
const isArray = message instanceof Array; | ||
if (isArray) { | ||
var label = message[0], content = message.slice(1); | ||
const [label, ...content] = message; | ||
log(label, { group: true }); | ||
content.forEach(function (c) { return console.log(c); }); | ||
content.forEach((c) => console.log(c)); | ||
} | ||
@@ -74,3 +38,3 @@ else { | ||
exports.logGroup = logGroup; | ||
var ensureDirExists = function (filePath) { | ||
const ensureDirExists = (filePath) => { | ||
var _a, _b; | ||
@@ -83,3 +47,3 @@ var dirname = path.dirname(filePath); | ||
}; | ||
var writeData2File = function (filePath, data) { | ||
const writeData2File = (filePath, data) => { | ||
var _a; | ||
@@ -104,10 +68,10 @@ if (!fs) { | ||
exports.writeData2File = writeData2File; | ||
var checkUrlFilters = function (urlString, options) { | ||
const checkUrlFilters = (urlString, options) => { | ||
var _a; | ||
var providerFilter = (_a = Object.values(options.providers)) === null || _a === void 0 ? void 0 : _a.some(function (validPaths) { return validPaths.some(function (path) { return urlString.includes(path); }); }); | ||
var includeFilter = !options.includeUrl || options.includeUrl.some(function (inc) { return urlString.includes(inc); }); | ||
var excludeFilter = !options.excludeUrl || !options.excludeUrl.some(function (exc) { return urlString.includes(exc); }); | ||
var matchIsAllowed = includeFilter && excludeFilter && providerFilter; | ||
const providerFilter = (_a = Object.values(options.providers)) === null || _a === void 0 ? void 0 : _a.some(validPaths => validPaths.some(path => urlString.includes(path))); | ||
const includeFilter = !options.includeUrl || options.includeUrl.some(inc => urlString.includes(inc)); | ||
const excludeFilter = !options.excludeUrl || !options.excludeUrl.some(exc => urlString.includes(exc)); | ||
const matchIsAllowed = includeFilter && excludeFilter && providerFilter; | ||
if (options.debug) { | ||
logGroup(['Checking request against url filters', { urlString: urlString, providerFilter: providerFilter, includeFilter: includeFilter, excludeFilter: excludeFilter, matchIsAllowed: matchIsAllowed }]); | ||
logGroup(['Checking request against url filters', { urlString, providerFilter, includeFilter, excludeFilter, matchIsAllowed }]); | ||
} | ||
@@ -117,13 +81,10 @@ return matchIsAllowed; | ||
exports.checkUrlFilters = checkUrlFilters; | ||
var addTimeout = function (promise, label, timeout) { return __awaiter(void 0, void 0, void 0, function () { | ||
var asyncTimeout; | ||
return __generator(this, function (_a) { | ||
asyncTimeout = new Promise(function (_, reject) { | ||
setTimeout(function () { | ||
reject(new Error("[pact-msw-adapter] ".concat(label, " timed out after ").concat(timeout, "ms"))); | ||
}, timeout); | ||
}); | ||
return [2 /*return*/, Promise.race([promise, asyncTimeout])]; | ||
const addTimeout = async (promise, label, timeout) => { | ||
const asyncTimeout = new Promise((_, reject) => { | ||
setTimeout(() => { | ||
reject(new Error(`[pact-msw-adapter] ${label} timed out after ${timeout}ms`)); | ||
}, timeout); | ||
}); | ||
}); }; | ||
return Promise.race([promise, asyncTimeout]); | ||
}; | ||
exports.addTimeout = addTimeout; |
{ | ||
"name": "@pactflow/pact-msw-adapter", | ||
"version": "0.11.1", | ||
"version": "1.1.0", | ||
"main": "./dist/pactMswAdapter.js", | ||
@@ -32,3 +32,10 @@ "keywords": [ | ||
"release": "standard-version", | ||
"release:trigger": "./scripts/trigger-release.sh" | ||
"release:trigger": "./scripts/trigger-release.sh", | ||
"example:test:cy:run": "cd examples/react && npm run start:test:cy:run", | ||
"example:test:cy:open": "cd examples/react && npm run start:test:cy:open", | ||
"example:test:unit": "cd examples/react && npm test", | ||
"example:test:all": "npm run example:test:unit && npm run example:test:cy", | ||
"example:link": "cd examples/react && yarn link @pactflow/pact-msw-adapter", | ||
"example:install": "cd examples/react && yarn install", | ||
"example:install:link": "yarn link && npm run example:install && npm run example:link" | ||
}, | ||
@@ -35,0 +42,0 @@ "devDependencies": { |
@@ -31,6 +31,8 @@ # pact-msw-adapter | ||
See [./src/pactFromMswServer.msw.spec.ts](./src/pactFromMswServer.msw.spec.ts) for an example testing an API client, used in a react application | ||
See [./src/pactFromMswServer.msw.spec.ts](./src/pactFromMswServer.msw.spec.ts) msw mock server example (jest/msw/react) | ||
This test will generate pacts, which can be found in the `./msw_generated_pacts` folder | ||
See [./examples/react/cypress/integration/pactFromMswWorker.spec.js](./examples/react/cypress/integration/pactFromMswWorker.spec.js) msw mock worker example (cypress/msw/react) | ||
These tests will generate pacts, which can be found in the `./msw_generated_pacts` folder | ||
## How to use | ||
@@ -37,0 +39,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1
208
32713
496