msw 2.0.12 → 2.0.13
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/lib/browser/index.d.mts +104 -0
- package/lib/browser/index.d.ts +1 -1
- package/lib/browser/index.js +1 -0
- package/lib/browser/index.js.map +1 -0
- package/lib/browser/index.mjs +1 -0
- package/lib/browser/index.mjs.map +1 -0
- package/lib/core/{GraphQLHandler-da09c680.d.ts → GraphQLHandler-SHlRCcy4.d.ts} +2 -2
- package/lib/core/GraphQLHandler-zlmUDnN6.d.mts +97 -0
- package/lib/core/HttpResponse.d.mts +2 -0
- package/lib/core/HttpResponse.d.ts +1 -1
- package/lib/core/HttpResponse.js +1 -0
- package/lib/core/HttpResponse.js.map +1 -0
- package/lib/core/HttpResponse.mjs +1 -0
- package/lib/core/HttpResponse.mjs.map +1 -0
- package/lib/core/{RequestHandler-25f9cfd1.d.ts → RequestHandler-rBDJQrEf.d.ts} +1 -1
- package/lib/core/RequestHandler-vxZdj6Tw.d.mts +179 -0
- package/lib/core/SetupApi.d.mts +26 -0
- package/lib/core/SetupApi.d.ts +1 -1
- package/lib/core/SetupApi.js +1 -0
- package/lib/core/SetupApi.js.map +1 -0
- package/lib/core/SetupApi.mjs +1 -0
- package/lib/core/SetupApi.mjs.map +1 -0
- package/lib/core/bypass.d.mts +16 -0
- package/lib/core/bypass.d.ts +1 -1
- package/lib/core/bypass.js +1 -0
- package/lib/core/bypass.js.map +1 -0
- package/lib/core/bypass.mjs +1 -0
- package/lib/core/bypass.mjs.map +1 -0
- package/lib/core/delay.d.mts +18 -0
- package/lib/core/delay.d.ts +1 -1
- package/lib/core/delay.js +1 -0
- package/lib/core/delay.js.map +1 -0
- package/lib/core/delay.mjs +1 -0
- package/lib/core/delay.mjs.map +1 -0
- package/lib/core/graphql.d.mts +109 -0
- package/lib/core/graphql.d.ts +3 -3
- package/lib/core/graphql.js +1 -0
- package/lib/core/graphql.js.map +1 -0
- package/lib/core/graphql.mjs +1 -0
- package/lib/core/graphql.mjs.map +1 -0
- package/lib/core/handlers/GraphQLHandler.d.mts +5 -0
- package/lib/core/handlers/GraphQLHandler.d.ts +2 -2
- package/lib/core/handlers/GraphQLHandler.js +3 -2
- package/lib/core/handlers/GraphQLHandler.js.map +1 -0
- package/lib/core/handlers/GraphQLHandler.mjs +3 -2
- package/lib/core/handlers/GraphQLHandler.mjs.map +1 -0
- package/lib/core/handlers/HttpHandler.d.mts +62 -0
- package/lib/core/handlers/HttpHandler.d.ts +2 -2
- package/lib/core/handlers/HttpHandler.js +1 -0
- package/lib/core/handlers/HttpHandler.js.map +1 -0
- package/lib/core/handlers/HttpHandler.mjs +1 -0
- package/lib/core/handlers/HttpHandler.mjs.map +1 -0
- package/lib/core/handlers/RequestHandler.d.mts +2 -0
- package/lib/core/handlers/RequestHandler.d.ts +1 -1
- package/lib/core/handlers/RequestHandler.js +3 -2
- package/lib/core/handlers/RequestHandler.js.map +1 -0
- package/lib/core/handlers/RequestHandler.mjs +3 -2
- package/lib/core/handlers/RequestHandler.mjs.map +1 -0
- package/lib/core/http.d.mts +26 -0
- package/lib/core/http.d.ts +1 -1
- package/lib/core/http.js +1 -0
- package/lib/core/http.js.map +1 -0
- package/lib/core/http.mjs +1 -0
- package/lib/core/http.mjs.map +1 -0
- package/lib/core/index.d.mts +18 -0
- package/lib/core/index.d.ts +2 -2
- package/lib/core/index.js +1 -0
- package/lib/core/index.js.map +1 -0
- package/lib/core/index.mjs +1 -0
- package/lib/core/index.mjs.map +1 -0
- package/lib/core/passthrough.d.mts +17 -0
- package/lib/core/passthrough.js +1 -0
- package/lib/core/passthrough.js.map +1 -0
- package/lib/core/passthrough.mjs +1 -0
- package/lib/core/passthrough.mjs.map +1 -0
- package/lib/core/sharedOptions.d.mts +66 -0
- package/lib/core/sharedOptions.d.ts +2 -2
- package/lib/core/sharedOptions.js +1 -0
- package/lib/core/sharedOptions.js.map +1 -0
- package/lib/core/sharedOptions.mjs +1 -0
- package/lib/core/sharedOptions.mjs.map +1 -0
- package/lib/core/typeUtils.d.mts +7 -0
- package/lib/core/typeUtils.d.ts +1 -1
- package/lib/core/typeUtils.js +1 -0
- package/lib/core/typeUtils.js.map +1 -0
- package/lib/core/typeUtils.mjs +1 -0
- package/lib/core/typeUtils.mjs.map +1 -0
- package/lib/core/utils/HttpResponse/decorators.d.mts +12 -0
- package/lib/core/utils/HttpResponse/decorators.d.ts +2 -2
- package/lib/core/utils/HttpResponse/decorators.js +1 -0
- package/lib/core/utils/HttpResponse/decorators.js.map +1 -0
- package/lib/core/utils/HttpResponse/decorators.mjs +1 -0
- package/lib/core/utils/HttpResponse/decorators.mjs.map +1 -0
- package/lib/core/utils/getResponse.d.mts +2 -0
- package/lib/core/utils/getResponse.d.ts +1 -1
- package/lib/core/utils/getResponse.js +1 -0
- package/lib/core/utils/getResponse.js.map +1 -0
- package/lib/core/utils/getResponse.mjs +1 -0
- package/lib/core/utils/getResponse.mjs.map +1 -0
- package/lib/core/utils/handleRequest.d.mts +37 -0
- package/lib/core/utils/handleRequest.d.ts +2 -2
- package/lib/core/utils/handleRequest.js +1 -0
- package/lib/core/utils/handleRequest.js.map +1 -0
- package/lib/core/utils/handleRequest.mjs +1 -0
- package/lib/core/utils/handleRequest.mjs.map +1 -0
- package/lib/core/utils/internal/Disposable.d.mts +7 -0
- package/lib/core/utils/internal/Disposable.d.ts +1 -1
- package/lib/core/utils/internal/Disposable.js +1 -0
- package/lib/core/utils/internal/Disposable.js.map +1 -0
- package/lib/core/utils/internal/Disposable.mjs +1 -0
- package/lib/core/utils/internal/Disposable.mjs.map +1 -0
- package/lib/core/utils/internal/checkGlobals.d.mts +3 -0
- package/lib/core/utils/internal/checkGlobals.js +1 -0
- package/lib/core/utils/internal/checkGlobals.js.map +1 -0
- package/lib/core/utils/internal/checkGlobals.mjs +1 -0
- package/lib/core/utils/internal/checkGlobals.mjs.map +1 -0
- package/lib/core/utils/internal/devUtils.d.mts +19 -0
- package/lib/core/utils/internal/devUtils.js +1 -0
- package/lib/core/utils/internal/devUtils.js.map +1 -0
- package/lib/core/utils/internal/devUtils.mjs +1 -0
- package/lib/core/utils/internal/devUtils.mjs.map +1 -0
- package/lib/core/utils/internal/getCallFrame.d.mts +6 -0
- package/lib/core/utils/internal/getCallFrame.js +1 -0
- package/lib/core/utils/internal/getCallFrame.js.map +1 -0
- package/lib/core/utils/internal/getCallFrame.mjs +1 -0
- package/lib/core/utils/internal/getCallFrame.mjs.map +1 -0
- package/lib/core/utils/internal/isIterable.d.mts +6 -0
- package/lib/core/utils/internal/isIterable.js +1 -0
- package/lib/core/utils/internal/isIterable.js.map +1 -0
- package/lib/core/utils/internal/isIterable.mjs +1 -0
- package/lib/core/utils/internal/isIterable.mjs.map +1 -0
- package/lib/core/utils/internal/isObject.d.mts +6 -0
- package/lib/core/utils/internal/isObject.js +1 -0
- package/lib/core/utils/internal/isObject.js.map +1 -0
- package/lib/core/utils/internal/isObject.mjs +1 -0
- package/lib/core/utils/internal/isObject.mjs.map +1 -0
- package/lib/core/utils/internal/isStringEqual.d.mts +6 -0
- package/lib/core/utils/internal/isStringEqual.js +1 -0
- package/lib/core/utils/internal/isStringEqual.js.map +1 -0
- package/lib/core/utils/internal/isStringEqual.mjs +1 -0
- package/lib/core/utils/internal/isStringEqual.mjs.map +1 -0
- package/lib/core/utils/internal/jsonParse.d.mts +7 -0
- package/lib/core/utils/internal/jsonParse.js +1 -0
- package/lib/core/utils/internal/jsonParse.js.map +1 -0
- package/lib/core/utils/internal/jsonParse.mjs +1 -0
- package/lib/core/utils/internal/jsonParse.mjs.map +1 -0
- package/lib/core/utils/internal/mergeRight.d.mts +7 -0
- package/lib/core/utils/internal/mergeRight.js +1 -0
- package/lib/core/utils/internal/mergeRight.js.map +1 -0
- package/lib/core/utils/internal/mergeRight.mjs +1 -0
- package/lib/core/utils/internal/mergeRight.mjs.map +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.d.mts +5 -0
- package/lib/core/utils/internal/parseGraphQLRequest.d.ts +2 -2
- package/lib/core/utils/internal/parseGraphQLRequest.js +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.js.map +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.mjs +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.mjs.map +1 -0
- package/lib/core/utils/internal/parseMultipartData.d.mts +10 -0
- package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
- package/lib/core/utils/internal/parseMultipartData.js +1 -0
- package/lib/core/utils/internal/parseMultipartData.js.map +1 -0
- package/lib/core/utils/internal/parseMultipartData.mjs +1 -0
- package/lib/core/utils/internal/parseMultipartData.mjs.map +1 -0
- package/lib/core/utils/internal/pipeEvents.d.mts +8 -0
- package/lib/core/utils/internal/pipeEvents.js +1 -0
- package/lib/core/utils/internal/pipeEvents.js.map +1 -0
- package/lib/core/utils/internal/pipeEvents.mjs +1 -0
- package/lib/core/utils/internal/pipeEvents.mjs.map +1 -0
- package/lib/core/utils/internal/requestHandlerUtils.d.mts +8 -0
- package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.js +1 -0
- package/lib/core/utils/internal/requestHandlerUtils.js.map +1 -0
- package/lib/core/utils/internal/requestHandlerUtils.mjs +1 -0
- package/lib/core/utils/internal/requestHandlerUtils.mjs.map +1 -0
- package/lib/core/utils/internal/toReadonlyArray.d.mts +6 -0
- package/lib/core/utils/internal/toReadonlyArray.js +1 -0
- package/lib/core/utils/internal/toReadonlyArray.js.map +1 -0
- package/lib/core/utils/internal/toReadonlyArray.mjs +1 -0
- package/lib/core/utils/internal/toReadonlyArray.mjs.map +1 -0
- package/lib/core/utils/internal/tryCatch.d.mts +3 -0
- package/lib/core/utils/internal/tryCatch.js +1 -0
- package/lib/core/utils/internal/tryCatch.js.map +1 -0
- package/lib/core/utils/internal/tryCatch.mjs +1 -0
- package/lib/core/utils/internal/tryCatch.mjs.map +1 -0
- package/lib/core/utils/internal/uuidv4.d.mts +3 -0
- package/lib/core/utils/internal/uuidv4.js +1 -0
- package/lib/core/utils/internal/uuidv4.js.map +1 -0
- package/lib/core/utils/internal/uuidv4.mjs +1 -0
- package/lib/core/utils/internal/uuidv4.mjs.map +1 -0
- package/lib/core/utils/logging/getStatusCodeColor.d.mts +11 -0
- package/lib/core/utils/logging/getStatusCodeColor.js +1 -0
- package/lib/core/utils/logging/getStatusCodeColor.js.map +1 -0
- package/lib/core/utils/logging/getStatusCodeColor.mjs +1 -0
- package/lib/core/utils/logging/getStatusCodeColor.mjs.map +1 -0
- package/lib/core/utils/logging/getTimestamp.d.mts +6 -0
- package/lib/core/utils/logging/getTimestamp.js +1 -0
- package/lib/core/utils/logging/getTimestamp.js.map +1 -0
- package/lib/core/utils/logging/getTimestamp.mjs +1 -0
- package/lib/core/utils/logging/getTimestamp.mjs.map +1 -0
- package/lib/core/utils/logging/serializeRequest.d.mts +12 -0
- package/lib/core/utils/logging/serializeRequest.d.ts +1 -1
- package/lib/core/utils/logging/serializeRequest.js +1 -0
- package/lib/core/utils/logging/serializeRequest.js.map +1 -0
- package/lib/core/utils/logging/serializeRequest.mjs +1 -0
- package/lib/core/utils/logging/serializeRequest.mjs.map +1 -0
- package/lib/core/utils/logging/serializeResponse.d.mts +9 -0
- package/lib/core/utils/logging/serializeResponse.d.ts +1 -1
- package/lib/core/utils/logging/serializeResponse.js +1 -0
- package/lib/core/utils/logging/serializeResponse.js.map +1 -0
- package/lib/core/utils/logging/serializeResponse.mjs +1 -0
- package/lib/core/utils/logging/serializeResponse.mjs.map +1 -0
- package/lib/core/utils/matching/matchRequestUrl.d.mts +19 -0
- package/lib/core/utils/matching/matchRequestUrl.d.ts +1 -1
- package/lib/core/utils/matching/matchRequestUrl.js +1 -0
- package/lib/core/utils/matching/matchRequestUrl.js.map +1 -0
- package/lib/core/utils/matching/matchRequestUrl.mjs +1 -0
- package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -0
- package/lib/core/utils/matching/normalizePath.d.mts +12 -0
- package/lib/core/utils/matching/normalizePath.js +1 -0
- package/lib/core/utils/matching/normalizePath.js.map +1 -0
- package/lib/core/utils/matching/normalizePath.mjs +1 -0
- package/lib/core/utils/matching/normalizePath.mjs.map +1 -0
- package/lib/core/utils/request/getPublicUrlFromRequest.d.mts +7 -0
- package/lib/core/utils/request/getPublicUrlFromRequest.js +1 -0
- package/lib/core/utils/request/getPublicUrlFromRequest.js.map +1 -0
- package/lib/core/utils/request/getPublicUrlFromRequest.mjs +1 -0
- package/lib/core/utils/request/getPublicUrlFromRequest.mjs.map +1 -0
- package/lib/core/utils/request/getRequestCookies.d.mts +8 -0
- package/lib/core/utils/request/getRequestCookies.js +1 -0
- package/lib/core/utils/request/getRequestCookies.js.map +1 -0
- package/lib/core/utils/request/getRequestCookies.mjs +1 -0
- package/lib/core/utils/request/getRequestCookies.mjs.map +1 -0
- package/lib/core/utils/request/onUnhandledRequest.d.mts +12 -0
- package/lib/core/utils/request/onUnhandledRequest.d.ts +2 -2
- package/lib/core/utils/request/onUnhandledRequest.js +1 -0
- package/lib/core/utils/request/onUnhandledRequest.js.map +1 -0
- package/lib/core/utils/request/onUnhandledRequest.mjs +1 -0
- package/lib/core/utils/request/onUnhandledRequest.mjs.map +1 -0
- package/lib/core/utils/request/readResponseCookies.d.mts +3 -0
- package/lib/core/utils/request/readResponseCookies.js +1 -0
- package/lib/core/utils/request/readResponseCookies.js.map +1 -0
- package/lib/core/utils/request/readResponseCookies.mjs +1 -0
- package/lib/core/utils/request/readResponseCookies.mjs.map +1 -0
- package/lib/core/utils/toResponseInit.d.mts +3 -0
- package/lib/core/utils/toResponseInit.js +1 -0
- package/lib/core/utils/toResponseInit.js.map +1 -0
- package/lib/core/utils/toResponseInit.mjs +1 -0
- package/lib/core/utils/toResponseInit.mjs.map +1 -0
- package/lib/core/utils/url/cleanUrl.d.mts +7 -0
- package/lib/core/utils/url/cleanUrl.js +1 -0
- package/lib/core/utils/url/cleanUrl.js.map +1 -0
- package/lib/core/utils/url/cleanUrl.mjs +1 -0
- package/lib/core/utils/url/cleanUrl.mjs.map +1 -0
- package/lib/core/utils/url/getAbsoluteUrl.d.mts +6 -0
- package/lib/core/utils/url/getAbsoluteUrl.js +1 -0
- package/lib/core/utils/url/getAbsoluteUrl.js.map +1 -0
- package/lib/core/utils/url/getAbsoluteUrl.mjs +1 -0
- package/lib/core/utils/url/getAbsoluteUrl.mjs.map +1 -0
- package/lib/core/utils/url/isAbsoluteUrl.d.mts +6 -0
- package/lib/core/utils/url/isAbsoluteUrl.js +1 -0
- package/lib/core/utils/url/isAbsoluteUrl.js.map +1 -0
- package/lib/core/utils/url/isAbsoluteUrl.mjs +1 -0
- package/lib/core/utils/url/isAbsoluteUrl.mjs.map +1 -0
- package/lib/iife/index.js +20 -19
- package/lib/iife/index.js.map +1 -0
- package/lib/mockServiceWorker.js +1 -1
- package/lib/native/index.d.mts +75 -0
- package/lib/native/index.js +1 -0
- package/lib/native/index.js.map +1 -0
- package/lib/native/index.mjs +1 -0
- package/lib/native/index.mjs.map +1 -0
- package/lib/node/index.d.mts +75 -0
- package/lib/node/index.d.ts +1 -1
- package/lib/node/index.js +1 -0
- package/lib/node/index.js.map +1 -0
- package/lib/node/index.mjs +1 -0
- package/lib/node/index.mjs.map +1 -0
- package/package.json +5 -4
- package/src/browser/global.browser.d.ts +1 -0
- package/src/browser/index.ts +3 -0
- package/src/browser/setupWorker/glossary.ts +259 -0
- package/src/browser/setupWorker/setupWorker.node.test.ts +10 -0
- package/src/browser/setupWorker/setupWorker.ts +199 -0
- package/src/browser/setupWorker/start/createFallbackRequestListener.ts +67 -0
- package/src/browser/setupWorker/start/createFallbackStart.ts +21 -0
- package/src/browser/setupWorker/start/createRequestListener.ts +127 -0
- package/src/browser/setupWorker/start/createResponseListener.ts +58 -0
- package/src/browser/setupWorker/start/createStartHandler.ts +143 -0
- package/src/browser/setupWorker/start/utils/createMessageChannel.ts +32 -0
- package/src/browser/setupWorker/start/utils/enableMocking.ts +32 -0
- package/src/browser/setupWorker/start/utils/getWorkerByRegistration.ts +25 -0
- package/src/browser/setupWorker/start/utils/getWorkerInstance.ts +94 -0
- package/src/browser/setupWorker/start/utils/prepareStartHandler.test.ts +59 -0
- package/src/browser/setupWorker/start/utils/prepareStartHandler.ts +44 -0
- package/src/browser/setupWorker/start/utils/printStartMessage.test.ts +84 -0
- package/src/browser/setupWorker/start/utils/printStartMessage.ts +40 -0
- package/src/browser/setupWorker/start/utils/validateWorkerScope.ts +18 -0
- package/src/browser/setupWorker/stop/createFallbackStop.ts +11 -0
- package/src/browser/setupWorker/stop/createStop.ts +29 -0
- package/src/browser/setupWorker/stop/utils/printStopMessage.test.ts +26 -0
- package/src/browser/setupWorker/stop/utils/printStopMessage.ts +12 -0
- package/src/browser/tsconfig.browser.build.json +6 -0
- package/src/browser/tsconfig.browser.json +9 -0
- package/src/browser/utils/deferNetworkRequestsUntil.test.ts +48 -0
- package/src/browser/utils/deferNetworkRequestsUntil.ts +29 -0
- package/src/browser/utils/getAbsoluteWorkerUrl.test.ts +31 -0
- package/src/browser/utils/getAbsoluteWorkerUrl.ts +7 -0
- package/src/browser/utils/parseWorkerRequest.ts +15 -0
- package/src/browser/utils/pruneGetRequestBody.test.ts +53 -0
- package/src/browser/utils/pruneGetRequestBody.ts +21 -0
- package/src/browser/utils/requestIntegrityCheck.ts +23 -0
- package/src/browser/utils/supportsReadableStreamTransfer.ts +17 -0
- package/src/core/HttpResponse.test.ts +200 -0
- package/src/core/HttpResponse.ts +134 -0
- package/src/core/SetupApi.ts +95 -0
- package/src/core/bypass.test.ts +47 -0
- package/src/core/bypass.ts +36 -0
- package/src/core/delay.ts +70 -0
- package/src/core/graphql.test.ts +11 -0
- package/src/core/graphql.ts +138 -0
- package/src/core/handlers/GraphQLHandler.test.ts +820 -0
- package/src/core/handlers/GraphQLHandler.ts +263 -0
- package/src/core/handlers/HttpHandler.test.ts +218 -0
- package/src/core/handlers/HttpHandler.ts +169 -0
- package/src/core/handlers/RequestHandler.ts +338 -0
- package/src/core/http.test.ts +15 -0
- package/src/core/http.ts +51 -0
- package/src/core/index.ts +56 -0
- package/src/core/passthrough.test.ts +13 -0
- package/src/core/passthrough.ts +23 -0
- package/src/core/sharedOptions.ts +66 -0
- package/src/core/typeUtils.ts +20 -0
- package/src/core/utils/HttpResponse/decorators.ts +56 -0
- package/src/core/utils/getResponse.ts +55 -0
- package/src/core/utils/handleRequest.test.ts +554 -0
- package/src/core/utils/handleRequest.ts +132 -0
- package/src/core/utils/internal/Disposable.ts +9 -0
- package/src/core/utils/internal/checkGlobals.ts +17 -0
- package/src/core/utils/internal/devUtils.ts +31 -0
- package/src/core/utils/internal/getCallFrame.test.ts +154 -0
- package/src/core/utils/internal/getCallFrame.ts +35 -0
- package/src/core/utils/internal/isIterable.test.ts +23 -0
- package/src/core/utils/internal/isIterable.ts +12 -0
- package/src/core/utils/internal/isObject.test.ts +20 -0
- package/src/core/utils/internal/isObject.ts +6 -0
- package/src/core/utils/internal/isStringEqual.test.ts +45 -0
- package/src/core/utils/internal/isStringEqual.ts +6 -0
- package/src/core/utils/internal/jsonParse.test.ts +13 -0
- package/src/core/utils/internal/jsonParse.ts +13 -0
- package/src/core/utils/internal/mergeRight.test.ts +43 -0
- package/src/core/utils/internal/mergeRight.ts +27 -0
- package/src/core/utils/internal/parseGraphQLRequest.test.ts +99 -0
- package/src/core/utils/internal/parseGraphQLRequest.ts +205 -0
- package/src/core/utils/internal/parseMultipartData.test.ts +76 -0
- package/src/core/utils/internal/parseMultipartData.ts +104 -0
- package/src/core/utils/internal/pipeEvents.test.ts +14 -0
- package/src/core/utils/internal/pipeEvents.ts +25 -0
- package/src/core/utils/internal/requestHandlerUtils.ts +21 -0
- package/src/core/utils/internal/toReadonlyArray.test.ts +30 -0
- package/src/core/utils/internal/toReadonlyArray.ts +8 -0
- package/src/core/utils/internal/tryCatch.test.ts +29 -0
- package/src/core/utils/internal/tryCatch.ts +11 -0
- package/src/core/utils/internal/uuidv4.ts +3 -0
- package/src/core/utils/logging/getStatusCodeColor.test.ts +22 -0
- package/src/core/utils/logging/getStatusCodeColor.ts +20 -0
- package/src/core/utils/logging/getTimestamp.test.ts +18 -0
- package/src/core/utils/logging/getTimestamp.ts +12 -0
- package/src/core/utils/logging/serializeRequest.test.ts +23 -0
- package/src/core/utils/logging/serializeRequest.ts +23 -0
- package/src/core/utils/logging/serializeResponse.test.ts +77 -0
- package/src/core/utils/logging/serializeResponse.ts +31 -0
- package/src/core/utils/matching/matchRequestUrl.test.ts +114 -0
- package/src/core/utils/matching/matchRequestUrl.ts +73 -0
- package/src/core/utils/matching/normalizePath.node.test.ts +44 -0
- package/src/core/utils/matching/normalizePath.test.ts +50 -0
- package/src/core/utils/matching/normalizePath.ts +21 -0
- package/src/core/utils/request/getPublicUrlFromRequest.test.ts +26 -0
- package/src/core/utils/request/getPublicUrlFromRequest.ts +15 -0
- package/src/core/utils/request/getRequestCookies.node.test.ts +29 -0
- package/src/core/utils/request/getRequestCookies.test.ts +64 -0
- package/src/core/utils/request/getRequestCookies.ts +75 -0
- package/src/core/utils/request/onUnhandledRequest.test.ts +215 -0
- package/src/core/utils/request/onUnhandledRequest.ts +247 -0
- package/src/core/utils/request/readResponseCookies.ts +9 -0
- package/src/core/utils/toResponseInit.ts +7 -0
- package/src/core/utils/url/cleanUrl.test.ts +17 -0
- package/src/core/utils/url/cleanUrl.ts +12 -0
- package/src/core/utils/url/getAbsoluteUrl.node.test.ts +19 -0
- package/src/core/utils/url/getAbsoluteUrl.test.ts +29 -0
- package/src/core/utils/url/getAbsoluteUrl.ts +26 -0
- package/src/core/utils/url/isAbsoluteUrl.test.ts +32 -0
- package/src/core/utils/url/isAbsoluteUrl.ts +6 -0
- package/src/iife/index.ts +2 -0
- package/src/mockServiceWorker.js +287 -0
- package/src/native/index.ts +17 -0
- package/src/node/SetupServerApi.ts +113 -0
- package/src/node/glossary.ts +62 -0
- package/src/node/index.ts +3 -0
- package/src/node/setupServer.ts +21 -0
- package/src/node/utils/isNodeExceptionLike.ts +14 -0
- package/src/tsconfig.core.build.json +6 -0
- package/src/tsconfig.node.build.json +6 -0
- package/src/tsconfig.node.json +8 -0
- package/src/tsconfig.src.json +15 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DocumentNode,
|
|
3
|
+
OperationDefinitionNode,
|
|
4
|
+
OperationTypeNode,
|
|
5
|
+
} from 'graphql'
|
|
6
|
+
import { parse } from 'graphql'
|
|
7
|
+
import type { GraphQLVariables } from '../../handlers/GraphQLHandler'
|
|
8
|
+
import { getPublicUrlFromRequest } from '../request/getPublicUrlFromRequest'
|
|
9
|
+
import { devUtils } from './devUtils'
|
|
10
|
+
import { jsonParse } from './jsonParse'
|
|
11
|
+
import { parseMultipartData } from './parseMultipartData'
|
|
12
|
+
|
|
13
|
+
interface GraphQLInput {
|
|
14
|
+
query: string | null
|
|
15
|
+
variables?: GraphQLVariables
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ParsedGraphQLQuery {
|
|
19
|
+
operationType: OperationTypeNode
|
|
20
|
+
operationName?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type ParsedGraphQLRequest<
|
|
24
|
+
VariablesType extends GraphQLVariables = GraphQLVariables,
|
|
25
|
+
> =
|
|
26
|
+
| (ParsedGraphQLQuery & {
|
|
27
|
+
query: string
|
|
28
|
+
variables?: VariablesType
|
|
29
|
+
})
|
|
30
|
+
| undefined
|
|
31
|
+
|
|
32
|
+
export function parseDocumentNode(node: DocumentNode): ParsedGraphQLQuery {
|
|
33
|
+
const operationDef = node.definitions.find((definition) => {
|
|
34
|
+
return definition.kind === 'OperationDefinition'
|
|
35
|
+
}) as OperationDefinitionNode
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
operationType: operationDef?.operation,
|
|
39
|
+
operationName: operationDef?.name?.value,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function parseQuery(query: string): ParsedGraphQLQuery | Error {
|
|
44
|
+
try {
|
|
45
|
+
const ast = parse(query)
|
|
46
|
+
return parseDocumentNode(ast)
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return error as Error
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type GraphQLParsedOperationsMap = Record<string, string[]>
|
|
53
|
+
export type GraphQLMultipartRequestBody = {
|
|
54
|
+
operations: string
|
|
55
|
+
map?: string
|
|
56
|
+
} & {
|
|
57
|
+
[fileName: string]: File
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function extractMultipartVariables<VariablesType extends GraphQLVariables>(
|
|
61
|
+
variables: VariablesType,
|
|
62
|
+
map: GraphQLParsedOperationsMap,
|
|
63
|
+
files: Record<string, File>,
|
|
64
|
+
) {
|
|
65
|
+
const operations = { variables }
|
|
66
|
+
|
|
67
|
+
for (const [key, pathArray] of Object.entries(map)) {
|
|
68
|
+
if (!(key in files)) {
|
|
69
|
+
throw new Error(`Given files do not have a key '${key}' .`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const dotPath of pathArray) {
|
|
73
|
+
const [lastPath, ...reversedPaths] = dotPath.split('.').reverse()
|
|
74
|
+
const paths = reversedPaths.reverse()
|
|
75
|
+
let target: Record<string, any> = operations
|
|
76
|
+
|
|
77
|
+
for (const path of paths) {
|
|
78
|
+
if (!(path in target)) {
|
|
79
|
+
throw new Error(`Property '${paths}' is not in operations.`)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
target = target[path]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
target[lastPath] = files[key]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return operations.variables
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function getGraphQLInput(request: Request): Promise<GraphQLInput | null> {
|
|
93
|
+
switch (request.method) {
|
|
94
|
+
case 'GET': {
|
|
95
|
+
const url = new URL(request.url)
|
|
96
|
+
const query = url.searchParams.get('query')
|
|
97
|
+
const variables = url.searchParams.get('variables') || ''
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
query,
|
|
101
|
+
variables: jsonParse(variables),
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
case 'POST': {
|
|
106
|
+
// Clone the request so we could read its body without locking
|
|
107
|
+
// the body stream to the downward consumers.
|
|
108
|
+
const requestClone = request.clone()
|
|
109
|
+
|
|
110
|
+
// Handle multipart body GraphQL operations.
|
|
111
|
+
if (
|
|
112
|
+
request.headers.get('content-type')?.includes('multipart/form-data')
|
|
113
|
+
) {
|
|
114
|
+
const responseJson = parseMultipartData<GraphQLMultipartRequestBody>(
|
|
115
|
+
await requestClone.text(),
|
|
116
|
+
request.headers,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if (!responseJson) {
|
|
120
|
+
return null
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const { operations, map, ...files } = responseJson
|
|
124
|
+
const parsedOperations =
|
|
125
|
+
jsonParse<{ query?: string; variables?: GraphQLVariables }>(
|
|
126
|
+
operations,
|
|
127
|
+
) || {}
|
|
128
|
+
|
|
129
|
+
if (!parsedOperations.query) {
|
|
130
|
+
return null
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const parsedMap = jsonParse<GraphQLParsedOperationsMap>(map || '') || {}
|
|
134
|
+
const variables = parsedOperations.variables
|
|
135
|
+
? extractMultipartVariables(
|
|
136
|
+
parsedOperations.variables,
|
|
137
|
+
parsedMap,
|
|
138
|
+
files,
|
|
139
|
+
)
|
|
140
|
+
: {}
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
query: parsedOperations.query,
|
|
144
|
+
variables,
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Handle plain POST GraphQL operations.
|
|
149
|
+
const requestJson: {
|
|
150
|
+
query: string
|
|
151
|
+
variables?: GraphQLVariables
|
|
152
|
+
operations?: any /** @todo Annotate this */
|
|
153
|
+
} = await requestClone.json().catch(() => null)
|
|
154
|
+
|
|
155
|
+
if (requestJson?.query) {
|
|
156
|
+
const { query, variables } = requestJson
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
query,
|
|
160
|
+
variables,
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
default:
|
|
166
|
+
return null
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Determines if a given request can be considered a GraphQL request.
|
|
172
|
+
* Does not parse the query and does not guarantee its validity.
|
|
173
|
+
*/
|
|
174
|
+
export async function parseGraphQLRequest(
|
|
175
|
+
request: Request,
|
|
176
|
+
): Promise<ParsedGraphQLRequest> {
|
|
177
|
+
const input = await getGraphQLInput(request)
|
|
178
|
+
|
|
179
|
+
if (!input || !input.query) {
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const { query, variables } = input
|
|
184
|
+
const parsedResult = parseQuery(query)
|
|
185
|
+
|
|
186
|
+
if (parsedResult instanceof Error) {
|
|
187
|
+
const requestPublicUrl = getPublicUrlFromRequest(request)
|
|
188
|
+
|
|
189
|
+
throw new Error(
|
|
190
|
+
devUtils.formatMessage(
|
|
191
|
+
'Failed to intercept a GraphQL request to "%s %s": cannot parse query. See the error message from the parser below.\n\n%s',
|
|
192
|
+
request.method,
|
|
193
|
+
requestPublicUrl,
|
|
194
|
+
parsedResult.message,
|
|
195
|
+
),
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
query: input.query,
|
|
201
|
+
operationType: parsedResult.operationType,
|
|
202
|
+
operationName: parsedResult.operationName,
|
|
203
|
+
variables,
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
import { parseMultipartData } from './parseMultipartData'
|
|
5
|
+
|
|
6
|
+
test('parses a given valid multipart string', async () => {
|
|
7
|
+
expect.assertions(3)
|
|
8
|
+
await testMultipartDataWithContentType(
|
|
9
|
+
'multipart/form-data; boundary=WebKitFormBoundaryvZ1cVXWyK0ilQdab',
|
|
10
|
+
)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
test('parses a given valid multipart string given non-pretty content-type', async () => {
|
|
14
|
+
expect.assertions(3)
|
|
15
|
+
// node-fetch will serialize content-type in this format, which is valid according to HTTP
|
|
16
|
+
// https://github.com/node-fetch/node-fetch/blob/d8fc32d6b29bd43d1ad377e80b3e439fe37f2904/test/main.js#L1438
|
|
17
|
+
await testMultipartDataWithContentType(
|
|
18
|
+
'multipart/form-data;boundary=WebKitFormBoundaryvZ1cVXWyK0ilQdab',
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('parses a given valid multipart string given content-type with extra spaces', async () => {
|
|
23
|
+
expect.assertions(3)
|
|
24
|
+
await testMultipartDataWithContentType(
|
|
25
|
+
'multipart/form-data; boundary=WebKitFormBoundaryvZ1cVXWyK0ilQdab',
|
|
26
|
+
)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
async function testMultipartDataWithContentType(
|
|
30
|
+
contentType: string,
|
|
31
|
+
): Promise<void> {
|
|
32
|
+
const body = `\
|
|
33
|
+
------WebKitFormBoundaryvZ1cVXWyK0ilQdab\r
|
|
34
|
+
Content-Disposition: form-data; name="file"; filename="file1.txt"\r
|
|
35
|
+
Content-Type: application/octet-stream\r
|
|
36
|
+
\r
|
|
37
|
+
file content\r
|
|
38
|
+
------WebKitFormBoundaryvZ1cVXWyK0ilQdab\r
|
|
39
|
+
Content-Disposition: form-data; name="text"\r
|
|
40
|
+
\r
|
|
41
|
+
text content\r
|
|
42
|
+
------WebKitFormBoundaryvZ1cVXWyK0ilQdab\r
|
|
43
|
+
Content-Disposition: form-data; name="text2"\r
|
|
44
|
+
\r
|
|
45
|
+
another text content\r
|
|
46
|
+
------WebKitFormBoundaryvZ1cVXWyK0ilQdab\r
|
|
47
|
+
Content-Disposition: form-data; name="text2"\r
|
|
48
|
+
\r
|
|
49
|
+
\r
|
|
50
|
+
another text content 2\r
|
|
51
|
+
\r
|
|
52
|
+
------WebKitFormBoundaryvZ1cVXWyK0ilQdab--`
|
|
53
|
+
const headers = new Headers({
|
|
54
|
+
'content-type': contentType,
|
|
55
|
+
})
|
|
56
|
+
const parsed = parseMultipartData(body, headers)
|
|
57
|
+
|
|
58
|
+
// Workaround: JSDOM does not have `Blob.text` implementation.
|
|
59
|
+
// see https://github.com/jsdom/jsdom/issues/2555
|
|
60
|
+
expect(parsed).toHaveProperty('file.name', 'file1.txt')
|
|
61
|
+
|
|
62
|
+
expect(parsed).toHaveProperty('text', 'text content')
|
|
63
|
+
expect(parsed).toHaveProperty('text2', [
|
|
64
|
+
'another text content',
|
|
65
|
+
'\r\nanother text content 2\r\n',
|
|
66
|
+
])
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
test('returns undefined without an error given an invalid multipart string', () => {
|
|
70
|
+
const headers = new Headers({
|
|
71
|
+
'content-type': 'multipart/form-data; boundary=dummyBoundary',
|
|
72
|
+
})
|
|
73
|
+
const parse = () => parseMultipartData(`{"invalid": ["multipart"]}`, headers)
|
|
74
|
+
expect(parse).not.toThrow()
|
|
75
|
+
expect(parse()).toBeUndefined()
|
|
76
|
+
})
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { stringToHeaders } from 'headers-polyfill'
|
|
2
|
+
import { DefaultRequestMultipartBody } from '../../handlers/RequestHandler'
|
|
3
|
+
|
|
4
|
+
interface ParsedContentHeaders {
|
|
5
|
+
name: string
|
|
6
|
+
filename?: string
|
|
7
|
+
contentType: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ContentDispositionDirective {
|
|
11
|
+
[key: string]: string | undefined
|
|
12
|
+
name: string
|
|
13
|
+
filename?: string
|
|
14
|
+
'form-data': string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function parseContentHeaders(headersString: string): ParsedContentHeaders {
|
|
18
|
+
const headers = stringToHeaders(headersString)
|
|
19
|
+
const contentType = headers.get('content-type') || 'text/plain'
|
|
20
|
+
const disposition = headers.get('content-disposition')
|
|
21
|
+
|
|
22
|
+
if (!disposition) {
|
|
23
|
+
throw new Error('"Content-Disposition" header is required.')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const directives = disposition.split(';').reduce((acc, chunk) => {
|
|
27
|
+
const [name, ...rest] = chunk.trim().split('=')
|
|
28
|
+
acc[name] = rest.join('=')
|
|
29
|
+
return acc
|
|
30
|
+
}, {} as ContentDispositionDirective)
|
|
31
|
+
|
|
32
|
+
const name = directives.name?.slice(1, -1)
|
|
33
|
+
const filename = directives.filename?.slice(1, -1)
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
name,
|
|
37
|
+
filename,
|
|
38
|
+
contentType,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Parses a given string as a multipart/form-data.
|
|
44
|
+
* Does not throw an exception on an invalid multipart string.
|
|
45
|
+
*/
|
|
46
|
+
export function parseMultipartData<T extends DefaultRequestMultipartBody>(
|
|
47
|
+
data: string,
|
|
48
|
+
headers?: Headers,
|
|
49
|
+
): T | undefined {
|
|
50
|
+
const contentType = headers?.get('content-type')
|
|
51
|
+
|
|
52
|
+
if (!contentType) {
|
|
53
|
+
return undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const [, ...directives] = contentType.split(/; */)
|
|
57
|
+
const boundary = directives
|
|
58
|
+
.filter((d) => d.startsWith('boundary='))
|
|
59
|
+
.map((s) => s.replace(/^boundary=/, ''))[0]
|
|
60
|
+
|
|
61
|
+
if (!boundary) {
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const boundaryRegExp = new RegExp(`--+${boundary}`)
|
|
66
|
+
const fields = data
|
|
67
|
+
.split(boundaryRegExp)
|
|
68
|
+
.filter((chunk) => chunk.startsWith('\r\n') && chunk.endsWith('\r\n'))
|
|
69
|
+
.map((chunk) => chunk.trimStart().replace(/\r\n$/, ''))
|
|
70
|
+
|
|
71
|
+
if (!fields.length) {
|
|
72
|
+
return undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const parsedBody: DefaultRequestMultipartBody = {}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
for (const field of fields) {
|
|
79
|
+
const [contentHeaders, ...rest] = field.split('\r\n\r\n')
|
|
80
|
+
const contentBody = rest.join('\r\n\r\n')
|
|
81
|
+
const { contentType, filename, name } =
|
|
82
|
+
parseContentHeaders(contentHeaders)
|
|
83
|
+
|
|
84
|
+
const value =
|
|
85
|
+
filename === undefined
|
|
86
|
+
? contentBody
|
|
87
|
+
: new File([contentBody], filename, { type: contentType })
|
|
88
|
+
|
|
89
|
+
const parsedValue = parsedBody[name]
|
|
90
|
+
|
|
91
|
+
if (parsedValue === undefined) {
|
|
92
|
+
parsedBody[name] = value
|
|
93
|
+
} else if (Array.isArray(parsedValue)) {
|
|
94
|
+
parsedBody[name] = [...parsedValue, value]
|
|
95
|
+
} else {
|
|
96
|
+
parsedBody[name] = [parsedValue, value]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return parsedBody as T
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return undefined
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Emitter } from 'strict-event-emitter'
|
|
2
|
+
import { pipeEvents } from './pipeEvents'
|
|
3
|
+
|
|
4
|
+
it('pipes events from the source emitter to the destination emitter', () => {
|
|
5
|
+
const source = new Emitter()
|
|
6
|
+
const destination = new Emitter()
|
|
7
|
+
pipeEvents(source, destination)
|
|
8
|
+
|
|
9
|
+
const callback = vi.fn()
|
|
10
|
+
destination.on('hello', callback)
|
|
11
|
+
|
|
12
|
+
source.emit('hello', 'world', { data: true })
|
|
13
|
+
expect(callback).toHaveBeenNthCalledWith(1, 'world', { data: true })
|
|
14
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Emitter, EventMap } from 'strict-event-emitter'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pipes all emitted events from one emitter to another.
|
|
5
|
+
*/
|
|
6
|
+
export function pipeEvents<Events extends EventMap>(
|
|
7
|
+
source: Emitter<Events>,
|
|
8
|
+
destination: Emitter<Events>,
|
|
9
|
+
): void {
|
|
10
|
+
const rawEmit: typeof source.emit & { _isPiped?: boolean } = source.emit
|
|
11
|
+
|
|
12
|
+
if (rawEmit._isPiped) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const sourceEmit: typeof source.emit & { _isPiped?: boolean } =
|
|
17
|
+
function sourceEmit(this: typeof source, event, ...data) {
|
|
18
|
+
destination.emit(event, ...data)
|
|
19
|
+
return rawEmit.call(this, event, ...data)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
sourceEmit._isPiped = true
|
|
23
|
+
|
|
24
|
+
source.emit = sourceEmit
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RequestHandler } from '../../handlers/RequestHandler'
|
|
2
|
+
|
|
3
|
+
export function use(
|
|
4
|
+
currentHandlers: Array<RequestHandler>,
|
|
5
|
+
...handlers: Array<RequestHandler>
|
|
6
|
+
): void {
|
|
7
|
+
currentHandlers.unshift(...handlers)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function restoreHandlers(handlers: Array<RequestHandler>): void {
|
|
11
|
+
handlers.forEach((handler) => {
|
|
12
|
+
handler.isUsed = false
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function resetHandlers(
|
|
17
|
+
initialHandlers: Array<RequestHandler>,
|
|
18
|
+
...nextHandlers: Array<RequestHandler>
|
|
19
|
+
) {
|
|
20
|
+
return nextHandlers.length > 0 ? [...nextHandlers] : [...initialHandlers]
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { toReadonlyArray } from './toReadonlyArray'
|
|
2
|
+
|
|
3
|
+
it('creates a copy of an array', () => {
|
|
4
|
+
expect(toReadonlyArray([1, 2, 3])).toEqual([1, 2, 3])
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
it('does not affect the source array', () => {
|
|
8
|
+
const source = ['a', 'b', 'c']
|
|
9
|
+
toReadonlyArray(source)
|
|
10
|
+
|
|
11
|
+
expect(source.push('d')).toBe(4)
|
|
12
|
+
expect(source).toEqual(['a', 'b', 'c', 'd'])
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('forbids modifying the array copy', () => {
|
|
16
|
+
const source = [1, 2, 3]
|
|
17
|
+
const copy = toReadonlyArray(source)
|
|
18
|
+
|
|
19
|
+
expect(() => {
|
|
20
|
+
// @ts-expect-error Intentional runtime misusage.
|
|
21
|
+
copy[2] = 1
|
|
22
|
+
}).toThrow(/Cannot assign to read only property '\d+' of object/)
|
|
23
|
+
|
|
24
|
+
expect(() => {
|
|
25
|
+
// @ts-expect-error Intentional runtime misusage.
|
|
26
|
+
copy.push(4)
|
|
27
|
+
}).toThrow(/Cannot add property \d+, object is not extensible/)
|
|
28
|
+
|
|
29
|
+
expect(source).toEqual([1, 2, 3])
|
|
30
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { tryCatch } from './tryCatch'
|
|
2
|
+
|
|
3
|
+
test('returns the function payload', () => {
|
|
4
|
+
const result = tryCatch(() => 'hello')
|
|
5
|
+
expect(result).toEqual('hello')
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test('silences exceptions by default', () => {
|
|
9
|
+
const result = tryCatch(() => {
|
|
10
|
+
throw new Error('Exception')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
expect(result).toBeUndefined()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('executes a custom callback function when an exception occurs', async () => {
|
|
17
|
+
await new Promise<void>((resolve) => {
|
|
18
|
+
tryCatch(
|
|
19
|
+
() => {
|
|
20
|
+
throw new Error('Exception')
|
|
21
|
+
},
|
|
22
|
+
(error) => {
|
|
23
|
+
expect(error).toBeInstanceOf(Error)
|
|
24
|
+
expect(error.message).toEqual('Exception')
|
|
25
|
+
resolve()
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getStatusCodeColor } from './getStatusCodeColor'
|
|
2
|
+
|
|
3
|
+
test('returns a green color for status codes lower than 300', () => {
|
|
4
|
+
expect(getStatusCodeColor(100)).toBe('#69AB32')
|
|
5
|
+
expect(getStatusCodeColor(200)).toBe('#69AB32')
|
|
6
|
+
expect(getStatusCodeColor(204)).toBe('#69AB32')
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test('returns a yellow color for status codes between 201 and 400', () => {
|
|
10
|
+
expect(getStatusCodeColor(300)).toBe('#F0BB4B')
|
|
11
|
+
expect(getStatusCodeColor(304)).toBe('#F0BB4B')
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('returns a red color for status codes higher than 400', () => {
|
|
15
|
+
expect(getStatusCodeColor(400)).toBe('#E95F5D')
|
|
16
|
+
expect(getStatusCodeColor(404)).toBe('#E95F5D')
|
|
17
|
+
expect(getStatusCodeColor(500)).toBe('#E95F5D')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('returns a red color for unknown status code', () => {
|
|
21
|
+
expect(getStatusCodeColor(700)).toBe('#E95F5D')
|
|
22
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export enum StatusCodeColor {
|
|
2
|
+
Success = '#69AB32',
|
|
3
|
+
Warning = '#F0BB4B',
|
|
4
|
+
Danger = '#E95F5D',
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns a HEX color for a given response status code number.
|
|
9
|
+
*/
|
|
10
|
+
export function getStatusCodeColor(status: number): StatusCodeColor {
|
|
11
|
+
if (status < 300) {
|
|
12
|
+
return StatusCodeColor.Success
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (status < 400) {
|
|
16
|
+
return StatusCodeColor.Warning
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return StatusCodeColor.Danger
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getTimestamp } from './getTimestamp'
|
|
2
|
+
|
|
3
|
+
beforeAll(() => {
|
|
4
|
+
// Stub native `Date` prototype methods used in the tested module,
|
|
5
|
+
// to always produce a predictable value for testing purposes.
|
|
6
|
+
vi.spyOn(global.Date.prototype, 'getHours').mockImplementation(() => 12)
|
|
7
|
+
vi.spyOn(global.Date.prototype, 'getMinutes').mockImplementation(() => 4)
|
|
8
|
+
vi.spyOn(global.Date.prototype, 'getSeconds').mockImplementation(() => 8)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
afterAll(() => {
|
|
12
|
+
vi.restoreAllMocks()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('returns a timestamp string of the invocation time', () => {
|
|
16
|
+
const timestamp = getTimestamp()
|
|
17
|
+
expect(timestamp).toBe('12:04:08')
|
|
18
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a timestamp string in a "HH:MM:SS" format.
|
|
3
|
+
*/
|
|
4
|
+
export function getTimestamp(): string {
|
|
5
|
+
const now = new Date()
|
|
6
|
+
|
|
7
|
+
return [now.getHours(), now.getMinutes(), now.getSeconds()]
|
|
8
|
+
.map(String)
|
|
9
|
+
.map((chunk) => chunk.slice(0, 2))
|
|
10
|
+
.map((chunk) => chunk.padStart(2, '0'))
|
|
11
|
+
.join(':')
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { encodeBuffer } from '@mswjs/interceptors'
|
|
2
|
+
import { serializeRequest } from './serializeRequest'
|
|
3
|
+
|
|
4
|
+
test('serializes given Request instance into a plain object', async () => {
|
|
5
|
+
const request = await serializeRequest(
|
|
6
|
+
new Request(new URL('http://test.mswjs.io/user'), {
|
|
7
|
+
method: 'POST',
|
|
8
|
+
headers: new Headers({
|
|
9
|
+
'Content-Type': 'text/plain',
|
|
10
|
+
'X-Header': 'secret',
|
|
11
|
+
}),
|
|
12
|
+
body: encodeBuffer('text-body'),
|
|
13
|
+
}),
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
expect(request.method).toBe('POST')
|
|
17
|
+
expect(request.url.href).toBe('http://test.mswjs.io/user')
|
|
18
|
+
expect(request.headers).toEqual({
|
|
19
|
+
'content-type': 'text/plain',
|
|
20
|
+
'x-header': 'secret',
|
|
21
|
+
})
|
|
22
|
+
expect(request.body).toBe('text-body')
|
|
23
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface LoggedRequest {
|
|
2
|
+
url: URL
|
|
3
|
+
method: string
|
|
4
|
+
headers: Record<string, string>
|
|
5
|
+
body: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Formats a mocked request for introspection in browser's console.
|
|
10
|
+
*/
|
|
11
|
+
export async function serializeRequest(
|
|
12
|
+
request: Request,
|
|
13
|
+
): Promise<LoggedRequest> {
|
|
14
|
+
const requestClone = request.clone()
|
|
15
|
+
const requestText = await requestClone.text()
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
url: new URL(request.url),
|
|
19
|
+
method: request.method,
|
|
20
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
21
|
+
body: requestText,
|
|
22
|
+
}
|
|
23
|
+
}
|