@zimic/interceptor 0.17.0-canary.2 → 0.17.0-canary.4
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-TYHJPU5G.js → chunk-MXHLBRPB.js} +521 -61
- package/dist/chunk-MXHLBRPB.js.map +1 -0
- package/dist/{chunk-3SKHNQLL.mjs → chunk-OGL76CKO.mjs} +510 -60
- package/dist/chunk-OGL76CKO.mjs.map +1 -0
- package/dist/cli.js +141 -17
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +137 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/http.d.ts +23 -2
- package/dist/http.js +473 -270
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +473 -270
- package/dist/http.mjs.map +1 -1
- package/dist/scripts/postinstall.js +6 -6
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/postinstall.mjs +5 -5
- package/dist/scripts/postinstall.mjs.map +1 -1
- package/dist/server.d.ts +16 -0
- package/dist/server.js +6 -6
- package/dist/server.mjs +1 -1
- package/package.json +12 -11
- package/src/cli/browser/init.ts +5 -6
- package/src/cli/cli.ts +140 -55
- package/src/cli/server/start.ts +22 -7
- package/src/cli/server/token/create.ts +33 -0
- package/src/cli/server/token/list.ts +23 -0
- package/src/cli/server/token/remove.ts +22 -0
- package/src/http/interceptor/HttpInterceptorClient.ts +49 -27
- package/src/http/interceptor/HttpInterceptorStore.ts +25 -9
- package/src/http/interceptor/LocalHttpInterceptor.ts +6 -3
- package/src/http/interceptor/RemoteHttpInterceptor.ts +41 -5
- package/src/http/interceptor/errors/RunningHttpInterceptorError.ts +1 -1
- package/src/http/interceptor/types/options.ts +15 -0
- package/src/http/interceptor/types/public.ts +11 -3
- package/src/http/interceptorWorker/HttpInterceptorWorker.ts +14 -16
- package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +17 -12
- package/src/http/interceptorWorker/types/options.ts +1 -0
- package/src/http/requestHandler/errors/TimesCheckError.ts +1 -1
- package/src/server/InterceptorServer.ts +52 -8
- package/src/server/constants.ts +1 -1
- package/src/server/errors/InvalidInterceptorTokenError.ts +13 -0
- package/src/server/errors/InvalidInterceptorTokenFileError.ts +13 -0
- package/src/server/errors/InvalidInterceptorTokenValueError.ts +13 -0
- package/src/server/types/options.ts +9 -0
- package/src/server/types/public.ts +9 -0
- package/src/server/types/schema.ts +4 -4
- package/src/server/utils/auth.ts +304 -0
- package/src/server/utils/fetch.ts +3 -1
- package/src/utils/data.ts +13 -0
- package/src/utils/files.ts +14 -0
- package/src/utils/{console.ts → logging.ts} +5 -7
- package/src/utils/webSocket.ts +57 -11
- package/src/webSocket/WebSocketClient.ts +11 -5
- package/src/webSocket/WebSocketHandler.ts +72 -51
- package/src/webSocket/WebSocketServer.ts +25 -4
- package/src/webSocket/constants.ts +2 -0
- package/src/webSocket/errors/UnauthorizedWebSocketConnectionError.ts +11 -0
- package/src/webSocket/types.ts +49 -52
- package/dist/chunk-3SKHNQLL.mjs.map +0 -1
- package/dist/chunk-TYHJPU5G.js.map +0 -1
package/dist/http.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var RunningHttpInterceptorError = class extends Error {
|
|
|
14
14
|
__name(this, "RunningHttpInterceptorError");
|
|
15
15
|
}
|
|
16
16
|
constructor(additionalMessage) {
|
|
17
|
-
super(`The interceptor is running
|
|
17
|
+
super(`The interceptor is running. ${additionalMessage}`);
|
|
18
18
|
this.name = "RunningHttpInterceptorError";
|
|
19
19
|
}
|
|
20
20
|
};
|
|
@@ -174,6 +174,88 @@ __name(createCachedDynamicImport, "createCachedDynamicImport");
|
|
|
174
174
|
__name2(createCachedDynamicImport, "createCachedDynamicImport");
|
|
175
175
|
var createCachedDynamicImport_default = createCachedDynamicImport;
|
|
176
176
|
|
|
177
|
+
// ../zimic-utils/dist/logging/Logger.mjs
|
|
178
|
+
var Logger = class _Logger {
|
|
179
|
+
static {
|
|
180
|
+
__name(this, "_Logger");
|
|
181
|
+
}
|
|
182
|
+
static {
|
|
183
|
+
__name2(this, "Logger");
|
|
184
|
+
}
|
|
185
|
+
prefix;
|
|
186
|
+
raw;
|
|
187
|
+
constructor(options = {}) {
|
|
188
|
+
const { prefix } = options;
|
|
189
|
+
this.prefix = prefix;
|
|
190
|
+
this.raw = prefix ? new _Logger({ ...options, prefix: void 0 }) : this;
|
|
191
|
+
}
|
|
192
|
+
logWithLevel(level, ...messages) {
|
|
193
|
+
if (this.prefix) {
|
|
194
|
+
console[level](this.prefix, ...messages);
|
|
195
|
+
} else {
|
|
196
|
+
console[level](...messages);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
info(...messages) {
|
|
200
|
+
this.logWithLevel("log", ...messages);
|
|
201
|
+
}
|
|
202
|
+
warn(...messages) {
|
|
203
|
+
this.logWithLevel("warn", ...messages);
|
|
204
|
+
}
|
|
205
|
+
error(...messages) {
|
|
206
|
+
this.logWithLevel("error", ...messages);
|
|
207
|
+
}
|
|
208
|
+
table(headers, rows) {
|
|
209
|
+
const columnLengths = headers.map((header) => {
|
|
210
|
+
let maxValueLength = header.title.length;
|
|
211
|
+
for (const row of rows) {
|
|
212
|
+
const value = row[header.property];
|
|
213
|
+
if (value.length > maxValueLength) {
|
|
214
|
+
maxValueLength = value.length;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return maxValueLength;
|
|
218
|
+
});
|
|
219
|
+
const formattedRows = [];
|
|
220
|
+
const horizontalLine = columnLengths.map((length) => "\u2500".repeat(length));
|
|
221
|
+
formattedRows.push(horizontalLine, []);
|
|
222
|
+
for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
|
223
|
+
const header = headers[headerIndex];
|
|
224
|
+
const columnLength = columnLengths[headerIndex];
|
|
225
|
+
const value = header.title;
|
|
226
|
+
formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
|
|
227
|
+
}
|
|
228
|
+
formattedRows.push(horizontalLine);
|
|
229
|
+
for (const row of rows) {
|
|
230
|
+
formattedRows.push([]);
|
|
231
|
+
for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
|
232
|
+
const header = headers[headerIndex];
|
|
233
|
+
const columnLength = columnLengths[headerIndex];
|
|
234
|
+
const value = row[header.property];
|
|
235
|
+
formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
formattedRows.push(horizontalLine);
|
|
239
|
+
const formattedTable = formattedRows.map((row, index) => {
|
|
240
|
+
const isFirstLine = index === 0;
|
|
241
|
+
if (isFirstLine) {
|
|
242
|
+
return `\u250C\u2500${row.join("\u2500\u252C\u2500")}\u2500\u2510`;
|
|
243
|
+
}
|
|
244
|
+
const isLineAfterHeaders = index === 2;
|
|
245
|
+
if (isLineAfterHeaders) {
|
|
246
|
+
return `\u251C\u2500${row.join("\u2500\u253C\u2500")}\u2500\u2524`;
|
|
247
|
+
}
|
|
248
|
+
const isLastLine = index === formattedRows.length - 1;
|
|
249
|
+
if (isLastLine) {
|
|
250
|
+
return `\u2514\u2500${row.join("\u2500\u2534\u2500")}\u2500\u2518`;
|
|
251
|
+
}
|
|
252
|
+
return `\u2502 ${row.join(" \u2502 ")} \u2502`;
|
|
253
|
+
}).join("\n");
|
|
254
|
+
this.logWithLevel("log", formattedTable);
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var Logger_default = Logger;
|
|
258
|
+
|
|
177
259
|
// src/utils/environment.ts
|
|
178
260
|
function isServerSide() {
|
|
179
261
|
return typeof process !== "undefined" && typeof process.versions !== "undefined";
|
|
@@ -188,7 +270,10 @@ function isGlobalFileAvailable() {
|
|
|
188
270
|
}
|
|
189
271
|
__name(isGlobalFileAvailable, "isGlobalFileAvailable");
|
|
190
272
|
|
|
191
|
-
// src/utils/
|
|
273
|
+
// src/utils/logging.ts
|
|
274
|
+
var logger = new Logger_default({
|
|
275
|
+
prefix: color2.cyan("[@zimic/interceptor]")
|
|
276
|
+
});
|
|
192
277
|
function stringifyJSONToLog(value) {
|
|
193
278
|
return JSON.stringify(
|
|
194
279
|
value,
|
|
@@ -243,12 +328,6 @@ async function formatValueToLog(value, options = {}) {
|
|
|
243
328
|
});
|
|
244
329
|
}
|
|
245
330
|
__name(formatValueToLog, "formatValueToLog");
|
|
246
|
-
function logWithPrefix(messageOrMessages, options = {}) {
|
|
247
|
-
const { method = "log" } = options;
|
|
248
|
-
const messages = Array.isArray(messageOrMessages) ? messageOrMessages : [messageOrMessages];
|
|
249
|
-
console[method](color2.cyan("[@zimic/interceptor]"), ...messages);
|
|
250
|
-
}
|
|
251
|
-
__name(logWithPrefix, "logWithPrefix");
|
|
252
331
|
|
|
253
332
|
// src/http/requestHandler/errors/TimesCheckError.ts
|
|
254
333
|
function createMessageHeader({
|
|
@@ -1173,209 +1252,23 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
|
|
|
1173
1252
|
formatValueToLog(request.searchParams.toObject()),
|
|
1174
1253
|
formatValueToLog(request.body)
|
|
1175
1254
|
]);
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
`${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2.yellow("bypassed") : color2.red("rejected")}.
|
|
1255
|
+
logger[action === "bypass" ? "warn" : "error"](
|
|
1256
|
+
`${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2.yellow("bypassed") : color2.red("rejected")}.
|
|
1179
1257
|
|
|
1180
1258
|
`,
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
],
|
|
1190
|
-
{ method: action === "bypass" ? "warn" : "error" }
|
|
1259
|
+
`${request.method} ${request.url}`,
|
|
1260
|
+
"\n Headers:",
|
|
1261
|
+
formattedHeaders,
|
|
1262
|
+
"\n Search params:",
|
|
1263
|
+
formattedSearchParams,
|
|
1264
|
+
"\n Body:",
|
|
1265
|
+
formattedBody,
|
|
1266
|
+
"\n\nLearn more: https://github.com/zimicjs/zimic/wiki/api\u2010zimic\u2010interceptor\u2010http#unhandled-requests"
|
|
1191
1267
|
);
|
|
1192
1268
|
}
|
|
1193
1269
|
};
|
|
1194
1270
|
var HttpInterceptorWorker_default = HttpInterceptorWorker;
|
|
1195
1271
|
|
|
1196
|
-
// ../zimic-utils/dist/url/validateURLPathParams.mjs
|
|
1197
|
-
var DuplicatedPathParamError = class extends Error {
|
|
1198
|
-
static {
|
|
1199
|
-
__name(this, "DuplicatedPathParamError");
|
|
1200
|
-
}
|
|
1201
|
-
static {
|
|
1202
|
-
__name2(this, "DuplicatedPathParamError");
|
|
1203
|
-
}
|
|
1204
|
-
constructor(url, paramName) {
|
|
1205
|
-
super(
|
|
1206
|
-
`The path parameter '${paramName}' appears more than once in the URL '${url.toString()}'. This is not supported. Please make sure that each parameter is unique.`
|
|
1207
|
-
);
|
|
1208
|
-
this.name = "DuplicatedPathParamError";
|
|
1209
|
-
}
|
|
1210
|
-
};
|
|
1211
|
-
function validateURLPathParams(url) {
|
|
1212
|
-
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
|
1213
|
-
const matches = url.toString().matchAll(URL_PATH_PARAM_REGEX);
|
|
1214
|
-
const uniqueParamNames = /* @__PURE__ */ new Set();
|
|
1215
|
-
for (const match of matches) {
|
|
1216
|
-
const paramName = match[1];
|
|
1217
|
-
if (uniqueParamNames.has(paramName)) {
|
|
1218
|
-
throw new DuplicatedPathParamError(url, paramName);
|
|
1219
|
-
}
|
|
1220
|
-
uniqueParamNames.add(paramName);
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
__name(validateURLPathParams, "validateURLPathParams");
|
|
1224
|
-
__name2(validateURLPathParams, "validateURLPathParams");
|
|
1225
|
-
var validateURLPathParams_default = validateURLPathParams;
|
|
1226
|
-
var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
1227
|
-
static {
|
|
1228
|
-
__name(this, "LocalHttpInterceptorWorker");
|
|
1229
|
-
}
|
|
1230
|
-
internalWorker;
|
|
1231
|
-
defaultHttpHandler;
|
|
1232
|
-
httpHandlerGroups = [];
|
|
1233
|
-
constructor(_options) {
|
|
1234
|
-
super();
|
|
1235
|
-
this.defaultHttpHandler = http.all("*", async (context) => {
|
|
1236
|
-
const request = context.request;
|
|
1237
|
-
return this.bypassOrRejectUnhandledRequest(request);
|
|
1238
|
-
});
|
|
1239
|
-
}
|
|
1240
|
-
get type() {
|
|
1241
|
-
return "local";
|
|
1242
|
-
}
|
|
1243
|
-
get internalWorkerOrThrow() {
|
|
1244
|
-
if (!this.internalWorker) {
|
|
1245
|
-
throw new NotRunningHttpInterceptorError_default();
|
|
1246
|
-
}
|
|
1247
|
-
return this.internalWorker;
|
|
1248
|
-
}
|
|
1249
|
-
get internalWorkerOrCreate() {
|
|
1250
|
-
this.internalWorker ??= this.createInternalWorker();
|
|
1251
|
-
return this.internalWorker;
|
|
1252
|
-
}
|
|
1253
|
-
createInternalWorker() {
|
|
1254
|
-
if (isServerSide() && "setupServer" in mswNode) {
|
|
1255
|
-
return mswNode.setupServer(this.defaultHttpHandler);
|
|
1256
|
-
}
|
|
1257
|
-
if (isClientSide() && "setupWorker" in mswBrowser) {
|
|
1258
|
-
return mswBrowser.setupWorker(this.defaultHttpHandler);
|
|
1259
|
-
}
|
|
1260
|
-
throw new UnknownHttpInterceptorPlatformError_default();
|
|
1261
|
-
}
|
|
1262
|
-
async start() {
|
|
1263
|
-
await super.sharedStart(async () => {
|
|
1264
|
-
const internalWorker = this.internalWorkerOrCreate;
|
|
1265
|
-
const sharedOptions = {
|
|
1266
|
-
onUnhandledRequest: "bypass"
|
|
1267
|
-
};
|
|
1268
|
-
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1269
|
-
this.platform = "browser";
|
|
1270
|
-
await this.startInBrowser(internalWorker, sharedOptions);
|
|
1271
|
-
} else {
|
|
1272
|
-
this.platform = "node";
|
|
1273
|
-
this.startInNode(internalWorker, sharedOptions);
|
|
1274
|
-
}
|
|
1275
|
-
this.isRunning = true;
|
|
1276
|
-
});
|
|
1277
|
-
}
|
|
1278
|
-
async startInBrowser(internalWorker, sharedOptions) {
|
|
1279
|
-
try {
|
|
1280
|
-
await internalWorker.start({ ...sharedOptions, quiet: true });
|
|
1281
|
-
} catch (error) {
|
|
1282
|
-
this.handleBrowserWorkerStartError(error);
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
handleBrowserWorkerStartError(error) {
|
|
1286
|
-
if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
|
|
1287
|
-
throw new UnregisteredBrowserServiceWorkerError_default();
|
|
1288
|
-
}
|
|
1289
|
-
throw error;
|
|
1290
|
-
}
|
|
1291
|
-
startInNode(internalWorker, sharedOptions) {
|
|
1292
|
-
internalWorker.listen(sharedOptions);
|
|
1293
|
-
}
|
|
1294
|
-
async stop() {
|
|
1295
|
-
await super.sharedStop(() => {
|
|
1296
|
-
const internalWorker = this.internalWorkerOrCreate;
|
|
1297
|
-
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1298
|
-
this.stopInBrowser(internalWorker);
|
|
1299
|
-
} else {
|
|
1300
|
-
this.stopInNode(internalWorker);
|
|
1301
|
-
}
|
|
1302
|
-
this.clearHandlers();
|
|
1303
|
-
this.internalWorker = void 0;
|
|
1304
|
-
this.isRunning = false;
|
|
1305
|
-
});
|
|
1306
|
-
}
|
|
1307
|
-
stopInBrowser(internalWorker) {
|
|
1308
|
-
internalWorker.stop();
|
|
1309
|
-
}
|
|
1310
|
-
stopInNode(internalWorker) {
|
|
1311
|
-
internalWorker.close();
|
|
1312
|
-
}
|
|
1313
|
-
isInternalBrowserWorker(worker) {
|
|
1314
|
-
return "start" in worker && "stop" in worker;
|
|
1315
|
-
}
|
|
1316
|
-
hasInternalBrowserWorker() {
|
|
1317
|
-
return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
|
|
1318
|
-
}
|
|
1319
|
-
hasInternalNodeWorker() {
|
|
1320
|
-
return !this.hasInternalBrowserWorker();
|
|
1321
|
-
}
|
|
1322
|
-
use(interceptor, method, rawURL, createResponse) {
|
|
1323
|
-
const lowercaseMethod = method.toLowerCase();
|
|
1324
|
-
const url = new URL(rawURL);
|
|
1325
|
-
excludeURLParams_default(url);
|
|
1326
|
-
validateURLPathParams_default(url);
|
|
1327
|
-
const httpHandler = http[lowercaseMethod](url.toString(), async (context) => {
|
|
1328
|
-
const request = context.request;
|
|
1329
|
-
const requestClone = request.clone();
|
|
1330
|
-
let response = null;
|
|
1331
|
-
try {
|
|
1332
|
-
response = await createResponse({ ...context, request });
|
|
1333
|
-
} catch (error) {
|
|
1334
|
-
console.error(error);
|
|
1335
|
-
}
|
|
1336
|
-
if (!response) {
|
|
1337
|
-
return this.bypassOrRejectUnhandledRequest(requestClone);
|
|
1338
|
-
}
|
|
1339
|
-
if (context.request.method === "HEAD") {
|
|
1340
|
-
return new Response(null, {
|
|
1341
|
-
status: response.status,
|
|
1342
|
-
statusText: response.statusText,
|
|
1343
|
-
headers: response.headers
|
|
1344
|
-
});
|
|
1345
|
-
}
|
|
1346
|
-
return response;
|
|
1347
|
-
});
|
|
1348
|
-
this.internalWorkerOrThrow.use(httpHandler);
|
|
1349
|
-
this.httpHandlerGroups.push({ interceptor, httpHandler });
|
|
1350
|
-
}
|
|
1351
|
-
async bypassOrRejectUnhandledRequest(request) {
|
|
1352
|
-
const requestClone = request.clone();
|
|
1353
|
-
const strategy = await super.getUnhandledRequestStrategy(request, "local");
|
|
1354
|
-
await super.logUnhandledRequestIfNecessary(requestClone, strategy);
|
|
1355
|
-
if (strategy?.action === "reject") {
|
|
1356
|
-
return Response.error();
|
|
1357
|
-
} else {
|
|
1358
|
-
return passthrough();
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
clearHandlers() {
|
|
1362
|
-
this.internalWorkerOrThrow.resetHandlers();
|
|
1363
|
-
this.httpHandlerGroups = [];
|
|
1364
|
-
}
|
|
1365
|
-
clearInterceptorHandlers(interceptor) {
|
|
1366
|
-
const groupToRemoveIndex = this.httpHandlerGroups.findIndex((group) => group.interceptor === interceptor);
|
|
1367
|
-
removeArrayIndex(this.httpHandlerGroups, groupToRemoveIndex);
|
|
1368
|
-
this.internalWorkerOrThrow.resetHandlers();
|
|
1369
|
-
for (const { httpHandler } of this.httpHandlerGroups) {
|
|
1370
|
-
this.internalWorkerOrThrow.use(httpHandler);
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
get interceptorsWithHandlers() {
|
|
1374
|
-
return this.httpHandlerGroups.map((group) => group.interceptor);
|
|
1375
|
-
}
|
|
1376
|
-
};
|
|
1377
|
-
var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
|
|
1378
|
-
|
|
1379
1272
|
// src/http/requestHandler/RemoteHttpRequestHandler.ts
|
|
1380
1273
|
var PENDING_PROPERTIES = /* @__PURE__ */ new Set(["then"]);
|
|
1381
1274
|
var RemoteHttpRequestHandler = class {
|
|
@@ -1485,9 +1378,11 @@ var HttpInterceptorClient = class {
|
|
|
1485
1378
|
static {
|
|
1486
1379
|
__name(this, "HttpInterceptorClient");
|
|
1487
1380
|
}
|
|
1488
|
-
worker;
|
|
1489
1381
|
store;
|
|
1490
1382
|
_baseURL;
|
|
1383
|
+
createWorker;
|
|
1384
|
+
deleteWorker;
|
|
1385
|
+
worker;
|
|
1491
1386
|
requestSaving;
|
|
1492
1387
|
numberOfSavedRequests = 0;
|
|
1493
1388
|
onUnhandledRequest;
|
|
@@ -1503,9 +1398,10 @@ var HttpInterceptorClient = class {
|
|
|
1503
1398
|
OPTIONS: /* @__PURE__ */ new Map()
|
|
1504
1399
|
};
|
|
1505
1400
|
constructor(options) {
|
|
1506
|
-
this.worker = options.worker;
|
|
1507
1401
|
this.store = options.store;
|
|
1508
1402
|
this.baseURL = options.baseURL;
|
|
1403
|
+
this.createWorker = options.createWorker;
|
|
1404
|
+
this.deleteWorker = options.deleteWorker;
|
|
1509
1405
|
this.requestSaving = {
|
|
1510
1406
|
enabled: options.requestSaving?.enabled ?? this.getDefaultRequestSavingEnabled(),
|
|
1511
1407
|
safeLimit: options.requestSaving?.safeLimit ?? DEFAULT_REQUEST_SAVING_SAFE_LIMIT
|
|
@@ -1535,32 +1431,49 @@ var HttpInterceptorClient = class {
|
|
|
1535
1431
|
}
|
|
1536
1432
|
return this.baseURL.href;
|
|
1537
1433
|
}
|
|
1434
|
+
get workerOrThrow() {
|
|
1435
|
+
if (!this.worker) {
|
|
1436
|
+
throw new NotRunningHttpInterceptorError_default();
|
|
1437
|
+
}
|
|
1438
|
+
return this.worker;
|
|
1439
|
+
}
|
|
1538
1440
|
get platform() {
|
|
1539
|
-
return this.worker
|
|
1441
|
+
return this.worker?.platform ?? null;
|
|
1540
1442
|
}
|
|
1541
1443
|
async start() {
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1444
|
+
try {
|
|
1445
|
+
this.worker = this.createWorker();
|
|
1446
|
+
await this.worker.start();
|
|
1447
|
+
this.worker.registerRunningInterceptor(this);
|
|
1448
|
+
this.markAsRunning(true);
|
|
1449
|
+
} catch (error) {
|
|
1450
|
+
await this.stop();
|
|
1451
|
+
throw error;
|
|
1452
|
+
}
|
|
1545
1453
|
}
|
|
1546
1454
|
async stop() {
|
|
1547
|
-
this.
|
|
1548
|
-
this.
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1455
|
+
this.worker?.unregisterRunningInterceptor(this);
|
|
1456
|
+
const isLastRunningInterceptor = this.numberOfRunningInterceptors === 0 || this.numberOfRunningInterceptors === 1;
|
|
1457
|
+
if (isLastRunningInterceptor) {
|
|
1458
|
+
await this.worker?.stop();
|
|
1459
|
+
this.deleteWorker();
|
|
1552
1460
|
}
|
|
1461
|
+
this.markAsRunning(false);
|
|
1462
|
+
this.worker = void 0;
|
|
1553
1463
|
}
|
|
1554
1464
|
markAsRunning(isRunning) {
|
|
1555
|
-
if (this.
|
|
1465
|
+
if (this.workerOrThrow.type === "local") {
|
|
1556
1466
|
this.store.markLocalInterceptorAsRunning(this, isRunning);
|
|
1557
1467
|
} else {
|
|
1558
1468
|
this.store.markRemoteInterceptorAsRunning(this, isRunning, this.baseURL);
|
|
1559
1469
|
}
|
|
1560
1470
|
this.isRunning = isRunning;
|
|
1561
1471
|
}
|
|
1562
|
-
numberOfRunningInterceptors() {
|
|
1563
|
-
if (this.
|
|
1472
|
+
get numberOfRunningInterceptors() {
|
|
1473
|
+
if (!this.isRunning) {
|
|
1474
|
+
return 0;
|
|
1475
|
+
}
|
|
1476
|
+
if (this.workerOrThrow.type === "local") {
|
|
1564
1477
|
return this.store.numberOfRunningLocalInterceptors;
|
|
1565
1478
|
} else {
|
|
1566
1479
|
return this.store.numberOfRunningRemoteInterceptors(this.baseURL);
|
|
@@ -1609,7 +1522,7 @@ var HttpInterceptorClient = class {
|
|
|
1609
1522
|
this.handlerClientsByMethod[handler.method].set(handler.path, handlerClients);
|
|
1610
1523
|
const url = joinURL_default(this.baseURLAsString, handler.path);
|
|
1611
1524
|
const urlRegex = createRegExpFromURL_default(url);
|
|
1612
|
-
const registrationResult = this.
|
|
1525
|
+
const registrationResult = this.workerOrThrow.use(this, handler.method, url, async (context) => {
|
|
1613
1526
|
const response = await this.handleInterceptedRequest(
|
|
1614
1527
|
urlRegex,
|
|
1615
1528
|
handler.method,
|
|
@@ -1668,10 +1581,9 @@ var HttpInterceptorClient = class {
|
|
|
1668
1581
|
}
|
|
1669
1582
|
}
|
|
1670
1583
|
clear(options = {}) {
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
const clearResults = [];
|
|
1584
|
+
const clearResults = [
|
|
1585
|
+
this.workerOrThrow.clearInterceptorHandlers(this)
|
|
1586
|
+
];
|
|
1675
1587
|
for (const method of HTTP_METHODS) {
|
|
1676
1588
|
const newClearResults = this.clearMethodHandlers(method);
|
|
1677
1589
|
for (const result of newClearResults) {
|
|
@@ -1680,8 +1592,6 @@ var HttpInterceptorClient = class {
|
|
|
1680
1592
|
const handlersByPath = this.handlerClientsByMethod[method];
|
|
1681
1593
|
handlersByPath.clear();
|
|
1682
1594
|
}
|
|
1683
|
-
const clearResult = this.worker.clearInterceptorHandlers(this);
|
|
1684
|
-
clearResults.push(clearResult);
|
|
1685
1595
|
if (options.onCommitSuccess) {
|
|
1686
1596
|
void Promise.all(clearResults).then(options.onCommitSuccess, options.onCommitError);
|
|
1687
1597
|
}
|
|
@@ -1699,6 +1609,189 @@ var HttpInterceptorClient = class {
|
|
|
1699
1609
|
};
|
|
1700
1610
|
var HttpInterceptorClient_default = HttpInterceptorClient;
|
|
1701
1611
|
|
|
1612
|
+
// ../zimic-utils/dist/url/validateURLPathParams.mjs
|
|
1613
|
+
var DuplicatedPathParamError = class extends Error {
|
|
1614
|
+
static {
|
|
1615
|
+
__name(this, "DuplicatedPathParamError");
|
|
1616
|
+
}
|
|
1617
|
+
static {
|
|
1618
|
+
__name2(this, "DuplicatedPathParamError");
|
|
1619
|
+
}
|
|
1620
|
+
constructor(url, paramName) {
|
|
1621
|
+
super(
|
|
1622
|
+
`The path parameter '${paramName}' appears more than once in the URL '${url.toString()}'. This is not supported. Please make sure that each parameter is unique.`
|
|
1623
|
+
);
|
|
1624
|
+
this.name = "DuplicatedPathParamError";
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1627
|
+
function validateURLPathParams(url) {
|
|
1628
|
+
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
|
1629
|
+
const matches = url.toString().matchAll(URL_PATH_PARAM_REGEX);
|
|
1630
|
+
const uniqueParamNames = /* @__PURE__ */ new Set();
|
|
1631
|
+
for (const match of matches) {
|
|
1632
|
+
const paramName = match[1];
|
|
1633
|
+
if (uniqueParamNames.has(paramName)) {
|
|
1634
|
+
throw new DuplicatedPathParamError(url, paramName);
|
|
1635
|
+
}
|
|
1636
|
+
uniqueParamNames.add(paramName);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
__name(validateURLPathParams, "validateURLPathParams");
|
|
1640
|
+
__name2(validateURLPathParams, "validateURLPathParams");
|
|
1641
|
+
var validateURLPathParams_default = validateURLPathParams;
|
|
1642
|
+
var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
1643
|
+
static {
|
|
1644
|
+
__name(this, "LocalHttpInterceptorWorker");
|
|
1645
|
+
}
|
|
1646
|
+
internalWorker;
|
|
1647
|
+
defaultHttpHandler;
|
|
1648
|
+
httpHandlerGroups = [];
|
|
1649
|
+
constructor(_options) {
|
|
1650
|
+
super();
|
|
1651
|
+
this.defaultHttpHandler = http.all("*", async (context) => {
|
|
1652
|
+
const request = context.request;
|
|
1653
|
+
return this.bypassOrRejectUnhandledRequest(request);
|
|
1654
|
+
});
|
|
1655
|
+
}
|
|
1656
|
+
get type() {
|
|
1657
|
+
return "local";
|
|
1658
|
+
}
|
|
1659
|
+
get internalWorkerOrThrow() {
|
|
1660
|
+
if (!this.internalWorker) {
|
|
1661
|
+
throw new NotRunningHttpInterceptorError_default();
|
|
1662
|
+
}
|
|
1663
|
+
return this.internalWorker;
|
|
1664
|
+
}
|
|
1665
|
+
get internalWorkerOrCreate() {
|
|
1666
|
+
this.internalWorker ??= this.createInternalWorker();
|
|
1667
|
+
return this.internalWorker;
|
|
1668
|
+
}
|
|
1669
|
+
createInternalWorker() {
|
|
1670
|
+
if (isServerSide() && "setupServer" in mswNode) {
|
|
1671
|
+
return mswNode.setupServer(this.defaultHttpHandler);
|
|
1672
|
+
}
|
|
1673
|
+
if (isClientSide() && "setupWorker" in mswBrowser) {
|
|
1674
|
+
return mswBrowser.setupWorker(this.defaultHttpHandler);
|
|
1675
|
+
}
|
|
1676
|
+
throw new UnknownHttpInterceptorPlatformError_default();
|
|
1677
|
+
}
|
|
1678
|
+
async start() {
|
|
1679
|
+
await super.sharedStart(async () => {
|
|
1680
|
+
const internalWorker = this.internalWorkerOrCreate;
|
|
1681
|
+
const sharedOptions = {
|
|
1682
|
+
onUnhandledRequest: "bypass"
|
|
1683
|
+
};
|
|
1684
|
+
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1685
|
+
this.platform = "browser";
|
|
1686
|
+
await this.startInBrowser(internalWorker, sharedOptions);
|
|
1687
|
+
} else {
|
|
1688
|
+
this.platform = "node";
|
|
1689
|
+
this.startInNode(internalWorker, sharedOptions);
|
|
1690
|
+
}
|
|
1691
|
+
this.isRunning = true;
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
async startInBrowser(internalWorker, sharedOptions) {
|
|
1695
|
+
try {
|
|
1696
|
+
await internalWorker.start({ ...sharedOptions, quiet: true });
|
|
1697
|
+
} catch (error) {
|
|
1698
|
+
this.handleBrowserWorkerStartError(error);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
handleBrowserWorkerStartError(error) {
|
|
1702
|
+
if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
|
|
1703
|
+
throw new UnregisteredBrowserServiceWorkerError_default();
|
|
1704
|
+
}
|
|
1705
|
+
throw error;
|
|
1706
|
+
}
|
|
1707
|
+
startInNode(internalWorker, sharedOptions) {
|
|
1708
|
+
internalWorker.listen(sharedOptions);
|
|
1709
|
+
}
|
|
1710
|
+
async stop() {
|
|
1711
|
+
await super.sharedStop(() => {
|
|
1712
|
+
const internalWorker = this.internalWorkerOrCreate;
|
|
1713
|
+
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1714
|
+
this.stopInBrowser(internalWorker);
|
|
1715
|
+
} else {
|
|
1716
|
+
this.stopInNode(internalWorker);
|
|
1717
|
+
}
|
|
1718
|
+
this.clearHandlers();
|
|
1719
|
+
this.internalWorker = void 0;
|
|
1720
|
+
this.isRunning = false;
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
stopInBrowser(internalWorker) {
|
|
1724
|
+
internalWorker.stop();
|
|
1725
|
+
}
|
|
1726
|
+
stopInNode(internalWorker) {
|
|
1727
|
+
internalWorker.close();
|
|
1728
|
+
}
|
|
1729
|
+
isInternalBrowserWorker(worker) {
|
|
1730
|
+
return "start" in worker && "stop" in worker;
|
|
1731
|
+
}
|
|
1732
|
+
hasInternalBrowserWorker() {
|
|
1733
|
+
return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
|
|
1734
|
+
}
|
|
1735
|
+
hasInternalNodeWorker() {
|
|
1736
|
+
return !this.hasInternalBrowserWorker();
|
|
1737
|
+
}
|
|
1738
|
+
use(interceptor, method, rawURL, createResponse) {
|
|
1739
|
+
const lowercaseMethod = method.toLowerCase();
|
|
1740
|
+
const url = new URL(rawURL);
|
|
1741
|
+
excludeURLParams_default(url);
|
|
1742
|
+
validateURLPathParams_default(url);
|
|
1743
|
+
const httpHandler = http[lowercaseMethod](url.toString(), async (context) => {
|
|
1744
|
+
const request = context.request;
|
|
1745
|
+
const requestClone = request.clone();
|
|
1746
|
+
let response = null;
|
|
1747
|
+
try {
|
|
1748
|
+
response = await createResponse({ ...context, request });
|
|
1749
|
+
} catch (error) {
|
|
1750
|
+
console.error(error);
|
|
1751
|
+
}
|
|
1752
|
+
if (!response) {
|
|
1753
|
+
return this.bypassOrRejectUnhandledRequest(requestClone);
|
|
1754
|
+
}
|
|
1755
|
+
if (context.request.method === "HEAD") {
|
|
1756
|
+
return new Response(null, {
|
|
1757
|
+
status: response.status,
|
|
1758
|
+
statusText: response.statusText,
|
|
1759
|
+
headers: response.headers
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
return response;
|
|
1763
|
+
});
|
|
1764
|
+
this.internalWorkerOrThrow.use(httpHandler);
|
|
1765
|
+
this.httpHandlerGroups.push({ interceptor, httpHandler });
|
|
1766
|
+
}
|
|
1767
|
+
async bypassOrRejectUnhandledRequest(request) {
|
|
1768
|
+
const requestClone = request.clone();
|
|
1769
|
+
const strategy = await super.getUnhandledRequestStrategy(request, "local");
|
|
1770
|
+
await super.logUnhandledRequestIfNecessary(requestClone, strategy);
|
|
1771
|
+
if (strategy?.action === "reject") {
|
|
1772
|
+
return Response.error();
|
|
1773
|
+
} else {
|
|
1774
|
+
return passthrough();
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
clearHandlers() {
|
|
1778
|
+
this.internalWorkerOrThrow.resetHandlers();
|
|
1779
|
+
this.httpHandlerGroups = [];
|
|
1780
|
+
}
|
|
1781
|
+
clearInterceptorHandlers(interceptor) {
|
|
1782
|
+
const groupToRemoveIndex = this.httpHandlerGroups.findIndex((group) => group.interceptor === interceptor);
|
|
1783
|
+
removeArrayIndex(this.httpHandlerGroups, groupToRemoveIndex);
|
|
1784
|
+
this.internalWorkerOrThrow.resetHandlers();
|
|
1785
|
+
for (const { httpHandler } of this.httpHandlerGroups) {
|
|
1786
|
+
this.internalWorkerOrThrow.use(httpHandler);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
get interceptorsWithHandlers() {
|
|
1790
|
+
return this.httpHandlerGroups.map((group) => group.interceptor);
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
|
|
1794
|
+
|
|
1702
1795
|
// src/utils/crypto.ts
|
|
1703
1796
|
var importCrypto = createCachedDynamicImport_default(async () => {
|
|
1704
1797
|
const globalCrypto = globalThis.crypto;
|
|
@@ -1762,6 +1855,19 @@ async function serializeResponse(response) {
|
|
|
1762
1855
|
}
|
|
1763
1856
|
__name(serializeResponse, "serializeResponse");
|
|
1764
1857
|
|
|
1858
|
+
// src/webSocket/errors/UnauthorizedWebSocketConnectionError.ts
|
|
1859
|
+
var UnauthorizedWebSocketConnectionError = class extends Error {
|
|
1860
|
+
constructor(event) {
|
|
1861
|
+
super(`${event.reason} (code ${event.code})`);
|
|
1862
|
+
this.event = event;
|
|
1863
|
+
this.name = "UnauthorizedWebSocketConnectionError";
|
|
1864
|
+
}
|
|
1865
|
+
static {
|
|
1866
|
+
__name(this, "UnauthorizedWebSocketConnectionError");
|
|
1867
|
+
}
|
|
1868
|
+
};
|
|
1869
|
+
var UnauthorizedWebSocketConnectionError_default = UnauthorizedWebSocketConnectionError;
|
|
1870
|
+
|
|
1765
1871
|
// src/utils/webSocket.ts
|
|
1766
1872
|
var WebSocketTimeoutError = class extends Error {
|
|
1767
1873
|
static {
|
|
@@ -1807,29 +1913,58 @@ var WebSocketCloseTimeoutError = class extends WebSocketTimeoutError {
|
|
|
1807
1913
|
var DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT = 60 * 1e3;
|
|
1808
1914
|
var DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT = 3 * 60 * 1e3;
|
|
1809
1915
|
async function waitForOpenClientSocket(socket, options = {}) {
|
|
1810
|
-
const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;
|
|
1916
|
+
const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT, waitForAuthentication = false } = options;
|
|
1811
1917
|
const isAlreadyOpen = socket.readyState === socket.OPEN;
|
|
1812
1918
|
if (isAlreadyOpen) {
|
|
1813
1919
|
return;
|
|
1814
1920
|
}
|
|
1815
1921
|
await new Promise((resolve, reject) => {
|
|
1816
|
-
function
|
|
1922
|
+
function removeAllSocketListeners() {
|
|
1923
|
+
socket.removeEventListener("message", handleSocketMessage);
|
|
1817
1924
|
socket.removeEventListener("open", handleOpenSuccess);
|
|
1925
|
+
socket.removeEventListener("error", handleOpenError);
|
|
1926
|
+
socket.removeEventListener("close", handleClose);
|
|
1927
|
+
}
|
|
1928
|
+
__name(removeAllSocketListeners, "removeAllSocketListeners");
|
|
1929
|
+
function handleOpenError(error) {
|
|
1930
|
+
removeAllSocketListeners();
|
|
1818
1931
|
reject(error);
|
|
1819
1932
|
}
|
|
1820
1933
|
__name(handleOpenError, "handleOpenError");
|
|
1934
|
+
function handleClose(event) {
|
|
1935
|
+
const isUnauthorized = event.code === 1008;
|
|
1936
|
+
if (isUnauthorized) {
|
|
1937
|
+
const unauthorizedError = new UnauthorizedWebSocketConnectionError_default(event);
|
|
1938
|
+
handleOpenError(unauthorizedError);
|
|
1939
|
+
} else {
|
|
1940
|
+
handleOpenError(event);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
__name(handleClose, "handleClose");
|
|
1821
1944
|
const openTimeout = setTimeout(() => {
|
|
1822
1945
|
const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);
|
|
1823
1946
|
handleOpenError(timeoutError);
|
|
1824
1947
|
}, timeoutDuration);
|
|
1825
1948
|
function handleOpenSuccess() {
|
|
1826
|
-
|
|
1949
|
+
removeAllSocketListeners();
|
|
1827
1950
|
clearTimeout(openTimeout);
|
|
1828
1951
|
resolve();
|
|
1829
1952
|
}
|
|
1830
1953
|
__name(handleOpenSuccess, "handleOpenSuccess");
|
|
1831
|
-
|
|
1954
|
+
function handleSocketMessage(message) {
|
|
1955
|
+
const hasValidAuth = message.data === "socket:auth:valid";
|
|
1956
|
+
if (hasValidAuth) {
|
|
1957
|
+
handleOpenSuccess();
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
__name(handleSocketMessage, "handleSocketMessage");
|
|
1961
|
+
if (waitForAuthentication) {
|
|
1962
|
+
socket.addEventListener("message", handleSocketMessage);
|
|
1963
|
+
} else {
|
|
1964
|
+
socket.addEventListener("open", handleOpenSuccess);
|
|
1965
|
+
}
|
|
1832
1966
|
socket.addEventListener("error", handleOpenError);
|
|
1967
|
+
socket.addEventListener("close", handleClose);
|
|
1833
1968
|
});
|
|
1834
1969
|
}
|
|
1835
1970
|
__name(waitForOpenClientSocket, "waitForOpenClientSocket");
|
|
@@ -1840,28 +1975,36 @@ async function closeClientSocket(socket, options = {}) {
|
|
|
1840
1975
|
return;
|
|
1841
1976
|
}
|
|
1842
1977
|
await new Promise((resolve, reject) => {
|
|
1843
|
-
function
|
|
1844
|
-
socket.removeEventListener("
|
|
1978
|
+
function removeAllSocketListeners() {
|
|
1979
|
+
socket.removeEventListener("error", handleError);
|
|
1980
|
+
socket.removeEventListener("close", handleClose);
|
|
1981
|
+
}
|
|
1982
|
+
__name(removeAllSocketListeners, "removeAllSocketListeners");
|
|
1983
|
+
function handleError(error) {
|
|
1984
|
+
removeAllSocketListeners();
|
|
1845
1985
|
reject(error);
|
|
1846
1986
|
}
|
|
1847
|
-
__name(
|
|
1987
|
+
__name(handleError, "handleError");
|
|
1848
1988
|
const closeTimeout = setTimeout(() => {
|
|
1849
1989
|
const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);
|
|
1850
|
-
|
|
1990
|
+
handleError(timeoutError);
|
|
1851
1991
|
}, timeoutDuration);
|
|
1852
|
-
function
|
|
1853
|
-
|
|
1992
|
+
function handleClose() {
|
|
1993
|
+
removeAllSocketListeners();
|
|
1854
1994
|
clearTimeout(closeTimeout);
|
|
1855
1995
|
resolve();
|
|
1856
1996
|
}
|
|
1857
|
-
__name(
|
|
1858
|
-
socket.addEventListener("error",
|
|
1859
|
-
socket.addEventListener("close",
|
|
1997
|
+
__name(handleClose, "handleClose");
|
|
1998
|
+
socket.addEventListener("error", handleError);
|
|
1999
|
+
socket.addEventListener("close", handleClose);
|
|
1860
2000
|
socket.close();
|
|
1861
2001
|
});
|
|
1862
2002
|
}
|
|
1863
2003
|
__name(closeClientSocket, "closeClientSocket");
|
|
1864
2004
|
|
|
2005
|
+
// src/webSocket/constants.ts
|
|
2006
|
+
var WEB_SOCKET_CONTROL_MESSAGES = Object.freeze(["socket:auth:valid"]);
|
|
2007
|
+
|
|
1865
2008
|
// src/webSocket/errors/InvalidWebSocketMessage.ts
|
|
1866
2009
|
var InvalidWebSocketMessage = class extends Error {
|
|
1867
2010
|
static {
|
|
@@ -1902,8 +2045,11 @@ var WebSocketHandler = class {
|
|
|
1902
2045
|
this.socketTimeout = options.socketTimeout ?? DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT;
|
|
1903
2046
|
this.messageTimeout = options.messageTimeout ?? DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT;
|
|
1904
2047
|
}
|
|
1905
|
-
async registerSocket(socket) {
|
|
1906
|
-
const openPromise = waitForOpenClientSocket(socket, {
|
|
2048
|
+
async registerSocket(socket, options = {}) {
|
|
2049
|
+
const openPromise = waitForOpenClientSocket(socket, {
|
|
2050
|
+
timeout: this.socketTimeout,
|
|
2051
|
+
waitForAuthentication: options.waitForAuthentication
|
|
2052
|
+
});
|
|
1907
2053
|
const handleSocketMessage = /* @__PURE__ */ __name(async (rawMessage) => {
|
|
1908
2054
|
await this.handleSocketMessage(socket, rawMessage);
|
|
1909
2055
|
}, "handleSocketMessage");
|
|
@@ -1916,8 +2062,8 @@ var WebSocketHandler = class {
|
|
|
1916
2062
|
socket.addEventListener("error", handleSocketError);
|
|
1917
2063
|
const handleSocketClose = /* @__PURE__ */ __name(() => {
|
|
1918
2064
|
socket.removeEventListener("message", handleSocketMessage);
|
|
1919
|
-
socket.removeEventListener("error", handleSocketError);
|
|
1920
2065
|
socket.removeEventListener("close", handleSocketClose);
|
|
2066
|
+
socket.removeEventListener("error", handleSocketError);
|
|
1921
2067
|
this.removeSocket(socket);
|
|
1922
2068
|
}, "handleSocketClose");
|
|
1923
2069
|
socket.addEventListener("close", handleSocketClose);
|
|
@@ -1925,6 +2071,9 @@ var WebSocketHandler = class {
|
|
|
1925
2071
|
}
|
|
1926
2072
|
handleSocketMessage = /* @__PURE__ */ __name(async (socket, rawMessage) => {
|
|
1927
2073
|
try {
|
|
2074
|
+
if (this.isControlMessageData(rawMessage.data)) {
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
1928
2077
|
const stringifiedMessageData = this.readRawMessageData(rawMessage.data);
|
|
1929
2078
|
const parsedMessageData = this.parseMessage(stringifiedMessageData);
|
|
1930
2079
|
await this.notifyListeners(parsedMessageData, socket);
|
|
@@ -1932,6 +2081,9 @@ var WebSocketHandler = class {
|
|
|
1932
2081
|
console.error(error);
|
|
1933
2082
|
}
|
|
1934
2083
|
}, "handleSocketMessage");
|
|
2084
|
+
isControlMessageData(messageData) {
|
|
2085
|
+
return typeof messageData === "string" && WEB_SOCKET_CONTROL_MESSAGES.includes(messageData);
|
|
2086
|
+
}
|
|
1935
2087
|
readRawMessageData(data) {
|
|
1936
2088
|
if (typeof data === "string") {
|
|
1937
2089
|
return data;
|
|
@@ -1946,7 +2098,7 @@ var WebSocketHandler = class {
|
|
|
1946
2098
|
} catch {
|
|
1947
2099
|
throw new InvalidWebSocketMessage_default(stringifiedMessage);
|
|
1948
2100
|
}
|
|
1949
|
-
if (!this.
|
|
2101
|
+
if (!this.isMessage(parsedMessage)) {
|
|
1950
2102
|
throw new InvalidWebSocketMessage_default(stringifiedMessage);
|
|
1951
2103
|
}
|
|
1952
2104
|
if (this.isReplyMessage(parsedMessage)) {
|
|
@@ -1963,7 +2115,7 @@ var WebSocketHandler = class {
|
|
|
1963
2115
|
data: parsedMessage.data
|
|
1964
2116
|
};
|
|
1965
2117
|
}
|
|
1966
|
-
|
|
2118
|
+
isMessage(message) {
|
|
1967
2119
|
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");
|
|
1968
2120
|
}
|
|
1969
2121
|
async notifyListeners(message, socket) {
|
|
@@ -2145,10 +2297,11 @@ var WebSocketClient = class extends WebSocketHandler_default {
|
|
|
2145
2297
|
get isRunning() {
|
|
2146
2298
|
return this.socket !== void 0 && this.socket.readyState === this.socket.OPEN;
|
|
2147
2299
|
}
|
|
2148
|
-
async start() {
|
|
2149
|
-
|
|
2300
|
+
async start(options = {}) {
|
|
2301
|
+
const parametersAsString = options.parameters ? Object.entries(options.parameters).map(([key, value]) => `${key}=${value}`).map(encodeURIComponent) : [];
|
|
2302
|
+
this.socket = new ClientSocket(this.url, parametersAsString);
|
|
2150
2303
|
try {
|
|
2151
|
-
await super.registerSocket(this.socket);
|
|
2304
|
+
await super.registerSocket(this.socket, options);
|
|
2152
2305
|
} catch (error) {
|
|
2153
2306
|
await this.stop();
|
|
2154
2307
|
throw error;
|
|
@@ -2169,26 +2322,30 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2169
2322
|
static {
|
|
2170
2323
|
__name(this, "RemoteHttpInterceptorWorker");
|
|
2171
2324
|
}
|
|
2172
|
-
webSocketClient;
|
|
2173
2325
|
httpHandlers = /* @__PURE__ */ new Map();
|
|
2326
|
+
webSocketClient;
|
|
2327
|
+
auth;
|
|
2174
2328
|
constructor(options) {
|
|
2175
2329
|
super();
|
|
2176
|
-
const webSocketServerURL = this.deriveWebSocketServerURL(options.serverURL);
|
|
2177
2330
|
this.webSocketClient = new WebSocketClient_default({
|
|
2178
|
-
url:
|
|
2331
|
+
url: this.getWebSocketServerURL(options.serverURL).toString()
|
|
2179
2332
|
});
|
|
2333
|
+
this.auth = options.auth;
|
|
2180
2334
|
}
|
|
2181
2335
|
get type() {
|
|
2182
2336
|
return "remote";
|
|
2183
2337
|
}
|
|
2184
|
-
|
|
2338
|
+
getWebSocketServerURL(serverURL) {
|
|
2185
2339
|
const webSocketServerURL = new URL(serverURL);
|
|
2186
2340
|
webSocketServerURL.protocol = serverURL.protocol.replace(/^http(s)?:$/, "ws$1:");
|
|
2187
2341
|
return webSocketServerURL;
|
|
2188
2342
|
}
|
|
2189
2343
|
async start() {
|
|
2190
2344
|
await super.sharedStart(async () => {
|
|
2191
|
-
await this.webSocketClient.start(
|
|
2345
|
+
await this.webSocketClient.start({
|
|
2346
|
+
parameters: this.auth ? { token: this.auth.token } : void 0,
|
|
2347
|
+
waitForAuthentication: true
|
|
2348
|
+
});
|
|
2192
2349
|
this.webSocketClient.onEvent("interceptors/responses/create", this.createResponse);
|
|
2193
2350
|
this.webSocketClient.onEvent("interceptors/responses/unhandled", this.handleUnhandledServerRequest);
|
|
2194
2351
|
this.platform = this.readPlatform();
|
|
@@ -2259,7 +2416,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2259
2416
|
}
|
|
2260
2417
|
};
|
|
2261
2418
|
this.httpHandlers.set(handler.id, handler);
|
|
2262
|
-
await this.webSocketClient.request("interceptors/workers/
|
|
2419
|
+
await this.webSocketClient.request("interceptors/workers/commit", {
|
|
2263
2420
|
id: handler.id,
|
|
2264
2421
|
url: handler.url,
|
|
2265
2422
|
method
|
|
@@ -2271,7 +2428,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2271
2428
|
}
|
|
2272
2429
|
this.httpHandlers.clear();
|
|
2273
2430
|
if (this.webSocketClient.isRunning) {
|
|
2274
|
-
await this.webSocketClient.request("interceptors/workers/
|
|
2431
|
+
await this.webSocketClient.request("interceptors/workers/reset", void 0);
|
|
2275
2432
|
}
|
|
2276
2433
|
}
|
|
2277
2434
|
async clearInterceptorHandlers(interceptor) {
|
|
@@ -2289,7 +2446,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2289
2446
|
url: handler.url,
|
|
2290
2447
|
method: handler.method
|
|
2291
2448
|
}));
|
|
2292
|
-
await this.webSocketClient.request("interceptors/workers/
|
|
2449
|
+
await this.webSocketClient.request("interceptors/workers/reset", groupsToRecommit);
|
|
2293
2450
|
}
|
|
2294
2451
|
}
|
|
2295
2452
|
get interceptorsWithHandlers() {
|
|
@@ -2322,8 +2479,15 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
|
|
|
2322
2479
|
get localWorker() {
|
|
2323
2480
|
return this.class._localWorker;
|
|
2324
2481
|
}
|
|
2325
|
-
|
|
2326
|
-
|
|
2482
|
+
getRemoteWorkerKey(baseURL, options) {
|
|
2483
|
+
if (!options.auth) {
|
|
2484
|
+
return baseURL.origin;
|
|
2485
|
+
}
|
|
2486
|
+
return `${baseURL.origin}:${options.auth.token}`;
|
|
2487
|
+
}
|
|
2488
|
+
remoteWorker(baseURL, options) {
|
|
2489
|
+
const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
|
|
2490
|
+
return this.class.remoteWorkers.get(remoteWorkerKey);
|
|
2327
2491
|
}
|
|
2328
2492
|
get numberOfRunningLocalInterceptors() {
|
|
2329
2493
|
return this.class.runningLocalInterceptors.size;
|
|
@@ -2361,20 +2525,22 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
|
|
|
2361
2525
|
this.class._localWorker = createdWorker;
|
|
2362
2526
|
return createdWorker;
|
|
2363
2527
|
}
|
|
2528
|
+
deleteLocalWorker() {
|
|
2529
|
+
this.class._localWorker = void 0;
|
|
2530
|
+
}
|
|
2364
2531
|
getOrCreateRemoteWorker(workerOptions) {
|
|
2365
|
-
const
|
|
2532
|
+
const remoteWorkerKey = this.getRemoteWorkerKey(workerOptions.serverURL, { auth: workerOptions.auth });
|
|
2533
|
+
const existingWorker = this.class.remoteWorkers.get(remoteWorkerKey);
|
|
2366
2534
|
if (existingWorker) {
|
|
2367
2535
|
return existingWorker;
|
|
2368
2536
|
}
|
|
2369
2537
|
const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: "remote" });
|
|
2370
|
-
this.class.remoteWorkers.set(
|
|
2538
|
+
this.class.remoteWorkers.set(remoteWorkerKey, createdWorker);
|
|
2371
2539
|
return createdWorker;
|
|
2372
2540
|
}
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
this.class.
|
|
2376
|
-
this.class.remoteWorkers.clear();
|
|
2377
|
-
this.class.runningRemoteInterceptors.clear();
|
|
2541
|
+
deleteRemoteWorker(baseURL, options) {
|
|
2542
|
+
const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
|
|
2543
|
+
this.class.remoteWorkers.delete(remoteWorkerKey);
|
|
2378
2544
|
}
|
|
2379
2545
|
};
|
|
2380
2546
|
var HttpInterceptorStore_default = HttpInterceptorStore;
|
|
@@ -2388,11 +2554,15 @@ var LocalHttpInterceptor = class {
|
|
|
2388
2554
|
client;
|
|
2389
2555
|
constructor(options) {
|
|
2390
2556
|
const baseURL = new URL(options.baseURL);
|
|
2391
|
-
const worker = this.store.getOrCreateLocalWorker({});
|
|
2392
2557
|
this.client = new HttpInterceptorClient_default({
|
|
2393
|
-
worker,
|
|
2394
2558
|
store: this.store,
|
|
2395
2559
|
baseURL,
|
|
2560
|
+
createWorker: /* @__PURE__ */ __name(() => {
|
|
2561
|
+
return this.store.getOrCreateLocalWorker({});
|
|
2562
|
+
}, "createWorker"),
|
|
2563
|
+
deleteWorker: /* @__PURE__ */ __name(() => {
|
|
2564
|
+
this.store.deleteLocalWorker();
|
|
2565
|
+
}, "deleteWorker"),
|
|
2396
2566
|
Handler: LocalHttpRequestHandler_default,
|
|
2397
2567
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
2398
2568
|
requestSaving: options.requestSaving
|
|
@@ -2475,14 +2645,22 @@ var RemoteHttpInterceptor = class {
|
|
|
2475
2645
|
}
|
|
2476
2646
|
store = new HttpInterceptorStore_default();
|
|
2477
2647
|
client;
|
|
2648
|
+
_auth;
|
|
2478
2649
|
constructor(options) {
|
|
2650
|
+
this._auth = options.auth;
|
|
2479
2651
|
const baseURL = new URL(options.baseURL);
|
|
2480
|
-
const serverURL = new URL(baseURL.origin);
|
|
2481
|
-
const worker = this.store.getOrCreateRemoteWorker({ serverURL });
|
|
2482
2652
|
this.client = new HttpInterceptorClient_default({
|
|
2483
|
-
worker,
|
|
2484
2653
|
store: this.store,
|
|
2485
2654
|
baseURL,
|
|
2655
|
+
createWorker: /* @__PURE__ */ __name(() => {
|
|
2656
|
+
return this.store.getOrCreateRemoteWorker({
|
|
2657
|
+
serverURL: new URL(baseURL.origin),
|
|
2658
|
+
auth: this._auth
|
|
2659
|
+
});
|
|
2660
|
+
}, "createWorker"),
|
|
2661
|
+
deleteWorker: /* @__PURE__ */ __name(() => {
|
|
2662
|
+
this.store.deleteRemoteWorker(baseURL, { auth: options.auth });
|
|
2663
|
+
}, "deleteWorker"),
|
|
2486
2664
|
Handler: RemoteHttpRequestHandler_default,
|
|
2487
2665
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
2488
2666
|
requestSaving: options.requestSaving
|
|
@@ -2503,6 +2681,27 @@ var RemoteHttpInterceptor = class {
|
|
|
2503
2681
|
set requestSaving(requestSaving) {
|
|
2504
2682
|
this.client.requestSaving = requestSaving;
|
|
2505
2683
|
}
|
|
2684
|
+
get auth() {
|
|
2685
|
+
return this._auth;
|
|
2686
|
+
}
|
|
2687
|
+
set auth(auth) {
|
|
2688
|
+
const cannotChangeAuthWhileRunningMessage = "Did you forget to call `await interceptor.stop()` before changing the authentication parameters?";
|
|
2689
|
+
if (this.isRunning) {
|
|
2690
|
+
throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
|
|
2691
|
+
}
|
|
2692
|
+
if (!auth) {
|
|
2693
|
+
this._auth = void 0;
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2696
|
+
this._auth = new Proxy(auth, {
|
|
2697
|
+
set: /* @__PURE__ */ __name((target, property, value) => {
|
|
2698
|
+
if (this.isRunning) {
|
|
2699
|
+
throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
|
|
2700
|
+
}
|
|
2701
|
+
return Reflect.set(target, property, value);
|
|
2702
|
+
}, "set")
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2506
2705
|
get onUnhandledRequest() {
|
|
2507
2706
|
return this.client.onUnhandledRequest;
|
|
2508
2707
|
}
|
|
@@ -2589,13 +2788,17 @@ function createHttpInterceptor(options) {
|
|
|
2589
2788
|
throw new UnknownHttpInterceptorTypeError_default(type);
|
|
2590
2789
|
}
|
|
2591
2790
|
__name(createHttpInterceptor, "createHttpInterceptor");
|
|
2791
|
+
/* istanbul ignore next -- @preserve
|
|
2792
|
+
* Ignoring because there will always be a handler for the given method and path at this point. */
|
|
2592
2793
|
/* istanbul ignore else -- @preserve */
|
|
2593
2794
|
/* istanbul ignore next -- @preserve
|
|
2594
2795
|
* Ignoring because checking unknown platforms is not configured in our test setup. */
|
|
2595
|
-
/* istanbul ignore next -- @preserve
|
|
2596
|
-
* Ignoring because there will always be a handler for the given method and path at this point. */
|
|
2597
2796
|
/* istanbul ignore next -- @preserve
|
|
2598
2797
|
* Ignoring as Node.js >=20 provides a global crypto and the import fallback won't run. */
|
|
2798
|
+
/* istanbul ignore else -- @preserve
|
|
2799
|
+
* An unauthorized close event is the only one we expect to happen here. */
|
|
2800
|
+
/* istanbul ignore else -- @preserve
|
|
2801
|
+
* We currently only support the 'socket:auth:valid' message and it is the only possible control message here. */
|
|
2599
2802
|
/* istanbul ignore next -- @preserve
|
|
2600
2803
|
* It is difficult to reliably simulate socket errors in tests. */
|
|
2601
2804
|
/* istanbul ignore else -- @preserve
|