@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.js
CHANGED
|
@@ -41,7 +41,7 @@ var RunningHttpInterceptorError = class extends Error {
|
|
|
41
41
|
__name(this, "RunningHttpInterceptorError");
|
|
42
42
|
}
|
|
43
43
|
constructor(additionalMessage) {
|
|
44
|
-
super(`The interceptor is running
|
|
44
|
+
super(`The interceptor is running. ${additionalMessage}`);
|
|
45
45
|
this.name = "RunningHttpInterceptorError";
|
|
46
46
|
}
|
|
47
47
|
};
|
|
@@ -201,6 +201,88 @@ __name(createCachedDynamicImport, "createCachedDynamicImport");
|
|
|
201
201
|
__name2(createCachedDynamicImport, "createCachedDynamicImport");
|
|
202
202
|
var createCachedDynamicImport_default = createCachedDynamicImport;
|
|
203
203
|
|
|
204
|
+
// ../zimic-utils/dist/logging/Logger.mjs
|
|
205
|
+
var Logger = class _Logger {
|
|
206
|
+
static {
|
|
207
|
+
__name(this, "_Logger");
|
|
208
|
+
}
|
|
209
|
+
static {
|
|
210
|
+
__name2(this, "Logger");
|
|
211
|
+
}
|
|
212
|
+
prefix;
|
|
213
|
+
raw;
|
|
214
|
+
constructor(options = {}) {
|
|
215
|
+
const { prefix } = options;
|
|
216
|
+
this.prefix = prefix;
|
|
217
|
+
this.raw = prefix ? new _Logger({ ...options, prefix: void 0 }) : this;
|
|
218
|
+
}
|
|
219
|
+
logWithLevel(level, ...messages) {
|
|
220
|
+
if (this.prefix) {
|
|
221
|
+
console[level](this.prefix, ...messages);
|
|
222
|
+
} else {
|
|
223
|
+
console[level](...messages);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
info(...messages) {
|
|
227
|
+
this.logWithLevel("log", ...messages);
|
|
228
|
+
}
|
|
229
|
+
warn(...messages) {
|
|
230
|
+
this.logWithLevel("warn", ...messages);
|
|
231
|
+
}
|
|
232
|
+
error(...messages) {
|
|
233
|
+
this.logWithLevel("error", ...messages);
|
|
234
|
+
}
|
|
235
|
+
table(headers, rows) {
|
|
236
|
+
const columnLengths = headers.map((header) => {
|
|
237
|
+
let maxValueLength = header.title.length;
|
|
238
|
+
for (const row of rows) {
|
|
239
|
+
const value = row[header.property];
|
|
240
|
+
if (value.length > maxValueLength) {
|
|
241
|
+
maxValueLength = value.length;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return maxValueLength;
|
|
245
|
+
});
|
|
246
|
+
const formattedRows = [];
|
|
247
|
+
const horizontalLine = columnLengths.map((length) => "\u2500".repeat(length));
|
|
248
|
+
formattedRows.push(horizontalLine, []);
|
|
249
|
+
for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
|
250
|
+
const header = headers[headerIndex];
|
|
251
|
+
const columnLength = columnLengths[headerIndex];
|
|
252
|
+
const value = header.title;
|
|
253
|
+
formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
|
|
254
|
+
}
|
|
255
|
+
formattedRows.push(horizontalLine);
|
|
256
|
+
for (const row of rows) {
|
|
257
|
+
formattedRows.push([]);
|
|
258
|
+
for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
|
259
|
+
const header = headers[headerIndex];
|
|
260
|
+
const columnLength = columnLengths[headerIndex];
|
|
261
|
+
const value = row[header.property];
|
|
262
|
+
formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
formattedRows.push(horizontalLine);
|
|
266
|
+
const formattedTable = formattedRows.map((row, index) => {
|
|
267
|
+
const isFirstLine = index === 0;
|
|
268
|
+
if (isFirstLine) {
|
|
269
|
+
return `\u250C\u2500${row.join("\u2500\u252C\u2500")}\u2500\u2510`;
|
|
270
|
+
}
|
|
271
|
+
const isLineAfterHeaders = index === 2;
|
|
272
|
+
if (isLineAfterHeaders) {
|
|
273
|
+
return `\u251C\u2500${row.join("\u2500\u253C\u2500")}\u2500\u2524`;
|
|
274
|
+
}
|
|
275
|
+
const isLastLine = index === formattedRows.length - 1;
|
|
276
|
+
if (isLastLine) {
|
|
277
|
+
return `\u2514\u2500${row.join("\u2500\u2534\u2500")}\u2500\u2518`;
|
|
278
|
+
}
|
|
279
|
+
return `\u2502 ${row.join(" \u2502 ")} \u2502`;
|
|
280
|
+
}).join("\n");
|
|
281
|
+
this.logWithLevel("log", formattedTable);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
var Logger_default = Logger;
|
|
285
|
+
|
|
204
286
|
// src/utils/environment.ts
|
|
205
287
|
function isServerSide() {
|
|
206
288
|
return typeof process !== "undefined" && typeof process.versions !== "undefined";
|
|
@@ -215,7 +297,10 @@ function isGlobalFileAvailable() {
|
|
|
215
297
|
}
|
|
216
298
|
__name(isGlobalFileAvailable, "isGlobalFileAvailable");
|
|
217
299
|
|
|
218
|
-
// src/utils/
|
|
300
|
+
// src/utils/logging.ts
|
|
301
|
+
var logger = new Logger_default({
|
|
302
|
+
prefix: color2__default.default.cyan("[@zimic/interceptor]")
|
|
303
|
+
});
|
|
219
304
|
function stringifyJSONToLog(value) {
|
|
220
305
|
return JSON.stringify(
|
|
221
306
|
value,
|
|
@@ -270,12 +355,6 @@ async function formatValueToLog(value, options = {}) {
|
|
|
270
355
|
});
|
|
271
356
|
}
|
|
272
357
|
__name(formatValueToLog, "formatValueToLog");
|
|
273
|
-
function logWithPrefix(messageOrMessages, options = {}) {
|
|
274
|
-
const { method = "log" } = options;
|
|
275
|
-
const messages = Array.isArray(messageOrMessages) ? messageOrMessages : [messageOrMessages];
|
|
276
|
-
console[method](color2__default.default.cyan("[@zimic/interceptor]"), ...messages);
|
|
277
|
-
}
|
|
278
|
-
__name(logWithPrefix, "logWithPrefix");
|
|
279
358
|
|
|
280
359
|
// src/http/requestHandler/errors/TimesCheckError.ts
|
|
281
360
|
function createMessageHeader({
|
|
@@ -1200,209 +1279,23 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
|
|
|
1200
1279
|
formatValueToLog(request.searchParams.toObject()),
|
|
1201
1280
|
formatValueToLog(request.body)
|
|
1202
1281
|
]);
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
`${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2__default.default.yellow("bypassed") : color2__default.default.red("rejected")}.
|
|
1282
|
+
logger[action === "bypass" ? "warn" : "error"](
|
|
1283
|
+
`${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2__default.default.yellow("bypassed") : color2__default.default.red("rejected")}.
|
|
1206
1284
|
|
|
1207
1285
|
`,
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
],
|
|
1217
|
-
{ method: action === "bypass" ? "warn" : "error" }
|
|
1286
|
+
`${request.method} ${request.url}`,
|
|
1287
|
+
"\n Headers:",
|
|
1288
|
+
formattedHeaders,
|
|
1289
|
+
"\n Search params:",
|
|
1290
|
+
formattedSearchParams,
|
|
1291
|
+
"\n Body:",
|
|
1292
|
+
formattedBody,
|
|
1293
|
+
"\n\nLearn more: https://github.com/zimicjs/zimic/wiki/api\u2010zimic\u2010interceptor\u2010http#unhandled-requests"
|
|
1218
1294
|
);
|
|
1219
1295
|
}
|
|
1220
1296
|
};
|
|
1221
1297
|
var HttpInterceptorWorker_default = HttpInterceptorWorker;
|
|
1222
1298
|
|
|
1223
|
-
// ../zimic-utils/dist/url/validateURLPathParams.mjs
|
|
1224
|
-
var DuplicatedPathParamError = class extends Error {
|
|
1225
|
-
static {
|
|
1226
|
-
__name(this, "DuplicatedPathParamError");
|
|
1227
|
-
}
|
|
1228
|
-
static {
|
|
1229
|
-
__name2(this, "DuplicatedPathParamError");
|
|
1230
|
-
}
|
|
1231
|
-
constructor(url, paramName) {
|
|
1232
|
-
super(
|
|
1233
|
-
`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.`
|
|
1234
|
-
);
|
|
1235
|
-
this.name = "DuplicatedPathParamError";
|
|
1236
|
-
}
|
|
1237
|
-
};
|
|
1238
|
-
function validateURLPathParams(url) {
|
|
1239
|
-
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
|
1240
|
-
const matches = url.toString().matchAll(URL_PATH_PARAM_REGEX);
|
|
1241
|
-
const uniqueParamNames = /* @__PURE__ */ new Set();
|
|
1242
|
-
for (const match of matches) {
|
|
1243
|
-
const paramName = match[1];
|
|
1244
|
-
if (uniqueParamNames.has(paramName)) {
|
|
1245
|
-
throw new DuplicatedPathParamError(url, paramName);
|
|
1246
|
-
}
|
|
1247
|
-
uniqueParamNames.add(paramName);
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
__name(validateURLPathParams, "validateURLPathParams");
|
|
1251
|
-
__name2(validateURLPathParams, "validateURLPathParams");
|
|
1252
|
-
var validateURLPathParams_default = validateURLPathParams;
|
|
1253
|
-
var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
1254
|
-
static {
|
|
1255
|
-
__name(this, "LocalHttpInterceptorWorker");
|
|
1256
|
-
}
|
|
1257
|
-
internalWorker;
|
|
1258
|
-
defaultHttpHandler;
|
|
1259
|
-
httpHandlerGroups = [];
|
|
1260
|
-
constructor(_options) {
|
|
1261
|
-
super();
|
|
1262
|
-
this.defaultHttpHandler = msw.http.all("*", async (context) => {
|
|
1263
|
-
const request = context.request;
|
|
1264
|
-
return this.bypassOrRejectUnhandledRequest(request);
|
|
1265
|
-
});
|
|
1266
|
-
}
|
|
1267
|
-
get type() {
|
|
1268
|
-
return "local";
|
|
1269
|
-
}
|
|
1270
|
-
get internalWorkerOrThrow() {
|
|
1271
|
-
if (!this.internalWorker) {
|
|
1272
|
-
throw new NotRunningHttpInterceptorError_default();
|
|
1273
|
-
}
|
|
1274
|
-
return this.internalWorker;
|
|
1275
|
-
}
|
|
1276
|
-
get internalWorkerOrCreate() {
|
|
1277
|
-
this.internalWorker ??= this.createInternalWorker();
|
|
1278
|
-
return this.internalWorker;
|
|
1279
|
-
}
|
|
1280
|
-
createInternalWorker() {
|
|
1281
|
-
if (isServerSide() && "setupServer" in mswNode__namespace) {
|
|
1282
|
-
return mswNode__namespace.setupServer(this.defaultHttpHandler);
|
|
1283
|
-
}
|
|
1284
|
-
if (isClientSide() && "setupWorker" in mswBrowser__namespace) {
|
|
1285
|
-
return mswBrowser__namespace.setupWorker(this.defaultHttpHandler);
|
|
1286
|
-
}
|
|
1287
|
-
throw new UnknownHttpInterceptorPlatformError_default();
|
|
1288
|
-
}
|
|
1289
|
-
async start() {
|
|
1290
|
-
await super.sharedStart(async () => {
|
|
1291
|
-
const internalWorker = this.internalWorkerOrCreate;
|
|
1292
|
-
const sharedOptions = {
|
|
1293
|
-
onUnhandledRequest: "bypass"
|
|
1294
|
-
};
|
|
1295
|
-
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1296
|
-
this.platform = "browser";
|
|
1297
|
-
await this.startInBrowser(internalWorker, sharedOptions);
|
|
1298
|
-
} else {
|
|
1299
|
-
this.platform = "node";
|
|
1300
|
-
this.startInNode(internalWorker, sharedOptions);
|
|
1301
|
-
}
|
|
1302
|
-
this.isRunning = true;
|
|
1303
|
-
});
|
|
1304
|
-
}
|
|
1305
|
-
async startInBrowser(internalWorker, sharedOptions) {
|
|
1306
|
-
try {
|
|
1307
|
-
await internalWorker.start({ ...sharedOptions, quiet: true });
|
|
1308
|
-
} catch (error) {
|
|
1309
|
-
this.handleBrowserWorkerStartError(error);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
handleBrowserWorkerStartError(error) {
|
|
1313
|
-
if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
|
|
1314
|
-
throw new UnregisteredBrowserServiceWorkerError_default();
|
|
1315
|
-
}
|
|
1316
|
-
throw error;
|
|
1317
|
-
}
|
|
1318
|
-
startInNode(internalWorker, sharedOptions) {
|
|
1319
|
-
internalWorker.listen(sharedOptions);
|
|
1320
|
-
}
|
|
1321
|
-
async stop() {
|
|
1322
|
-
await super.sharedStop(() => {
|
|
1323
|
-
const internalWorker = this.internalWorkerOrCreate;
|
|
1324
|
-
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1325
|
-
this.stopInBrowser(internalWorker);
|
|
1326
|
-
} else {
|
|
1327
|
-
this.stopInNode(internalWorker);
|
|
1328
|
-
}
|
|
1329
|
-
this.clearHandlers();
|
|
1330
|
-
this.internalWorker = void 0;
|
|
1331
|
-
this.isRunning = false;
|
|
1332
|
-
});
|
|
1333
|
-
}
|
|
1334
|
-
stopInBrowser(internalWorker) {
|
|
1335
|
-
internalWorker.stop();
|
|
1336
|
-
}
|
|
1337
|
-
stopInNode(internalWorker) {
|
|
1338
|
-
internalWorker.close();
|
|
1339
|
-
}
|
|
1340
|
-
isInternalBrowserWorker(worker) {
|
|
1341
|
-
return "start" in worker && "stop" in worker;
|
|
1342
|
-
}
|
|
1343
|
-
hasInternalBrowserWorker() {
|
|
1344
|
-
return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
|
|
1345
|
-
}
|
|
1346
|
-
hasInternalNodeWorker() {
|
|
1347
|
-
return !this.hasInternalBrowserWorker();
|
|
1348
|
-
}
|
|
1349
|
-
use(interceptor, method, rawURL, createResponse) {
|
|
1350
|
-
const lowercaseMethod = method.toLowerCase();
|
|
1351
|
-
const url = new URL(rawURL);
|
|
1352
|
-
excludeURLParams_default(url);
|
|
1353
|
-
validateURLPathParams_default(url);
|
|
1354
|
-
const httpHandler = msw.http[lowercaseMethod](url.toString(), async (context) => {
|
|
1355
|
-
const request = context.request;
|
|
1356
|
-
const requestClone = request.clone();
|
|
1357
|
-
let response = null;
|
|
1358
|
-
try {
|
|
1359
|
-
response = await createResponse({ ...context, request });
|
|
1360
|
-
} catch (error) {
|
|
1361
|
-
console.error(error);
|
|
1362
|
-
}
|
|
1363
|
-
if (!response) {
|
|
1364
|
-
return this.bypassOrRejectUnhandledRequest(requestClone);
|
|
1365
|
-
}
|
|
1366
|
-
if (context.request.method === "HEAD") {
|
|
1367
|
-
return new Response(null, {
|
|
1368
|
-
status: response.status,
|
|
1369
|
-
statusText: response.statusText,
|
|
1370
|
-
headers: response.headers
|
|
1371
|
-
});
|
|
1372
|
-
}
|
|
1373
|
-
return response;
|
|
1374
|
-
});
|
|
1375
|
-
this.internalWorkerOrThrow.use(httpHandler);
|
|
1376
|
-
this.httpHandlerGroups.push({ interceptor, httpHandler });
|
|
1377
|
-
}
|
|
1378
|
-
async bypassOrRejectUnhandledRequest(request) {
|
|
1379
|
-
const requestClone = request.clone();
|
|
1380
|
-
const strategy = await super.getUnhandledRequestStrategy(request, "local");
|
|
1381
|
-
await super.logUnhandledRequestIfNecessary(requestClone, strategy);
|
|
1382
|
-
if (strategy?.action === "reject") {
|
|
1383
|
-
return Response.error();
|
|
1384
|
-
} else {
|
|
1385
|
-
return msw.passthrough();
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
clearHandlers() {
|
|
1389
|
-
this.internalWorkerOrThrow.resetHandlers();
|
|
1390
|
-
this.httpHandlerGroups = [];
|
|
1391
|
-
}
|
|
1392
|
-
clearInterceptorHandlers(interceptor) {
|
|
1393
|
-
const groupToRemoveIndex = this.httpHandlerGroups.findIndex((group) => group.interceptor === interceptor);
|
|
1394
|
-
removeArrayIndex(this.httpHandlerGroups, groupToRemoveIndex);
|
|
1395
|
-
this.internalWorkerOrThrow.resetHandlers();
|
|
1396
|
-
for (const { httpHandler } of this.httpHandlerGroups) {
|
|
1397
|
-
this.internalWorkerOrThrow.use(httpHandler);
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
get interceptorsWithHandlers() {
|
|
1401
|
-
return this.httpHandlerGroups.map((group) => group.interceptor);
|
|
1402
|
-
}
|
|
1403
|
-
};
|
|
1404
|
-
var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
|
|
1405
|
-
|
|
1406
1299
|
// src/http/requestHandler/RemoteHttpRequestHandler.ts
|
|
1407
1300
|
var PENDING_PROPERTIES = /* @__PURE__ */ new Set(["then"]);
|
|
1408
1301
|
var RemoteHttpRequestHandler = class {
|
|
@@ -1512,9 +1405,11 @@ var HttpInterceptorClient = class {
|
|
|
1512
1405
|
static {
|
|
1513
1406
|
__name(this, "HttpInterceptorClient");
|
|
1514
1407
|
}
|
|
1515
|
-
worker;
|
|
1516
1408
|
store;
|
|
1517
1409
|
_baseURL;
|
|
1410
|
+
createWorker;
|
|
1411
|
+
deleteWorker;
|
|
1412
|
+
worker;
|
|
1518
1413
|
requestSaving;
|
|
1519
1414
|
numberOfSavedRequests = 0;
|
|
1520
1415
|
onUnhandledRequest;
|
|
@@ -1530,9 +1425,10 @@ var HttpInterceptorClient = class {
|
|
|
1530
1425
|
OPTIONS: /* @__PURE__ */ new Map()
|
|
1531
1426
|
};
|
|
1532
1427
|
constructor(options) {
|
|
1533
|
-
this.worker = options.worker;
|
|
1534
1428
|
this.store = options.store;
|
|
1535
1429
|
this.baseURL = options.baseURL;
|
|
1430
|
+
this.createWorker = options.createWorker;
|
|
1431
|
+
this.deleteWorker = options.deleteWorker;
|
|
1536
1432
|
this.requestSaving = {
|
|
1537
1433
|
enabled: options.requestSaving?.enabled ?? this.getDefaultRequestSavingEnabled(),
|
|
1538
1434
|
safeLimit: options.requestSaving?.safeLimit ?? DEFAULT_REQUEST_SAVING_SAFE_LIMIT
|
|
@@ -1562,32 +1458,49 @@ var HttpInterceptorClient = class {
|
|
|
1562
1458
|
}
|
|
1563
1459
|
return this.baseURL.href;
|
|
1564
1460
|
}
|
|
1461
|
+
get workerOrThrow() {
|
|
1462
|
+
if (!this.worker) {
|
|
1463
|
+
throw new NotRunningHttpInterceptorError_default();
|
|
1464
|
+
}
|
|
1465
|
+
return this.worker;
|
|
1466
|
+
}
|
|
1565
1467
|
get platform() {
|
|
1566
|
-
return this.worker
|
|
1468
|
+
return this.worker?.platform ?? null;
|
|
1567
1469
|
}
|
|
1568
1470
|
async start() {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1471
|
+
try {
|
|
1472
|
+
this.worker = this.createWorker();
|
|
1473
|
+
await this.worker.start();
|
|
1474
|
+
this.worker.registerRunningInterceptor(this);
|
|
1475
|
+
this.markAsRunning(true);
|
|
1476
|
+
} catch (error) {
|
|
1477
|
+
await this.stop();
|
|
1478
|
+
throw error;
|
|
1479
|
+
}
|
|
1572
1480
|
}
|
|
1573
1481
|
async stop() {
|
|
1574
|
-
this.
|
|
1575
|
-
this.
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1482
|
+
this.worker?.unregisterRunningInterceptor(this);
|
|
1483
|
+
const isLastRunningInterceptor = this.numberOfRunningInterceptors === 0 || this.numberOfRunningInterceptors === 1;
|
|
1484
|
+
if (isLastRunningInterceptor) {
|
|
1485
|
+
await this.worker?.stop();
|
|
1486
|
+
this.deleteWorker();
|
|
1579
1487
|
}
|
|
1488
|
+
this.markAsRunning(false);
|
|
1489
|
+
this.worker = void 0;
|
|
1580
1490
|
}
|
|
1581
1491
|
markAsRunning(isRunning) {
|
|
1582
|
-
if (this.
|
|
1492
|
+
if (this.workerOrThrow.type === "local") {
|
|
1583
1493
|
this.store.markLocalInterceptorAsRunning(this, isRunning);
|
|
1584
1494
|
} else {
|
|
1585
1495
|
this.store.markRemoteInterceptorAsRunning(this, isRunning, this.baseURL);
|
|
1586
1496
|
}
|
|
1587
1497
|
this.isRunning = isRunning;
|
|
1588
1498
|
}
|
|
1589
|
-
numberOfRunningInterceptors() {
|
|
1590
|
-
if (this.
|
|
1499
|
+
get numberOfRunningInterceptors() {
|
|
1500
|
+
if (!this.isRunning) {
|
|
1501
|
+
return 0;
|
|
1502
|
+
}
|
|
1503
|
+
if (this.workerOrThrow.type === "local") {
|
|
1591
1504
|
return this.store.numberOfRunningLocalInterceptors;
|
|
1592
1505
|
} else {
|
|
1593
1506
|
return this.store.numberOfRunningRemoteInterceptors(this.baseURL);
|
|
@@ -1636,7 +1549,7 @@ var HttpInterceptorClient = class {
|
|
|
1636
1549
|
this.handlerClientsByMethod[handler.method].set(handler.path, handlerClients);
|
|
1637
1550
|
const url = joinURL_default(this.baseURLAsString, handler.path);
|
|
1638
1551
|
const urlRegex = createRegExpFromURL_default(url);
|
|
1639
|
-
const registrationResult = this.
|
|
1552
|
+
const registrationResult = this.workerOrThrow.use(this, handler.method, url, async (context) => {
|
|
1640
1553
|
const response = await this.handleInterceptedRequest(
|
|
1641
1554
|
urlRegex,
|
|
1642
1555
|
handler.method,
|
|
@@ -1695,10 +1608,9 @@ var HttpInterceptorClient = class {
|
|
|
1695
1608
|
}
|
|
1696
1609
|
}
|
|
1697
1610
|
clear(options = {}) {
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
const clearResults = [];
|
|
1611
|
+
const clearResults = [
|
|
1612
|
+
this.workerOrThrow.clearInterceptorHandlers(this)
|
|
1613
|
+
];
|
|
1702
1614
|
for (const method of http.HTTP_METHODS) {
|
|
1703
1615
|
const newClearResults = this.clearMethodHandlers(method);
|
|
1704
1616
|
for (const result of newClearResults) {
|
|
@@ -1707,8 +1619,6 @@ var HttpInterceptorClient = class {
|
|
|
1707
1619
|
const handlersByPath = this.handlerClientsByMethod[method];
|
|
1708
1620
|
handlersByPath.clear();
|
|
1709
1621
|
}
|
|
1710
|
-
const clearResult = this.worker.clearInterceptorHandlers(this);
|
|
1711
|
-
clearResults.push(clearResult);
|
|
1712
1622
|
if (options.onCommitSuccess) {
|
|
1713
1623
|
void Promise.all(clearResults).then(options.onCommitSuccess, options.onCommitError);
|
|
1714
1624
|
}
|
|
@@ -1726,6 +1636,189 @@ var HttpInterceptorClient = class {
|
|
|
1726
1636
|
};
|
|
1727
1637
|
var HttpInterceptorClient_default = HttpInterceptorClient;
|
|
1728
1638
|
|
|
1639
|
+
// ../zimic-utils/dist/url/validateURLPathParams.mjs
|
|
1640
|
+
var DuplicatedPathParamError = class extends Error {
|
|
1641
|
+
static {
|
|
1642
|
+
__name(this, "DuplicatedPathParamError");
|
|
1643
|
+
}
|
|
1644
|
+
static {
|
|
1645
|
+
__name2(this, "DuplicatedPathParamError");
|
|
1646
|
+
}
|
|
1647
|
+
constructor(url, paramName) {
|
|
1648
|
+
super(
|
|
1649
|
+
`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.`
|
|
1650
|
+
);
|
|
1651
|
+
this.name = "DuplicatedPathParamError";
|
|
1652
|
+
}
|
|
1653
|
+
};
|
|
1654
|
+
function validateURLPathParams(url) {
|
|
1655
|
+
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
|
1656
|
+
const matches = url.toString().matchAll(URL_PATH_PARAM_REGEX);
|
|
1657
|
+
const uniqueParamNames = /* @__PURE__ */ new Set();
|
|
1658
|
+
for (const match of matches) {
|
|
1659
|
+
const paramName = match[1];
|
|
1660
|
+
if (uniqueParamNames.has(paramName)) {
|
|
1661
|
+
throw new DuplicatedPathParamError(url, paramName);
|
|
1662
|
+
}
|
|
1663
|
+
uniqueParamNames.add(paramName);
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
__name(validateURLPathParams, "validateURLPathParams");
|
|
1667
|
+
__name2(validateURLPathParams, "validateURLPathParams");
|
|
1668
|
+
var validateURLPathParams_default = validateURLPathParams;
|
|
1669
|
+
var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
1670
|
+
static {
|
|
1671
|
+
__name(this, "LocalHttpInterceptorWorker");
|
|
1672
|
+
}
|
|
1673
|
+
internalWorker;
|
|
1674
|
+
defaultHttpHandler;
|
|
1675
|
+
httpHandlerGroups = [];
|
|
1676
|
+
constructor(_options) {
|
|
1677
|
+
super();
|
|
1678
|
+
this.defaultHttpHandler = msw.http.all("*", async (context) => {
|
|
1679
|
+
const request = context.request;
|
|
1680
|
+
return this.bypassOrRejectUnhandledRequest(request);
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
get type() {
|
|
1684
|
+
return "local";
|
|
1685
|
+
}
|
|
1686
|
+
get internalWorkerOrThrow() {
|
|
1687
|
+
if (!this.internalWorker) {
|
|
1688
|
+
throw new NotRunningHttpInterceptorError_default();
|
|
1689
|
+
}
|
|
1690
|
+
return this.internalWorker;
|
|
1691
|
+
}
|
|
1692
|
+
get internalWorkerOrCreate() {
|
|
1693
|
+
this.internalWorker ??= this.createInternalWorker();
|
|
1694
|
+
return this.internalWorker;
|
|
1695
|
+
}
|
|
1696
|
+
createInternalWorker() {
|
|
1697
|
+
if (isServerSide() && "setupServer" in mswNode__namespace) {
|
|
1698
|
+
return mswNode__namespace.setupServer(this.defaultHttpHandler);
|
|
1699
|
+
}
|
|
1700
|
+
if (isClientSide() && "setupWorker" in mswBrowser__namespace) {
|
|
1701
|
+
return mswBrowser__namespace.setupWorker(this.defaultHttpHandler);
|
|
1702
|
+
}
|
|
1703
|
+
throw new UnknownHttpInterceptorPlatformError_default();
|
|
1704
|
+
}
|
|
1705
|
+
async start() {
|
|
1706
|
+
await super.sharedStart(async () => {
|
|
1707
|
+
const internalWorker = this.internalWorkerOrCreate;
|
|
1708
|
+
const sharedOptions = {
|
|
1709
|
+
onUnhandledRequest: "bypass"
|
|
1710
|
+
};
|
|
1711
|
+
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1712
|
+
this.platform = "browser";
|
|
1713
|
+
await this.startInBrowser(internalWorker, sharedOptions);
|
|
1714
|
+
} else {
|
|
1715
|
+
this.platform = "node";
|
|
1716
|
+
this.startInNode(internalWorker, sharedOptions);
|
|
1717
|
+
}
|
|
1718
|
+
this.isRunning = true;
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
async startInBrowser(internalWorker, sharedOptions) {
|
|
1722
|
+
try {
|
|
1723
|
+
await internalWorker.start({ ...sharedOptions, quiet: true });
|
|
1724
|
+
} catch (error) {
|
|
1725
|
+
this.handleBrowserWorkerStartError(error);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
handleBrowserWorkerStartError(error) {
|
|
1729
|
+
if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
|
|
1730
|
+
throw new UnregisteredBrowserServiceWorkerError_default();
|
|
1731
|
+
}
|
|
1732
|
+
throw error;
|
|
1733
|
+
}
|
|
1734
|
+
startInNode(internalWorker, sharedOptions) {
|
|
1735
|
+
internalWorker.listen(sharedOptions);
|
|
1736
|
+
}
|
|
1737
|
+
async stop() {
|
|
1738
|
+
await super.sharedStop(() => {
|
|
1739
|
+
const internalWorker = this.internalWorkerOrCreate;
|
|
1740
|
+
if (this.isInternalBrowserWorker(internalWorker)) {
|
|
1741
|
+
this.stopInBrowser(internalWorker);
|
|
1742
|
+
} else {
|
|
1743
|
+
this.stopInNode(internalWorker);
|
|
1744
|
+
}
|
|
1745
|
+
this.clearHandlers();
|
|
1746
|
+
this.internalWorker = void 0;
|
|
1747
|
+
this.isRunning = false;
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
stopInBrowser(internalWorker) {
|
|
1751
|
+
internalWorker.stop();
|
|
1752
|
+
}
|
|
1753
|
+
stopInNode(internalWorker) {
|
|
1754
|
+
internalWorker.close();
|
|
1755
|
+
}
|
|
1756
|
+
isInternalBrowserWorker(worker) {
|
|
1757
|
+
return "start" in worker && "stop" in worker;
|
|
1758
|
+
}
|
|
1759
|
+
hasInternalBrowserWorker() {
|
|
1760
|
+
return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
|
|
1761
|
+
}
|
|
1762
|
+
hasInternalNodeWorker() {
|
|
1763
|
+
return !this.hasInternalBrowserWorker();
|
|
1764
|
+
}
|
|
1765
|
+
use(interceptor, method, rawURL, createResponse) {
|
|
1766
|
+
const lowercaseMethod = method.toLowerCase();
|
|
1767
|
+
const url = new URL(rawURL);
|
|
1768
|
+
excludeURLParams_default(url);
|
|
1769
|
+
validateURLPathParams_default(url);
|
|
1770
|
+
const httpHandler = msw.http[lowercaseMethod](url.toString(), async (context) => {
|
|
1771
|
+
const request = context.request;
|
|
1772
|
+
const requestClone = request.clone();
|
|
1773
|
+
let response = null;
|
|
1774
|
+
try {
|
|
1775
|
+
response = await createResponse({ ...context, request });
|
|
1776
|
+
} catch (error) {
|
|
1777
|
+
console.error(error);
|
|
1778
|
+
}
|
|
1779
|
+
if (!response) {
|
|
1780
|
+
return this.bypassOrRejectUnhandledRequest(requestClone);
|
|
1781
|
+
}
|
|
1782
|
+
if (context.request.method === "HEAD") {
|
|
1783
|
+
return new Response(null, {
|
|
1784
|
+
status: response.status,
|
|
1785
|
+
statusText: response.statusText,
|
|
1786
|
+
headers: response.headers
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
return response;
|
|
1790
|
+
});
|
|
1791
|
+
this.internalWorkerOrThrow.use(httpHandler);
|
|
1792
|
+
this.httpHandlerGroups.push({ interceptor, httpHandler });
|
|
1793
|
+
}
|
|
1794
|
+
async bypassOrRejectUnhandledRequest(request) {
|
|
1795
|
+
const requestClone = request.clone();
|
|
1796
|
+
const strategy = await super.getUnhandledRequestStrategy(request, "local");
|
|
1797
|
+
await super.logUnhandledRequestIfNecessary(requestClone, strategy);
|
|
1798
|
+
if (strategy?.action === "reject") {
|
|
1799
|
+
return Response.error();
|
|
1800
|
+
} else {
|
|
1801
|
+
return msw.passthrough();
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
clearHandlers() {
|
|
1805
|
+
this.internalWorkerOrThrow.resetHandlers();
|
|
1806
|
+
this.httpHandlerGroups = [];
|
|
1807
|
+
}
|
|
1808
|
+
clearInterceptorHandlers(interceptor) {
|
|
1809
|
+
const groupToRemoveIndex = this.httpHandlerGroups.findIndex((group) => group.interceptor === interceptor);
|
|
1810
|
+
removeArrayIndex(this.httpHandlerGroups, groupToRemoveIndex);
|
|
1811
|
+
this.internalWorkerOrThrow.resetHandlers();
|
|
1812
|
+
for (const { httpHandler } of this.httpHandlerGroups) {
|
|
1813
|
+
this.internalWorkerOrThrow.use(httpHandler);
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
get interceptorsWithHandlers() {
|
|
1817
|
+
return this.httpHandlerGroups.map((group) => group.interceptor);
|
|
1818
|
+
}
|
|
1819
|
+
};
|
|
1820
|
+
var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
|
|
1821
|
+
|
|
1729
1822
|
// src/utils/crypto.ts
|
|
1730
1823
|
var importCrypto = createCachedDynamicImport_default(async () => {
|
|
1731
1824
|
const globalCrypto = globalThis.crypto;
|
|
@@ -1789,6 +1882,19 @@ async function serializeResponse(response) {
|
|
|
1789
1882
|
}
|
|
1790
1883
|
__name(serializeResponse, "serializeResponse");
|
|
1791
1884
|
|
|
1885
|
+
// src/webSocket/errors/UnauthorizedWebSocketConnectionError.ts
|
|
1886
|
+
var UnauthorizedWebSocketConnectionError = class extends Error {
|
|
1887
|
+
constructor(event) {
|
|
1888
|
+
super(`${event.reason} (code ${event.code})`);
|
|
1889
|
+
this.event = event;
|
|
1890
|
+
this.name = "UnauthorizedWebSocketConnectionError";
|
|
1891
|
+
}
|
|
1892
|
+
static {
|
|
1893
|
+
__name(this, "UnauthorizedWebSocketConnectionError");
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1896
|
+
var UnauthorizedWebSocketConnectionError_default = UnauthorizedWebSocketConnectionError;
|
|
1897
|
+
|
|
1792
1898
|
// src/utils/webSocket.ts
|
|
1793
1899
|
var WebSocketTimeoutError = class extends Error {
|
|
1794
1900
|
static {
|
|
@@ -1834,29 +1940,58 @@ var WebSocketCloseTimeoutError = class extends WebSocketTimeoutError {
|
|
|
1834
1940
|
var DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT = 60 * 1e3;
|
|
1835
1941
|
var DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT = 3 * 60 * 1e3;
|
|
1836
1942
|
async function waitForOpenClientSocket(socket, options = {}) {
|
|
1837
|
-
const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;
|
|
1943
|
+
const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT, waitForAuthentication = false } = options;
|
|
1838
1944
|
const isAlreadyOpen = socket.readyState === socket.OPEN;
|
|
1839
1945
|
if (isAlreadyOpen) {
|
|
1840
1946
|
return;
|
|
1841
1947
|
}
|
|
1842
1948
|
await new Promise((resolve, reject) => {
|
|
1843
|
-
function
|
|
1949
|
+
function removeAllSocketListeners() {
|
|
1950
|
+
socket.removeEventListener("message", handleSocketMessage);
|
|
1844
1951
|
socket.removeEventListener("open", handleOpenSuccess);
|
|
1952
|
+
socket.removeEventListener("error", handleOpenError);
|
|
1953
|
+
socket.removeEventListener("close", handleClose);
|
|
1954
|
+
}
|
|
1955
|
+
__name(removeAllSocketListeners, "removeAllSocketListeners");
|
|
1956
|
+
function handleOpenError(error) {
|
|
1957
|
+
removeAllSocketListeners();
|
|
1845
1958
|
reject(error);
|
|
1846
1959
|
}
|
|
1847
1960
|
__name(handleOpenError, "handleOpenError");
|
|
1961
|
+
function handleClose(event) {
|
|
1962
|
+
const isUnauthorized = event.code === 1008;
|
|
1963
|
+
if (isUnauthorized) {
|
|
1964
|
+
const unauthorizedError = new UnauthorizedWebSocketConnectionError_default(event);
|
|
1965
|
+
handleOpenError(unauthorizedError);
|
|
1966
|
+
} else {
|
|
1967
|
+
handleOpenError(event);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
__name(handleClose, "handleClose");
|
|
1848
1971
|
const openTimeout = setTimeout(() => {
|
|
1849
1972
|
const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);
|
|
1850
1973
|
handleOpenError(timeoutError);
|
|
1851
1974
|
}, timeoutDuration);
|
|
1852
1975
|
function handleOpenSuccess() {
|
|
1853
|
-
|
|
1976
|
+
removeAllSocketListeners();
|
|
1854
1977
|
clearTimeout(openTimeout);
|
|
1855
1978
|
resolve();
|
|
1856
1979
|
}
|
|
1857
1980
|
__name(handleOpenSuccess, "handleOpenSuccess");
|
|
1858
|
-
|
|
1981
|
+
function handleSocketMessage(message) {
|
|
1982
|
+
const hasValidAuth = message.data === "socket:auth:valid";
|
|
1983
|
+
if (hasValidAuth) {
|
|
1984
|
+
handleOpenSuccess();
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
__name(handleSocketMessage, "handleSocketMessage");
|
|
1988
|
+
if (waitForAuthentication) {
|
|
1989
|
+
socket.addEventListener("message", handleSocketMessage);
|
|
1990
|
+
} else {
|
|
1991
|
+
socket.addEventListener("open", handleOpenSuccess);
|
|
1992
|
+
}
|
|
1859
1993
|
socket.addEventListener("error", handleOpenError);
|
|
1994
|
+
socket.addEventListener("close", handleClose);
|
|
1860
1995
|
});
|
|
1861
1996
|
}
|
|
1862
1997
|
__name(waitForOpenClientSocket, "waitForOpenClientSocket");
|
|
@@ -1867,28 +2002,36 @@ async function closeClientSocket(socket, options = {}) {
|
|
|
1867
2002
|
return;
|
|
1868
2003
|
}
|
|
1869
2004
|
await new Promise((resolve, reject) => {
|
|
1870
|
-
function
|
|
1871
|
-
socket.removeEventListener("
|
|
2005
|
+
function removeAllSocketListeners() {
|
|
2006
|
+
socket.removeEventListener("error", handleError);
|
|
2007
|
+
socket.removeEventListener("close", handleClose);
|
|
2008
|
+
}
|
|
2009
|
+
__name(removeAllSocketListeners, "removeAllSocketListeners");
|
|
2010
|
+
function handleError(error) {
|
|
2011
|
+
removeAllSocketListeners();
|
|
1872
2012
|
reject(error);
|
|
1873
2013
|
}
|
|
1874
|
-
__name(
|
|
2014
|
+
__name(handleError, "handleError");
|
|
1875
2015
|
const closeTimeout = setTimeout(() => {
|
|
1876
2016
|
const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);
|
|
1877
|
-
|
|
2017
|
+
handleError(timeoutError);
|
|
1878
2018
|
}, timeoutDuration);
|
|
1879
|
-
function
|
|
1880
|
-
|
|
2019
|
+
function handleClose() {
|
|
2020
|
+
removeAllSocketListeners();
|
|
1881
2021
|
clearTimeout(closeTimeout);
|
|
1882
2022
|
resolve();
|
|
1883
2023
|
}
|
|
1884
|
-
__name(
|
|
1885
|
-
socket.addEventListener("error",
|
|
1886
|
-
socket.addEventListener("close",
|
|
2024
|
+
__name(handleClose, "handleClose");
|
|
2025
|
+
socket.addEventListener("error", handleError);
|
|
2026
|
+
socket.addEventListener("close", handleClose);
|
|
1887
2027
|
socket.close();
|
|
1888
2028
|
});
|
|
1889
2029
|
}
|
|
1890
2030
|
__name(closeClientSocket, "closeClientSocket");
|
|
1891
2031
|
|
|
2032
|
+
// src/webSocket/constants.ts
|
|
2033
|
+
var WEB_SOCKET_CONTROL_MESSAGES = Object.freeze(["socket:auth:valid"]);
|
|
2034
|
+
|
|
1892
2035
|
// src/webSocket/errors/InvalidWebSocketMessage.ts
|
|
1893
2036
|
var InvalidWebSocketMessage = class extends Error {
|
|
1894
2037
|
static {
|
|
@@ -1929,8 +2072,11 @@ var WebSocketHandler = class {
|
|
|
1929
2072
|
this.socketTimeout = options.socketTimeout ?? DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT;
|
|
1930
2073
|
this.messageTimeout = options.messageTimeout ?? DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT;
|
|
1931
2074
|
}
|
|
1932
|
-
async registerSocket(socket) {
|
|
1933
|
-
const openPromise = waitForOpenClientSocket(socket, {
|
|
2075
|
+
async registerSocket(socket, options = {}) {
|
|
2076
|
+
const openPromise = waitForOpenClientSocket(socket, {
|
|
2077
|
+
timeout: this.socketTimeout,
|
|
2078
|
+
waitForAuthentication: options.waitForAuthentication
|
|
2079
|
+
});
|
|
1934
2080
|
const handleSocketMessage = /* @__PURE__ */ __name(async (rawMessage) => {
|
|
1935
2081
|
await this.handleSocketMessage(socket, rawMessage);
|
|
1936
2082
|
}, "handleSocketMessage");
|
|
@@ -1943,8 +2089,8 @@ var WebSocketHandler = class {
|
|
|
1943
2089
|
socket.addEventListener("error", handleSocketError);
|
|
1944
2090
|
const handleSocketClose = /* @__PURE__ */ __name(() => {
|
|
1945
2091
|
socket.removeEventListener("message", handleSocketMessage);
|
|
1946
|
-
socket.removeEventListener("error", handleSocketError);
|
|
1947
2092
|
socket.removeEventListener("close", handleSocketClose);
|
|
2093
|
+
socket.removeEventListener("error", handleSocketError);
|
|
1948
2094
|
this.removeSocket(socket);
|
|
1949
2095
|
}, "handleSocketClose");
|
|
1950
2096
|
socket.addEventListener("close", handleSocketClose);
|
|
@@ -1952,6 +2098,9 @@ var WebSocketHandler = class {
|
|
|
1952
2098
|
}
|
|
1953
2099
|
handleSocketMessage = /* @__PURE__ */ __name(async (socket, rawMessage) => {
|
|
1954
2100
|
try {
|
|
2101
|
+
if (this.isControlMessageData(rawMessage.data)) {
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
1955
2104
|
const stringifiedMessageData = this.readRawMessageData(rawMessage.data);
|
|
1956
2105
|
const parsedMessageData = this.parseMessage(stringifiedMessageData);
|
|
1957
2106
|
await this.notifyListeners(parsedMessageData, socket);
|
|
@@ -1959,6 +2108,9 @@ var WebSocketHandler = class {
|
|
|
1959
2108
|
console.error(error);
|
|
1960
2109
|
}
|
|
1961
2110
|
}, "handleSocketMessage");
|
|
2111
|
+
isControlMessageData(messageData) {
|
|
2112
|
+
return typeof messageData === "string" && WEB_SOCKET_CONTROL_MESSAGES.includes(messageData);
|
|
2113
|
+
}
|
|
1962
2114
|
readRawMessageData(data) {
|
|
1963
2115
|
if (typeof data === "string") {
|
|
1964
2116
|
return data;
|
|
@@ -1973,7 +2125,7 @@ var WebSocketHandler = class {
|
|
|
1973
2125
|
} catch {
|
|
1974
2126
|
throw new InvalidWebSocketMessage_default(stringifiedMessage);
|
|
1975
2127
|
}
|
|
1976
|
-
if (!this.
|
|
2128
|
+
if (!this.isMessage(parsedMessage)) {
|
|
1977
2129
|
throw new InvalidWebSocketMessage_default(stringifiedMessage);
|
|
1978
2130
|
}
|
|
1979
2131
|
if (this.isReplyMessage(parsedMessage)) {
|
|
@@ -1990,7 +2142,7 @@ var WebSocketHandler = class {
|
|
|
1990
2142
|
data: parsedMessage.data
|
|
1991
2143
|
};
|
|
1992
2144
|
}
|
|
1993
|
-
|
|
2145
|
+
isMessage(message) {
|
|
1994
2146
|
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");
|
|
1995
2147
|
}
|
|
1996
2148
|
async notifyListeners(message, socket) {
|
|
@@ -2172,10 +2324,11 @@ var WebSocketClient = class extends WebSocketHandler_default {
|
|
|
2172
2324
|
get isRunning() {
|
|
2173
2325
|
return this.socket !== void 0 && this.socket.readyState === this.socket.OPEN;
|
|
2174
2326
|
}
|
|
2175
|
-
async start() {
|
|
2176
|
-
|
|
2327
|
+
async start(options = {}) {
|
|
2328
|
+
const parametersAsString = options.parameters ? Object.entries(options.parameters).map(([key, value]) => `${key}=${value}`).map(encodeURIComponent) : [];
|
|
2329
|
+
this.socket = new ClientSocket__default.default(this.url, parametersAsString);
|
|
2177
2330
|
try {
|
|
2178
|
-
await super.registerSocket(this.socket);
|
|
2331
|
+
await super.registerSocket(this.socket, options);
|
|
2179
2332
|
} catch (error) {
|
|
2180
2333
|
await this.stop();
|
|
2181
2334
|
throw error;
|
|
@@ -2196,26 +2349,30 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2196
2349
|
static {
|
|
2197
2350
|
__name(this, "RemoteHttpInterceptorWorker");
|
|
2198
2351
|
}
|
|
2199
|
-
webSocketClient;
|
|
2200
2352
|
httpHandlers = /* @__PURE__ */ new Map();
|
|
2353
|
+
webSocketClient;
|
|
2354
|
+
auth;
|
|
2201
2355
|
constructor(options) {
|
|
2202
2356
|
super();
|
|
2203
|
-
const webSocketServerURL = this.deriveWebSocketServerURL(options.serverURL);
|
|
2204
2357
|
this.webSocketClient = new WebSocketClient_default({
|
|
2205
|
-
url:
|
|
2358
|
+
url: this.getWebSocketServerURL(options.serverURL).toString()
|
|
2206
2359
|
});
|
|
2360
|
+
this.auth = options.auth;
|
|
2207
2361
|
}
|
|
2208
2362
|
get type() {
|
|
2209
2363
|
return "remote";
|
|
2210
2364
|
}
|
|
2211
|
-
|
|
2365
|
+
getWebSocketServerURL(serverURL) {
|
|
2212
2366
|
const webSocketServerURL = new URL(serverURL);
|
|
2213
2367
|
webSocketServerURL.protocol = serverURL.protocol.replace(/^http(s)?:$/, "ws$1:");
|
|
2214
2368
|
return webSocketServerURL;
|
|
2215
2369
|
}
|
|
2216
2370
|
async start() {
|
|
2217
2371
|
await super.sharedStart(async () => {
|
|
2218
|
-
await this.webSocketClient.start(
|
|
2372
|
+
await this.webSocketClient.start({
|
|
2373
|
+
parameters: this.auth ? { token: this.auth.token } : void 0,
|
|
2374
|
+
waitForAuthentication: true
|
|
2375
|
+
});
|
|
2219
2376
|
this.webSocketClient.onEvent("interceptors/responses/create", this.createResponse);
|
|
2220
2377
|
this.webSocketClient.onEvent("interceptors/responses/unhandled", this.handleUnhandledServerRequest);
|
|
2221
2378
|
this.platform = this.readPlatform();
|
|
@@ -2286,7 +2443,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2286
2443
|
}
|
|
2287
2444
|
};
|
|
2288
2445
|
this.httpHandlers.set(handler.id, handler);
|
|
2289
|
-
await this.webSocketClient.request("interceptors/workers/
|
|
2446
|
+
await this.webSocketClient.request("interceptors/workers/commit", {
|
|
2290
2447
|
id: handler.id,
|
|
2291
2448
|
url: handler.url,
|
|
2292
2449
|
method
|
|
@@ -2298,7 +2455,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2298
2455
|
}
|
|
2299
2456
|
this.httpHandlers.clear();
|
|
2300
2457
|
if (this.webSocketClient.isRunning) {
|
|
2301
|
-
await this.webSocketClient.request("interceptors/workers/
|
|
2458
|
+
await this.webSocketClient.request("interceptors/workers/reset", void 0);
|
|
2302
2459
|
}
|
|
2303
2460
|
}
|
|
2304
2461
|
async clearInterceptorHandlers(interceptor) {
|
|
@@ -2316,7 +2473,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2316
2473
|
url: handler.url,
|
|
2317
2474
|
method: handler.method
|
|
2318
2475
|
}));
|
|
2319
|
-
await this.webSocketClient.request("interceptors/workers/
|
|
2476
|
+
await this.webSocketClient.request("interceptors/workers/reset", groupsToRecommit);
|
|
2320
2477
|
}
|
|
2321
2478
|
}
|
|
2322
2479
|
get interceptorsWithHandlers() {
|
|
@@ -2349,8 +2506,15 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
|
|
|
2349
2506
|
get localWorker() {
|
|
2350
2507
|
return this.class._localWorker;
|
|
2351
2508
|
}
|
|
2352
|
-
|
|
2353
|
-
|
|
2509
|
+
getRemoteWorkerKey(baseURL, options) {
|
|
2510
|
+
if (!options.auth) {
|
|
2511
|
+
return baseURL.origin;
|
|
2512
|
+
}
|
|
2513
|
+
return `${baseURL.origin}:${options.auth.token}`;
|
|
2514
|
+
}
|
|
2515
|
+
remoteWorker(baseURL, options) {
|
|
2516
|
+
const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
|
|
2517
|
+
return this.class.remoteWorkers.get(remoteWorkerKey);
|
|
2354
2518
|
}
|
|
2355
2519
|
get numberOfRunningLocalInterceptors() {
|
|
2356
2520
|
return this.class.runningLocalInterceptors.size;
|
|
@@ -2388,20 +2552,22 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
|
|
|
2388
2552
|
this.class._localWorker = createdWorker;
|
|
2389
2553
|
return createdWorker;
|
|
2390
2554
|
}
|
|
2555
|
+
deleteLocalWorker() {
|
|
2556
|
+
this.class._localWorker = void 0;
|
|
2557
|
+
}
|
|
2391
2558
|
getOrCreateRemoteWorker(workerOptions) {
|
|
2392
|
-
const
|
|
2559
|
+
const remoteWorkerKey = this.getRemoteWorkerKey(workerOptions.serverURL, { auth: workerOptions.auth });
|
|
2560
|
+
const existingWorker = this.class.remoteWorkers.get(remoteWorkerKey);
|
|
2393
2561
|
if (existingWorker) {
|
|
2394
2562
|
return existingWorker;
|
|
2395
2563
|
}
|
|
2396
2564
|
const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: "remote" });
|
|
2397
|
-
this.class.remoteWorkers.set(
|
|
2565
|
+
this.class.remoteWorkers.set(remoteWorkerKey, createdWorker);
|
|
2398
2566
|
return createdWorker;
|
|
2399
2567
|
}
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
this.class.
|
|
2403
|
-
this.class.remoteWorkers.clear();
|
|
2404
|
-
this.class.runningRemoteInterceptors.clear();
|
|
2568
|
+
deleteRemoteWorker(baseURL, options) {
|
|
2569
|
+
const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
|
|
2570
|
+
this.class.remoteWorkers.delete(remoteWorkerKey);
|
|
2405
2571
|
}
|
|
2406
2572
|
};
|
|
2407
2573
|
var HttpInterceptorStore_default = HttpInterceptorStore;
|
|
@@ -2415,11 +2581,15 @@ var LocalHttpInterceptor = class {
|
|
|
2415
2581
|
client;
|
|
2416
2582
|
constructor(options) {
|
|
2417
2583
|
const baseURL = new URL(options.baseURL);
|
|
2418
|
-
const worker = this.store.getOrCreateLocalWorker({});
|
|
2419
2584
|
this.client = new HttpInterceptorClient_default({
|
|
2420
|
-
worker,
|
|
2421
2585
|
store: this.store,
|
|
2422
2586
|
baseURL,
|
|
2587
|
+
createWorker: /* @__PURE__ */ __name(() => {
|
|
2588
|
+
return this.store.getOrCreateLocalWorker({});
|
|
2589
|
+
}, "createWorker"),
|
|
2590
|
+
deleteWorker: /* @__PURE__ */ __name(() => {
|
|
2591
|
+
this.store.deleteLocalWorker();
|
|
2592
|
+
}, "deleteWorker"),
|
|
2423
2593
|
Handler: LocalHttpRequestHandler_default,
|
|
2424
2594
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
2425
2595
|
requestSaving: options.requestSaving
|
|
@@ -2502,14 +2672,22 @@ var RemoteHttpInterceptor = class {
|
|
|
2502
2672
|
}
|
|
2503
2673
|
store = new HttpInterceptorStore_default();
|
|
2504
2674
|
client;
|
|
2675
|
+
_auth;
|
|
2505
2676
|
constructor(options) {
|
|
2677
|
+
this._auth = options.auth;
|
|
2506
2678
|
const baseURL = new URL(options.baseURL);
|
|
2507
|
-
const serverURL = new URL(baseURL.origin);
|
|
2508
|
-
const worker = this.store.getOrCreateRemoteWorker({ serverURL });
|
|
2509
2679
|
this.client = new HttpInterceptorClient_default({
|
|
2510
|
-
worker,
|
|
2511
2680
|
store: this.store,
|
|
2512
2681
|
baseURL,
|
|
2682
|
+
createWorker: /* @__PURE__ */ __name(() => {
|
|
2683
|
+
return this.store.getOrCreateRemoteWorker({
|
|
2684
|
+
serverURL: new URL(baseURL.origin),
|
|
2685
|
+
auth: this._auth
|
|
2686
|
+
});
|
|
2687
|
+
}, "createWorker"),
|
|
2688
|
+
deleteWorker: /* @__PURE__ */ __name(() => {
|
|
2689
|
+
this.store.deleteRemoteWorker(baseURL, { auth: options.auth });
|
|
2690
|
+
}, "deleteWorker"),
|
|
2513
2691
|
Handler: RemoteHttpRequestHandler_default,
|
|
2514
2692
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
2515
2693
|
requestSaving: options.requestSaving
|
|
@@ -2530,6 +2708,27 @@ var RemoteHttpInterceptor = class {
|
|
|
2530
2708
|
set requestSaving(requestSaving) {
|
|
2531
2709
|
this.client.requestSaving = requestSaving;
|
|
2532
2710
|
}
|
|
2711
|
+
get auth() {
|
|
2712
|
+
return this._auth;
|
|
2713
|
+
}
|
|
2714
|
+
set auth(auth) {
|
|
2715
|
+
const cannotChangeAuthWhileRunningMessage = "Did you forget to call `await interceptor.stop()` before changing the authentication parameters?";
|
|
2716
|
+
if (this.isRunning) {
|
|
2717
|
+
throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
|
|
2718
|
+
}
|
|
2719
|
+
if (!auth) {
|
|
2720
|
+
this._auth = void 0;
|
|
2721
|
+
return;
|
|
2722
|
+
}
|
|
2723
|
+
this._auth = new Proxy(auth, {
|
|
2724
|
+
set: /* @__PURE__ */ __name((target, property, value) => {
|
|
2725
|
+
if (this.isRunning) {
|
|
2726
|
+
throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
|
|
2727
|
+
}
|
|
2728
|
+
return Reflect.set(target, property, value);
|
|
2729
|
+
}, "set")
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2533
2732
|
get onUnhandledRequest() {
|
|
2534
2733
|
return this.client.onUnhandledRequest;
|
|
2535
2734
|
}
|
|
@@ -2616,13 +2815,17 @@ function createHttpInterceptor(options) {
|
|
|
2616
2815
|
throw new UnknownHttpInterceptorTypeError_default(type);
|
|
2617
2816
|
}
|
|
2618
2817
|
__name(createHttpInterceptor, "createHttpInterceptor");
|
|
2818
|
+
/* istanbul ignore next -- @preserve
|
|
2819
|
+
* Ignoring because there will always be a handler for the given method and path at this point. */
|
|
2619
2820
|
/* istanbul ignore else -- @preserve */
|
|
2620
2821
|
/* istanbul ignore next -- @preserve
|
|
2621
2822
|
* Ignoring because checking unknown platforms is not configured in our test setup. */
|
|
2622
|
-
/* istanbul ignore next -- @preserve
|
|
2623
|
-
* Ignoring because there will always be a handler for the given method and path at this point. */
|
|
2624
2823
|
/* istanbul ignore next -- @preserve
|
|
2625
2824
|
* Ignoring as Node.js >=20 provides a global crypto and the import fallback won't run. */
|
|
2825
|
+
/* istanbul ignore else -- @preserve
|
|
2826
|
+
* An unauthorized close event is the only one we expect to happen here. */
|
|
2827
|
+
/* istanbul ignore else -- @preserve
|
|
2828
|
+
* We currently only support the 'socket:auth:valid' message and it is the only possible control message here. */
|
|
2626
2829
|
/* istanbul ignore next -- @preserve
|
|
2627
2830
|
* It is difficult to reliably simulate socket errors in tests. */
|
|
2628
2831
|
/* istanbul ignore else -- @preserve
|