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,373 @@
1
+ import * as _ from 'lodash';
2
+ import { Duplex } from 'stream';
3
+ import { v4 as uuid } from "uuid";
4
+
5
+ import { MaybePromise } from '../util/type-utils';
6
+ import {
7
+ dereferenceParam,
8
+ isParamReference,
9
+ MOCKTTP_PARAM_REF,
10
+ RuleParameterReference,
11
+ RuleParameters
12
+ } from '../rules/rule-parameters';
13
+ import type {
14
+ ProxySetting,
15
+ ProxySettingSource,
16
+ ProxySettingCallbackParams,
17
+ ProxyConfig
18
+ } from '../rules/proxy-config';
19
+
20
+ export function serialize<T extends Serializable>(
21
+ obj: T,
22
+ stream: Duplex
23
+ ): SerializedValue<T> {
24
+ const channel = new ClientServerChannel(stream);
25
+ const data = obj.serialize(channel) as SerializedValue<T>;
26
+ data.topicId = channel.topicId;
27
+ return data;
28
+ }
29
+
30
+ export function deserialize<
31
+ T extends SerializedValue<Serializable>,
32
+ C extends {
33
+ new(...args: any): any;
34
+ deserialize(data: SerializedValue<any>, channel: ClientServerChannel, ruleParams: RuleParameters): any;
35
+ }
36
+ >(
37
+ data: T,
38
+ stream: Duplex,
39
+ ruleParams: RuleParameters,
40
+ lookup: { [key: string]: C }
41
+ ): InstanceType<C> {
42
+ const type = <keyof typeof lookup> data.type;
43
+ const channel = new ClientServerChannel(stream, data.topicId);
44
+
45
+ const deserialized = lookup[type].deserialize(data, channel, ruleParams);
46
+
47
+ // Wrap .dispose and ensure the channel is always disposed too.
48
+ const builtinDispose = deserialized.dispose;
49
+ deserialized.dispose = () => {
50
+ builtinDispose();
51
+ channel.dispose();
52
+ };
53
+
54
+ return deserialized;
55
+ }
56
+
57
+ export type SerializedValue<T> = T & { topicId: string };
58
+
59
+ // Serialized data = data + type + topicId on every prop/prop's array elements
60
+ export type Serialized<T> = {
61
+ [K in keyof T]:
62
+ T[K] extends string | undefined
63
+ ? string | undefined
64
+ : T[K] extends Array<unknown>
65
+ ? Array<SerializedValue<T[K][0]>>
66
+ : SerializedValue<T[K]>;
67
+ };
68
+
69
+ export abstract class Serializable {
70
+ abstract type: string;
71
+
72
+ /**
73
+ * @internal
74
+ */
75
+ serialize(_channel: ClientServerChannel): unknown {
76
+ // By default, we assume data is transferrable as-is
77
+ return this;
78
+ }
79
+
80
+ /**
81
+ * @internal
82
+ */
83
+ static deserialize(
84
+ data: SerializedValue<any>,
85
+ _channel: ClientServerChannel,
86
+ _ruleParams: RuleParameters
87
+ ): any {
88
+ // By default, we assume we just need to assign the right prototype
89
+ return _.create(this.prototype, data);
90
+ }
91
+
92
+ // This rule is being unregistered. Any handlers who need to cleanup when they know
93
+ // they're no longer in use should implement this and dispose accordingly.
94
+ // Only deserialized rules are disposed - if the originating rule needs
95
+ // disposing too, ping the channel and let it know.
96
+ dispose(): void { }
97
+ }
98
+
99
+ interface Message {
100
+ topicId?: string;
101
+ }
102
+
103
+ interface RequestMessage<R> {
104
+ requestId?: string;
105
+ action?: string;
106
+ error?: Error;
107
+ data?: R;
108
+ }
109
+
110
+ const DISPOSE_MESSAGE = { disposeChannel: true };
111
+
112
+ // Wraps another stream, ensuring that messages go only to the paired channel on the
113
+ // other client/server. In practice, each handler gets one end of these streams in
114
+ // their serialize/deserialize methods, and can use them to sync live data reliably.
115
+ export class ClientServerChannel extends Duplex {
116
+
117
+ public readonly topicId: string;
118
+
119
+ constructor(
120
+ private rawStream: Duplex,
121
+ topicId?: string
122
+ ) {
123
+ super({ objectMode: true });
124
+
125
+ this.topicId = topicId || uuid();
126
+ this.rawStream.on('error', this._onRawStreamError);
127
+ this.rawStream.on('finish', this._onRawStreamFinish);
128
+ }
129
+
130
+ private _onRawStreamError = (error: Error) => {
131
+ this.destroy(error);
132
+ };
133
+
134
+ private _onRawStreamFinish = () => {
135
+ this.end();
136
+ }
137
+
138
+ /**
139
+ * @internal @hidden
140
+ */
141
+ _write(message: Message, encoding: BufferEncoding, callback: (error?: Error | null) => void) {
142
+ message.topicId = this.topicId;
143
+ const chunk = JSON.stringify(message) + '\n';
144
+
145
+ if (!this.rawStream.write(chunk, encoding)) {
146
+ this.rawStream.once('drain', callback);
147
+ } else {
148
+ callback();
149
+ }
150
+ }
151
+
152
+ _readFromRawStream = (rawData: any) => {
153
+ const stringData: string = rawData.toString();
154
+ stringData.split('\n').filter(d => !!d).forEach((rawDataLine) => {
155
+ let data: Message;
156
+ try {
157
+ data = JSON.parse(rawDataLine);
158
+ } catch (e) {
159
+ console.log(e);
160
+ console.log('Received unparseable message, dropping.', rawDataLine.toString());
161
+ return;
162
+ }
163
+
164
+ if (data.topicId === this.topicId) {
165
+ if (_.isEqual(_.omit(data, 'topicId'), DISPOSE_MESSAGE)) this.dispose(true);
166
+ else this.push(data);
167
+ }
168
+ });
169
+ }
170
+
171
+ private reading = false;
172
+
173
+ _read() {
174
+ if (!this.reading) {
175
+ this.rawStream.on('data', this._readFromRawStream);
176
+ this.reading = true;
177
+ }
178
+ }
179
+
180
+ request<T extends {}, R>(data: T): Promise<R>;
181
+ request<T extends {}, R>(action: string, data: T): Promise<R>;
182
+ request<T extends {}, R>(actionOrData: string | T, dataOrNothing?: T): Promise<R> {
183
+ let action: string | undefined;
184
+ let data: T;
185
+ if (_.isString(actionOrData)) {
186
+ action = actionOrData;
187
+ data = dataOrNothing!;
188
+ } else {
189
+ data = actionOrData;
190
+ }
191
+
192
+ const requestId = uuid();
193
+
194
+ return new Promise<R>((resolve, reject) => {
195
+ const responseListener = (response: RequestMessage<R>) => {
196
+ if (response.requestId === requestId) {
197
+ if (response.error) {
198
+ // Derialize error from plain object
199
+ reject(Object.assign(new Error(), { stack: undefined }, response.error));
200
+ } else {
201
+ resolve(response.data!);
202
+ }
203
+ this.removeListener('data', responseListener);
204
+ }
205
+ }
206
+
207
+ const request: RequestMessage<T> = { data, requestId };
208
+ if (action) request.action = action;
209
+
210
+ this.write(request, (e) => {
211
+ if (e) reject(e);
212
+ else this.on('data', responseListener);
213
+ });
214
+ });
215
+ }
216
+
217
+ // Wait for requests from the other side, and respond to them
218
+ onRequest<T, R>(cb: (request: T) => MaybePromise<R>): void;
219
+ // Wait for requests with a specific { action: actionName } property, and respond
220
+ onRequest<T, R>(
221
+ actionName: string,
222
+ cb: (request: T) => MaybePromise<R>
223
+ ): void;
224
+ onRequest<T, R>(
225
+ cbOrAction: string | ((r: T) => MaybePromise<R>),
226
+ cbOrNothing?: (request: T) => MaybePromise<R>
227
+ ): void {
228
+ let actionName: string | undefined;
229
+ let cb: (request: T) => MaybePromise<R>;
230
+
231
+ if (_.isString(cbOrAction)) {
232
+ actionName = cbOrAction;
233
+ cb = cbOrNothing!;
234
+ } else {
235
+ cb = cbOrAction;
236
+ }
237
+
238
+ this.on('data', async (request: RequestMessage<T>) => {
239
+ const { requestId, action } = request;
240
+
241
+ // Filter by actionName, if set
242
+ if (actionName !== undefined && action !== actionName) return;
243
+
244
+ try {
245
+ const response = {
246
+ requestId,
247
+ data: await cb(request.data!)
248
+ };
249
+ if (!this.writable) return; // Response too slow - drop it
250
+ this.write(response);
251
+ } catch (error) {
252
+ // Make the error serializable:
253
+ error = _.pick(error, Object.getOwnPropertyNames(error));
254
+ if (!this.writable) return; // Response too slow - drop it
255
+ this.write({ requestId, error });
256
+ }
257
+ });
258
+ }
259
+
260
+ // Shuts down the channel. Only needs to be called on one side, the other side
261
+ // will be shut down automatically when it receives DISPOSE_MESSAGE.
262
+ dispose(disposeReceived: boolean = false) {
263
+ this.on('error', () => {}); // Dispose is best effort - we don't care about errors
264
+
265
+ // Only one side needs to send a dispose - we send first if we haven't seen one.
266
+ if (!disposeReceived) this.end(DISPOSE_MESSAGE);
267
+ else this.end();
268
+
269
+ // Detach any remaining onRequest handlers:
270
+ this.removeAllListeners('data');
271
+ // Stop receiving upstream messages from the global stream:
272
+ this.rawStream.removeListener('data', this._readFromRawStream);
273
+ this.rawStream.removeListener('error', this._onRawStreamError);
274
+ this.rawStream.removeListener('finish', this._onRawStreamFinish);
275
+ }
276
+ }
277
+
278
+ export function serializeBuffer(buffer: Buffer): string {
279
+ return buffer.toString('base64');
280
+ }
281
+
282
+ export function deserializeBuffer(buffer: string): Buffer {
283
+ return Buffer.from(buffer, 'base64');
284
+ }
285
+
286
+ const SERIALIZED_PARAM_REFERENCE = "__mockttp__param__reference__";
287
+ export type SerializedRuleParameterReference<R> = { [SERIALIZED_PARAM_REFERENCE]: string };
288
+
289
+ function serializeParam<R>(value: RuleParameterReference<R>): SerializedRuleParameterReference<R> {
290
+ // Swap the symbol for a string, since we can't serialize symbols in JSON:
291
+ return { [SERIALIZED_PARAM_REFERENCE]: value[MOCKTTP_PARAM_REF] };
292
+ }
293
+
294
+ function isSerializedRuleParam(value: any): value is SerializedRuleParameterReference<unknown> {
295
+ return value && SERIALIZED_PARAM_REFERENCE in value;
296
+ }
297
+
298
+ export function ensureParamsDeferenced<T>(
299
+ value: T | SerializedRuleParameterReference<T>,
300
+ ruleParams: RuleParameters
301
+ ): T {
302
+ if (isSerializedRuleParam(value)) {
303
+ const paramRef = {
304
+ [MOCKTTP_PARAM_REF]: value[SERIALIZED_PARAM_REFERENCE]
305
+ };
306
+ return dereferenceParam(paramRef, ruleParams);
307
+ } else {
308
+ return value;
309
+ }
310
+ }
311
+
312
+ export type SerializedProxyConfig =
313
+ | ProxySetting
314
+ | string // Callback id on the serialization channel
315
+ | undefined
316
+ | SerializedRuleParameterReference<ProxySettingSource>
317
+ | Array<SerializedProxyConfig>;
318
+
319
+ export function serializeProxyConfig(
320
+ proxyConfig: ProxyConfig,
321
+ channel: ClientServerChannel
322
+ ): SerializedProxyConfig {
323
+ if (_.isFunction(proxyConfig)) {
324
+ const callbackId = `proxyConfig-callback-${uuid()}`;
325
+
326
+ channel.onRequest<
327
+ ProxySettingCallbackParams,
328
+ ProxySetting | undefined
329
+ >(callbackId, proxyConfig);
330
+
331
+ return callbackId;
332
+ } else if (_.isArray(proxyConfig)) {
333
+ return proxyConfig.map((config) => serializeProxyConfig(config, channel));
334
+ } else if (isParamReference(proxyConfig)) {
335
+ return serializeParam(proxyConfig);
336
+ } else if (proxyConfig) {
337
+ return {
338
+ ...proxyConfig,
339
+ trustedCAs: proxyConfig.trustedCAs?.map((caDefinition) =>
340
+ typeof caDefinition !== 'string' && 'cert' in caDefinition
341
+ ? { cert: caDefinition.cert.toString('utf8') } // Stringify in case of buffers
342
+ : caDefinition
343
+ ),
344
+ additionalTrustedCAs: proxyConfig.additionalTrustedCAs?.map((caDefinition) =>
345
+ 'cert' in caDefinition
346
+ ? { cert: caDefinition.cert.toString('utf8') } // Stringify in case of buffers
347
+ : caDefinition
348
+ )
349
+ };
350
+ }
351
+ }
352
+
353
+ export function deserializeProxyConfig(
354
+ proxyConfig: SerializedProxyConfig,
355
+ channel: ClientServerChannel,
356
+ ruleParams: RuleParameters
357
+ ): ProxySettingSource {
358
+ if (_.isString(proxyConfig)) {
359
+ const callbackId = proxyConfig;
360
+
361
+ const proxyConfigCallback = async (options: ProxySettingCallbackParams) => {
362
+ return await channel.request<
363
+ ProxySettingCallbackParams,
364
+ ProxySetting | undefined
365
+ >(callbackId, options);
366
+ };
367
+ return proxyConfigCallback;
368
+ } else if (_.isArray(proxyConfig)) {
369
+ return proxyConfig.map((config) => deserializeProxyConfig(config, channel, ruleParams));
370
+ } else {
371
+ return ensureParamsDeferenced(proxyConfig, ruleParams);
372
+ }
373
+ }