@zimic/interceptor 1.2.3-canary.7 → 1.2.4-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ZU6IGW27.js → chunk-IPL73BDI.js} +99 -73
- package/dist/chunk-IPL73BDI.js.map +1 -0
- package/dist/{chunk-XCYZ5L2M.mjs → chunk-OTZ5Z633.mjs} +99 -73
- package/dist/chunk-OTZ5Z633.mjs.map +1 -0
- package/dist/cli.js +18 -18
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/http.js +101 -99
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +101 -99
- package/dist/http.mjs.map +1 -1
- package/dist/server.js +6 -6
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
- package/src/http/interceptor/HttpInterceptorClient.ts +1 -1
- package/src/http/interceptor/HttpInterceptorStore.ts +6 -3
- package/src/http/interceptor/RemoteHttpInterceptor.ts +1 -1
- package/src/http/interceptorWorker/HttpInterceptorWorker.ts +3 -5
- package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +16 -12
- package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +20 -43
- package/src/server/InterceptorServer.ts +39 -21
- package/src/server/types/schema.ts +1 -1
- package/src/webSocket/WebSocketClient.ts +4 -4
- package/src/webSocket/WebSocketHandler.ts +115 -65
- package/src/webSocket/WebSocketServer.ts +2 -3
- package/src/webSocket/types.ts +9 -14
- package/dist/chunk-XCYZ5L2M.mjs.map +0 -1
- package/dist/chunk-ZU6IGW27.js.map +0 -1
|
@@ -866,7 +866,7 @@ var WebSocketHandler = class {
|
|
|
866
866
|
messageTimeout;
|
|
867
867
|
channelListeners = {};
|
|
868
868
|
socketListeners = {
|
|
869
|
-
|
|
869
|
+
abortRequests: /* @__PURE__ */ new Map()
|
|
870
870
|
};
|
|
871
871
|
constructor(options) {
|
|
872
872
|
this.socketTimeout = options.socketTimeout ?? DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT;
|
|
@@ -887,10 +887,12 @@ var WebSocketHandler = class {
|
|
|
887
887
|
}
|
|
888
888
|
socket.addEventListener("error", handleSocketError);
|
|
889
889
|
const handleSocketClose = () => {
|
|
890
|
+
this.sockets.delete(socket);
|
|
891
|
+
this.emitSocket("abortRequests", socket);
|
|
892
|
+
this.socketListeners.abortRequests.delete(socket);
|
|
890
893
|
socket.removeEventListener("message", handleSocketMessage);
|
|
891
894
|
socket.removeEventListener("close", handleSocketClose);
|
|
892
895
|
socket.removeEventListener("error", handleSocketError);
|
|
893
|
-
this.removeSocket(socket);
|
|
894
896
|
};
|
|
895
897
|
socket.addEventListener("close", handleSocketClose);
|
|
896
898
|
this.sockets.add(socket);
|
|
@@ -944,6 +946,9 @@ var WebSocketHandler = class {
|
|
|
944
946
|
isMessage(message) {
|
|
945
947
|
return typeof message === "object" && message !== null && "id" in message && typeof message.id === "string" && "channel" in message && typeof message.channel === "string" && (!("requestId" in message) || typeof message.requestId === "string");
|
|
946
948
|
}
|
|
949
|
+
isChannelEvent(event, channel) {
|
|
950
|
+
return event.channel === channel;
|
|
951
|
+
}
|
|
947
952
|
async notifyListeners(message, socket) {
|
|
948
953
|
if (this.isReplyMessage(message)) {
|
|
949
954
|
await this.notifyReplyListeners(message, socket);
|
|
@@ -972,10 +977,6 @@ var WebSocketHandler = class {
|
|
|
972
977
|
});
|
|
973
978
|
await Promise.all(closingPromises);
|
|
974
979
|
}
|
|
975
|
-
removeSocket(socket) {
|
|
976
|
-
this.abortSocketMessages([socket]);
|
|
977
|
-
this.sockets.delete(socket);
|
|
978
|
-
}
|
|
979
980
|
async createEventMessage(channel, eventData) {
|
|
980
981
|
const crypto2 = await importCrypto();
|
|
981
982
|
const eventMessage = {
|
|
@@ -992,31 +993,46 @@ var WebSocketHandler = class {
|
|
|
992
993
|
async request(channel, requestData, options = {}) {
|
|
993
994
|
const request = await this.createEventMessage(channel, requestData);
|
|
994
995
|
this.sendMessage(request, options.sockets);
|
|
995
|
-
const response = await this.waitForReply(channel, request
|
|
996
|
+
const response = await this.waitForReply(channel, request, options.sockets);
|
|
996
997
|
return response.data;
|
|
997
998
|
}
|
|
998
|
-
async waitForReply(channel,
|
|
999
|
+
async waitForReply(channel, request, sockets = this.sockets) {
|
|
999
1000
|
return new Promise((resolve, reject) => {
|
|
1000
1001
|
const replyTimeout = setTimeout(() => {
|
|
1001
|
-
this.
|
|
1002
|
-
|
|
1002
|
+
this.offChannel("reply", channel, replyListener);
|
|
1003
|
+
for (const socket of sockets) {
|
|
1004
|
+
this.offSocket("abortRequests", socket, abortRequestsHandler);
|
|
1005
|
+
}
|
|
1003
1006
|
const timeoutError = new WebSocketMessageTimeoutError(this.messageTimeout);
|
|
1004
1007
|
reject(timeoutError);
|
|
1005
1008
|
}, this.messageTimeout);
|
|
1006
|
-
const
|
|
1009
|
+
const replyListener = this.onChannel("reply", channel, (message) => {
|
|
1010
|
+
if (message.requestId !== request.id) {
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1007
1013
|
clearTimeout(replyTimeout);
|
|
1008
|
-
this.
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
});
|
|
1012
|
-
const replyListener = this.onReply(channel, (message) => {
|
|
1013
|
-
if (message.requestId === requestId) {
|
|
1014
|
-
clearTimeout(replyTimeout);
|
|
1015
|
-
this.offReply(channel, replyListener);
|
|
1016
|
-
this.offAbortSocketMessages(sockets, abortListener);
|
|
1017
|
-
resolve(message);
|
|
1014
|
+
this.offChannel("reply", channel, replyListener);
|
|
1015
|
+
for (const socket of sockets) {
|
|
1016
|
+
this.offSocket("abortRequests", socket, abortRequestsHandler);
|
|
1018
1017
|
}
|
|
1018
|
+
resolve(message);
|
|
1019
1019
|
});
|
|
1020
|
+
const abortRequestsHandler = (options) => {
|
|
1021
|
+
const shouldAbortRequest = options.shouldAbortRequest === void 0 || options.shouldAbortRequest(request);
|
|
1022
|
+
if (!shouldAbortRequest) {
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
clearTimeout(replyTimeout);
|
|
1026
|
+
this.offChannel("reply", channel, replyListener);
|
|
1027
|
+
for (const socket of sockets) {
|
|
1028
|
+
this.offSocket("abortRequests", socket, abortRequestsHandler);
|
|
1029
|
+
}
|
|
1030
|
+
const abortError = new WebSocketMessageAbortError();
|
|
1031
|
+
reject(abortError);
|
|
1032
|
+
};
|
|
1033
|
+
for (const socket of sockets) {
|
|
1034
|
+
this.onSocket("abortRequests", socket, abortRequestsHandler);
|
|
1035
|
+
}
|
|
1020
1036
|
});
|
|
1021
1037
|
}
|
|
1022
1038
|
isReplyMessage(message) {
|
|
@@ -1047,9 +1063,9 @@ var WebSocketHandler = class {
|
|
|
1047
1063
|
socket.send(stringifiedMessage);
|
|
1048
1064
|
}
|
|
1049
1065
|
}
|
|
1050
|
-
|
|
1066
|
+
onChannel(type, channel, listener) {
|
|
1051
1067
|
const listeners = this.getOrCreateChannelListeners(channel);
|
|
1052
|
-
listeners.
|
|
1068
|
+
listeners[type].add(listener);
|
|
1053
1069
|
return listener;
|
|
1054
1070
|
}
|
|
1055
1071
|
getOrCreateChannelListeners(channel) {
|
|
@@ -1062,42 +1078,36 @@ var WebSocketHandler = class {
|
|
|
1062
1078
|
}
|
|
1063
1079
|
return listeners;
|
|
1064
1080
|
}
|
|
1065
|
-
|
|
1066
|
-
const listeners = this.
|
|
1067
|
-
listeners.
|
|
1068
|
-
return listener;
|
|
1069
|
-
}
|
|
1070
|
-
offEvent(channel, listener) {
|
|
1071
|
-
this.channelListeners[channel]?.event.delete(listener);
|
|
1081
|
+
offChannel(type, channel, listener) {
|
|
1082
|
+
const listeners = this.channelListeners[channel];
|
|
1083
|
+
listeners?.[type].delete(listener);
|
|
1072
1084
|
}
|
|
1073
|
-
|
|
1074
|
-
this.
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
this.channelListeners = {};
|
|
1085
|
+
onSocket(type, socket, listener) {
|
|
1086
|
+
const listeners = this.getOrCreateSocketListeners(type, socket);
|
|
1087
|
+
listeners.add(listener);
|
|
1088
|
+
return listener;
|
|
1078
1089
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
listeners = /* @__PURE__ */ new Set();
|
|
1084
|
-
this.socketListeners.messageAbort.set(socket, listeners);
|
|
1085
|
-
}
|
|
1086
|
-
listeners.add(listener);
|
|
1090
|
+
getOrCreateSocketListeners(type, socket) {
|
|
1091
|
+
const listeners = this.socketListeners[type].get(socket) ?? /* @__PURE__ */ new Set();
|
|
1092
|
+
if (!this.socketListeners[type].has(socket)) {
|
|
1093
|
+
this.socketListeners[type].set(socket, listeners);
|
|
1087
1094
|
}
|
|
1088
|
-
return
|
|
1095
|
+
return listeners;
|
|
1089
1096
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1097
|
+
offSocket(type, socket, listener) {
|
|
1098
|
+
const listeners = this.socketListeners[type].get(socket);
|
|
1099
|
+
listeners?.delete(listener);
|
|
1100
|
+
}
|
|
1101
|
+
emitSocket(type, socket, options = {}) {
|
|
1102
|
+
for (const listener of this.socketListeners[type].get(socket) ?? []) {
|
|
1103
|
+
listener(options);
|
|
1093
1104
|
}
|
|
1094
1105
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
for (const
|
|
1098
|
-
const listeners
|
|
1099
|
-
|
|
1100
|
-
listener(abortError);
|
|
1106
|
+
offAny() {
|
|
1107
|
+
this.channelListeners = {};
|
|
1108
|
+
for (const listenersBySocket of Object.values(this.socketListeners)) {
|
|
1109
|
+
for (const listeners of listenersBySocket.values()) {
|
|
1110
|
+
listeners.clear();
|
|
1101
1111
|
}
|
|
1102
1112
|
}
|
|
1103
1113
|
}
|
|
@@ -1150,11 +1160,9 @@ var WebSocketServer = class extends WebSocketHandler_default {
|
|
|
1150
1160
|
if (!this.webSocketServer || !this.isRunning) {
|
|
1151
1161
|
return;
|
|
1152
1162
|
}
|
|
1153
|
-
super.
|
|
1154
|
-
super.abortSocketMessages();
|
|
1163
|
+
super.offAny();
|
|
1155
1164
|
await super.closeClientSockets();
|
|
1156
1165
|
await closeServerSocket(this.webSocketServer, { timeout: this.socketTimeout });
|
|
1157
|
-
this.webSocketServer.removeAllListeners();
|
|
1158
1166
|
this.webSocketServer = void 0;
|
|
1159
1167
|
}
|
|
1160
1168
|
};
|
|
@@ -1504,17 +1512,17 @@ var InterceptorServer = class {
|
|
|
1504
1512
|
return void 0;
|
|
1505
1513
|
}
|
|
1506
1514
|
async startHttpServer() {
|
|
1515
|
+
this.httpServerOrThrow.on("request", this.handleHttpRequest);
|
|
1507
1516
|
await startHttpServer(this.httpServerOrThrow, {
|
|
1508
1517
|
hostname: this.hostname,
|
|
1509
1518
|
port: this.port
|
|
1510
1519
|
});
|
|
1511
1520
|
this.port = getHttpServerPort(this.httpServerOrThrow);
|
|
1512
|
-
this.httpServerOrThrow.on("request", this.handleHttpRequest);
|
|
1513
1521
|
}
|
|
1514
1522
|
startWebSocketServer() {
|
|
1523
|
+
this.webSocketServerOrThrow.onChannel("event", "interceptors/workers/commit", this.commitWorker);
|
|
1524
|
+
this.webSocketServerOrThrow.onChannel("event", "interceptors/workers/reset", this.resetWorker);
|
|
1515
1525
|
this.webSocketServerOrThrow.start();
|
|
1516
|
-
this.webSocketServerOrThrow.onEvent("interceptors/workers/commit", this.commitWorker);
|
|
1517
|
-
this.webSocketServerOrThrow.onEvent("interceptors/workers/reset", this.resetWorker);
|
|
1518
1526
|
}
|
|
1519
1527
|
commitWorker = (message, socket) => {
|
|
1520
1528
|
const commit = message.data;
|
|
@@ -1522,18 +1530,31 @@ var InterceptorServer = class {
|
|
|
1522
1530
|
this.registerWorkerSocketIfUnknown(socket);
|
|
1523
1531
|
return {};
|
|
1524
1532
|
};
|
|
1525
|
-
resetWorker = (
|
|
1526
|
-
this.
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1533
|
+
resetWorker = ({ data: handlersToRecommit }, socket) => {
|
|
1534
|
+
this.registerWorkerSocketIfUnknown(socket);
|
|
1535
|
+
this.webSocketServerOrThrow.emitSocket("abortRequests", socket, {
|
|
1536
|
+
shouldAbortRequest: (request) => {
|
|
1537
|
+
const isResponseCreationRequest = this.webSocketServerOrThrow.isChannelEvent(
|
|
1538
|
+
request,
|
|
1539
|
+
"interceptors/responses/create"
|
|
1540
|
+
);
|
|
1541
|
+
if (!isResponseCreationRequest) {
|
|
1542
|
+
return false;
|
|
1543
|
+
}
|
|
1544
|
+
const isHandlerStillCommitted = handlersToRecommit.some(
|
|
1545
|
+
/* istanbul ignore next -- @preserve
|
|
1546
|
+
* Ensuring this function is called in tests is difficult because it requires clearing or stopping a worker
|
|
1547
|
+
* at the exact moment a request is being handled, in a scenario when there are other handlers still
|
|
1548
|
+
* committed. */
|
|
1549
|
+
(handler) => request.data.handlerId === handler.id
|
|
1550
|
+
);
|
|
1551
|
+
return !isHandlerStillCommitted;
|
|
1534
1552
|
}
|
|
1553
|
+
});
|
|
1554
|
+
this.removeHttpHandlersBySocket(socket);
|
|
1555
|
+
for (const handler of handlersToRecommit) {
|
|
1556
|
+
this.registerHttpHandler(handler, socket);
|
|
1535
1557
|
}
|
|
1536
|
-
this.registerWorkerSocketIfUnknown(socket);
|
|
1537
1558
|
return {};
|
|
1538
1559
|
};
|
|
1539
1560
|
registerHttpHandler({ id, baseURL, method, path: path2 }, socket) {
|
|
@@ -1574,8 +1595,8 @@ var InterceptorServer = class {
|
|
|
1574
1595
|
this.httpServer = void 0;
|
|
1575
1596
|
}
|
|
1576
1597
|
async stopWebSocketServer() {
|
|
1577
|
-
this.webSocketServerOrThrow.
|
|
1578
|
-
this.webSocketServerOrThrow.
|
|
1598
|
+
this.webSocketServerOrThrow.offChannel("event", "interceptors/workers/commit", this.commitWorker);
|
|
1599
|
+
this.webSocketServerOrThrow.offChannel("event", "interceptors/workers/reset", this.resetWorker);
|
|
1579
1600
|
await this.webSocketServerOrThrow.stop();
|
|
1580
1601
|
this.webSocketServer = void 0;
|
|
1581
1602
|
}
|
|
@@ -1705,6 +1726,8 @@ function createInterceptorServer(options = {}) {
|
|
|
1705
1726
|
/* istanbul ignore next -- @preserve
|
|
1706
1727
|
* Reply listeners are always present when notified in normal conditions. If they were not present, the request
|
|
1707
1728
|
* would reach a timeout and not be responded. The empty set serves as a fallback. */
|
|
1729
|
+
/* istanbul ignore if -- @preserve
|
|
1730
|
+
* Aborting requests is highly non-deterministic because it depends on specific timing of socket events. */
|
|
1708
1731
|
/* istanbul ignore if -- @preserve
|
|
1709
1732
|
* This should never happen, but let's check that the token identifier is valid after generated. */
|
|
1710
1733
|
/* istanbul ignore if -- @preserve
|
|
@@ -1715,6 +1738,9 @@ function createInterceptorServer(options = {}) {
|
|
|
1715
1738
|
* The HTTP server is initialized before using this method in normal conditions. */
|
|
1716
1739
|
/* istanbul ignore if -- @preserve
|
|
1717
1740
|
* The web socket server is initialized before using this method in normal conditions. */
|
|
1741
|
+
/* istanbul ignore if -- @preserve
|
|
1742
|
+
* While resetting a worker, there could be other types of requests in progress. These are not guaranteed to
|
|
1743
|
+
* exist and are not related to handler resets, so we let them continue. */
|
|
1718
1744
|
/* istanbul ignore else -- @preserve
|
|
1719
1745
|
* This is always true during tests because we force max-age=0 to disable CORS caching. */
|
|
1720
1746
|
/* istanbul ignore next -- @preserve
|
|
@@ -1727,5 +1753,5 @@ function createInterceptorServer(options = {}) {
|
|
|
1727
1753
|
* Due to the rare nature of this edge case, we can't reliably reproduce it in tests. */
|
|
1728
1754
|
|
|
1729
1755
|
export { DEFAULT_ACCESS_CONTROL_HEADERS, DEFAULT_INTERCEPTOR_TOKENS_DIRECTORY, DEFAULT_PREFLIGHT_STATUS_CODE, NotRunningInterceptorServerError_default, RunningInterceptorServerError_default, createCachedDynamicImport_default, createInterceptorServer, createInterceptorToken, listInterceptorTokens, logger, readInterceptorTokenFromFile, removeInterceptorToken };
|
|
1730
|
-
//# sourceMappingURL=chunk-
|
|
1731
|
-
//# sourceMappingURL=chunk-
|
|
1756
|
+
//# sourceMappingURL=chunk-OTZ5Z633.mjs.map
|
|
1757
|
+
//# sourceMappingURL=chunk-OTZ5Z633.mjs.map
|