msw 0.20.1 → 0.20.5

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.
@@ -1,6 +1,7 @@
1
1
  import { OperationTypeNode } from 'graphql';
2
- import { RequestHandler, MockedRequest } from './handlers/requestHandler';
2
+ import { RequestHandler, MockedRequest, AsyncResponseResolverReturnType } from './handlers/requestHandler';
3
3
  import { MockedResponse, ResponseComposition } from './response';
4
+ import { Mask } from './setupWorker/glossary';
4
5
  import { set } from './context/set';
5
6
  import { status } from './context/status';
6
7
  import { delay } from './context/delay';
@@ -21,7 +22,7 @@ export interface GraphQLMockedContext<QueryType> {
21
22
  errors: typeof errors;
22
23
  }
23
24
  export declare const graphqlContext: GraphQLMockedContext<any>;
24
- export declare type GraphQLResponseResolver<QueryType, VariablesType> = (req: GraphQLMockedRequest<VariablesType>, res: ResponseComposition, context: GraphQLMockedContext<QueryType>) => MockedResponse;
25
+ export declare type GraphQLResponseResolver<QueryType, VariablesType> = (req: GraphQLMockedRequest<VariablesType>, res: ResponseComposition, context: GraphQLMockedContext<QueryType>) => AsyncResponseResolverReturnType<MockedResponse>;
25
26
  export interface GraphQLRequestPayload<VariablesType> {
26
27
  query: string;
27
28
  variables?: VariablesType;
@@ -35,7 +36,13 @@ interface ParsedQueryPayload {
35
36
  operationName: string | undefined;
36
37
  }
37
38
  export declare function parseQuery(query: string, definitionOperation?: OperationTypeNode): ParsedQueryPayload;
39
+ declare const graphqlStandardHandlers: {
40
+ query: <QueryType, VariablesType = Record<string, any>>(expectedOperation: GraphQLRequestHandlerSelector, resolver: GraphQLResponseResolver<QueryType, VariablesType>) => RequestHandler<GraphQLMockedRequest<VariablesType>, GraphQLMockedContext<QueryType>, GraphQLRequestParsedResult<VariablesType>, GraphQLMockedRequest<VariablesType>>;
41
+ mutation: <QueryType, VariablesType = Record<string, any>>(expectedOperation: GraphQLRequestHandlerSelector, resolver: GraphQLResponseResolver<QueryType, VariablesType>) => RequestHandler<GraphQLMockedRequest<VariablesType>, GraphQLMockedContext<QueryType>, GraphQLRequestParsedResult<VariablesType>, GraphQLMockedRequest<VariablesType>>;
42
+ };
43
+ declare function createGraphQLLink(uri: Mask): typeof graphqlStandardHandlers;
38
44
  export declare const graphql: {
45
+ link: typeof createGraphQLLink;
39
46
  query: <QueryType, VariablesType = Record<string, any>>(expectedOperation: GraphQLRequestHandlerSelector, resolver: GraphQLResponseResolver<QueryType, VariablesType>) => RequestHandler<GraphQLMockedRequest<VariablesType>, GraphQLMockedContext<QueryType>, GraphQLRequestParsedResult<VariablesType>, GraphQLMockedRequest<VariablesType>>;
40
47
  mutation: <QueryType, VariablesType = Record<string, any>>(expectedOperation: GraphQLRequestHandlerSelector, resolver: GraphQLResponseResolver<QueryType, VariablesType>) => RequestHandler<GraphQLMockedRequest<VariablesType>, GraphQLMockedContext<QueryType>, GraphQLRequestParsedResult<VariablesType>, GraphQLMockedRequest<VariablesType>>;
41
48
  };
@@ -32,14 +32,15 @@ export declare type RequestQuery = {
32
32
  export declare type RequestParams = {
33
33
  [paramName: string]: any;
34
34
  };
35
- declare type ResponseResolverReturnType = MockedResponse | undefined | void;
36
- export declare type ResponseResolver<RequestType = MockedRequest, ContextType = typeof defaultContext> = (req: RequestType, res: ResponseComposition, context: ContextType) => Promise<ResponseResolverReturnType> | ResponseResolverReturnType;
35
+ export declare type ResponseResolverReturnType<R> = R | undefined | void;
36
+ export declare type AsyncResponseResolverReturnType<R> = Promise<ResponseResolverReturnType<R>> | ResponseResolverReturnType<R>;
37
+ export declare type ResponseResolver<RequestType = MockedRequest, ContextType = typeof defaultContext> = (req: RequestType, res: ResponseComposition, context: ContextType) => AsyncResponseResolverReturnType<MockedResponse>;
37
38
  export interface RequestHandler<RequestType = MockedRequest, ContextType = typeof defaultContext, ParsedRequest = any, PublicRequest = RequestType> {
38
39
  /**
39
40
  * Parses a captured request to retrieve additional
40
41
  * information meant for internal usage in the request handler.
41
42
  */
42
- parse?: (req: MockedRequest) => ParsedRequest | null;
43
+ parse?: (req: RequestType) => ParsedRequest | null;
43
44
  /**
44
45
  * Returns a modified request with necessary public properties appended.
45
46
  */
@@ -2,6 +2,7 @@ import * as context from './context';
2
2
  export { setupWorker } from './setupWorker/setupWorker';
3
3
  export { MockedResponse, ResponseTransformer, response } from './response';
4
4
  export { context };
5
- export { MockedRequest, RequestHandler, RequestParams, RequestQuery, ResponseResolver, defaultContext, } from './handlers/requestHandler';
6
- export { rest, restContext, RESTMethods } from './rest';
5
+ export { MockedRequest, RequestHandler, RequestParams, RequestQuery, ResponseResolver, ResponseResolverReturnType, AsyncResponseResolverReturnType, defaultContext, } from './handlers/requestHandler';
6
+ export { rest, restContext, RESTMethods, ParsedRestRequest } from './rest';
7
7
  export { graphql, graphqlContext, GraphQLMockedRequest, GraphQLMockedContext, GraphQLRequestPayload, GraphQLResponseResolver, } from './graphql';
8
+ export { matchRequestUrl } from './utils/matching/matchRequest';
@@ -1,6 +1,7 @@
1
1
  import { RequestHandler, ResponseResolver, MockedRequest } from './handlers/requestHandler';
2
2
  import { Mask } from './setupWorker/glossary';
3
3
  import { set } from './context/set';
4
+ import { matchRequestUrl } from './utils/matching/matchRequest';
4
5
  export declare enum RESTMethods {
5
6
  GET = "GET",
6
7
  POST = "POST",
@@ -20,11 +21,14 @@ export declare const restContext: {
20
21
  delay: (durationMs?: number | undefined) => import("./response").ResponseTransformer;
21
22
  fetch: <ResponseType_1 = any>(input: string | MockedRequest, requestInit?: RequestInit) => Promise<ResponseType_1>;
22
23
  };
24
+ export interface ParsedRestRequest {
25
+ match: ReturnType<typeof matchRequestUrl>;
26
+ }
23
27
  export declare const rest: {
24
- get: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext>;
25
- post: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext>;
26
- put: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext>;
27
- delete: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext>;
28
- patch: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext>;
29
- options: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext>;
28
+ get: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext, ParsedRestRequest>;
29
+ post: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext, ParsedRestRequest>;
30
+ put: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext, ParsedRestRequest>;
31
+ delete: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext, ParsedRestRequest>;
32
+ patch: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext, ParsedRestRequest>;
33
+ options: (mask: Mask, resolver: ResponseResolver<MockedRequest, typeof restContext>) => RequestHandler<MockedRequest, typeof restContext, ParsedRestRequest>;
30
34
  };
@@ -4,6 +4,7 @@ import { MockedResponse } from '../response';
4
4
  import { SharedOptions } from '../sharedOptions';
5
5
  import { ServiceWorkerMessage } from '../utils/createBroadcastChannel';
6
6
  export declare type Mask = RegExp | string;
7
+ export declare type ResolvedMask = Mask | URL;
7
8
  export interface SetupWorkerInternalContext {
8
9
  worker: ServiceWorker | null;
9
10
  registration: ServiceWorkerRegistration | null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Attempts to resolve a Service Worker instance from any of its states:
3
- * active, installing, or waiting.
2
+ * Attempts to resolve a Service Worker instance from a given registration,
3
+ * regardless of its state (active, installing, waiting).
4
4
  */
5
- export declare const getWorkerByRegistration: (registration: ServiceWorkerRegistration) => ServiceWorker | null;
5
+ export declare const getWorkerByRegistration: (registration: ServiceWorkerRegistration, absoluteWorkerUrl: string) => ServiceWorker | null;
@@ -0,0 +1,2 @@
1
+ import { Mask, ResolvedMask } from '../../setupWorker/glossary';
2
+ export declare function getCleanMask(resolvedMask: ResolvedMask): Mask;
@@ -0,0 +1,7 @@
1
+ import { match } from 'node-match-path';
2
+ import { Mask } from '../../setupWorker/glossary';
3
+ /**
4
+ * Returns the result of matching given request URL
5
+ * against a mask.
6
+ */
7
+ export declare function matchRequestUrl(url: URL, mask: Mask): ReturnType<typeof match>;
package/lib/umd/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MockServiceWorker = {}));
5
5
  }(this, (function (exports) { 'use strict';
6
6
 
7
- var statuses = {
7
+ var codes = {
8
8
  "100": "Continue",
9
9
  "101": "Switching Protocols",
10
10
  "102": "Processing",
@@ -70,6 +70,11 @@
70
70
  "511": "Network Authentication Required"
71
71
  };
72
72
 
73
+ var statuses = /*#__PURE__*/Object.freeze({
74
+ __proto__: null,
75
+ 'default': codes
76
+ });
77
+
73
78
  const status = (statusCode, statusText) => {
74
79
  return (res) => {
75
80
  res.status = statusCode;
@@ -550,21 +555,18 @@
550
555
  }
551
556
  }
552
557
 
553
- var cookie = {
554
- parse: parse_1,
555
- serialize: serialize_1
556
- };
557
-
558
558
  /**
559
559
  * Sets a given cookie on the response.
560
560
  * @example
561
561
  * res(cookie('name', 'value'))
562
562
  */
563
- const cookie$1 = (name, value, options) => {
563
+ const cookie = (name, value, options) => {
564
564
  return (res) => {
565
- const serializedCookie = cookie.serialize(name, value, options);
565
+ const serializedCookie = serialize_1(name, value, options);
566
566
  res.headers.set('Set-Cookie', serializedCookie);
567
- document.cookie = serializedCookie;
567
+ if (typeof document !== 'undefined') {
568
+ document.cookie = serializedCookie;
569
+ }
568
570
  return res;
569
571
  };
570
572
  };
@@ -711,7 +713,7 @@
711
713
  __proto__: null,
712
714
  status: status,
713
715
  set: set,
714
- cookie: cookie$1,
716
+ cookie: cookie,
715
717
  body: body,
716
718
  data: data,
717
719
  delay: delay,
@@ -774,11 +776,20 @@
774
776
  });
775
777
 
776
778
  /**
777
- * Attempts to resolve a Service Worker instance from any of its states:
778
- * active, installing, or waiting.
779
+ * Attempts to resolve a Service Worker instance from a given registration,
780
+ * regardless of its state (active, installing, waiting).
779
781
  */
780
- const getWorkerByRegistration = (registration) => {
781
- return registration.active || registration.installing || registration.waiting;
782
+ const getWorkerByRegistration = (registration, absoluteWorkerUrl) => {
783
+ const allStates = [
784
+ registration.active,
785
+ registration.installing,
786
+ registration.waiting,
787
+ ];
788
+ const existingStates = allStates.filter(Boolean);
789
+ const mockWorker = existingStates.find((worker) => {
790
+ return worker.scriptURL === absoluteWorkerUrl;
791
+ });
792
+ return mockWorker || null;
782
793
  };
783
794
 
784
795
  /**
@@ -799,9 +810,7 @@
799
810
  const [, mockRegistrations] = yield lib$1.until(() => __awaiter(void 0, void 0, void 0, function* () {
800
811
  const registrations = yield navigator.serviceWorker.getRegistrations();
801
812
  return registrations.filter((registration) => {
802
- const worker = getWorkerByRegistration(registration);
803
- // Filter out other workers that can be associated with this page
804
- return (worker === null || worker === void 0 ? void 0 : worker.scriptURL) === absoluteWorkerUrl;
813
+ return getWorkerByRegistration(registration, absoluteWorkerUrl);
805
814
  });
806
815
  }));
807
816
  if (!navigator.serviceWorker.controller && mockRegistrations.length > 0) {
@@ -813,21 +822,24 @@
813
822
  // at this point we are sure it's hard reload that falls into this clause.
814
823
  location.reload();
815
824
  }
816
- const [, existingRegistration] = yield lib$1.until(() => {
817
- return navigator.serviceWorker.getRegistration(url);
818
- });
825
+ const [existingRegistration] = mockRegistrations;
819
826
  if (existingRegistration) {
820
827
  // Update existing service worker to ensure it's up-to-date
821
828
  return existingRegistration.update().then(() => {
822
829
  return [
823
- getWorkerByRegistration(existingRegistration),
830
+ getWorkerByRegistration(existingRegistration, absoluteWorkerUrl),
824
831
  existingRegistration,
825
832
  ];
826
833
  });
827
834
  }
828
835
  const [error, instance] = yield lib$1.until(() => __awaiter(void 0, void 0, void 0, function* () {
829
836
  const registration = yield navigator.serviceWorker.register(url, options);
830
- return [getWorkerByRegistration(registration), registration];
837
+ return [
838
+ // Compare existing worker registration by its worker URL,
839
+ // to prevent irrelevant workers to resolve here (such as Codesandbox worker).
840
+ getWorkerByRegistration(registration, absoluteWorkerUrl),
841
+ registration,
842
+ ];
831
843
  }));
832
844
  if (error) {
833
845
  const isWorkerMissing = error.message.includes('(404)');
@@ -934,49 +946,72 @@ Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/i
934
946
  * Returns a mocked response for a given request using following request handlers.
935
947
  */
936
948
  const getResponse = (req, handlers) => __awaiter(void 0, void 0, void 0, function* () {
937
- const [relevantHandler, parsedRequest] = handlers.reduce((found, requestHandler) => {
938
- // Skip any request handlers lookup if a handler is already found,
939
- // or the current handler is a one-time handler that's been already used.
940
- if ((found && found[0]) || requestHandler.shouldSkip) {
941
- return found;
942
- }
949
+ const relevantHandlers = handlers
950
+ .filter((requestHandler) => {
951
+ // Skip a handler if it has been already used for a one-time response.
952
+ return !requestHandler.shouldSkip;
953
+ })
954
+ .map((requestHandler) => {
943
955
  // Parse the captured request to get additional information.
944
956
  // Make the predicate function accept all the necessary information
945
957
  // to decide on the interception.
946
958
  const parsedRequest = requestHandler.parse
947
959
  ? requestHandler.parse(req)
948
960
  : null;
949
- if (requestHandler.predicate(req, parsedRequest)) {
950
- return [requestHandler, parsedRequest];
951
- }
952
- }, []) || [null, null];
953
- if (relevantHandler == null) {
961
+ return [requestHandler, parsedRequest];
962
+ })
963
+ .filter(([requestHandler, parsedRequest]) => {
964
+ return requestHandler.predicate(req, parsedRequest);
965
+ });
966
+ if (relevantHandlers.length == 0) {
967
+ // Handle a scenario when a request has no relevant request handlers.
968
+ // In that case it would be bypassed (performed as-is).
954
969
  return {
955
970
  handler: null,
956
971
  response: null,
957
972
  };
958
973
  }
959
- const { getPublicRequest, defineContext, resolver } = relevantHandler;
960
- const publicRequest = getPublicRequest
961
- ? getPublicRequest(req, parsedRequest)
962
- : req;
963
- const context = defineContext ? defineContext(publicRequest) : defaultContext;
964
- const mockedResponse = yield resolver(publicRequest, response, context);
965
- // Handle a scenario when a request handler is present,
966
- // but returns no mocked response (i.e. misses a `return res()` statement).
967
- if (!mockedResponse) {
974
+ const { requestHandler, parsedRequest, mockedResponse, publicRequest, } = yield relevantHandlers.reduce((asyncAcc, [requestHandler, parsedRequest]) => __awaiter(void 0, void 0, void 0, function* () {
975
+ // Now the reduce function is async so we need to await if response was found
976
+ const acc = yield asyncAcc;
977
+ // If a first not empty response was found we'll stop evaluating other requests
978
+ if (acc.requestHandler) {
979
+ return acc;
980
+ }
981
+ const { getPublicRequest, defineContext, resolver } = requestHandler;
982
+ const publicRequest = getPublicRequest
983
+ ? getPublicRequest(req, parsedRequest)
984
+ : req;
985
+ const context = defineContext
986
+ ? defineContext(publicRequest)
987
+ : defaultContext;
988
+ const mockedResponse = yield resolver(publicRequest, response, context);
989
+ if (!mockedResponse) {
990
+ return acc;
991
+ }
992
+ if (mockedResponse && mockedResponse.once) {
993
+ // When responded with a one-time response, match the relevant request handler
994
+ // as skipped, so it cannot affect the captured requests anymore.
995
+ requestHandler.shouldSkip = true;
996
+ }
968
997
  return {
969
- handler: relevantHandler,
998
+ requestHandler,
999
+ parsedRequest,
1000
+ mockedResponse,
1001
+ publicRequest,
1002
+ };
1003
+ }), Promise.resolve({ mockedResponse: null }));
1004
+ // Although reducing a list of relevant request handlers, it's possible
1005
+ // that in the end there will be no handler associted with the request
1006
+ // (i.e. if relevant handlers are fall-through).
1007
+ if (!requestHandler) {
1008
+ return {
1009
+ handler: null,
970
1010
  response: null,
971
1011
  };
972
1012
  }
973
- if (mockedResponse.once) {
974
- // When responded with a one-time response, match the relevant request handler
975
- // as skipped, so it cannot affect the captured requests anymore.
976
- relevantHandler.shouldSkip = true;
977
- }
978
1013
  return {
979
- handler: relevantHandler,
1014
+ handler: requestHandler,
980
1015
  response: mockedResponse,
981
1016
  publicRequest,
982
1017
  parsedRequest,
@@ -1038,7 +1073,7 @@ Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/i
1038
1073
  }
1039
1074
 
1040
1075
  function getAllCookies() {
1041
- return cookie.parse(document.cookie);
1076
+ return parse_1(document.cookie);
1042
1077
  }
1043
1078
  /**
1044
1079
  * Returns relevant document cookies based on the request `credentials` option.
@@ -2698,6 +2733,47 @@ If this message still persists after updating, please report an issue: https://g
2698
2733
  if (host) this.hostname = host;
2699
2734
  };
2700
2735
 
2736
+ /**
2737
+ * Formats a mocked request for introspection in browser's console.
2738
+ */
2739
+ function prepareRequest(req) {
2740
+ return Object.assign(Object.assign({}, req), { headers: req.headers.getAllHeaders() });
2741
+ }
2742
+
2743
+ /**
2744
+ * Formats a mocked response for introspection in browser's console.
2745
+ */
2746
+ function prepareResponse(res) {
2747
+ var _a;
2748
+ const resHeaders = lib.listToHeaders(res.headers);
2749
+ return Object.assign(Object.assign({}, res), {
2750
+ // Parse a response JSON body for preview in the logs
2751
+ body: ((_a = resHeaders.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json')) ? getJsonBody(res.body)
2752
+ : res.body });
2753
+ }
2754
+
2755
+ function getTimestamp() {
2756
+ const now = new Date();
2757
+ return [now.getHours(), now.getMinutes(), now.getSeconds()]
2758
+ .map(String)
2759
+ .map((chunk) => chunk.slice(0, 2))
2760
+ .map((chunk) => chunk.padStart(2, '0'))
2761
+ .join(':');
2762
+ }
2763
+
2764
+ /**
2765
+ * Returns a HEX color for a given response status code number.
2766
+ */
2767
+ function getStatusCodeColor(status) {
2768
+ if (status < 300) {
2769
+ return '#69AB32';
2770
+ }
2771
+ if (status < 400) {
2772
+ return '#F0BB4B';
2773
+ }
2774
+ return '#E95F5D';
2775
+ }
2776
+
2701
2777
  /**
2702
2778
  * Converts a string path to a Regular Expression.
2703
2779
  * Transforms path parameters into named RegExp groups.
@@ -2762,47 +2838,6 @@ If this message still persists after updating, please report an issue: https://g
2762
2838
  : mask;
2763
2839
  };
2764
2840
 
2765
- /**
2766
- * Formats a mocked request for introspection in browser's console.
2767
- */
2768
- function prepareRequest(req) {
2769
- return Object.assign(Object.assign({}, req), { headers: req.headers.getAllHeaders() });
2770
- }
2771
-
2772
- /**
2773
- * Formats a mocked response for introspection in browser's console.
2774
- */
2775
- function prepareResponse(res) {
2776
- var _a;
2777
- const resHeaders = lib.listToHeaders(res.headers);
2778
- return Object.assign(Object.assign({}, res), {
2779
- // Parse a response JSON body for preview in the logs
2780
- body: ((_a = resHeaders.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json')) ? getJsonBody(res.body)
2781
- : res.body });
2782
- }
2783
-
2784
- function getTimestamp() {
2785
- const now = new Date();
2786
- return [now.getHours(), now.getMinutes(), now.getSeconds()]
2787
- .map(String)
2788
- .map((chunk) => chunk.slice(0, 2))
2789
- .map((chunk) => chunk.padStart(2, '0'))
2790
- .join(':');
2791
- }
2792
-
2793
- /**
2794
- * Returns a HEX color for a given response status code number.
2795
- */
2796
- function getStatusCodeColor(status) {
2797
- if (status < 300) {
2798
- return '#69AB32';
2799
- }
2800
- if (status < 400) {
2801
- return '#F0BB4B';
2802
- }
2803
- return '#E95F5D';
2804
- }
2805
-
2806
2841
  /**
2807
2842
  * Converts a given request handler mask into a URL, if given a valid URL string.
2808
2843
  * Otherwise, returns the mask as-is.
@@ -2823,6 +2858,25 @@ If this message still persists after updating, please report an issue: https://g
2823
2858
  }
2824
2859
  }
2825
2860
 
2861
+ function getCleanMask(resolvedMask) {
2862
+ return resolvedMask instanceof URL
2863
+ ? getCleanUrl_1.getCleanUrl(resolvedMask)
2864
+ : resolvedMask instanceof RegExp
2865
+ ? resolvedMask
2866
+ : resolveRelativeUrl(resolvedMask);
2867
+ }
2868
+
2869
+ /**
2870
+ * Returns the result of matching given request URL
2871
+ * against a mask.
2872
+ */
2873
+ function matchRequestUrl(url, mask) {
2874
+ const resolvedMask = resolveMask(mask);
2875
+ const cleanMask = getCleanMask(resolvedMask);
2876
+ const cleanRequestUrl = getCleanUrl_1.getCleanUrl(url);
2877
+ return match(cleanMask, cleanRequestUrl);
2878
+ }
2879
+
2826
2880
  (function (RESTMethods) {
2827
2881
  RESTMethods["GET"] = "GET";
2828
2882
  RESTMethods["POST"] = "POST";
@@ -2834,7 +2888,7 @@ If this message still persists after updating, please report an issue: https://g
2834
2888
  const restContext = {
2835
2889
  set,
2836
2890
  status,
2837
- cookie: cookie$1,
2891
+ cookie,
2838
2892
  body,
2839
2893
  text,
2840
2894
  json,
@@ -2845,24 +2899,21 @@ If this message still persists after updating, please report an issue: https://g
2845
2899
  const createRestHandler = (method) => {
2846
2900
  return (mask, resolver) => {
2847
2901
  const resolvedMask = resolveMask(mask);
2848
- const cleanMask = resolvedMask instanceof URL
2849
- ? getCleanUrl_1.getCleanUrl(resolvedMask)
2850
- : resolvedMask instanceof RegExp
2851
- ? resolvedMask
2852
- : resolveRelativeUrl(resolvedMask);
2853
2902
  return {
2854
- predicate(req) {
2855
- // Ignore query parameters and hash when matching requests URI
2856
- const cleanUrl = getCleanUrl_1.getCleanUrl(req.url);
2857
- const hasSameMethod = isStringEqual(method, req.method);
2858
- const urlMatch = match(cleanMask, cleanUrl);
2859
- return hasSameMethod && urlMatch.matches;
2903
+ parse(req) {
2904
+ // Match the request during parsing to prevent matching it twice
2905
+ // in order to get the request URL parameters.
2906
+ const match = matchRequestUrl(req.url, mask);
2907
+ return {
2908
+ match,
2909
+ };
2910
+ },
2911
+ predicate(req, parsedRequest) {
2912
+ return isStringEqual(method, req.method) && parsedRequest.match.matches;
2860
2913
  },
2861
- getPublicRequest(req) {
2914
+ getPublicRequest(req, parsedRequest) {
2862
2915
  // Get request path parameters based on the given mask
2863
- const params = (mask &&
2864
- match(resolveRelativeUrl(mask), getCleanUrl_1.getCleanUrl(req.url)).params) ||
2865
- {};
2916
+ const params = (mask && parsedRequest.match.params) || {};
2866
2917
  return Object.assign(Object.assign({}, req), { params });
2867
2918
  },
2868
2919
  resolver,
@@ -5930,11 +5981,12 @@ ${queryParams
5930
5981
  operationName: (_a = operationDef === null || operationDef === void 0 ? void 0 : operationDef.name) === null || _a === void 0 ? void 0 : _a.value,
5931
5982
  };
5932
5983
  }
5933
- const createGraphQLHandler = (operationType) => {
5984
+ const createGraphQLHandler = (operationType, mask) => {
5934
5985
  return (expectedOperation, resolver) => {
5935
5986
  return {
5936
5987
  resolver,
5937
5988
  parse(req) {
5989
+ var _a;
5938
5990
  // According to the GraphQL specification, a GraphQL request can be issued
5939
5991
  // using both "GET" and "POST" methods.
5940
5992
  switch (req.method) {
@@ -5955,7 +6007,7 @@ ${queryParams
5955
6007
  };
5956
6008
  }
5957
6009
  case 'POST': {
5958
- if (!req.body) {
6010
+ if (!((_a = req.body) === null || _a === void 0 ? void 0 : _a.query)) {
5959
6011
  return null;
5960
6012
  }
5961
6013
  const { query, variables } = req.body;
@@ -5977,10 +6029,13 @@ ${queryParams
5977
6029
  if (!parsed || !parsed.operationName) {
5978
6030
  return false;
5979
6031
  }
6032
+ // Match the request URL against a given mask,
6033
+ // in case of an endpoint-specific request handler.
6034
+ const hasMatchingMask = matchRequestUrl(req.url, mask);
5980
6035
  const isMatchingOperation = expectedOperation instanceof RegExp
5981
6036
  ? expectedOperation.test(parsed.operationName)
5982
6037
  : expectedOperation === parsed.operationName;
5983
- return isMatchingOperation;
6038
+ return isMatchingOperation && hasMatchingMask.matches;
5984
6039
  },
5985
6040
  defineContext() {
5986
6041
  return graphqlContext;
@@ -6002,15 +6057,23 @@ ${queryParams
6002
6057
  };
6003
6058
  };
6004
6059
  };
6005
- const graphql = {
6006
- query: createGraphQLHandler('query'),
6007
- mutation: createGraphQLHandler('mutation'),
6008
- };
6060
+ const graphqlStandardHandlers = {
6061
+ query: createGraphQLHandler('query', '*'),
6062
+ mutation: createGraphQLHandler('mutation', '*'),
6063
+ };
6064
+ function createGraphQLLink(uri) {
6065
+ return {
6066
+ query: createGraphQLHandler('query', uri),
6067
+ mutation: createGraphQLHandler('mutation', uri),
6068
+ };
6069
+ }
6070
+ const graphql = Object.assign(Object.assign({}, graphqlStandardHandlers), { link: createGraphQLLink });
6009
6071
 
6010
6072
  exports.context = index;
6011
6073
  exports.defaultContext = defaultContext;
6012
6074
  exports.graphql = graphql;
6013
6075
  exports.graphqlContext = graphqlContext;
6076
+ exports.matchRequestUrl = matchRequestUrl;
6014
6077
  exports.response = response;
6015
6078
  exports.rest = rest;
6016
6079
  exports.restContext = restContext;