Skip to content

Commit c7fe5f7

Browse files
committed
Dramatically simplify server-side subscription linking code
This notably removes a very old tiny bit of backward compat, which provided a zero-length body on abort data to remote clients who might've expected it (clients running versions before Mockttp v3). This is not a breaking change as such, since we don't formally support super old (3+ years) clients anyway, but worth nothing.
1 parent ad9e42f commit c7fe5f7

File tree

2 files changed

+33
-178
lines changed

2 files changed

+33
-178
lines changed

src/admin/mockttp-admin-model.ts

Lines changed: 32 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,27 @@ import type { RequestRuleData } from "../rules/requests/request-rule";
1818
import type { WebSocketRuleData } from "../rules/websockets/websocket-rule";
1919

2020
import { deserializeRuleData, deserializeWebSocketRuleData } from "../rules/rule-deserialization";
21-
22-
const REQUEST_INITIATED_TOPIC = 'request-initiated';
23-
const REQUEST_RECEIVED_TOPIC = 'request-received';
24-
const RESPONSE_COMPLETED_TOPIC = 'response-completed';
25-
const WEBSOCKET_REQUEST_TOPIC = 'websocket-request';
26-
const WEBSOCKET_ACCEPTED_TOPIC = 'websocket-accepted';
27-
const WEBSOCKET_MESSAGE_RECEIVED_TOPIC = 'websocket-message-received';
28-
const WEBSOCKET_MESSAGE_SENT_TOPIC = 'websocket-message-sent';
29-
const WEBSOCKET_CLOSE_TOPIC = 'websocket-close';
30-
const REQUEST_ABORTED_TOPIC = 'request-aborted';
31-
const TLS_PASSTHROUGH_OPENED_TOPIC = 'tls-passthrough-opened';
32-
const TLS_PASSTHROUGH_CLOSED_TOPIC = 'tls-passthrough-closed';
33-
const TLS_CLIENT_ERROR_TOPIC = 'tls-client-error';
34-
const CLIENT_ERROR_TOPIC = 'client-error';
35-
const RAW_PASSTHROUGH_OPENED_TOPIC = 'raw-passthrough-opened';
36-
const RAW_PASSTHROUGH_CLOSED_TOPIC = 'raw-passthrough-closed';
37-
const RAW_PASSTHROUGH_DATA_TOPIC = 'raw-passthrough-data';
38-
const RULE_EVENT_TOPIC = 'rule-event';
21+
import { SubscribableEvent } from "../main";
22+
23+
const graphqlSubscriptionPairs = Object.entries({
24+
'requestInitiated': 'request-initiated',
25+
'requestReceived': 'request',
26+
'responseCompleted': 'response',
27+
'webSocketRequest': 'websocket-request',
28+
'webSocketAccepted': 'websocket-accepted',
29+
'webSocketMessageReceived': 'websocket-message-received',
30+
'webSocketMessageSent': 'websocket-message-sent',
31+
'webSocketClose': 'websocket-close',
32+
'requestAborted': 'abort',
33+
'tlsPassthroughOpened': 'tls-passthrough-opened',
34+
'tlsPassthroughClosed': 'tls-passthrough-closed',
35+
'failedTlsRequest': 'tls-client-error',
36+
'failedClientRequest': 'client-error',
37+
'rawPassthroughOpened': 'raw-passthrough-opened',
38+
'rawPassthroughClosed': 'raw-passthrough-closed',
39+
'rawPassthroughData': 'raw-passthrough-data',
40+
'ruleEvent': 'rule-event'
41+
} satisfies { [key: string]: SubscribableEvent });
3942

4043
async function buildMockedEndpointData(endpoint: ServerMockedEndpoint): Promise<MockedEndpointData> {
4144
return {
@@ -53,111 +56,17 @@ export function buildAdminServerModel(
5356
): IResolvers {
5457
const pubsub = new PubSub();
5558

56-
mockServer.on('request-initiated', (evt) => {
57-
pubsub.publish(REQUEST_INITIATED_TOPIC, {
58-
requestInitiated: evt
59-
})
60-
});
61-
62-
mockServer.on('request', (evt) => {
63-
pubsub.publish(REQUEST_RECEIVED_TOPIC, {
64-
requestReceived: evt
65-
})
66-
});
67-
68-
mockServer.on('response', (evt) => {
69-
pubsub.publish(RESPONSE_COMPLETED_TOPIC, {
70-
responseCompleted: evt
71-
})
72-
});
73-
74-
mockServer.on('websocket-request', (evt) => {
75-
pubsub.publish(WEBSOCKET_REQUEST_TOPIC, {
76-
webSocketRequest: evt
77-
})
78-
});
79-
80-
mockServer.on('websocket-accepted', (evt) => {
81-
pubsub.publish(WEBSOCKET_ACCEPTED_TOPIC, {
82-
webSocketAccepted: evt
83-
})
84-
});
85-
86-
mockServer.on('websocket-message-received', (evt) => {
87-
pubsub.publish(WEBSOCKET_MESSAGE_RECEIVED_TOPIC, {
88-
webSocketMessageReceived: evt
89-
})
90-
});
91-
92-
mockServer.on('websocket-message-sent', (evt) => {
93-
pubsub.publish(WEBSOCKET_MESSAGE_SENT_TOPIC, {
94-
webSocketMessageSent: evt
95-
})
96-
});
97-
98-
mockServer.on('websocket-close', (evt) => {
99-
pubsub.publish(WEBSOCKET_CLOSE_TOPIC, {
100-
webSocketClose: evt
101-
})
102-
});
103-
104-
mockServer.on('abort', (evt) => {
105-
pubsub.publish(REQUEST_ABORTED_TOPIC, {
106-
requestAborted: Object.assign(evt, {
107-
// Backward compat: old clients expect this to be present. In future this can be
108-
// removed and abort events can lose the 'body' in the schema.
109-
body: Buffer.alloc(0)
110-
})
111-
})
112-
});
59+
for (let [gqlName, eventName] of graphqlSubscriptionPairs) {
60+
mockServer.on(eventName as any, (evt) => {
61+
pubsub.publish(eventName, { [gqlName]: evt });
62+
});
63+
}
11364

114-
mockServer.on('tls-passthrough-opened', (evt) => {
115-
pubsub.publish(TLS_PASSTHROUGH_OPENED_TOPIC, {
116-
tlsPassthroughOpened: evt
117-
})
118-
});
119-
120-
mockServer.on('tls-passthrough-closed', (evt) => {
121-
pubsub.publish(TLS_PASSTHROUGH_CLOSED_TOPIC, {
122-
tlsPassthroughClosed: evt
123-
})
124-
});
125-
126-
mockServer.on('tls-client-error', (evt) => {
127-
pubsub.publish(TLS_CLIENT_ERROR_TOPIC, {
128-
failedTlsRequest: evt
129-
})
130-
});
131-
132-
mockServer.on('client-error', (evt) => {
133-
pubsub.publish(CLIENT_ERROR_TOPIC, {
134-
failedClientRequest: evt
135-
})
136-
});
137-
138-
mockServer.on('raw-passthrough-opened', (evt) => {
139-
pubsub.publish(RAW_PASSTHROUGH_OPENED_TOPIC, {
140-
rawPassthroughOpened: evt
141-
})
142-
});
143-
144-
mockServer.on('raw-passthrough-closed', (evt) => {
145-
pubsub.publish(RAW_PASSTHROUGH_CLOSED_TOPIC, {
146-
rawPassthroughClosed: evt
147-
})
148-
});
149-
150-
mockServer.on('raw-passthrough-data', (evt) => {
151-
pubsub.publish(RAW_PASSTHROUGH_DATA_TOPIC, {
152-
rawPassthroughData: evt
153-
})
154-
});
155-
156-
mockServer.on('rule-event', (evt) => {
157-
pubsub.publish(RULE_EVENT_TOPIC, {
158-
ruleEvent: evt
159-
})
160-
});
65+
const subscriptionResolvers = Object.fromEntries(graphqlSubscriptionPairs.map(([gqlName, eventName]) => ([
66+
gqlName, {
67+
subscribe: () => pubsub.asyncIterator(eventName)
68+
}
69+
])));
16170

16271
return {
16372
Query: {
@@ -218,59 +127,7 @@ export function buildAdminServerModel(
218127
}
219128
},
220129

221-
Subscription: {
222-
requestInitiated: {
223-
subscribe: () => pubsub.asyncIterator(REQUEST_INITIATED_TOPIC)
224-
},
225-
requestReceived: {
226-
subscribe: () => pubsub.asyncIterator(REQUEST_RECEIVED_TOPIC)
227-
},
228-
responseCompleted: {
229-
subscribe: () => pubsub.asyncIterator(RESPONSE_COMPLETED_TOPIC)
230-
},
231-
webSocketRequest: {
232-
subscribe: () => pubsub.asyncIterator(WEBSOCKET_REQUEST_TOPIC)
233-
},
234-
webSocketAccepted: {
235-
subscribe: () => pubsub.asyncIterator(WEBSOCKET_ACCEPTED_TOPIC)
236-
},
237-
webSocketMessageReceived: {
238-
subscribe: () => pubsub.asyncIterator(WEBSOCKET_MESSAGE_RECEIVED_TOPIC)
239-
},
240-
webSocketMessageSent: {
241-
subscribe: () => pubsub.asyncIterator(WEBSOCKET_MESSAGE_SENT_TOPIC)
242-
},
243-
webSocketClose: {
244-
subscribe: () => pubsub.asyncIterator(WEBSOCKET_CLOSE_TOPIC)
245-
},
246-
requestAborted: {
247-
subscribe: () => pubsub.asyncIterator(REQUEST_ABORTED_TOPIC)
248-
},
249-
tlsPassthroughOpened: {
250-
subscribe: () => pubsub.asyncIterator(TLS_PASSTHROUGH_OPENED_TOPIC)
251-
},
252-
tlsPassthroughClosed: {
253-
subscribe: () => pubsub.asyncIterator(TLS_PASSTHROUGH_CLOSED_TOPIC)
254-
},
255-
failedTlsRequest: {
256-
subscribe: () => pubsub.asyncIterator(TLS_CLIENT_ERROR_TOPIC)
257-
},
258-
failedClientRequest: {
259-
subscribe: () => pubsub.asyncIterator(CLIENT_ERROR_TOPIC)
260-
},
261-
rawPassthroughOpened: {
262-
subscribe: () => pubsub.asyncIterator(RAW_PASSTHROUGH_OPENED_TOPIC)
263-
},
264-
rawPassthroughClosed: {
265-
subscribe: () => pubsub.asyncIterator(RAW_PASSTHROUGH_CLOSED_TOPIC)
266-
},
267-
rawPassthroughData: {
268-
subscribe: () => pubsub.asyncIterator(RAW_PASSTHROUGH_DATA_TOPIC)
269-
},
270-
ruleEvent: {
271-
subscribe: () => pubsub.asyncIterator(RULE_EVENT_TOPIC)
272-
}
273-
},
130+
Subscription: subscriptionResolvers,
274131

275132
Request: {
276133
body: (request: CompletedRequest) => {

src/admin/mockttp-schema.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ export const MockttpSchema = gql`
3131
tlsPassthroughOpened: TlsPassthroughEvent!
3232
tlsPassthroughClosed: TlsPassthroughEvent!
3333
failedTlsRequest: TlsHandshakeFailure!
34+
failedClientRequest: ClientError!
3435
rawPassthroughOpened: RawPassthroughEvent!
3536
rawPassthroughClosed: RawPassthroughEvent!
3637
rawPassthroughData: RawPassthroughDataEvent!
37-
failedClientRequest: ClientError!
3838
ruleEvent: RuleEvent!
3939
}
4040
@@ -204,8 +204,6 @@ export const MockttpSchema = gql`
204204
headers: Json!
205205
rawHeaders: Json!
206206
207-
body: Buffer!
208-
209207
error: Json
210208
}
211209

0 commit comments

Comments
 (0)