@stuntman/client 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +8 -4
- package/dist/apiClient.d.ts +0 -22
- package/dist/apiClient.js +0 -163
- package/dist/clientError.d.ts +0 -18
- package/dist/clientError.js +0 -22
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -7
- package/dist/ruleBuilder.d.ts +0 -77
- package/dist/ruleBuilder.js +0 -444
package/README.md
CHANGED
|
@@ -30,4 +30,4 @@ const rule = ruleBuilder()
|
|
|
30
30
|
client.addRule(rule).then((x) => console.log(x));
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Check [example app](https://github.com/andrzej-woof/stuntman/tree/master/
|
|
33
|
+
Check [example app](https://github.com/andrzej-woof/stuntman/tree/master/apps/example#readme) for more samples
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stuntman/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Stuntman - HTTP proxy / mock API client",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -37,8 +37,12 @@
|
|
|
37
37
|
"uuid": "9.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
+
"@jest/globals": "29.4.3",
|
|
40
41
|
"@types/serialize-javascript": "5.0.2",
|
|
41
|
-
"@types/uuid": "9.0.0"
|
|
42
|
+
"@types/uuid": "9.0.0",
|
|
43
|
+
"jest": "29.4.3",
|
|
44
|
+
"ts-jest": "29.0.5",
|
|
45
|
+
"typescript": "4.9.5"
|
|
42
46
|
},
|
|
43
47
|
"files": [
|
|
44
48
|
"dist/",
|
|
@@ -47,10 +51,10 @@
|
|
|
47
51
|
"CHANGELOG.md"
|
|
48
52
|
],
|
|
49
53
|
"scripts": {
|
|
50
|
-
"test": "
|
|
54
|
+
"test": "SUPPRESS_NO_CONFIG_WARNING=1 jest",
|
|
51
55
|
"clean": "rm -fr dist",
|
|
52
56
|
"build": "tsc",
|
|
53
57
|
"lint": "prettier --check . && eslint . --ext ts",
|
|
54
|
-
"lint:fix": "prettier --write ./src && eslint ./src --ext ts --fix"
|
|
58
|
+
"lint:fix": "prettier --write ./{src,test} && eslint ./{src,test} --ext ts --fix"
|
|
55
59
|
}
|
|
56
60
|
}
|
package/dist/apiClient.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type * as Stuntman from '@stuntman/shared';
|
|
2
|
-
type ClientOptions = {
|
|
3
|
-
protocol?: 'http' | 'https';
|
|
4
|
-
host?: string;
|
|
5
|
-
port?: number;
|
|
6
|
-
timeout?: number;
|
|
7
|
-
};
|
|
8
|
-
export declare class Client {
|
|
9
|
-
private options;
|
|
10
|
-
private get baseUrl();
|
|
11
|
-
constructor(options?: ClientOptions);
|
|
12
|
-
private fetch;
|
|
13
|
-
getRules(): Promise<Stuntman.LiveRule[]>;
|
|
14
|
-
getRule(id: string): Promise<Stuntman.LiveRule>;
|
|
15
|
-
disableRule(id: string): Promise<void>;
|
|
16
|
-
enableRule(id: string): Promise<void>;
|
|
17
|
-
removeRule(id: string): Promise<void>;
|
|
18
|
-
addRule(rule: Stuntman.SerializableRule): Promise<Stuntman.Rule>;
|
|
19
|
-
getTraffic(rule: Stuntman.Rule): Promise<Record<string, Stuntman.LogEntry>>;
|
|
20
|
-
getTraffic(ruleIdOrLabel: string): Promise<Record<string, Stuntman.LogEntry>>;
|
|
21
|
-
}
|
|
22
|
-
export {};
|
package/dist/apiClient.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Client = void 0;
|
|
7
|
-
const serialize_javascript_1 = __importDefault(require("serialize-javascript"));
|
|
8
|
-
const clientError_1 = require("./clientError");
|
|
9
|
-
const shared_1 = require("@stuntman/shared");
|
|
10
|
-
const SERIALIZE_JAVASCRIPT_OPTIONS = {
|
|
11
|
-
unsafe: true,
|
|
12
|
-
ignoreFunction: true,
|
|
13
|
-
};
|
|
14
|
-
const getFunctionParams = (func) => {
|
|
15
|
-
const funstr = func.toString();
|
|
16
|
-
const params = funstr.slice(funstr.indexOf('(') + 1, funstr.indexOf(')')).match(/([^\s,]+)/g) || new Array();
|
|
17
|
-
if (params.includes('=')) {
|
|
18
|
-
throw new Error('default argument values are not supported');
|
|
19
|
-
}
|
|
20
|
-
return params;
|
|
21
|
-
};
|
|
22
|
-
const serializeApiFunction = (fn, variables) => {
|
|
23
|
-
const variableInitializer = [];
|
|
24
|
-
const functionParams = getFunctionParams(fn);
|
|
25
|
-
if (variables) {
|
|
26
|
-
for (const varName of Object.keys(variables)) {
|
|
27
|
-
let varValue = variables[varName];
|
|
28
|
-
if (varValue === undefined || varValue === null || typeof varValue === 'number' || typeof varValue === 'boolean') {
|
|
29
|
-
varValue = `${varValue}`;
|
|
30
|
-
}
|
|
31
|
-
else if (typeof varValue === 'string') {
|
|
32
|
-
varValue = `${(0, serialize_javascript_1.default)(variables[varName], SERIALIZE_JAVASCRIPT_OPTIONS)}`;
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
varValue = `eval('(${(0, serialize_javascript_1.default)(variables[varName], SERIALIZE_JAVASCRIPT_OPTIONS).replace(/'/g, "\\'")})')`;
|
|
36
|
-
}
|
|
37
|
-
variableInitializer.push(`const ${varName} = ${varValue};`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
const functionString = fn.toString();
|
|
41
|
-
const serializedHeader = `return ((${functionParams.map((_param, index) => `____arg${index}`).join(',')}) => {`;
|
|
42
|
-
const serializedParams = `${functionParams
|
|
43
|
-
.map((_param, index) => `const ${functionParams[index]} = ____arg${index};`)
|
|
44
|
-
.join('\n')}`;
|
|
45
|
-
const serializedVariables = `${variableInitializer.join('\n')}`;
|
|
46
|
-
// prettier-ignore
|
|
47
|
-
const serializedFunction = `return (${functionString.substring(0, functionString.indexOf('('))}()${functionString.substring(functionString.indexOf(')') + 1)})(); })(${functionParams.map((_param, index) => `____arg${index}`).join(',')})`;
|
|
48
|
-
if (!serializedParams && !serializedVariables) {
|
|
49
|
-
return `${serializedHeader}${serializedFunction}`;
|
|
50
|
-
}
|
|
51
|
-
return [serializedHeader, serializedParams, serializedVariables, serializedFunction].filter((x) => !!x).join('\n');
|
|
52
|
-
};
|
|
53
|
-
const keysOf = (obj) => {
|
|
54
|
-
return Array.from(Object.keys(obj));
|
|
55
|
-
};
|
|
56
|
-
const serializeRemotableFunctions = (obj) => {
|
|
57
|
-
const objectKeys = keysOf(obj);
|
|
58
|
-
if (!objectKeys || objectKeys.length === 0) {
|
|
59
|
-
return obj;
|
|
60
|
-
}
|
|
61
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
const output = {};
|
|
64
|
-
for (const key of objectKeys) {
|
|
65
|
-
if (typeof obj[key] === 'object') {
|
|
66
|
-
if ('localFn' in obj[key]) {
|
|
67
|
-
const remotableFunction = obj[key];
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
69
|
-
// @ts-ignore
|
|
70
|
-
output[key] = {
|
|
71
|
-
remoteFn: serializeApiFunction(remotableFunction.localFn, remotableFunction.localVariables),
|
|
72
|
-
localFn: remotableFunction.localFn.toString(),
|
|
73
|
-
localVariables: (0, serialize_javascript_1.default)(remotableFunction.localVariables, SERIALIZE_JAVASCRIPT_OPTIONS),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
78
|
-
// @ts-ignore
|
|
79
|
-
output[key] = serializeRemotableFunctions(obj[key]);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
84
|
-
// @ts-ignore
|
|
85
|
-
output[key] = obj[key];
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return output;
|
|
89
|
-
};
|
|
90
|
-
class Client {
|
|
91
|
-
get baseUrl() {
|
|
92
|
-
return `${this.options.protocol}://${this.options.host}${this.options.port ? `:${this.options.port}` : ''}`;
|
|
93
|
-
}
|
|
94
|
-
constructor(options) {
|
|
95
|
-
this.options = {
|
|
96
|
-
...options,
|
|
97
|
-
timeout: (options === null || options === void 0 ? void 0 : options.timeout) || 60000,
|
|
98
|
-
host: (options === null || options === void 0 ? void 0 : options.host) || 'localhost',
|
|
99
|
-
protocol: (options === null || options === void 0 ? void 0 : options.protocol) || 'http',
|
|
100
|
-
port: (options === null || options === void 0 ? void 0 : options.port) || (options === null || options === void 0 ? void 0 : options.protocol) ? (options.protocol === 'https' ? 443 : 80) : shared_1.DEFAULT_API_PORT,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
async fetch(url, init) {
|
|
104
|
-
var _a;
|
|
105
|
-
const controller = new AbortController();
|
|
106
|
-
const timeout = setTimeout(() => {
|
|
107
|
-
controller.abort();
|
|
108
|
-
}, this.options.timeout);
|
|
109
|
-
try {
|
|
110
|
-
const response = await fetch(url, { ...init, signal: (_a = init === null || init === void 0 ? void 0 : init.signal) !== null && _a !== void 0 ? _a : controller.signal });
|
|
111
|
-
if (!response.ok) {
|
|
112
|
-
const text = await response.text();
|
|
113
|
-
let json;
|
|
114
|
-
try {
|
|
115
|
-
json = JSON.parse(text);
|
|
116
|
-
}
|
|
117
|
-
catch (kiss) {
|
|
118
|
-
// and swallow
|
|
119
|
-
}
|
|
120
|
-
if ('error' in json) {
|
|
121
|
-
throw new clientError_1.ClientError(json.error);
|
|
122
|
-
}
|
|
123
|
-
throw new Error(`Unexpected errror: ${text}`);
|
|
124
|
-
}
|
|
125
|
-
return response;
|
|
126
|
-
}
|
|
127
|
-
finally {
|
|
128
|
-
clearTimeout(timeout);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
async getRules() {
|
|
132
|
-
const response = await this.fetch(`${this.baseUrl}/rules`);
|
|
133
|
-
return response.json();
|
|
134
|
-
}
|
|
135
|
-
async getRule(id) {
|
|
136
|
-
const response = await this.fetch(`${this.baseUrl}/rule/${encodeURIComponent(id)}`);
|
|
137
|
-
return response.json();
|
|
138
|
-
}
|
|
139
|
-
async disableRule(id) {
|
|
140
|
-
await this.fetch(`${this.baseUrl}/rule/${encodeURIComponent(id)}/disable`);
|
|
141
|
-
}
|
|
142
|
-
async enableRule(id) {
|
|
143
|
-
await this.fetch(`${this.baseUrl}/rule/${encodeURIComponent(id)}/enable`);
|
|
144
|
-
}
|
|
145
|
-
async removeRule(id) {
|
|
146
|
-
await this.fetch(`${this.baseUrl}/rule/${encodeURIComponent(id)}/remove`);
|
|
147
|
-
}
|
|
148
|
-
async addRule(rule) {
|
|
149
|
-
const serializedRule = serializeRemotableFunctions(rule);
|
|
150
|
-
const response = await this.fetch(`${this.baseUrl}/rule`, {
|
|
151
|
-
method: 'POST',
|
|
152
|
-
body: JSON.stringify(serializedRule),
|
|
153
|
-
headers: { 'content-type': 'application/json' },
|
|
154
|
-
});
|
|
155
|
-
return response.json();
|
|
156
|
-
}
|
|
157
|
-
async getTraffic(ruleOrIdOrLabel) {
|
|
158
|
-
const ruleId = typeof ruleOrIdOrLabel === 'object' ? ruleOrIdOrLabel.id : ruleOrIdOrLabel;
|
|
159
|
-
const response = await this.fetch(`${this.baseUrl}/traffic${ruleId ? `/${encodeURIComponent(ruleId)}` : ''}`);
|
|
160
|
-
return response.json();
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
exports.Client = Client;
|
package/dist/clientError.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { AppError } from '@stuntman/shared';
|
|
2
|
-
import type * as Stuntman from '@stuntman/shared';
|
|
3
|
-
export declare enum HttpCode {
|
|
4
|
-
OK = 200,
|
|
5
|
-
NO_CONTENT = 204,
|
|
6
|
-
BAD_REQUEST = 400,
|
|
7
|
-
UNAUTHORIZED = 401,
|
|
8
|
-
NOT_FOUND = 404,
|
|
9
|
-
CONFLICT = 409,
|
|
10
|
-
UNPROCESSABLE_ENTITY = 422,
|
|
11
|
-
INTERNAL_SERVER_ERROR = 500
|
|
12
|
-
}
|
|
13
|
-
export declare class ClientError extends AppError {
|
|
14
|
-
readonly originalStack?: string;
|
|
15
|
-
constructor(args: Stuntman.AppError & {
|
|
16
|
-
stack?: string;
|
|
17
|
-
});
|
|
18
|
-
}
|
package/dist/clientError.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ClientError = exports.HttpCode = void 0;
|
|
4
|
-
const shared_1 = require("@stuntman/shared");
|
|
5
|
-
var HttpCode;
|
|
6
|
-
(function (HttpCode) {
|
|
7
|
-
HttpCode[HttpCode["OK"] = 200] = "OK";
|
|
8
|
-
HttpCode[HttpCode["NO_CONTENT"] = 204] = "NO_CONTENT";
|
|
9
|
-
HttpCode[HttpCode["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
10
|
-
HttpCode[HttpCode["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
|
11
|
-
HttpCode[HttpCode["NOT_FOUND"] = 404] = "NOT_FOUND";
|
|
12
|
-
HttpCode[HttpCode["CONFLICT"] = 409] = "CONFLICT";
|
|
13
|
-
HttpCode[HttpCode["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
|
|
14
|
-
HttpCode[HttpCode["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
15
|
-
})(HttpCode = exports.HttpCode || (exports.HttpCode = {}));
|
|
16
|
-
class ClientError extends shared_1.AppError {
|
|
17
|
-
constructor(args) {
|
|
18
|
-
super(args);
|
|
19
|
-
this.originalStack = args.stack;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
exports.ClientError = ClientError;
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ruleBuilder = exports.StuntmanClient = void 0;
|
|
4
|
-
var apiClient_1 = require("./apiClient");
|
|
5
|
-
Object.defineProperty(exports, "StuntmanClient", { enumerable: true, get: function () { return apiClient_1.Client; } });
|
|
6
|
-
var ruleBuilder_1 = require("./ruleBuilder");
|
|
7
|
-
Object.defineProperty(exports, "ruleBuilder", { enumerable: true, get: function () { return ruleBuilder_1.ruleBuilder; } });
|
package/dist/ruleBuilder.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import type * as Stuntman from '@stuntman/shared';
|
|
2
|
-
type KeyValueMatcher = string | RegExp | {
|
|
3
|
-
key: string;
|
|
4
|
-
value?: string | RegExp;
|
|
5
|
-
};
|
|
6
|
-
type ObjectValueMatcher = string | RegExp | number | boolean | null;
|
|
7
|
-
type ObjectKeyValueMatcher = {
|
|
8
|
-
key: string;
|
|
9
|
-
value?: ObjectValueMatcher;
|
|
10
|
-
};
|
|
11
|
-
type GQLRequestMatcher = {
|
|
12
|
-
operationName?: string | RegExp;
|
|
13
|
-
variables?: ObjectKeyValueMatcher[];
|
|
14
|
-
query?: string | RegExp;
|
|
15
|
-
type?: 'query' | 'mutation';
|
|
16
|
-
methodName?: string | RegExp;
|
|
17
|
-
};
|
|
18
|
-
type MatchBuilderVariables = {
|
|
19
|
-
filter?: string | RegExp;
|
|
20
|
-
hostname?: string | RegExp;
|
|
21
|
-
pathname?: string | RegExp;
|
|
22
|
-
port?: number | string | RegExp;
|
|
23
|
-
searchParams?: KeyValueMatcher[];
|
|
24
|
-
headers?: KeyValueMatcher[];
|
|
25
|
-
bodyText?: string | RegExp | null;
|
|
26
|
-
bodyJson?: ObjectKeyValueMatcher[];
|
|
27
|
-
bodyGql?: GQLRequestMatcher;
|
|
28
|
-
};
|
|
29
|
-
declare class RuleBuilderBaseBase {
|
|
30
|
-
protected rule: Stuntman.SerializableRule;
|
|
31
|
-
protected _matchBuilderVariables: MatchBuilderVariables;
|
|
32
|
-
constructor(rule?: Stuntman.SerializableRule, _matchBuilderVariables?: MatchBuilderVariables);
|
|
33
|
-
}
|
|
34
|
-
declare class RuleBuilderBase extends RuleBuilderBaseBase {
|
|
35
|
-
limitedUse(hitCount: number): this;
|
|
36
|
-
singleUse(): this;
|
|
37
|
-
storeTraffic(): this;
|
|
38
|
-
disabled(): void;
|
|
39
|
-
}
|
|
40
|
-
declare class RuleBuilder extends RuleBuilderBase {
|
|
41
|
-
raisePriority(by?: number): this;
|
|
42
|
-
decreasePriority(by?: number): this;
|
|
43
|
-
customTtl(ttlSeconds: number): this;
|
|
44
|
-
customId(id: string): this;
|
|
45
|
-
onRequestTo(filter: string | RegExp): RuleBuilderInitialized;
|
|
46
|
-
onRequestToHostname(hostname: string | RegExp): RuleBuilderInitialized;
|
|
47
|
-
onRequestToPathname(pathname: string | RegExp): RuleBuilderInitialized;
|
|
48
|
-
onAnyRequest(): RuleBuilderInitialized;
|
|
49
|
-
}
|
|
50
|
-
declare class RuleBuilderInitialized extends RuleBuilderBase {
|
|
51
|
-
withHostname(hostname: string | RegExp): this;
|
|
52
|
-
withPathname(pathname: string | RegExp): this;
|
|
53
|
-
withPort(port: number | string | RegExp): this;
|
|
54
|
-
withSearchParam(key: string | RegExp): RuleBuilderInitialized;
|
|
55
|
-
withSearchParam(key: string, value?: string | RegExp): RuleBuilderInitialized;
|
|
56
|
-
withSearchParams(params: KeyValueMatcher[]): RuleBuilderInitialized;
|
|
57
|
-
withHeader(key: string | RegExp): RuleBuilderInitialized;
|
|
58
|
-
withHeader(key: string, value?: string | RegExp): RuleBuilderInitialized;
|
|
59
|
-
withHeaders(headers: KeyValueMatcher[]): RuleBuilderInitialized;
|
|
60
|
-
withBodyText(includes: string): RuleBuilderInitialized;
|
|
61
|
-
withBodyText(matches: RegExp): RuleBuilderInitialized;
|
|
62
|
-
withoutBody(): RuleBuilderInitialized;
|
|
63
|
-
withBodyJson(hasKey: string): RuleBuilderInitialized;
|
|
64
|
-
withBodyJson(hasKey: string, withValue: ObjectValueMatcher): RuleBuilderInitialized;
|
|
65
|
-
withBodyJson(matches: ObjectKeyValueMatcher): RuleBuilderInitialized;
|
|
66
|
-
withBodyGql(gqlMatcher: GQLRequestMatcher): RuleBuilderInitialized;
|
|
67
|
-
proxyPass(): Stuntman.SerializableRule;
|
|
68
|
-
mockResponse(staticResponse: Stuntman.Response): Stuntman.SerializableRule;
|
|
69
|
-
mockResponse(generationFunction: Stuntman.RemotableFunction<Stuntman.ResponseGenerationFn>): Stuntman.SerializableRule;
|
|
70
|
-
modifyRequest(modifyFunction: Stuntman.RemotableFunction<Stuntman.RequestManipulationFn>): RuleBuilderRequestInitialized;
|
|
71
|
-
modifyResponse(modifyFunction: Stuntman.RemotableFunction<Stuntman.ResponseManipulationFn>): Stuntman.SerializableRule;
|
|
72
|
-
}
|
|
73
|
-
declare class RuleBuilderRequestInitialized extends RuleBuilderBase {
|
|
74
|
-
modifyResponse(modifyFunction: Stuntman.RemotableFunction<Stuntman.ResponseManipulationFn>): Stuntman.SerializableRule;
|
|
75
|
-
}
|
|
76
|
-
export declare const ruleBuilder: () => RuleBuilder;
|
|
77
|
-
export {};
|
package/dist/ruleBuilder.js
DELETED
|
@@ -1,444 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ruleBuilder = void 0;
|
|
4
|
-
const uuid_1 = require("uuid");
|
|
5
|
-
const shared_1 = require("@stuntman/shared");
|
|
6
|
-
// TODO add fluent match on multipart from data
|
|
7
|
-
class RuleBuilderBaseBase {
|
|
8
|
-
constructor(rule, _matchBuilderVariables) {
|
|
9
|
-
this._matchBuilderVariables = _matchBuilderVariables || {};
|
|
10
|
-
this.rule = rule || {
|
|
11
|
-
id: (0, uuid_1.v4)(),
|
|
12
|
-
ttlSeconds: shared_1.DEFAULT_RULE_TTL_SECONDS,
|
|
13
|
-
priority: shared_1.DEFAULT_RULE_PRIORITY,
|
|
14
|
-
matches: {
|
|
15
|
-
localFn: (req) => {
|
|
16
|
-
var _a, _b, _c;
|
|
17
|
-
const ___url = new URL(req.url);
|
|
18
|
-
const ___headers = req.rawHeaders;
|
|
19
|
-
const arrayIndexerRegex = /\[(?<arrayIndex>[0-9]*)\]/i;
|
|
20
|
-
const matchObject = (obj, path, value, parentPath) => {
|
|
21
|
-
var _a, _b;
|
|
22
|
-
if (!obj) {
|
|
23
|
-
return { result: false, description: `${parentPath} is falsey` };
|
|
24
|
-
}
|
|
25
|
-
const [rawKey, ...rest] = path.split('.');
|
|
26
|
-
const key = rawKey.replace(arrayIndexerRegex, '');
|
|
27
|
-
const shouldBeArray = arrayIndexerRegex.test(rawKey);
|
|
28
|
-
const arrayIndex = Number((_b = (_a = arrayIndexerRegex.exec(rawKey)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.arrayIndex);
|
|
29
|
-
const actualValue = key ? obj[key] : obj;
|
|
30
|
-
const currentPath = `${parentPath ? `${parentPath}.` : ''}${rawKey}`;
|
|
31
|
-
if (value === undefined && actualValue === undefined) {
|
|
32
|
-
return { result: false, description: `${currentPath}=undefined` };
|
|
33
|
-
}
|
|
34
|
-
if (rest.length === 0) {
|
|
35
|
-
if (shouldBeArray &&
|
|
36
|
-
(!Array.isArray(actualValue) ||
|
|
37
|
-
!(!Number.isInteger(arrayIndex) && actualValue.length > Number(arrayIndex)))) {
|
|
38
|
-
return { result: false, description: `${currentPath} empty array` };
|
|
39
|
-
}
|
|
40
|
-
if (value === undefined) {
|
|
41
|
-
const result = shouldBeArray
|
|
42
|
-
? !Number.isInteger(arrayIndex) || actualValue.length >= Number(arrayIndex)
|
|
43
|
-
: actualValue !== undefined;
|
|
44
|
-
return { result, description: `${currentPath}` };
|
|
45
|
-
}
|
|
46
|
-
if (!shouldBeArray) {
|
|
47
|
-
const result = value instanceof RegExp ? value.test(actualValue) : value === actualValue;
|
|
48
|
-
return { result, description: `${currentPath}` };
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (shouldBeArray) {
|
|
52
|
-
if (Number.isInteger(arrayIndex)) {
|
|
53
|
-
return matchObject(actualValue[Number(arrayIndex)], rest.join('.'), value, currentPath);
|
|
54
|
-
}
|
|
55
|
-
const hasArrayMatch = actualValue.some((arrayValue) => matchObject(arrayValue, rest.join('.'), value, currentPath));
|
|
56
|
-
return { result: hasArrayMatch, description: `array match ${currentPath}` };
|
|
57
|
-
}
|
|
58
|
-
if (typeof actualValue !== 'object') {
|
|
59
|
-
return { result: false, description: `${currentPath} not an object` };
|
|
60
|
-
}
|
|
61
|
-
return matchObject(actualValue, rest.join('.'), value, currentPath);
|
|
62
|
-
};
|
|
63
|
-
const ___matchesValue = (matcher, value) => {
|
|
64
|
-
if (matcher === undefined) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
if (typeof matcher !== 'string' && !(matcher instanceof RegExp) && typeof matcher !== 'number') {
|
|
68
|
-
throw new Error('invalid matcher');
|
|
69
|
-
}
|
|
70
|
-
if (typeof matcher === 'string' && matcher !== value) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (matcher instanceof RegExp && (typeof value !== 'string' || !matcher.test(value))) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
if (typeof matcher === 'number' && (typeof value !== 'number' || matcher !== value)) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
return true;
|
|
80
|
-
};
|
|
81
|
-
if (!___matchesValue(matchBuilderVariables.filter, req.url)) {
|
|
82
|
-
return {
|
|
83
|
-
result: false,
|
|
84
|
-
description: `url ${req.url} doesn't match ${(_a = matchBuilderVariables.filter) === null || _a === void 0 ? void 0 : _a.toString()}`,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
if (!___matchesValue(matchBuilderVariables.hostname, ___url.hostname)) {
|
|
88
|
-
return {
|
|
89
|
-
result: false,
|
|
90
|
-
description: `hostname ${___url.hostname} doesn't match ${(_b = matchBuilderVariables.hostname) === null || _b === void 0 ? void 0 : _b.toString()}`,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
if (!___matchesValue(matchBuilderVariables.pathname, ___url.pathname)) {
|
|
94
|
-
return {
|
|
95
|
-
result: false,
|
|
96
|
-
description: `pathname ${___url.pathname} doesn't match ${(_c = matchBuilderVariables.pathname) === null || _c === void 0 ? void 0 : _c.toString()}`,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
if (matchBuilderVariables.searchParams) {
|
|
100
|
-
for (const searchParamMatcher of matchBuilderVariables.searchParams) {
|
|
101
|
-
if (typeof searchParamMatcher === 'string') {
|
|
102
|
-
const result = ___url.searchParams.has(searchParamMatcher);
|
|
103
|
-
return { result, description: `searchParams.has("${searchParamMatcher}")` };
|
|
104
|
-
}
|
|
105
|
-
if (searchParamMatcher instanceof RegExp) {
|
|
106
|
-
const result = Array.from(___url.searchParams.keys()).some((key) => searchParamMatcher.test(key));
|
|
107
|
-
return { result, description: `searchParams.keys() matches ${searchParamMatcher.toString()}` };
|
|
108
|
-
}
|
|
109
|
-
if (!___url.searchParams.has(searchParamMatcher.key)) {
|
|
110
|
-
return { result: false, description: `searchParams.has("${searchParamMatcher.key}")` };
|
|
111
|
-
}
|
|
112
|
-
if (searchParamMatcher.value) {
|
|
113
|
-
const value = ___url.searchParams.get(searchParamMatcher.key);
|
|
114
|
-
if (value === null) {
|
|
115
|
-
return {
|
|
116
|
-
result: false,
|
|
117
|
-
description: `searchParams.get("${searchParamMatcher.key}") === null`,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
if (!___matchesValue(searchParamMatcher.value, value)) {
|
|
121
|
-
return {
|
|
122
|
-
result: false,
|
|
123
|
-
description: `searchParams.get("${searchParamMatcher.key}") = "${searchParamMatcher.value}"`,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (matchBuilderVariables.headers) {
|
|
130
|
-
for (const headerMatcher of matchBuilderVariables.headers) {
|
|
131
|
-
if (typeof headerMatcher === 'string') {
|
|
132
|
-
const result = ___headers.has(headerMatcher);
|
|
133
|
-
return { result, description: `headers.has("${headerMatcher}")` };
|
|
134
|
-
}
|
|
135
|
-
if (headerMatcher instanceof RegExp) {
|
|
136
|
-
const result = ___headers.toHeaderPairs().some(([key]) => headerMatcher.test(key));
|
|
137
|
-
return { result, description: `headers.keys matches ${headerMatcher.toString()}` };
|
|
138
|
-
}
|
|
139
|
-
if (!___headers.has(headerMatcher.key)) {
|
|
140
|
-
return { result: false, description: `headers.has("${headerMatcher.key}")` };
|
|
141
|
-
}
|
|
142
|
-
if (headerMatcher.value) {
|
|
143
|
-
const value = ___headers.get(headerMatcher.key);
|
|
144
|
-
if (value === null) {
|
|
145
|
-
return { result: false, description: `headers.get("${headerMatcher.key}") === null` };
|
|
146
|
-
}
|
|
147
|
-
if (!___matchesValue(headerMatcher.value, value)) {
|
|
148
|
-
return {
|
|
149
|
-
result: false,
|
|
150
|
-
description: `headerMatcher.get("${headerMatcher.key}") = "${headerMatcher.value}"`,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
if (matchBuilderVariables.bodyText === null && !!req.body) {
|
|
157
|
-
return { result: false, description: `empty body` };
|
|
158
|
-
}
|
|
159
|
-
if (matchBuilderVariables.bodyText) {
|
|
160
|
-
if (!req.body) {
|
|
161
|
-
return { result: false, description: `empty body` };
|
|
162
|
-
}
|
|
163
|
-
if (matchBuilderVariables.bodyText instanceof RegExp) {
|
|
164
|
-
if (!___matchesValue(matchBuilderVariables.bodyText, req.body)) {
|
|
165
|
-
return {
|
|
166
|
-
result: false,
|
|
167
|
-
description: `body text doesn't match ${matchBuilderVariables.bodyText.toString()}`,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
else if (!req.body.includes(matchBuilderVariables.bodyText)) {
|
|
172
|
-
return {
|
|
173
|
-
result: false,
|
|
174
|
-
description: `body text doesn't include "${matchBuilderVariables.bodyText}"`,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (matchBuilderVariables.bodyJson) {
|
|
179
|
-
let json;
|
|
180
|
-
try {
|
|
181
|
-
json = JSON.parse(req.body);
|
|
182
|
-
}
|
|
183
|
-
catch (kiss) {
|
|
184
|
-
return { result: false, description: `unparseable json` };
|
|
185
|
-
}
|
|
186
|
-
if (!json) {
|
|
187
|
-
return { result: false, description: `empty json object` };
|
|
188
|
-
}
|
|
189
|
-
for (const jsonMatcher of Array.isArray(matchBuilderVariables.bodyJson)
|
|
190
|
-
? matchBuilderVariables.bodyJson
|
|
191
|
-
: [matchBuilderVariables.bodyJson]) {
|
|
192
|
-
if (!matchObject(json, jsonMatcher.key, jsonMatcher.value)) {
|
|
193
|
-
return { result: false, description: `$.${jsonMatcher.key} != "${jsonMatcher.value}"` };
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
if (matchBuilderVariables.bodyGql) {
|
|
198
|
-
if (!req.gqlBody) {
|
|
199
|
-
return { result: false, description: `not a gql body` };
|
|
200
|
-
}
|
|
201
|
-
if (!___matchesValue(matchBuilderVariables.bodyGql.methodName, req.gqlBody.methodName)) {
|
|
202
|
-
return {
|
|
203
|
-
result: false,
|
|
204
|
-
description: `methodName "${matchBuilderVariables.bodyGql.methodName}" !== "${req.gqlBody.methodName}"`,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
if (!___matchesValue(matchBuilderVariables.bodyGql.operationName, req.gqlBody.operationName)) {
|
|
208
|
-
return {
|
|
209
|
-
result: false,
|
|
210
|
-
description: `operationName "${matchBuilderVariables.bodyGql.operationName}" !== "${req.gqlBody.operationName}"`,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
if (!___matchesValue(matchBuilderVariables.bodyGql.query, req.gqlBody.query)) {
|
|
214
|
-
return {
|
|
215
|
-
result: false,
|
|
216
|
-
description: `query "${matchBuilderVariables.bodyGql.query}" !== "${req.gqlBody.query}"`,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
if (!___matchesValue(matchBuilderVariables.bodyGql.type, req.gqlBody.type)) {
|
|
220
|
-
return {
|
|
221
|
-
result: false,
|
|
222
|
-
description: `type "${matchBuilderVariables.bodyGql.type}" !== "${req.gqlBody.type}"`,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
if (!matchBuilderVariables.bodyGql.variables) {
|
|
226
|
-
return { result: true, description: `no variables to match` };
|
|
227
|
-
}
|
|
228
|
-
for (const jsonMatcher of Array.isArray(matchBuilderVariables.bodyGql.variables)
|
|
229
|
-
? matchBuilderVariables.bodyGql.variables
|
|
230
|
-
: [matchBuilderVariables.bodyGql.variables]) {
|
|
231
|
-
const matchObjectResult = matchObject(req.gqlBody.variables, jsonMatcher.key, jsonMatcher.value);
|
|
232
|
-
if (!matchObjectResult.result) {
|
|
233
|
-
return {
|
|
234
|
-
result: false,
|
|
235
|
-
description: `GQL variable ${jsonMatcher.key} != "${jsonMatcher.value}". Detail: ${matchObjectResult.description}`,
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return { result: true, description: 'match' };
|
|
241
|
-
},
|
|
242
|
-
localVariables: { matchBuilderVariables: this._matchBuilderVariables },
|
|
243
|
-
},
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
class RuleBuilderBase extends RuleBuilderBaseBase {
|
|
248
|
-
limitedUse(hitCount) {
|
|
249
|
-
if (Number.isNaN(hitCount) || !Number.isFinite(hitCount) || !Number.isInteger(hitCount) || hitCount <= 0) {
|
|
250
|
-
throw new Error('Invalid hitCount');
|
|
251
|
-
}
|
|
252
|
-
this.rule.removeAfterUse = hitCount;
|
|
253
|
-
return this;
|
|
254
|
-
}
|
|
255
|
-
singleUse() {
|
|
256
|
-
return this.limitedUse(1);
|
|
257
|
-
}
|
|
258
|
-
storeTraffic() {
|
|
259
|
-
this.rule.storeTraffic = true;
|
|
260
|
-
return this;
|
|
261
|
-
}
|
|
262
|
-
disabled() {
|
|
263
|
-
this.rule.isEnabled = false;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
class RuleBuilder extends RuleBuilderBase {
|
|
267
|
-
raisePriority(by) {
|
|
268
|
-
const subtract = by !== null && by !== void 0 ? by : 1;
|
|
269
|
-
if (subtract >= shared_1.DEFAULT_RULE_PRIORITY) {
|
|
270
|
-
throw new Error(`Unable to raise priority over the default ${shared_1.DEFAULT_RULE_PRIORITY}`);
|
|
271
|
-
}
|
|
272
|
-
this.rule.priority = shared_1.DEFAULT_RULE_PRIORITY - subtract;
|
|
273
|
-
return this;
|
|
274
|
-
}
|
|
275
|
-
decreasePriority(by) {
|
|
276
|
-
const add = by !== null && by !== void 0 ? by : 1;
|
|
277
|
-
this.rule.priority = shared_1.DEFAULT_RULE_PRIORITY + add;
|
|
278
|
-
return this;
|
|
279
|
-
}
|
|
280
|
-
customTtl(ttlSeconds) {
|
|
281
|
-
if (Number.isNaN(ttlSeconds) || !Number.isInteger(ttlSeconds) || !Number.isFinite(ttlSeconds) || ttlSeconds < 0) {
|
|
282
|
-
throw new Error('Invalid ttl');
|
|
283
|
-
}
|
|
284
|
-
if (ttlSeconds < shared_1.MIN_RULE_TTL_SECONDS || ttlSeconds > shared_1.MAX_RULE_TTL_SECONDS) {
|
|
285
|
-
throw new Error(`ttl of ${ttlSeconds} seconds is outside range min: ${shared_1.MIN_RULE_TTL_SECONDS}, max:${shared_1.MAX_RULE_TTL_SECONDS}`);
|
|
286
|
-
}
|
|
287
|
-
this.rule.ttlSeconds = ttlSeconds;
|
|
288
|
-
return this;
|
|
289
|
-
}
|
|
290
|
-
customId(id) {
|
|
291
|
-
this.rule.id = id;
|
|
292
|
-
return this;
|
|
293
|
-
}
|
|
294
|
-
onRequestTo(filter) {
|
|
295
|
-
this._matchBuilderVariables.filter = filter;
|
|
296
|
-
return new RuleBuilderInitialized(this.rule, this._matchBuilderVariables);
|
|
297
|
-
}
|
|
298
|
-
onRequestToHostname(hostname) {
|
|
299
|
-
this._matchBuilderVariables.hostname = hostname;
|
|
300
|
-
return new RuleBuilderInitialized(this.rule, this._matchBuilderVariables);
|
|
301
|
-
}
|
|
302
|
-
onRequestToPathname(pathname) {
|
|
303
|
-
this._matchBuilderVariables.pathname = pathname;
|
|
304
|
-
return new RuleBuilderInitialized(this.rule, this._matchBuilderVariables);
|
|
305
|
-
}
|
|
306
|
-
onAnyRequest() {
|
|
307
|
-
return this.onRequestTo(/.*/);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
class RuleBuilderInitialized extends RuleBuilderBase {
|
|
311
|
-
withHostname(hostname) {
|
|
312
|
-
this._matchBuilderVariables.hostname = hostname;
|
|
313
|
-
return this;
|
|
314
|
-
}
|
|
315
|
-
withPathname(pathname) {
|
|
316
|
-
this._matchBuilderVariables.pathname = pathname;
|
|
317
|
-
return this;
|
|
318
|
-
}
|
|
319
|
-
withPort(port) {
|
|
320
|
-
this._matchBuilderVariables.port = port;
|
|
321
|
-
return this;
|
|
322
|
-
}
|
|
323
|
-
withSearchParam(key, value) {
|
|
324
|
-
if (!this._matchBuilderVariables.searchParams) {
|
|
325
|
-
this._matchBuilderVariables.searchParams = [];
|
|
326
|
-
}
|
|
327
|
-
if (!key) {
|
|
328
|
-
throw new Error('key cannot be empty');
|
|
329
|
-
}
|
|
330
|
-
if (!value) {
|
|
331
|
-
this._matchBuilderVariables.searchParams.push(key);
|
|
332
|
-
return this;
|
|
333
|
-
}
|
|
334
|
-
if (key instanceof RegExp) {
|
|
335
|
-
throw new Error('Unsupported regex param key with value');
|
|
336
|
-
}
|
|
337
|
-
this._matchBuilderVariables.searchParams.push({ key, value });
|
|
338
|
-
return this;
|
|
339
|
-
}
|
|
340
|
-
withSearchParams(params) {
|
|
341
|
-
if (!this._matchBuilderVariables.searchParams) {
|
|
342
|
-
this._matchBuilderVariables.searchParams = [];
|
|
343
|
-
}
|
|
344
|
-
for (const param of params) {
|
|
345
|
-
if (typeof param === 'string' || param instanceof RegExp) {
|
|
346
|
-
this.withSearchParam(param);
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
this.withSearchParam(param.key, param.value);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return this;
|
|
353
|
-
}
|
|
354
|
-
withHeader(key, value) {
|
|
355
|
-
if (!this._matchBuilderVariables.headers) {
|
|
356
|
-
this._matchBuilderVariables.headers = [];
|
|
357
|
-
}
|
|
358
|
-
if (!key) {
|
|
359
|
-
throw new Error('key cannot be empty');
|
|
360
|
-
}
|
|
361
|
-
if (!value) {
|
|
362
|
-
this._matchBuilderVariables.headers.push(key);
|
|
363
|
-
return this;
|
|
364
|
-
}
|
|
365
|
-
if (key instanceof RegExp) {
|
|
366
|
-
throw new Error('Unsupported regex param key with value');
|
|
367
|
-
}
|
|
368
|
-
this._matchBuilderVariables.headers.push({ key, value });
|
|
369
|
-
return this;
|
|
370
|
-
}
|
|
371
|
-
withHeaders(headers) {
|
|
372
|
-
if (!this._matchBuilderVariables.headers) {
|
|
373
|
-
this._matchBuilderVariables.headers = [];
|
|
374
|
-
}
|
|
375
|
-
for (const header of headers) {
|
|
376
|
-
if (typeof header === 'string' || header instanceof RegExp) {
|
|
377
|
-
this.withHeader(header);
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
this.withHeader(header.key, header.value);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return this;
|
|
384
|
-
}
|
|
385
|
-
withBodyText(includesOrMatches) {
|
|
386
|
-
this._matchBuilderVariables.bodyText = includesOrMatches;
|
|
387
|
-
return this;
|
|
388
|
-
}
|
|
389
|
-
withoutBody() {
|
|
390
|
-
this._matchBuilderVariables.bodyText = null;
|
|
391
|
-
return this;
|
|
392
|
-
}
|
|
393
|
-
withBodyJson(keyOrMatcher, withValue) {
|
|
394
|
-
const keyRegex = /^(?:(?:[a-z0-9_-]+)|(?:\[[0-9]*\]))(?:\.(?:(?:[a-z0-9_-]+)|(?:\[[0-9]*\])))*$/i;
|
|
395
|
-
if (!this._matchBuilderVariables.bodyJson) {
|
|
396
|
-
this._matchBuilderVariables.bodyJson = [];
|
|
397
|
-
}
|
|
398
|
-
if (typeof keyOrMatcher === 'string') {
|
|
399
|
-
if (!keyRegex.test(keyOrMatcher)) {
|
|
400
|
-
throw new Error('invalid key');
|
|
401
|
-
}
|
|
402
|
-
this._matchBuilderVariables.bodyJson.push({ key: keyOrMatcher, value: withValue });
|
|
403
|
-
return this;
|
|
404
|
-
}
|
|
405
|
-
if (withValue !== undefined) {
|
|
406
|
-
throw new Error('invalid usage');
|
|
407
|
-
}
|
|
408
|
-
if (!keyRegex.test(keyOrMatcher.key)) {
|
|
409
|
-
throw new Error('invalid key');
|
|
410
|
-
}
|
|
411
|
-
this._matchBuilderVariables.bodyJson.push(keyOrMatcher);
|
|
412
|
-
return this;
|
|
413
|
-
}
|
|
414
|
-
withBodyGql(gqlMatcher) {
|
|
415
|
-
this._matchBuilderVariables.bodyGql = gqlMatcher;
|
|
416
|
-
return this;
|
|
417
|
-
}
|
|
418
|
-
proxyPass() {
|
|
419
|
-
return this.rule;
|
|
420
|
-
}
|
|
421
|
-
mockResponse(response) {
|
|
422
|
-
this.rule.actions = { mockResponse: response };
|
|
423
|
-
return this.rule;
|
|
424
|
-
}
|
|
425
|
-
modifyRequest(modifyFunction) {
|
|
426
|
-
this.rule.actions = { modifyRequest: modifyFunction };
|
|
427
|
-
return new RuleBuilderRequestInitialized(this.rule, this._matchBuilderVariables);
|
|
428
|
-
}
|
|
429
|
-
modifyResponse(modifyFunction) {
|
|
430
|
-
this.rule.actions = { modifyResponse: modifyFunction };
|
|
431
|
-
return this.rule;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
class RuleBuilderRequestInitialized extends RuleBuilderBase {
|
|
435
|
-
modifyResponse(modifyFunction) {
|
|
436
|
-
if (!this.rule.actions) {
|
|
437
|
-
throw new Error('rule.actions not defined - builder implementation error');
|
|
438
|
-
}
|
|
439
|
-
this.rule.actions.modifyResponse = modifyFunction;
|
|
440
|
-
return this.rule;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
const ruleBuilder = () => new RuleBuilder();
|
|
444
|
-
exports.ruleBuilder = ruleBuilder;
|