@stuntman/client 0.1.11 → 0.2.1

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.
@@ -48,7 +48,10 @@ declare class RuleBuilder extends RuleBuilderBase {
48
48
  onRequestToPort(port: string | number | RegExp): RuleBuilderInitialized;
49
49
  onAnyRequest(): RuleBuilderInitialized;
50
50
  }
51
- declare class RuleBuilderInitialized extends RuleBuilderBase {
51
+ declare class RuleBuilderRequestInitialized extends RuleBuilderBase {
52
+ modifyResponse(modifyFunction: Stuntman.ResponseManipulationFn | Stuntman.RemotableFunction<Stuntman.ResponseManipulationFn>, localVariables?: Stuntman.LocalVariables): Stuntman.SerializableRule;
53
+ }
54
+ declare class RuleBuilderInitialized extends RuleBuilderRequestInitialized {
52
55
  withHostname(hostname: string | RegExp): this;
53
56
  withPathname(pathname: string | RegExp): this;
54
57
  withPort(port: number | string | RegExp): this;
@@ -72,9 +75,6 @@ declare class RuleBuilderInitialized extends RuleBuilderBase {
72
75
  modifyRequest(modifyFunction: Stuntman.RequestManipulationFn | Stuntman.RemotableFunction<Stuntman.RequestManipulationFn>, localVariables?: Stuntman.LocalVariables): RuleBuilderRequestInitialized;
73
76
  modifyResponse(modifyFunction: Stuntman.ResponseManipulationFn | Stuntman.RemotableFunction<Stuntman.ResponseManipulationFn>, localVariables?: Stuntman.LocalVariables): Stuntman.SerializableRule;
74
77
  }
75
- declare class RuleBuilderRequestInitialized extends RuleBuilderBase {
76
- modifyResponse(modifyFunction: Stuntman.ResponseManipulationFn | Stuntman.RemotableFunction<Stuntman.ResponseManipulationFn>, localVariables?: Stuntman.LocalVariables): Stuntman.SerializableRule;
77
- }
78
78
  export declare const ruleBuilder: () => RuleBuilder;
79
79
  export {};
80
80
  //# sourceMappingURL=ruleBuilder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ruleBuilder.d.ts","sourceRoot":"","sources":["../src/ruleBuilder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAGlD,KAAK,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAClF,KAAK,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AACpE,KAAK,qBAAqB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAAC;AACzE,KAAK,iBAAiB,GAAG;IACrB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,SAAS,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAChC,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC/B,CAAC;AAOF,cAAM,mBAAmB;IACrB,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC;IAC1C,SAAS,CAAC,sBAAsB,EAAE,qBAAqB,CAAC;gBAE5C,IAAI,CAAC,EAAE,QAAQ,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,EAAE,qBAAqB;CAsR/F;AAED,cAAM,eAAgB,SAAQ,mBAAmB;IAC7C,UAAU,CAAC,QAAQ,EAAE,MAAM;IAW3B,SAAS;IAIT,YAAY;IAKZ,QAAQ;CAGX;AAED,cAAM,WAAY,SAAQ,eAAe;IACrC,aAAa,CAAC,EAAE,CAAC,EAAE,MAAM;IAYzB,gBAAgB,CAAC,EAAE,CAAC,EAAE,MAAM;IAS5B,SAAS,CAAC,UAAU,EAAE,MAAM;IAa5B,QAAQ,CAAC,EAAE,EAAE,MAAM;IAKnB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAK5D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAKtE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAKtE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAKvE,YAAY,IAAI,sBAAsB;CAGzC;AAED,cAAM,sBAAuB,SAAQ,eAAe;IAChD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQtC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAQvC,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAC7D,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAmB7E,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,sBAAsB;IAcnE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IACxD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB;IAmBxE,WAAW,CAAC,GAAG,OAAO,EAAE,eAAe,EAAE,GAAG,sBAAsB;IAclE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB;IACtD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB;IAYrD,WAAW,IAAI,sBAAsB;IAQrC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB;IACpD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,GAAG,sBAAsB;IACnF,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,sBAAsB;IA2BpE,WAAW,CAAC,UAAU,EAAE,iBAAiB,GAAG,sBAAsB;IAQlE,SAAS,IAAI,QAAQ,CAAC,gBAAgB;IAKtC,YAAY,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,gBAAgB;IAC1E,YAAY,CAAC,kBAAkB,EAAE,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,oBAAoB,CAAC,GAAG,QAAQ,CAAC,gBAAgB;IACtH,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,EAAE,cAAc,CAAC,EAAE,QAAQ,CAAC,cAAc,GAAG,QAAQ,CAAC,gBAAgB;IAgBzH,aAAa,CACT,cAAc,EAAE,QAAQ,CAAC,qBAAqB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAC3G,cAAc,CAAC,EAAE,QAAQ,CAAC,cAAc,GACzC,6BAA6B;IAYhC,cAAc,CACV,cAAc,EAAE,QAAQ,CAAC,sBAAsB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAC7G,cAAc,CAAC,EAAE,QAAQ,CAAC,cAAc,GACzC,QAAQ,CAAC,gBAAgB;CAW/B;AAED,cAAM,6BAA8B,SAAQ,eAAe;IACvD,cAAc,CACV,cAAc,EAAE,QAAQ,CAAC,sBAAsB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAC7G,cAAc,CAAC,EAAE,QAAQ,CAAC,cAAc,GACzC,QAAQ,CAAC,gBAAgB;CAc/B;AAED,eAAO,MAAM,WAAW,mBAA0B,CAAC"}
1
+ {"version":3,"file":"ruleBuilder.d.ts","sourceRoot":"","sources":["../src/ruleBuilder.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,251 @@ exports.ruleBuilder = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const shared_1 = require("@stuntman/shared");
6
6
  // TODO add fluent match on multipart from data
7
+ function matchFunction(req) {
8
+ var _a, _b, _c, _d, _e;
9
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
10
+ // @ts-ignore
11
+ const localMatchBuilderVariables = (_a = this === null || this === void 0 ? void 0 : this.matchBuilderVariables) !== null && _a !== void 0 ? _a : matchBuilderVariables;
12
+ const ___url = new URL(req.url);
13
+ const ___headers = req.rawHeaders;
14
+ const arrayIndexerRegex = /\[(?<arrayIndex>[0-9]*)\]/i;
15
+ const matchObject = (obj, path, value, parentPath) => {
16
+ var _a, _b, _c, _d;
17
+ if (!obj) {
18
+ return { result: false, description: `${parentPath} is falsey` };
19
+ }
20
+ const [rawKey, ...rest] = path.split('.');
21
+ const key = (rawKey !== null && rawKey !== void 0 ? rawKey : '').replace(arrayIndexerRegex, '');
22
+ const shouldBeArray = rawKey ? arrayIndexerRegex.test(rawKey) : false;
23
+ const arrayIndex = rawKey && (((_b = (_a = arrayIndexerRegex.exec(rawKey)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.arrayIndex) || '').length > 0
24
+ ? Number((_d = (_c = arrayIndexerRegex.exec(rawKey)) === null || _c === void 0 ? void 0 : _c.groups) === null || _d === void 0 ? void 0 : _d.arrayIndex)
25
+ : Number.NaN;
26
+ const actualValue = key ? obj[key] : obj;
27
+ const currentPath = `${parentPath ? `${parentPath}.` : ''}${rawKey}`;
28
+ if (value === undefined && actualValue === undefined) {
29
+ return { result: false, description: `${currentPath}=undefined` };
30
+ }
31
+ if (rest.length === 0) {
32
+ if (shouldBeArray &&
33
+ (!Array.isArray(actualValue) || (Number.isInteger(arrayIndex) && actualValue.length <= Number(arrayIndex)))) {
34
+ return { result: false, description: `${currentPath} empty array` };
35
+ }
36
+ if (value === undefined) {
37
+ const result = shouldBeArray
38
+ ? !Number.isInteger(arrayIndex) || actualValue.length >= Number(arrayIndex)
39
+ : actualValue !== undefined;
40
+ return { result, description: `${currentPath} === undefined` };
41
+ }
42
+ if (!shouldBeArray) {
43
+ const result = value instanceof RegExp ? value.test(actualValue) : value === actualValue;
44
+ return { result, description: `${currentPath} === "${actualValue}"` };
45
+ }
46
+ }
47
+ if (shouldBeArray) {
48
+ if (Number.isInteger(arrayIndex)) {
49
+ return matchObject(actualValue[Number(arrayIndex)], rest.join('.'), value, currentPath);
50
+ }
51
+ const hasArrayMatch = actualValue.some((arrayValue) => matchObject(arrayValue, rest.join('.'), value, currentPath).result);
52
+ return { result: hasArrayMatch, description: `array match ${currentPath}` };
53
+ }
54
+ if (typeof actualValue !== 'object') {
55
+ return { result: false, description: `${currentPath} not an object` };
56
+ }
57
+ return matchObject(actualValue, rest.join('.'), value, currentPath);
58
+ };
59
+ const ___matchesValue = (matcher, value) => {
60
+ if (matcher === undefined) {
61
+ return true;
62
+ }
63
+ if (typeof matcher !== 'string' && !(matcher instanceof RegExp) && typeof matcher !== 'number') {
64
+ throw new Error('invalid matcher');
65
+ }
66
+ if (typeof matcher === 'string' && matcher !== value) {
67
+ return false;
68
+ }
69
+ if (matcher instanceof RegExp && (typeof value !== 'string' || !matcher.test(value))) {
70
+ return false;
71
+ }
72
+ if (typeof matcher === 'number' && (typeof value !== 'number' || matcher !== value)) {
73
+ return false;
74
+ }
75
+ return true;
76
+ };
77
+ if (!___matchesValue(localMatchBuilderVariables.filter, req.url)) {
78
+ return {
79
+ result: false,
80
+ description: `url ${req.url} doesn't match ${(_b = localMatchBuilderVariables.filter) === null || _b === void 0 ? void 0 : _b.toString()}`,
81
+ };
82
+ }
83
+ if (!___matchesValue(localMatchBuilderVariables.hostname, ___url.hostname)) {
84
+ return {
85
+ result: false,
86
+ description: `hostname ${___url.hostname} doesn't match ${(_c = localMatchBuilderVariables.hostname) === null || _c === void 0 ? void 0 : _c.toString()}`,
87
+ };
88
+ }
89
+ if (!___matchesValue(localMatchBuilderVariables.pathname, ___url.pathname)) {
90
+ return {
91
+ result: false,
92
+ description: `pathname ${___url.pathname} doesn't match ${(_d = localMatchBuilderVariables.pathname) === null || _d === void 0 ? void 0 : _d.toString()}`,
93
+ };
94
+ }
95
+ if (localMatchBuilderVariables.port) {
96
+ const port = ___url.port && ___url.port !== '' ? ___url.port : ___url.protocol === 'https:' ? '443' : '80';
97
+ if (!___matchesValue(localMatchBuilderVariables.port instanceof RegExp
98
+ ? localMatchBuilderVariables.port
99
+ : `${localMatchBuilderVariables.port}`, port)) {
100
+ return {
101
+ result: false,
102
+ description: `port ${port} doesn't match ${(_e = localMatchBuilderVariables.port) === null || _e === void 0 ? void 0 : _e.toString()}`,
103
+ };
104
+ }
105
+ }
106
+ if (localMatchBuilderVariables.searchParams) {
107
+ for (const searchParamMatcher of localMatchBuilderVariables.searchParams) {
108
+ if (typeof searchParamMatcher === 'string') {
109
+ const result = ___url.searchParams.has(searchParamMatcher);
110
+ if (!result) {
111
+ return { result, description: `searchParams.has("${searchParamMatcher}")` };
112
+ }
113
+ continue;
114
+ }
115
+ if (searchParamMatcher instanceof RegExp) {
116
+ const result = Array.from(___url.searchParams.keys()).some((key) => searchParamMatcher.test(key));
117
+ if (!result) {
118
+ return { result, description: `searchParams.keys() matches ${searchParamMatcher.toString()}` };
119
+ }
120
+ continue;
121
+ }
122
+ if (!___url.searchParams.has(searchParamMatcher.key)) {
123
+ return { result: false, description: `searchParams.has("${searchParamMatcher.key}")` };
124
+ }
125
+ if (searchParamMatcher.value) {
126
+ const value = ___url.searchParams.get(searchParamMatcher.key);
127
+ if (!___matchesValue(searchParamMatcher.value, value)) {
128
+ return {
129
+ result: false,
130
+ description: `searchParams.get("${searchParamMatcher.key}") = "${searchParamMatcher.value}"`,
131
+ };
132
+ }
133
+ }
134
+ }
135
+ }
136
+ if (localMatchBuilderVariables.headers) {
137
+ for (const headerMatcher of localMatchBuilderVariables.headers) {
138
+ if (typeof headerMatcher === 'string') {
139
+ const result = ___headers.has(headerMatcher);
140
+ if (result) {
141
+ continue;
142
+ }
143
+ return { result: false, description: `headers.has("${headerMatcher}")` };
144
+ }
145
+ if (headerMatcher instanceof RegExp) {
146
+ const result = ___headers.toHeaderPairs().some(([key]) => headerMatcher.test(key));
147
+ if (result) {
148
+ continue;
149
+ }
150
+ return { result: false, description: `headers.keys matches ${headerMatcher.toString()}` };
151
+ }
152
+ if (!___headers.has(headerMatcher.key)) {
153
+ return { result: false, description: `headers.has("${headerMatcher.key}")` };
154
+ }
155
+ if (headerMatcher.value) {
156
+ const value = ___headers.get(headerMatcher.key);
157
+ if (!___matchesValue(headerMatcher.value, value)) {
158
+ return {
159
+ result: false,
160
+ description: `headerMatcher.get("${headerMatcher.key}") = "${headerMatcher.value}"`,
161
+ };
162
+ }
163
+ }
164
+ }
165
+ }
166
+ if (localMatchBuilderVariables.bodyText === null && !!req.body) {
167
+ return { result: false, description: `empty body` };
168
+ }
169
+ if (localMatchBuilderVariables.bodyText) {
170
+ if (!req.body) {
171
+ return { result: false, description: `empty body` };
172
+ }
173
+ if (localMatchBuilderVariables.bodyText instanceof RegExp) {
174
+ if (!___matchesValue(localMatchBuilderVariables.bodyText, req.body)) {
175
+ return {
176
+ result: false,
177
+ description: `body text doesn't match ${localMatchBuilderVariables.bodyText.toString()}`,
178
+ };
179
+ }
180
+ }
181
+ else if (!req.body.includes(localMatchBuilderVariables.bodyText)) {
182
+ return {
183
+ result: false,
184
+ description: `body text doesn't include "${localMatchBuilderVariables.bodyText}"`,
185
+ };
186
+ }
187
+ }
188
+ if (localMatchBuilderVariables.bodyJson) {
189
+ let json;
190
+ try {
191
+ json = JSON.parse(req.body);
192
+ }
193
+ catch (kiss) {
194
+ return { result: false, description: `unparseable json` };
195
+ }
196
+ if (!json) {
197
+ return { result: false, description: `empty json object` };
198
+ }
199
+ for (const jsonMatcher of Array.isArray(localMatchBuilderVariables.bodyJson)
200
+ ? localMatchBuilderVariables.bodyJson
201
+ : [localMatchBuilderVariables.bodyJson]) {
202
+ const matchObjectResult = matchObject(json, jsonMatcher.key, jsonMatcher.value);
203
+ if (!matchObjectResult.result) {
204
+ return { result: false, description: `$.${jsonMatcher.key} != "${jsonMatcher.value}"` };
205
+ }
206
+ }
207
+ }
208
+ if (localMatchBuilderVariables.bodyGql) {
209
+ if (!req.gqlBody) {
210
+ return { result: false, description: `not a gql body` };
211
+ }
212
+ if (!___matchesValue(localMatchBuilderVariables.bodyGql.methodName, req.gqlBody.methodName)) {
213
+ return {
214
+ result: false,
215
+ description: `methodName "${localMatchBuilderVariables.bodyGql.methodName}" !== "${req.gqlBody.methodName}"`,
216
+ };
217
+ }
218
+ if (!___matchesValue(localMatchBuilderVariables.bodyGql.operationName, req.gqlBody.operationName)) {
219
+ return {
220
+ result: false,
221
+ description: `operationName "${localMatchBuilderVariables.bodyGql.operationName}" !== "${req.gqlBody.operationName}"`,
222
+ };
223
+ }
224
+ if (!___matchesValue(localMatchBuilderVariables.bodyGql.query, req.gqlBody.query)) {
225
+ return {
226
+ result: false,
227
+ description: `query "${localMatchBuilderVariables.bodyGql.query}" !== "${req.gqlBody.query}"`,
228
+ };
229
+ }
230
+ if (!___matchesValue(localMatchBuilderVariables.bodyGql.type, req.gqlBody.type)) {
231
+ return {
232
+ result: false,
233
+ description: `type "${localMatchBuilderVariables.bodyGql.type}" !== "${req.gqlBody.type}"`,
234
+ };
235
+ }
236
+ if (localMatchBuilderVariables.bodyGql.variables) {
237
+ for (const jsonMatcher of Array.isArray(localMatchBuilderVariables.bodyGql.variables)
238
+ ? localMatchBuilderVariables.bodyGql.variables
239
+ : [localMatchBuilderVariables.bodyGql.variables]) {
240
+ const matchObjectResult = matchObject(req.gqlBody.variables, jsonMatcher.key, jsonMatcher.value);
241
+ if (!matchObjectResult.result) {
242
+ return {
243
+ result: false,
244
+ description: `GQL variable ${jsonMatcher.key} != "${jsonMatcher.value}". Detail: ${matchObjectResult.description}`,
245
+ };
246
+ }
247
+ }
248
+ }
249
+ }
250
+ return { result: true, description: 'match' };
251
+ }
7
252
  class RuleBuilderBaseBase {
8
253
  constructor(rule, _matchBuilderVariables) {
9
254
  this._matchBuilderVariables = _matchBuilderVariables || {};
@@ -15,252 +260,7 @@ class RuleBuilderBaseBase {
15
260
  mockResponse: { status: 200 },
16
261
  },
17
262
  matches: {
18
- localFn: (req) => {
19
- var _a, _b, _c, _d;
20
- const ___url = new URL(req.url);
21
- const ___headers = req.rawHeaders;
22
- const arrayIndexerRegex = /\[(?<arrayIndex>[0-9]*)\]/i;
23
- const matchObject = (obj, path, value, parentPath) => {
24
- var _a, _b, _c, _d;
25
- if (!obj) {
26
- return { result: false, description: `${parentPath} is falsey` };
27
- }
28
- const [rawKey, ...rest] = path.split('.');
29
- const key = (rawKey !== null && rawKey !== void 0 ? rawKey : '').replace(arrayIndexerRegex, '');
30
- const shouldBeArray = rawKey ? arrayIndexerRegex.test(rawKey) : false;
31
- const arrayIndex = rawKey && (((_b = (_a = arrayIndexerRegex.exec(rawKey)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.arrayIndex) || '').length > 0
32
- ? Number((_d = (_c = arrayIndexerRegex.exec(rawKey)) === null || _c === void 0 ? void 0 : _c.groups) === null || _d === void 0 ? void 0 : _d.arrayIndex)
33
- : Number.NaN;
34
- const actualValue = key ? obj[key] : obj;
35
- const currentPath = `${parentPath ? `${parentPath}.` : ''}${rawKey}`;
36
- if (value === undefined && actualValue === undefined) {
37
- return { result: false, description: `${currentPath}=undefined` };
38
- }
39
- if (rest.length === 0) {
40
- if (shouldBeArray &&
41
- (!Array.isArray(actualValue) ||
42
- (Number.isInteger(arrayIndex) && actualValue.length <= Number(arrayIndex)))) {
43
- return { result: false, description: `${currentPath} empty array` };
44
- }
45
- if (value === undefined) {
46
- const result = shouldBeArray
47
- ? !Number.isInteger(arrayIndex) || actualValue.length >= Number(arrayIndex)
48
- : actualValue !== undefined;
49
- return { result, description: `${currentPath} === undefined` };
50
- }
51
- if (!shouldBeArray) {
52
- const result = value instanceof RegExp ? value.test(actualValue) : value === actualValue;
53
- return { result, description: `${currentPath} === "${actualValue}"` };
54
- }
55
- }
56
- if (shouldBeArray) {
57
- if (Number.isInteger(arrayIndex)) {
58
- return matchObject(actualValue[Number(arrayIndex)], rest.join('.'), value, currentPath);
59
- }
60
- const hasArrayMatch = actualValue.some((arrayValue) => matchObject(arrayValue, rest.join('.'), value, currentPath).result);
61
- return { result: hasArrayMatch, description: `array match ${currentPath}` };
62
- }
63
- if (typeof actualValue !== 'object') {
64
- return { result: false, description: `${currentPath} not an object` };
65
- }
66
- return matchObject(actualValue, rest.join('.'), value, currentPath);
67
- };
68
- const ___matchesValue = (matcher, value) => {
69
- if (matcher === undefined) {
70
- return true;
71
- }
72
- if (typeof matcher !== 'string' && !(matcher instanceof RegExp) && typeof matcher !== 'number') {
73
- throw new Error('invalid matcher');
74
- }
75
- if (typeof matcher === 'string' && matcher !== value) {
76
- return false;
77
- }
78
- if (matcher instanceof RegExp && (typeof value !== 'string' || !matcher.test(value))) {
79
- return false;
80
- }
81
- if (typeof matcher === 'number' && (typeof value !== 'number' || matcher !== value)) {
82
- return false;
83
- }
84
- return true;
85
- };
86
- if (!___matchesValue(matchBuilderVariables.filter, req.url)) {
87
- return {
88
- result: false,
89
- description: `url ${req.url} doesn't match ${(_a = matchBuilderVariables.filter) === null || _a === void 0 ? void 0 : _a.toString()}`,
90
- };
91
- }
92
- if (!___matchesValue(matchBuilderVariables.hostname, ___url.hostname)) {
93
- return {
94
- result: false,
95
- description: `hostname ${___url.hostname} doesn't match ${(_b = matchBuilderVariables.hostname) === null || _b === void 0 ? void 0 : _b.toString()}`,
96
- };
97
- }
98
- if (!___matchesValue(matchBuilderVariables.pathname, ___url.pathname)) {
99
- return {
100
- result: false,
101
- description: `pathname ${___url.pathname} doesn't match ${(_c = matchBuilderVariables.pathname) === null || _c === void 0 ? void 0 : _c.toString()}`,
102
- };
103
- }
104
- if (matchBuilderVariables.port) {
105
- const port = ___url.port && ___url.port !== '' ? ___url.port : ___url.protocol === 'https:' ? '443' : '80';
106
- if (!___matchesValue(matchBuilderVariables.port instanceof RegExp
107
- ? matchBuilderVariables.port
108
- : `${matchBuilderVariables.port}`, port)) {
109
- return {
110
- result: false,
111
- description: `port ${port} doesn't match ${(_d = matchBuilderVariables.port) === null || _d === void 0 ? void 0 : _d.toString()}`,
112
- };
113
- }
114
- }
115
- if (matchBuilderVariables.searchParams) {
116
- for (const searchParamMatcher of matchBuilderVariables.searchParams) {
117
- if (typeof searchParamMatcher === 'string') {
118
- const result = ___url.searchParams.has(searchParamMatcher);
119
- return { result, description: `searchParams.has("${searchParamMatcher}")` };
120
- }
121
- if (searchParamMatcher instanceof RegExp) {
122
- const result = Array.from(___url.searchParams.keys()).some((key) => searchParamMatcher.test(key));
123
- return { result, description: `searchParams.keys() matches ${searchParamMatcher.toString()}` };
124
- }
125
- if (!___url.searchParams.has(searchParamMatcher.key)) {
126
- return { result: false, description: `searchParams.has("${searchParamMatcher.key}")` };
127
- }
128
- if (searchParamMatcher.value) {
129
- const value = ___url.searchParams.get(searchParamMatcher.key);
130
- if (value === null) {
131
- return {
132
- result: false,
133
- description: `searchParams.get("${searchParamMatcher.key}") === null`,
134
- };
135
- }
136
- if (!___matchesValue(searchParamMatcher.value, value)) {
137
- return {
138
- result: false,
139
- description: `searchParams.get("${searchParamMatcher.key}") = "${searchParamMatcher.value}"`,
140
- };
141
- }
142
- }
143
- }
144
- }
145
- if (matchBuilderVariables.headers) {
146
- for (const headerMatcher of matchBuilderVariables.headers) {
147
- if (typeof headerMatcher === 'string') {
148
- const result = ___headers.has(headerMatcher);
149
- if (result) {
150
- continue;
151
- }
152
- return { result: false, description: `headers.has("${headerMatcher}")` };
153
- }
154
- if (headerMatcher instanceof RegExp) {
155
- const result = ___headers.toHeaderPairs().some(([key]) => headerMatcher.test(key));
156
- if (result) {
157
- continue;
158
- }
159
- return { result: false, description: `headers.keys matches ${headerMatcher.toString()}` };
160
- }
161
- if (!___headers.has(headerMatcher.key)) {
162
- return { result: false, description: `headers.has("${headerMatcher.key}")` };
163
- }
164
- if (headerMatcher.value) {
165
- const value = ___headers.get(headerMatcher.key);
166
- if (value === null) {
167
- return { result: false, description: `headers.get("${headerMatcher.key}") === null` };
168
- }
169
- if (!___matchesValue(headerMatcher.value, value)) {
170
- return {
171
- result: false,
172
- description: `headerMatcher.get("${headerMatcher.key}") = "${headerMatcher.value}"`,
173
- };
174
- }
175
- }
176
- }
177
- }
178
- if (matchBuilderVariables.bodyText === null && !!req.body) {
179
- return { result: false, description: `empty body` };
180
- }
181
- if (matchBuilderVariables.bodyText) {
182
- if (!req.body) {
183
- return { result: false, description: `empty body` };
184
- }
185
- if (matchBuilderVariables.bodyText instanceof RegExp) {
186
- if (!___matchesValue(matchBuilderVariables.bodyText, req.body)) {
187
- return {
188
- result: false,
189
- description: `body text doesn't match ${matchBuilderVariables.bodyText.toString()}`,
190
- };
191
- }
192
- }
193
- else if (!req.body.includes(matchBuilderVariables.bodyText)) {
194
- return {
195
- result: false,
196
- description: `body text doesn't include "${matchBuilderVariables.bodyText}"`,
197
- };
198
- }
199
- }
200
- if (matchBuilderVariables.bodyJson) {
201
- let json;
202
- try {
203
- json = JSON.parse(req.body);
204
- }
205
- catch (kiss) {
206
- return { result: false, description: `unparseable json` };
207
- }
208
- if (!json) {
209
- return { result: false, description: `empty json object` };
210
- }
211
- for (const jsonMatcher of Array.isArray(matchBuilderVariables.bodyJson)
212
- ? matchBuilderVariables.bodyJson
213
- : [matchBuilderVariables.bodyJson]) {
214
- const matchObjectResult = matchObject(json, jsonMatcher.key, jsonMatcher.value);
215
- if (!matchObjectResult.result) {
216
- return { result: false, description: `$.${jsonMatcher.key} != "${jsonMatcher.value}"` };
217
- }
218
- }
219
- }
220
- if (matchBuilderVariables.bodyGql) {
221
- if (!req.gqlBody) {
222
- return { result: false, description: `not a gql body` };
223
- }
224
- if (!___matchesValue(matchBuilderVariables.bodyGql.methodName, req.gqlBody.methodName)) {
225
- return {
226
- result: false,
227
- description: `methodName "${matchBuilderVariables.bodyGql.methodName}" !== "${req.gqlBody.methodName}"`,
228
- };
229
- }
230
- if (!___matchesValue(matchBuilderVariables.bodyGql.operationName, req.gqlBody.operationName)) {
231
- return {
232
- result: false,
233
- description: `operationName "${matchBuilderVariables.bodyGql.operationName}" !== "${req.gqlBody.operationName}"`,
234
- };
235
- }
236
- if (!___matchesValue(matchBuilderVariables.bodyGql.query, req.gqlBody.query)) {
237
- return {
238
- result: false,
239
- description: `query "${matchBuilderVariables.bodyGql.query}" !== "${req.gqlBody.query}"`,
240
- };
241
- }
242
- if (!___matchesValue(matchBuilderVariables.bodyGql.type, req.gqlBody.type)) {
243
- return {
244
- result: false,
245
- description: `type "${matchBuilderVariables.bodyGql.type}" !== "${req.gqlBody.type}"`,
246
- };
247
- }
248
- if (matchBuilderVariables.bodyGql.variables) {
249
- for (const jsonMatcher of Array.isArray(matchBuilderVariables.bodyGql.variables)
250
- ? matchBuilderVariables.bodyGql.variables
251
- : [matchBuilderVariables.bodyGql.variables]) {
252
- const matchObjectResult = matchObject(req.gqlBody.variables, jsonMatcher.key, jsonMatcher.value);
253
- if (!matchObjectResult.result) {
254
- return {
255
- result: false,
256
- description: `GQL variable ${jsonMatcher.key} != "${jsonMatcher.value}". Detail: ${matchObjectResult.description}`,
257
- };
258
- }
259
- }
260
- }
261
- }
262
- return { result: true, description: 'match' };
263
- },
263
+ localFn: matchFunction,
264
264
  localVariables: { matchBuilderVariables: this._matchBuilderVariables },
265
265
  },
266
266
  };
@@ -342,7 +342,23 @@ class RuleBuilder extends RuleBuilderBase {
342
342
  return new RuleBuilderInitialized(this.rule, this._matchBuilderVariables);
343
343
  }
344
344
  }
345
- class RuleBuilderInitialized extends RuleBuilderBase {
345
+ class RuleBuilderRequestInitialized extends RuleBuilderBase {
346
+ modifyResponse(modifyFunction, localVariables) {
347
+ if (!this.rule.actions) {
348
+ throw new Error('rule.actions not defined - builder implementation error');
349
+ }
350
+ if (typeof modifyFunction === 'function') {
351
+ this.rule.actions.modifyResponse = { localFn: modifyFunction, localVariables: localVariables !== null && localVariables !== void 0 ? localVariables : {} };
352
+ return this.rule;
353
+ }
354
+ if (localVariables) {
355
+ throw new Error('invalid call - localVariables cannot be used together with Response or RemotableFunction');
356
+ }
357
+ this.rule.actions.modifyResponse = modifyFunction;
358
+ return this.rule;
359
+ }
360
+ }
361
+ class RuleBuilderInitialized extends RuleBuilderRequestInitialized {
346
362
  withHostname(hostname) {
347
363
  if (this._matchBuilderVariables.hostname) {
348
364
  throw new Error('hostname already set');
@@ -502,32 +518,11 @@ class RuleBuilderInitialized extends RuleBuilderBase {
502
518
  this.rule.actions = { modifyRequest: modifyFunction };
503
519
  return new RuleBuilderRequestInitialized(this.rule, this._matchBuilderVariables);
504
520
  }
505
- modifyResponse(modifyFunction, localVariables) {
506
- if (typeof modifyFunction === 'function') {
507
- this.rule.actions = { modifyResponse: { localFn: modifyFunction, localVariables: localVariables !== null && localVariables !== void 0 ? localVariables : {} } };
508
- return this.rule;
509
- }
510
- if (localVariables) {
511
- throw new Error('invalid call - localVariables cannot be used together with Response or RemotableFunction');
512
- }
513
- this.rule.actions = { modifyResponse: modifyFunction };
514
- return this.rule;
515
- }
516
- }
517
- class RuleBuilderRequestInitialized extends RuleBuilderBase {
518
521
  modifyResponse(modifyFunction, localVariables) {
519
522
  if (!this.rule.actions) {
520
- throw new Error('rule.actions not defined - builder implementation error');
521
- }
522
- if (typeof modifyFunction === 'function') {
523
- this.rule.actions = { modifyResponse: { localFn: modifyFunction, localVariables: localVariables !== null && localVariables !== void 0 ? localVariables : {} } };
524
- return this.rule;
523
+ this.rule.actions = { proxyPass: true };
525
524
  }
526
- if (localVariables) {
527
- throw new Error('invalid call - localVariables cannot be used together with Response or RemotableFunction');
528
- }
529
- this.rule.actions.modifyResponse = modifyFunction;
530
- return this.rule;
525
+ return super.modifyResponse(modifyFunction, localVariables);
531
526
  }
532
527
  }
533
528
  const ruleBuilder = () => new RuleBuilder();