Skip to content

Commit 83e8a1f

Browse files
committed
Drop 'Definition' from step defn names and refactor impl classes
This makes the handler implementations entirely internal (no longer expected to be provided through the manual or chained APIs, neither types nor classes actually exposed directly) so that the external API is simpler for manual rule building (just use requestSteps.XStep), the internal state is better contained, and the rule creation flow loses a branch - it now always converts a definition to a rule. This is a breaking change, but combined with previous changes to rename the export may mean that cumulatively existing code actually still works just fine. If you have any references to Definitions, you should simply drop those.
1 parent 814a941 commit 83e8a1f

13 files changed

+196
-188
lines changed

src/main.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,16 @@ export type {
2626

2727
// Export rule data builders & type definitions:
2828
import * as matchers from './rules/matchers';
29-
import type { RequestStep, RequestStepOptions } from './rules/requests/request-steps';
3029
import * as requestStepDefinitions from './rules/requests/request-step-definitions';
31-
import type { WebSocketStep } from './rules/websockets/websocket-steps';
3230
import * as webSocketStepDefinitions from './rules/websockets/websocket-step-definitions';
3331
import * as completionCheckers from './rules/completion-checkers';
3432

33+
export type RequestStep = requestStepDefinitions.RequestStepDefinition;
34+
export type WebSocketStep = webSocketStepDefinitions.WebSocketStepDefinition;
35+
3536
export {
3637
matchers,
37-
RequestStep,
38-
RequestStepOptions,
3938
requestStepDefinitions as requestSteps,
40-
WebSocketStep,
4139
webSocketStepDefinitions as webSocketSteps,
4240
completionCheckers
4341
};

src/rules/passthrough-handling.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
CallbackRequestResult,
2121
CallbackResponseMessageResult
2222
} from './requests/request-step-definitions';
23-
import { AbortError } from './requests/request-steps';
23+
import { AbortError } from './requests/request-step-impls';
2424
import {
2525
CADefinition,
2626
PassThroughLookupOptions

src/rules/requests/request-rule-builder.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ import { Headers, CompletedRequest, Method, MockedEndpoint, Trailers } from "../
66
import type { RequestRuleData } from "./request-rule";
77

88
import {
9-
FixedResponseStepDefinition,
10-
PassThroughStepDefinition,
11-
CallbackStepDefinition,
9+
RequestStepDefinition,
10+
FixedResponseStep,
11+
PassThroughStep,
12+
CallbackStep,
1213
CallbackResponseResult,
13-
StreamStepDefinition,
14-
CloseConnectionStepDefinition,
15-
TimeoutStepDefinition,
14+
StreamStep,
15+
CloseConnectionStep,
16+
TimeoutStep,
1617
PassThroughStepOptions,
17-
FileStepDefinition,
18-
JsonRpcResponseStepDefinition,
19-
ResetConnectionStepDefinition,
18+
FileStep,
19+
JsonRpcResponseStep,
20+
ResetConnectionStep,
2021
CallbackResponseMessageResult,
21-
RequestStepDefinition,
22-
DelayStepDefinition
22+
DelayStep
2323
} from "./request-step-definitions";
2424
import { byteLength } from "../../util/util";
2525
import { BaseRuleBuilder } from "../base-rule-builder";
@@ -94,7 +94,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
9494
* Add a delay (in milliseconds) before the next step in the rule
9595
*/
9696
waitFor(ms: number): this {
97-
this.steps.push(new DelayStepDefinition(ms));
97+
this.steps.push(new DelayStep(ms));
9898
return this;
9999
}
100100

@@ -151,7 +151,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
151151
trailers = headersOrTrailers as Trailers | undefined;
152152
}
153153

154-
this.steps.push(new FixedResponseStepDefinition(
154+
this.steps.push(new FixedResponseStep(
155155
status,
156156
statusMessage,
157157
data,
@@ -196,7 +196,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
196196
// connection after the response is sent, which can confuse clients.
197197
}, headers);
198198

199-
this.steps.push(new FixedResponseStepDefinition(status, undefined, jsonData, headers));
199+
this.steps.push(new FixedResponseStep(status, undefined, jsonData, headers));
200200

201201
const rule: RequestRuleData = {
202202
...this.buildBaseRuleData(),
@@ -232,7 +232,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
232232
thenCallback(callback:
233233
(request: CompletedRequest) => MaybePromise<CallbackResponseResult>
234234
): Promise<MockedEndpoint> {
235-
this.steps.push(new CallbackStepDefinition(callback));
235+
this.steps.push(new CallbackStep(callback));
236236

237237
const rule: RequestRuleData = {
238238
...this.buildBaseRuleData(),
@@ -263,7 +263,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
263263
* @category Responses
264264
*/
265265
thenStream(status: number, stream: Readable, headers?: Headers): Promise<MockedEndpoint> {
266-
this.steps.push(new StreamStepDefinition(status, stream, headers));
266+
this.steps.push(new StreamStep(status, stream, headers));
267267

268268
const rule: RequestRuleData = {
269269
...this.buildBaseRuleData(),
@@ -314,7 +314,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
314314
headers = pathOrHeaders as Headers | undefined;
315315
}
316316

317-
this.steps.push(new FileStepDefinition(status, statusMessage, path, headers));
317+
this.steps.push(new FileStep(status, statusMessage, path, headers));
318318

319319
const rule: RequestRuleData = {
320320
...this.buildBaseRuleData(),
@@ -344,7 +344,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
344344
* @category Responses
345345
*/
346346
thenPassThrough(options?: PassThroughStepOptions): Promise<MockedEndpoint> {
347-
this.steps.push(new PassThroughStepDefinition(options));
347+
this.steps.push(new PassThroughStep(options));
348348

349349
const rule: RequestRuleData = {
350350
...this.buildBaseRuleData(),
@@ -384,7 +384,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
384384
forwarding?: Omit<PassThroughStepOptions['forwarding'], 'targetHost'>
385385
} = {}
386386
): Promise<MockedEndpoint> {
387-
this.steps.push(new PassThroughStepDefinition({
387+
this.steps.push(new PassThroughStep({
388388
...options,
389389
forwarding: {
390390
...options.forwarding,
@@ -415,7 +415,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
415415
* @category Responses
416416
*/
417417
thenCloseConnection(): Promise<MockedEndpoint> {
418-
this.steps.push(new CloseConnectionStepDefinition());
418+
this.steps.push(new CloseConnectionStep());
419419

420420
const rule: RequestRuleData = {
421421
...this.buildBaseRuleData(),
@@ -444,7 +444,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
444444
* @category Responses
445445
*/
446446
thenResetConnection(): Promise<MockedEndpoint> {
447-
this.steps.push(new ResetConnectionStepDefinition());
447+
this.steps.push(new ResetConnectionStep());
448448

449449
const rule: RequestRuleData = {
450450
...this.buildBaseRuleData(),
@@ -469,7 +469,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
469469
* @category Responses
470470
*/
471471
thenTimeout(): Promise<MockedEndpoint> {
472-
this.steps.push(new TimeoutStepDefinition());
472+
this.steps.push(new TimeoutStep());
473473

474474
const rule: RequestRuleData = {
475475
...this.buildBaseRuleData(),
@@ -487,7 +487,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
487487
* @category Responses
488488
*/
489489
thenSendJsonRpcResult(result: any) {
490-
this.steps.push(new JsonRpcResponseStepDefinition({ result }));
490+
this.steps.push(new JsonRpcResponseStep({ result }));
491491

492492
const rule = {
493493
...this.buildBaseRuleData(),
@@ -505,7 +505,7 @@ export class RequestRuleBuilder extends BaseRuleBuilder {
505505
* @category Responses
506506
*/
507507
thenSendJsonRpcError(error: any) {
508-
this.steps.push(new JsonRpcResponseStepDefinition({ error }));
508+
this.steps.push(new JsonRpcResponseStep({ error }));
509509

510510
const rule = {
511511
...this.buildBaseRuleData(),

src/rules/requests/request-rule.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { MaybePromise } from '@httptoolkit/util';
77

88
import * as matchers from "../matchers";
99
import { type RequestStepDefinition } from "./request-step-definitions";
10-
import { StepLookup, RequestStep } from "./request-steps";
10+
import { StepLookup, RequestStepImpl } from "./request-step-impls";
1111
import * as completionCheckers from "../completion-checkers";
1212
import { validateMockRuleData } from '../rule-serialization';
1313

@@ -29,13 +29,13 @@ export interface RequestRuleData {
2929
id?: string;
3030
priority?: number; // Higher is higher, by default 0 is fallback, 1 is normal, must be positive
3131
matchers: matchers.RequestMatcher[];
32-
steps: Array<RequestStep | RequestStepDefinition>;
32+
steps: Array<RequestStepDefinition>;
3333
completionChecker?: completionCheckers.RuleCompletionChecker;
3434
}
3535

3636
export class RequestRule implements RequestRule {
3737
private matchers: matchers.RequestMatcher[];
38-
private steps: Array<RequestStep>;
38+
private steps: Array<RequestStepImpl>;
3939
private completionChecker?: completionCheckers.RuleCompletionChecker;
4040

4141
public id: string;
@@ -52,12 +52,10 @@ export class RequestRule implements RequestRule {
5252
this.completionChecker = data.completionChecker;
5353

5454
this.steps = data.steps.map((stepDefinition, i) => {
55-
const step = 'handle' in stepDefinition
56-
? stepDefinition
57-
: Object.assign(
58-
Object.create(StepLookup[stepDefinition.type].prototype),
59-
stepDefinition
60-
) as RequestStep;
55+
const step = Object.assign(
56+
Object.create(StepLookup[stepDefinition.type].prototype),
57+
stepDefinition
58+
) as RequestStepImpl;
6159

6260
if (StepLookup[step.type].isFinal && i !== data.steps.length - 1) {
6361
throw new Error(

src/rules/requests/request-step-definitions.ts

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,23 @@ import {
4444
/*
4545
This file defines request step *definitions*, which includes everything necessary to define
4646
and serialize their behaviour, but doesn't include the actual handling logic (which
47-
lives in ./request-steps instead). This is intended to allow tree-shaking in browser usage
48-
or remote clients to import only the necessary code, with no need to include all the real
49-
request-processing and handling code that is only used at HTTP-runtime, so isn't relevant when
50-
defining rules.
47+
lives in the Impl classes in ./request-steps instead). This is intended to allow tree-shaking
48+
in browser usage or remote clients, importing only the necessary code, with no need to include
49+
all the real request-processing and handling code that is only used at HTTP-runtime, so isn't
50+
relevant when defining rules.
5151
52-
Every RequestStep extends its definition, simply adding a handle() method, which handles
52+
Every RequestStepImpl extends its definition, simply adding a handle() method, which handles
5353
requests according to the configuration, and adding a deserialize static method that takes
5454
the serialized output from the serialize() methods defined here and creates a working step.
5555
*/
5656

57+
/**
58+
* The definition of a request rule step, which can be passed to Mockttp to define
59+
* a rule.
60+
*
61+
* Implementation of the step is not included in the definition classes, but
62+
* instead exists in an *Impl class defined separately and used internally.
63+
*/
5764
export interface RequestStepDefinition extends Explainable, Serializable {
5865
type: keyof typeof StepDefinitionLookup;
5966
}
@@ -251,7 +258,7 @@ function validateCustomHeaders(
251258
}
252259
}
253260

254-
export class FixedResponseStepDefinition extends Serializable implements RequestStepDefinition {
261+
export class FixedResponseStep extends Serializable implements RequestStepDefinition {
255262

256263
readonly type = 'simple';
257264
static readonly isFinal = true;
@@ -301,7 +308,7 @@ export interface CallbackRequestMessage {
301308
args: [Replace<CompletedRequest, { body: SerializedBody }>];
302309
}
303310

304-
export class CallbackStepDefinition extends Serializable implements RequestStepDefinition {
311+
export class CallbackStep extends Serializable implements RequestStepDefinition {
305312

306313
readonly type = 'callback';
307314
static readonly isFinal = true;
@@ -359,7 +366,7 @@ type StreamStepEventMessage =
359366
{ type: 'arraybuffer', value: string } |
360367
{ type: 'nil' };
361368

362-
export class StreamStepDefinition extends Serializable implements RequestStepDefinition {
369+
export class StreamStep extends Serializable implements RequestStepDefinition {
363370

364371
readonly type = 'stream';
365372
static readonly isFinal = true;
@@ -421,7 +428,7 @@ export class StreamStepDefinition extends Serializable implements RequestStepDef
421428
}
422429
}
423430

424-
export class FileStepDefinition extends Serializable implements RequestStepDefinition {
431+
export class FileStep extends Serializable implements RequestStepDefinition {
425432

426433
readonly type = 'file';
427434
static readonly isFinal = true;
@@ -722,7 +729,7 @@ export interface BeforePassthroughResponseRequest {
722729
*/
723730
export const SERIALIZED_OMIT = "__mockttp__transform__omit__";
724731

725-
export class PassThroughStepDefinition extends Serializable implements RequestStepDefinition {
732+
export class PassThroughStep extends Serializable implements RequestStepDefinition {
726733

727734
readonly type = 'passthrough';
728735
static readonly isFinal = true;
@@ -988,7 +995,7 @@ export class PassThroughStepDefinition extends Serializable implements RequestSt
988995
}
989996
}
990997

991-
export class CloseConnectionStepDefinition extends Serializable implements RequestStepDefinition {
998+
export class CloseConnectionStep extends Serializable implements RequestStepDefinition {
992999
readonly type = 'close-connection';
9931000
static readonly isFinal = true;
9941001

@@ -997,7 +1004,7 @@ export class CloseConnectionStepDefinition extends Serializable implements Reque
9971004
}
9981005
}
9991006

1000-
export class ResetConnectionStepDefinition extends Serializable implements RequestStepDefinition {
1007+
export class ResetConnectionStep extends Serializable implements RequestStepDefinition {
10011008
readonly type = 'reset-connection';
10021009
static readonly isFinal = true;
10031010

@@ -1006,7 +1013,7 @@ export class ResetConnectionStepDefinition extends Serializable implements Reque
10061013
}
10071014
}
10081015

1009-
export class TimeoutStepDefinition extends Serializable implements RequestStepDefinition {
1016+
export class TimeoutStep extends Serializable implements RequestStepDefinition {
10101017
readonly type = 'timeout';
10111018
static readonly isFinal = true;
10121019

@@ -1015,7 +1022,7 @@ export class TimeoutStepDefinition extends Serializable implements RequestStepDe
10151022
}
10161023
}
10171024

1018-
export class JsonRpcResponseStepDefinition extends Serializable implements RequestStepDefinition {
1025+
export class JsonRpcResponseStep extends Serializable implements RequestStepDefinition {
10191026
readonly type = 'json-rpc-response';
10201027
static readonly isFinal = true;
10211028

@@ -1040,7 +1047,7 @@ export class JsonRpcResponseStepDefinition extends Serializable implements Reque
10401047
}
10411048
}
10421049

1043-
export class DelayStepDefinition extends Serializable implements RequestStepDefinition {
1050+
export class DelayStep extends Serializable implements RequestStepDefinition {
10441051

10451052
readonly type = 'delay';
10461053
static readonly isFinal = false;
@@ -1058,14 +1065,14 @@ export class DelayStepDefinition extends Serializable implements RequestStepDefi
10581065
}
10591066

10601067
export const StepDefinitionLookup = {
1061-
'simple': FixedResponseStepDefinition,
1062-
'callback': CallbackStepDefinition,
1063-
'stream': StreamStepDefinition,
1064-
'file': FileStepDefinition,
1065-
'passthrough': PassThroughStepDefinition,
1066-
'close-connection': CloseConnectionStepDefinition,
1067-
'reset-connection': ResetConnectionStepDefinition,
1068-
'timeout': TimeoutStepDefinition,
1069-
'json-rpc-response': JsonRpcResponseStepDefinition,
1070-
'delay': DelayStepDefinition
1068+
'simple': FixedResponseStep,
1069+
'callback': CallbackStep,
1070+
'stream': StreamStep,
1071+
'file': FileStep,
1072+
'passthrough': PassThroughStep,
1073+
'close-connection': CloseConnectionStep,
1074+
'reset-connection': ResetConnectionStep,
1075+
'timeout': TimeoutStep,
1076+
'json-rpc-response': JsonRpcResponseStep,
1077+
'delay': DelayStep
10711078
}

0 commit comments

Comments
 (0)