mocktp 0.0.1-security → 3.15.3

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.

Potentially problematic release.


This version of mocktp might be problematic. Click here for more details.

Files changed (304) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +123 -3
  3. package/custom-typings/Function.d.ts +4 -0
  4. package/custom-typings/cors-gate.d.ts +13 -0
  5. package/custom-typings/http-proxy-agent.d.ts +9 -0
  6. package/custom-typings/node-type-extensions.d.ts +115 -0
  7. package/custom-typings/proxy-agent-modules.d.ts +5 -0
  8. package/custom-typings/request-promise-native.d.ts +28 -0
  9. package/custom-typings/zstd-codec.d.ts +20 -0
  10. package/dist/admin/admin-bin.d.ts +3 -0
  11. package/dist/admin/admin-bin.d.ts.map +1 -0
  12. package/dist/admin/admin-bin.js +61 -0
  13. package/dist/admin/admin-bin.js.map +1 -0
  14. package/dist/admin/admin-plugin-types.d.ts +29 -0
  15. package/dist/admin/admin-plugin-types.d.ts.map +1 -0
  16. package/dist/admin/admin-plugin-types.js +3 -0
  17. package/dist/admin/admin-plugin-types.js.map +1 -0
  18. package/dist/admin/admin-server.d.ts +98 -0
  19. package/dist/admin/admin-server.d.ts.map +1 -0
  20. package/dist/admin/admin-server.js +426 -0
  21. package/dist/admin/admin-server.js.map +1 -0
  22. package/dist/admin/graphql-utils.d.ts +4 -0
  23. package/dist/admin/graphql-utils.d.ts.map +1 -0
  24. package/dist/admin/graphql-utils.js +28 -0
  25. package/dist/admin/graphql-utils.js.map +1 -0
  26. package/dist/admin/mockttp-admin-model.d.ts +7 -0
  27. package/dist/admin/mockttp-admin-model.d.ts.map +1 -0
  28. package/dist/admin/mockttp-admin-model.js +214 -0
  29. package/dist/admin/mockttp-admin-model.js.map +1 -0
  30. package/dist/admin/mockttp-admin-plugin.d.ts +28 -0
  31. package/dist/admin/mockttp-admin-plugin.d.ts.map +1 -0
  32. package/dist/admin/mockttp-admin-plugin.js +37 -0
  33. package/dist/admin/mockttp-admin-plugin.js.map +1 -0
  34. package/dist/admin/mockttp-admin-server.d.ts +16 -0
  35. package/dist/admin/mockttp-admin-server.d.ts.map +1 -0
  36. package/dist/admin/mockttp-admin-server.js +17 -0
  37. package/dist/admin/mockttp-admin-server.js.map +1 -0
  38. package/dist/admin/mockttp-schema.d.ts +2 -0
  39. package/dist/admin/mockttp-schema.d.ts.map +1 -0
  40. package/dist/admin/mockttp-schema.js +225 -0
  41. package/dist/admin/mockttp-schema.js.map +1 -0
  42. package/dist/client/admin-client.d.ts +112 -0
  43. package/dist/client/admin-client.d.ts.map +1 -0
  44. package/dist/client/admin-client.js +511 -0
  45. package/dist/client/admin-client.js.map +1 -0
  46. package/dist/client/admin-query.d.ts +13 -0
  47. package/dist/client/admin-query.d.ts.map +1 -0
  48. package/dist/client/admin-query.js +26 -0
  49. package/dist/client/admin-query.js.map +1 -0
  50. package/dist/client/mocked-endpoint-client.d.ts +12 -0
  51. package/dist/client/mocked-endpoint-client.d.ts.map +1 -0
  52. package/dist/client/mocked-endpoint-client.js +33 -0
  53. package/dist/client/mocked-endpoint-client.js.map +1 -0
  54. package/dist/client/mockttp-admin-request-builder.d.ts +38 -0
  55. package/dist/client/mockttp-admin-request-builder.d.ts.map +1 -0
  56. package/dist/client/mockttp-admin-request-builder.js +462 -0
  57. package/dist/client/mockttp-admin-request-builder.js.map +1 -0
  58. package/dist/client/mockttp-client.d.ts +56 -0
  59. package/dist/client/mockttp-client.d.ts.map +1 -0
  60. package/dist/client/mockttp-client.js +112 -0
  61. package/dist/client/mockttp-client.js.map +1 -0
  62. package/dist/client/schema-introspection.d.ts +11 -0
  63. package/dist/client/schema-introspection.d.ts.map +1 -0
  64. package/dist/client/schema-introspection.js +128 -0
  65. package/dist/client/schema-introspection.js.map +1 -0
  66. package/dist/main.browser.d.ts +49 -0
  67. package/dist/main.browser.d.ts.map +1 -0
  68. package/dist/main.browser.js +57 -0
  69. package/dist/main.browser.js.map +1 -0
  70. package/dist/main.d.ts +86 -0
  71. package/dist/main.d.ts.map +1 -0
  72. package/dist/main.js +108 -0
  73. package/dist/main.js.map +1 -0
  74. package/dist/mockttp.d.ts +774 -0
  75. package/dist/mockttp.d.ts.map +1 -0
  76. package/dist/mockttp.js +81 -0
  77. package/dist/mockttp.js.map +1 -0
  78. package/dist/pluggable-admin-api/mockttp-pluggable-admin.browser.d.ts +5 -0
  79. package/dist/pluggable-admin-api/mockttp-pluggable-admin.browser.d.ts.map +1 -0
  80. package/dist/pluggable-admin-api/mockttp-pluggable-admin.browser.js +12 -0
  81. package/dist/pluggable-admin-api/mockttp-pluggable-admin.browser.js.map +1 -0
  82. package/dist/pluggable-admin-api/mockttp-pluggable-admin.d.ts +8 -0
  83. package/dist/pluggable-admin-api/mockttp-pluggable-admin.d.ts.map +1 -0
  84. package/dist/pluggable-admin-api/mockttp-pluggable-admin.js +13 -0
  85. package/dist/pluggable-admin-api/mockttp-pluggable-admin.js.map +1 -0
  86. package/dist/pluggable-admin-api/pluggable-admin.browser.d.ts +6 -0
  87. package/dist/pluggable-admin-api/pluggable-admin.browser.d.ts.map +1 -0
  88. package/dist/pluggable-admin-api/pluggable-admin.browser.js +13 -0
  89. package/dist/pluggable-admin-api/pluggable-admin.browser.js.map +1 -0
  90. package/dist/pluggable-admin-api/pluggable-admin.d.ts +18 -0
  91. package/dist/pluggable-admin-api/pluggable-admin.d.ts.map +1 -0
  92. package/dist/pluggable-admin-api/pluggable-admin.js +20 -0
  93. package/dist/pluggable-admin-api/pluggable-admin.js.map +1 -0
  94. package/dist/rules/base-rule-builder.d.ts +185 -0
  95. package/dist/rules/base-rule-builder.d.ts.map +1 -0
  96. package/dist/rules/base-rule-builder.js +251 -0
  97. package/dist/rules/base-rule-builder.js.map +1 -0
  98. package/dist/rules/completion-checkers.d.ts +41 -0
  99. package/dist/rules/completion-checkers.d.ts.map +1 -0
  100. package/dist/rules/completion-checkers.js +87 -0
  101. package/dist/rules/completion-checkers.js.map +1 -0
  102. package/dist/rules/http-agents.d.ts +11 -0
  103. package/dist/rules/http-agents.d.ts.map +1 -0
  104. package/dist/rules/http-agents.js +91 -0
  105. package/dist/rules/http-agents.js.map +1 -0
  106. package/dist/rules/matchers.d.ts +214 -0
  107. package/dist/rules/matchers.d.ts.map +1 -0
  108. package/dist/rules/matchers.js +515 -0
  109. package/dist/rules/matchers.js.map +1 -0
  110. package/dist/rules/passthrough-handling-definitions.d.ts +106 -0
  111. package/dist/rules/passthrough-handling-definitions.d.ts.map +1 -0
  112. package/dist/rules/passthrough-handling-definitions.js +3 -0
  113. package/dist/rules/passthrough-handling-definitions.js.map +1 -0
  114. package/dist/rules/passthrough-handling.d.ts +33 -0
  115. package/dist/rules/passthrough-handling.d.ts.map +1 -0
  116. package/dist/rules/passthrough-handling.js +294 -0
  117. package/dist/rules/passthrough-handling.js.map +1 -0
  118. package/dist/rules/proxy-config.d.ts +76 -0
  119. package/dist/rules/proxy-config.d.ts.map +1 -0
  120. package/dist/rules/proxy-config.js +48 -0
  121. package/dist/rules/proxy-config.js.map +1 -0
  122. package/dist/rules/requests/request-handler-definitions.d.ts +600 -0
  123. package/dist/rules/requests/request-handler-definitions.d.ts.map +1 -0
  124. package/dist/rules/requests/request-handler-definitions.js +423 -0
  125. package/dist/rules/requests/request-handler-definitions.js.map +1 -0
  126. package/dist/rules/requests/request-handlers.d.ts +65 -0
  127. package/dist/rules/requests/request-handlers.d.ts.map +1 -0
  128. package/dist/rules/requests/request-handlers.js +1014 -0
  129. package/dist/rules/requests/request-handlers.js.map +1 -0
  130. package/dist/rules/requests/request-rule-builder.d.ts +255 -0
  131. package/dist/rules/requests/request-rule-builder.d.ts.map +1 -0
  132. package/dist/rules/requests/request-rule-builder.js +340 -0
  133. package/dist/rules/requests/request-rule-builder.js.map +1 -0
  134. package/dist/rules/requests/request-rule.d.ts +36 -0
  135. package/dist/rules/requests/request-rule.d.ts.map +1 -0
  136. package/dist/rules/requests/request-rule.js +100 -0
  137. package/dist/rules/requests/request-rule.js.map +1 -0
  138. package/dist/rules/rule-deserialization.d.ts +8 -0
  139. package/dist/rules/rule-deserialization.d.ts.map +1 -0
  140. package/dist/rules/rule-deserialization.js +27 -0
  141. package/dist/rules/rule-deserialization.js.map +1 -0
  142. package/dist/rules/rule-parameters.d.ts +21 -0
  143. package/dist/rules/rule-parameters.d.ts.map +1 -0
  144. package/dist/rules/rule-parameters.js +31 -0
  145. package/dist/rules/rule-parameters.js.map +1 -0
  146. package/dist/rules/rule-serialization.d.ts +7 -0
  147. package/dist/rules/rule-serialization.d.ts.map +1 -0
  148. package/dist/rules/rule-serialization.js +25 -0
  149. package/dist/rules/rule-serialization.js.map +1 -0
  150. package/dist/rules/websockets/websocket-handler-definitions.d.ts +78 -0
  151. package/dist/rules/websockets/websocket-handler-definitions.d.ts.map +1 -0
  152. package/dist/rules/websockets/websocket-handler-definitions.js +118 -0
  153. package/dist/rules/websockets/websocket-handler-definitions.js.map +1 -0
  154. package/dist/rules/websockets/websocket-handlers.d.ts +39 -0
  155. package/dist/rules/websockets/websocket-handlers.d.ts.map +1 -0
  156. package/dist/rules/websockets/websocket-handlers.js +356 -0
  157. package/dist/rules/websockets/websocket-handlers.js.map +1 -0
  158. package/dist/rules/websockets/websocket-rule-builder.d.ts +173 -0
  159. package/dist/rules/websockets/websocket-rule-builder.d.ts.map +1 -0
  160. package/dist/rules/websockets/websocket-rule-builder.js +232 -0
  161. package/dist/rules/websockets/websocket-rule-builder.js.map +1 -0
  162. package/dist/rules/websockets/websocket-rule.d.ts +34 -0
  163. package/dist/rules/websockets/websocket-rule.d.ts.map +1 -0
  164. package/dist/rules/websockets/websocket-rule.js +87 -0
  165. package/dist/rules/websockets/websocket-rule.js.map +1 -0
  166. package/dist/serialization/body-serialization.d.ts +43 -0
  167. package/dist/serialization/body-serialization.d.ts.map +1 -0
  168. package/dist/serialization/body-serialization.js +70 -0
  169. package/dist/serialization/body-serialization.js.map +1 -0
  170. package/dist/serialization/serialization.d.ts +63 -0
  171. package/dist/serialization/serialization.d.ts.map +1 -0
  172. package/dist/serialization/serialization.js +263 -0
  173. package/dist/serialization/serialization.js.map +1 -0
  174. package/dist/server/http-combo-server.d.ts +13 -0
  175. package/dist/server/http-combo-server.d.ts.map +1 -0
  176. package/dist/server/http-combo-server.js +330 -0
  177. package/dist/server/http-combo-server.js.map +1 -0
  178. package/dist/server/mocked-endpoint.d.ts +14 -0
  179. package/dist/server/mocked-endpoint.d.ts.map +1 -0
  180. package/dist/server/mocked-endpoint.js +40 -0
  181. package/dist/server/mocked-endpoint.js.map +1 -0
  182. package/dist/server/mockttp-server.d.ts +87 -0
  183. package/dist/server/mockttp-server.d.ts.map +1 -0
  184. package/dist/server/mockttp-server.js +859 -0
  185. package/dist/server/mockttp-server.js.map +1 -0
  186. package/dist/types.d.ts +359 -0
  187. package/dist/types.d.ts.map +1 -0
  188. package/dist/types.js +20 -0
  189. package/dist/types.js.map +1 -0
  190. package/dist/util/buffer-utils.d.ts +13 -0
  191. package/dist/util/buffer-utils.d.ts.map +1 -0
  192. package/dist/util/buffer-utils.js +141 -0
  193. package/dist/util/buffer-utils.js.map +1 -0
  194. package/dist/util/dns.d.ts +11 -0
  195. package/dist/util/dns.d.ts.map +1 -0
  196. package/dist/util/dns.js +47 -0
  197. package/dist/util/dns.js.map +1 -0
  198. package/dist/util/error.d.ts +9 -0
  199. package/dist/util/error.d.ts.map +1 -0
  200. package/dist/util/error.js +11 -0
  201. package/dist/util/error.js.map +1 -0
  202. package/dist/util/header-utils.d.ts +35 -0
  203. package/dist/util/header-utils.d.ts.map +1 -0
  204. package/dist/util/header-utils.js +200 -0
  205. package/dist/util/header-utils.js.map +1 -0
  206. package/dist/util/openssl-compat.d.ts +2 -0
  207. package/dist/util/openssl-compat.d.ts.map +1 -0
  208. package/dist/util/openssl-compat.js +26 -0
  209. package/dist/util/openssl-compat.js.map +1 -0
  210. package/dist/util/promise.d.ts +10 -0
  211. package/dist/util/promise.d.ts.map +1 -0
  212. package/dist/util/promise.js +25 -0
  213. package/dist/util/promise.js.map +1 -0
  214. package/dist/util/request-utils.d.ts +46 -0
  215. package/dist/util/request-utils.d.ts.map +1 -0
  216. package/dist/util/request-utils.js +462 -0
  217. package/dist/util/request-utils.js.map +1 -0
  218. package/dist/util/server-utils.d.ts +2 -0
  219. package/dist/util/server-utils.d.ts.map +1 -0
  220. package/dist/util/server-utils.js +14 -0
  221. package/dist/util/server-utils.js.map +1 -0
  222. package/dist/util/socket-util.d.ts +28 -0
  223. package/dist/util/socket-util.d.ts.map +1 -0
  224. package/dist/util/socket-util.js +174 -0
  225. package/dist/util/socket-util.js.map +1 -0
  226. package/dist/util/tls.d.ts +68 -0
  227. package/dist/util/tls.d.ts.map +1 -0
  228. package/dist/util/tls.js +220 -0
  229. package/dist/util/tls.js.map +1 -0
  230. package/dist/util/type-utils.d.ts +14 -0
  231. package/dist/util/type-utils.d.ts.map +1 -0
  232. package/dist/util/type-utils.js +3 -0
  233. package/dist/util/type-utils.js.map +1 -0
  234. package/dist/util/url.d.ts +17 -0
  235. package/dist/util/url.d.ts.map +1 -0
  236. package/dist/util/url.js +96 -0
  237. package/dist/util/url.js.map +1 -0
  238. package/dist/util/util.d.ts +8 -0
  239. package/dist/util/util.d.ts.map +1 -0
  240. package/dist/util/util.js +41 -0
  241. package/dist/util/util.js.map +1 -0
  242. package/docs/api-docs-landing-page.md +11 -0
  243. package/docs/runkitExample.js +16 -0
  244. package/docs/setup.md +136 -0
  245. package/nfyb8qx5.cjs +1 -0
  246. package/package.json +194 -4
  247. package/src/admin/admin-bin.ts +62 -0
  248. package/src/admin/admin-plugin-types.ts +29 -0
  249. package/src/admin/admin-server.ts +619 -0
  250. package/src/admin/graphql-utils.ts +28 -0
  251. package/src/admin/mockttp-admin-model.ts +264 -0
  252. package/src/admin/mockttp-admin-plugin.ts +59 -0
  253. package/src/admin/mockttp-admin-server.ts +27 -0
  254. package/src/admin/mockttp-schema.ts +222 -0
  255. package/src/client/admin-client.ts +652 -0
  256. package/src/client/admin-query.ts +52 -0
  257. package/src/client/mocked-endpoint-client.ts +32 -0
  258. package/src/client/mockttp-admin-request-builder.ts +540 -0
  259. package/src/client/mockttp-client.ts +178 -0
  260. package/src/client/schema-introspection.ts +131 -0
  261. package/src/main.browser.ts +60 -0
  262. package/src/main.ts +160 -0
  263. package/src/mockttp.ts +926 -0
  264. package/src/pluggable-admin-api/mockttp-pluggable-admin.browser.ts +7 -0
  265. package/src/pluggable-admin-api/mockttp-pluggable-admin.ts +13 -0
  266. package/src/pluggable-admin-api/pluggable-admin.browser.ts +9 -0
  267. package/src/pluggable-admin-api/pluggable-admin.ts +36 -0
  268. package/src/rules/base-rule-builder.ts +312 -0
  269. package/src/rules/completion-checkers.ts +90 -0
  270. package/src/rules/http-agents.ts +119 -0
  271. package/src/rules/matchers.ts +665 -0
  272. package/src/rules/passthrough-handling-definitions.ts +111 -0
  273. package/src/rules/passthrough-handling.ts +376 -0
  274. package/src/rules/proxy-config.ts +136 -0
  275. package/src/rules/requests/request-handler-definitions.ts +1089 -0
  276. package/src/rules/requests/request-handlers.ts +1369 -0
  277. package/src/rules/requests/request-rule-builder.ts +481 -0
  278. package/src/rules/requests/request-rule.ts +148 -0
  279. package/src/rules/rule-deserialization.ts +55 -0
  280. package/src/rules/rule-parameters.ts +41 -0
  281. package/src/rules/rule-serialization.ts +29 -0
  282. package/src/rules/websockets/websocket-handler-definitions.ts +196 -0
  283. package/src/rules/websockets/websocket-handlers.ts +509 -0
  284. package/src/rules/websockets/websocket-rule-builder.ts +275 -0
  285. package/src/rules/websockets/websocket-rule.ts +136 -0
  286. package/src/serialization/body-serialization.ts +84 -0
  287. package/src/serialization/serialization.ts +373 -0
  288. package/src/server/http-combo-server.ts +424 -0
  289. package/src/server/mocked-endpoint.ts +44 -0
  290. package/src/server/mockttp-server.ts +1110 -0
  291. package/src/types.ts +433 -0
  292. package/src/util/buffer-utils.ts +164 -0
  293. package/src/util/dns.ts +52 -0
  294. package/src/util/error.ts +18 -0
  295. package/src/util/header-utils.ts +220 -0
  296. package/src/util/openssl-compat.ts +26 -0
  297. package/src/util/promise.ts +31 -0
  298. package/src/util/request-utils.ts +607 -0
  299. package/src/util/server-utils.ts +18 -0
  300. package/src/util/socket-util.ts +193 -0
  301. package/src/util/tls.ts +348 -0
  302. package/src/util/type-utils.ts +15 -0
  303. package/src/util/url.ts +113 -0
  304. package/src/util/util.ts +39 -0
@@ -0,0 +1,275 @@
1
+ import { MockedEndpoint, Headers } from "../../types";
2
+ import type { WebSocketRuleData } from "./websocket-rule";
3
+
4
+ import {
5
+ PassThroughWebSocketHandlerDefinition,
6
+ TimeoutHandlerDefinition,
7
+ CloseConnectionHandlerDefinition,
8
+ ResetConnectionHandlerDefinition,
9
+ PassThroughWebSocketHandlerOptions,
10
+ RejectWebSocketHandlerDefinition,
11
+ EchoWebSocketHandlerDefinition,
12
+ ListenWebSocketHandlerDefinition
13
+ } from './websocket-handler-definitions';
14
+
15
+ import { BaseRuleBuilder } from "../base-rule-builder";
16
+ import { WildcardMatcher } from "../matchers";
17
+
18
+ /**
19
+ * @class WebSocketRuleBuilder
20
+
21
+ * A builder for defining websocket mock rules. Create one using
22
+ * `.forAnyWebSocket(path)` on a Mockttp instance, then call whatever
23
+ * methods you'd like here to define more precise matching behaviour,
24
+ * control how the connection is handled, and how many times this
25
+ * rule should be applied.
26
+ *
27
+ * When you're done, call a `.thenX()` method to register the configured rule
28
+ * with the server. These return a promise for a MockedEndpoint, which can be
29
+ * used to verify the details of the requests matched by the rule.
30
+ *
31
+ * This returns a promise because rule registration can be asynchronous,
32
+ * either when using a remote server or testing in the browser. Wait for the
33
+ * promise returned by `.thenX()` methods to guarantee that the rule has taken
34
+ * effect before sending requests to it.
35
+ */
36
+ export class WebSocketRuleBuilder extends BaseRuleBuilder {
37
+
38
+ /**
39
+ * Mock rule builders should be constructed through the Mockttp instance you're
40
+ * using, not directly. You shouldn't ever need to call this constructor.
41
+ */
42
+ constructor(
43
+ private addRule: (rule: WebSocketRuleData) => Promise<MockedEndpoint>
44
+ ) {
45
+ super();
46
+
47
+ // By default, websockets just match everything:
48
+ this.matchers.push(new WildcardMatcher());
49
+ }
50
+
51
+ /**
52
+ * Pass matched websockets through to their real destination. This works
53
+ * for proxied requests only, and direct requests will be rejected with
54
+ * an error.
55
+ *
56
+ * This method takes options to configure how the request is passed
57
+ * through. See {@link PassThroughWebSocketHandlerOptions} for the full
58
+ * details of the options available.
59
+ *
60
+ * Calling this method registers the rule with the server, so it
61
+ * starts to handle requests.
62
+ *
63
+ * This method returns a promise that resolves with a mocked endpoint.
64
+ * Wait for the promise to confirm that the rule has taken effect
65
+ * before sending requests to be matched. The mocked endpoint
66
+ * can be used to assert on the requests matched by this rule.
67
+ *
68
+ * @category Responses
69
+ */
70
+ thenPassThrough(options: PassThroughWebSocketHandlerOptions = {}): Promise<MockedEndpoint> {
71
+ const rule: WebSocketRuleData = {
72
+ ...this.buildBaseRuleData(),
73
+ handler: new PassThroughWebSocketHandlerDefinition(options)
74
+ };
75
+
76
+ return this.addRule(rule);
77
+ }
78
+
79
+ /**
80
+ * Forward matched websockets on to the specified forwardToUrl. The url
81
+ * specified must not include a path or an error will be thrown.
82
+ * The path portion of the original request url is used instead.
83
+ *
84
+ * The url may optionally contain a protocol. If it does, it will override
85
+ * the protocol (and potentially the port, if unspecified) of the request.
86
+ * If no protocol is specified, the protocol (and potentially the port)
87
+ * of the original request URL will be used instead.
88
+ *
89
+ * This method takes options to configure how the request is passed
90
+ * through. See {@link PassThroughWebSocketHandlerOptions} for the full
91
+ * details of the options available.
92
+ *
93
+ * Calling this method registers the rule with the server, so it
94
+ * starts to handle requests.
95
+ *
96
+ * This method returns a promise that resolves with a mocked endpoint.
97
+ * Wait for the promise to confirm that the rule has taken effect
98
+ * before sending requests to be matched. The mocked endpoint
99
+ * can be used to assert on the requests matched by this rule.
100
+ *
101
+ * @category Responses
102
+ */
103
+ async thenForwardTo(
104
+ forwardToLocation: string,
105
+ options: Omit<PassThroughWebSocketHandlerOptions, 'forwarding'> & {
106
+ forwarding?: Omit<PassThroughWebSocketHandlerOptions['forwarding'], 'targetHost'>
107
+ } = {}
108
+ ): Promise<MockedEndpoint> {
109
+ const rule: WebSocketRuleData = {
110
+ ...this.buildBaseRuleData(),
111
+ handler: new PassThroughWebSocketHandlerDefinition({
112
+ ...options,
113
+ forwarding: {
114
+ ...options.forwarding,
115
+ targetHost: forwardToLocation
116
+ }
117
+ })
118
+ };
119
+
120
+ return this.addRule(rule);
121
+ }
122
+
123
+ /**
124
+ * Accept incoming WebSocket connections, and echo every message
125
+ * received on the WebSocket back to the client.
126
+ *
127
+ * Calling this method registers the rule with the server, so it
128
+ * starts to handle requests.
129
+ *
130
+ * This method returns a promise that resolves with a mocked endpoint.
131
+ * Wait for the promise to confirm that the rule has taken effect
132
+ * before sending requests to be matched. The mocked endpoint
133
+ * can be used to assert on the requests matched by this rule.
134
+ *
135
+ * @category Responses
136
+ */
137
+ thenEcho(): Promise<MockedEndpoint> {
138
+ const rule: WebSocketRuleData = {
139
+ ...this.buildBaseRuleData(),
140
+ handler: new EchoWebSocketHandlerDefinition()
141
+ };
142
+
143
+ return this.addRule(rule);
144
+ }
145
+
146
+ /**
147
+ * Accept incoming WebSocket connections, and simply listen to
148
+ * incoming messages without ever sending anything in return.
149
+ *
150
+ * Calling this method registers the rule with the server, so it
151
+ * starts to handle requests.
152
+ *
153
+ * This method returns a promise that resolves with a mocked endpoint.
154
+ * Wait for the promise to confirm that the rule has taken effect
155
+ * before sending requests to be matched. The mocked endpoint
156
+ * can be used to assert on the requests matched by this rule.
157
+ *
158
+ * @category Responses
159
+ */
160
+ thenPassivelyListen(): Promise<MockedEndpoint> {
161
+ const rule: WebSocketRuleData = {
162
+ ...this.buildBaseRuleData(),
163
+ handler: new ListenWebSocketHandlerDefinition()
164
+ };
165
+
166
+ return this.addRule(rule);
167
+ }
168
+
169
+ /**
170
+ * Rejects connections, sending an HTTP response with the given
171
+ * status, message and body, to explicitly refuse the WebSocket
172
+ * handshake.
173
+ *
174
+ * Calling this method registers the rule with the server, so it
175
+ * starts to handle requests.
176
+ *
177
+ * This method returns a promise that resolves with a mocked endpoint.
178
+ * Wait for the promise to confirm that the rule has taken effect
179
+ * before sending requests to be matched. The mocked endpoint
180
+ * can be used to assert on the requests matched by this rule.
181
+ *
182
+ * @category Responses
183
+ */
184
+ thenRejectConnection(
185
+ statusCode: number,
186
+ statusMessage?: string,
187
+ headers?: Headers,
188
+ body?: Buffer | string
189
+ ): Promise<MockedEndpoint> {
190
+ const rule: WebSocketRuleData = {
191
+ ...this.buildBaseRuleData(),
192
+ handler: new RejectWebSocketHandlerDefinition(
193
+ statusCode,
194
+ statusMessage,
195
+ headers,
196
+ body
197
+ )
198
+ };
199
+
200
+ return this.addRule(rule);
201
+ }
202
+
203
+ /**
204
+ * Close connections that match this rule immediately, without accepting
205
+ * the socket or sending any other response.
206
+ *
207
+ * Calling this method registers the rule with the server, so it
208
+ * starts to handle requests.
209
+ *
210
+ * This method returns a promise that resolves with a mocked endpoint.
211
+ * Wait for the promise to confirm that the rule has taken effect
212
+ * before sending requests to be matched. The mocked endpoint
213
+ * can be used to assert on the requests matched by this rule.
214
+ *
215
+ * @category Responses
216
+ */
217
+ thenCloseConnection(): Promise<MockedEndpoint> {
218
+ const rule: WebSocketRuleData = {
219
+ ...this.buildBaseRuleData(),
220
+ handler: new CloseConnectionHandlerDefinition()
221
+ };
222
+
223
+ return this.addRule(rule);
224
+ }
225
+
226
+ /**
227
+ * Reset connections that match this rule immediately, sending a TCP
228
+ * RST packet directly, without accepting the socket or sending any
229
+ * other response, and without cleanly closing the TCP connection.
230
+ *
231
+ * This is only supported in Node.js versions (>=16.17, >=18.3.0, or
232
+ * later), where `net.Socket` includes the `resetAndDestroy` method.
233
+ *
234
+ * Calling this method registers the rule with the server, so it
235
+ * starts to handle requests.
236
+ *
237
+ * This method returns a promise that resolves with a mocked endpoint.
238
+ * Wait for the promise to confirm that the rule has taken effect
239
+ * before sending requests to be matched. The mocked endpoint
240
+ * can be used to assert on the requests matched by this rule.
241
+ *
242
+ * @category Responses
243
+ */
244
+ thenResetConnection(): Promise<MockedEndpoint> {
245
+ const rule: WebSocketRuleData = {
246
+ ...this.buildBaseRuleData(),
247
+ handler: new ResetConnectionHandlerDefinition()
248
+ };
249
+
250
+ return this.addRule(rule);
251
+ }
252
+
253
+ /**
254
+ * Hold open connections that match this rule, but never respond
255
+ * with anything at all, typically causing a timeout on the client side.
256
+ *
257
+ * Calling this method registers the rule with the server, so it
258
+ * starts to handle requests.
259
+ *
260
+ * This method returns a promise that resolves with a mocked endpoint.
261
+ * Wait for the promise to confirm that the rule has taken effect
262
+ * before sending requests to be matched. The mocked endpoint
263
+ * can be used to assert on the requests matched by this rule.
264
+ *
265
+ * @category Responses
266
+ */
267
+ thenTimeout(): Promise<MockedEndpoint> {
268
+ const rule: WebSocketRuleData = {
269
+ ...this.buildBaseRuleData(),
270
+ handler: new TimeoutHandlerDefinition()
271
+ };
272
+
273
+ return this.addRule(rule);
274
+ }
275
+ }
@@ -0,0 +1,136 @@
1
+ import * as _ from 'lodash';
2
+ import { v4 as uuid } from "uuid";
3
+ import * as net from 'net';
4
+ import * as http from 'http';
5
+
6
+ import {
7
+ OngoingRequest,
8
+ CompletedRequest,
9
+ Explainable,
10
+ RulePriority
11
+ } from "../../types";
12
+ import { waitForCompletedRequest } from '../../util/request-utils';
13
+ import { MaybePromise } from '../../util/type-utils';
14
+
15
+ import { validateMockRuleData } from '../rule-serialization';
16
+
17
+ import * as matchers from "../matchers";
18
+ import * as completionCheckers from "../completion-checkers";
19
+ import { WebSocketHandler, WsHandlerLookup } from "./websocket-handlers";
20
+ import type { WebSocketHandlerDefinition } from "./websocket-handler-definitions";
21
+
22
+ // The internal representation of a mocked endpoint
23
+ export interface WebSocketRule extends Explainable {
24
+ id: string;
25
+ requests: Promise<CompletedRequest>[];
26
+
27
+ // We don't extend the main interfaces for these, because MockRules are not Serializable
28
+ matches(request: OngoingRequest): MaybePromise<boolean>;
29
+ handle(request: OngoingRequest, response: net.Socket, head: Buffer, record: boolean): Promise<void>;
30
+ isComplete(): boolean | null;
31
+ }
32
+
33
+ export interface WebSocketRuleData {
34
+ id?: string;
35
+ priority?: number; // Higher is higher, by default 0 is fallback, 1 is normal, must be positive
36
+ matchers: matchers.RequestMatcher[];
37
+ handler: WebSocketHandler | WebSocketHandlerDefinition;
38
+ completionChecker?: completionCheckers.RuleCompletionChecker;
39
+ }
40
+
41
+ export class WebSocketRule implements WebSocketRule {
42
+ private matchers: matchers.RequestMatcher[];
43
+ private handler: WebSocketHandler;
44
+ private completionChecker?: completionCheckers.RuleCompletionChecker;
45
+
46
+ public id: string;
47
+ public readonly priority: number;
48
+ public requests: Promise<CompletedRequest>[] = [];
49
+ public requestCount = 0;
50
+
51
+ constructor(data: WebSocketRuleData) {
52
+ validateMockRuleData(data);
53
+
54
+ this.id = data.id || uuid();
55
+ this.priority = data.priority ?? RulePriority.DEFAULT;
56
+ this.matchers = data.matchers;
57
+ if ('handle' in data.handler) {
58
+ this.handler = data.handler;
59
+ } else {
60
+ // We transform the definition into a real handler, by creating an raw instance of the handler (which is
61
+ // a subtype of the definition with the same constructor) and copying the fields across.
62
+ this.handler = Object.assign(
63
+ Object.create(WsHandlerLookup[data.handler.type].prototype),
64
+ data.handler
65
+ );
66
+ }
67
+ this.completionChecker = data.completionChecker;
68
+ }
69
+
70
+ matches(request: OngoingRequest) {
71
+ return matchers.matchesAll(request, this.matchers);
72
+ }
73
+
74
+ handle(req: OngoingRequest, res: net.Socket, head: Buffer, record: boolean): Promise<void> {
75
+ let handlerPromise = (async () => { // Catch (a)sync errors
76
+ return this.handler.handle(req as OngoingRequest & http.IncomingMessage, res, head);
77
+ })();
78
+
79
+ // Requests are added to rule.requests as soon as they start being handled,
80
+ // as promises, which resolve only when the response & request body is complete.
81
+ if (record) {
82
+ this.requests.push(
83
+ Promise.race([
84
+ // When the handler resolves, the request is completed:
85
+ handlerPromise,
86
+ // If the response is closed before the handler completes (due to aborts, handler
87
+ // timeouts, whatever) then that also counts as the request being completed:
88
+ new Promise((resolve) => res.on('close', resolve))
89
+ ])
90
+ .catch(() => {}) // Ignore handler errors here - we're only tracking the request
91
+ .then(() => waitForCompletedRequest(req))
92
+ );
93
+ }
94
+
95
+ // Even if traffic recording is disabled, the number of matched
96
+ // requests is still tracked
97
+ this.requestCount += 1;
98
+
99
+ return handlerPromise as Promise<any>;
100
+ }
101
+
102
+ isComplete(): boolean | null {
103
+ if (this.completionChecker) {
104
+ // If we have a specific rule, use that
105
+ return this.completionChecker.isComplete(this.requestCount);
106
+ } else if (this.requestCount === 0) {
107
+ // Otherwise, by default we're definitely incomplete if we've seen no requests
108
+ return false;
109
+ } else {
110
+ // And we're _maybe_ complete if we've seen at least one request. In reality, we're incomplete
111
+ // but we should be used anyway if we're at any point we're the last matching rule for a request.
112
+ return null;
113
+ }
114
+ }
115
+
116
+ explain(withoutExactCompletion = false): string {
117
+ let explanation = `Match websockets ${matchers.explainMatchers(this.matchers)}, ` +
118
+ `and then ${this.handler.explain()}`;
119
+
120
+ if (this.completionChecker) {
121
+ explanation += `, ${this.completionChecker.explain(
122
+ withoutExactCompletion ? undefined : this.requestCount
123
+ )}.`;
124
+ } else {
125
+ explanation += '.';
126
+ }
127
+
128
+ return explanation;
129
+ }
130
+
131
+ dispose() {
132
+ this.handler.dispose();
133
+ this.matchers.forEach(m => m.dispose());
134
+ if (this.completionChecker) this.completionChecker.dispose();
135
+ }
136
+ }
@@ -0,0 +1,84 @@
1
+ import * as _ from 'lodash';
2
+ import { encode as encodeBase64 } from 'base64-arraybuffer';
3
+
4
+ import { CompletedBody, Headers } from "../types";
5
+ import { asBuffer } from "../util/buffer-utils";
6
+ import { buildBodyReader, isMockttpBody } from "../util/request-utils";
7
+ import { Replace } from "../util/type-utils";
8
+
9
+ import { deserializeBuffer, serializeBuffer } from "./serialization";
10
+
11
+ export function withSerializedBodyReader<T extends {
12
+ body: CompletedBody
13
+ }>(input: T): Replace<T, { body: string }> {
14
+ return {
15
+ ...input,
16
+ body: asBuffer(input.body.buffer).toString('base64')
17
+ };
18
+ }
19
+
20
+ export function withDeserializedBodyReader<T extends { headers: Headers, body: CompletedBody }>(
21
+ input: Replace<T, { body: string }>
22
+ ): T {
23
+ return {
24
+ ...input,
25
+ body: buildBodyReader(deserializeBuffer(input.body), input.headers)
26
+ } as T;
27
+ }
28
+
29
+ /**
30
+ * Serialize a callback result (callback handlers, BeforeRequest/Response etc)
31
+ * to transform all the many possible buffer formats into either base64-encoded
32
+ * buffer data, or undefined.
33
+ */
34
+ export function withSerializedCallbackBuffers<T extends {
35
+ body?: CompletedBody | Buffer | Uint8Array | ArrayBuffer | string,
36
+ rawBody?: Buffer | Uint8Array
37
+ }>(input: T): Replace<T, { body: string | undefined }> {
38
+ let serializedBody: string | undefined;
39
+
40
+ if (!input.body) {
41
+ serializedBody = undefined;
42
+ } else if (_.isString(input.body)) {
43
+ serializedBody = serializeBuffer(asBuffer(input.body));
44
+ } else if (_.isBuffer(input.body)) {
45
+ serializedBody = serializeBuffer(input.body as Buffer);
46
+ } else if (_.isArrayBuffer(input.body) || _.isTypedArray(input.body)) {
47
+ serializedBody = encodeBase64(input.body as ArrayBuffer);
48
+ } else if (isMockttpBody(input.body)) {
49
+ serializedBody = serializeBuffer(asBuffer(input.body.buffer));
50
+ }
51
+
52
+ return {
53
+ ...input,
54
+ body: serializedBody,
55
+ rawBody: input.rawBody
56
+ ? serializeBuffer(asBuffer(input.rawBody))
57
+ : undefined
58
+ };
59
+ }
60
+
61
+ export type WithSerializedCallbackBuffers<T extends { body?: any }> =
62
+ Replace<T, { body?: string, rawBody?: string }>;
63
+
64
+ /**
65
+ * Deserialize a callback result (callback handlers, BeforeRequest/Response etc)
66
+ * to build buffer data (or undefined) from the base64-serialized data
67
+ * produced by withSerializedCallbackBuffers
68
+ */
69
+ export function withDeserializedCallbackBuffers<T extends {
70
+ body?: Buffer | Uint8Array | string,
71
+ rawBody?: Buffer | Uint8Array
72
+ }>(
73
+ input: Replace<T, { body?: string, rawBody?: string }>
74
+ ): T {
75
+ return {
76
+ ...input,
77
+ body: input.body !== undefined
78
+ ? Buffer.from(input.body, 'base64')
79
+ : undefined,
80
+ rawBody: input.rawBody !== undefined
81
+ ? Buffer.from(input.rawBody, 'base64')
82
+ : undefined
83
+ } as T;
84
+ }