@mbtest/mountebank 2.9.2-beta.9050

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.
Files changed (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/bin/mb +136 -0
  4. package/package.json +71 -0
  5. package/releases.json +52 -0
  6. package/src/cli/api.js +112 -0
  7. package/src/cli/cli.js +420 -0
  8. package/src/controllers/configController.js +64 -0
  9. package/src/controllers/feedController.js +115 -0
  10. package/src/controllers/homeController.js +58 -0
  11. package/src/controllers/imposterController.js +328 -0
  12. package/src/controllers/impostersController.js +215 -0
  13. package/src/controllers/logsController.js +52 -0
  14. package/src/models/behaviors.js +553 -0
  15. package/src/models/behaviorsValidator.js +186 -0
  16. package/src/models/compatibility.js +133 -0
  17. package/src/models/dryRunValidator.js +261 -0
  18. package/src/models/filesystemBackedImpostersRepository.js +908 -0
  19. package/src/models/http/baseHttpServer.js +207 -0
  20. package/src/models/http/headersMap.js +87 -0
  21. package/src/models/http/httpProxy.js +230 -0
  22. package/src/models/http/httpRequest.js +82 -0
  23. package/src/models/http/httpServer.js +18 -0
  24. package/src/models/http/index.js +18 -0
  25. package/src/models/https/cert/mb-cert.pem +20 -0
  26. package/src/models/https/cert/mb-csr.pem +16 -0
  27. package/src/models/https/cert/mb-key.pem +27 -0
  28. package/src/models/https/httpsServer.js +42 -0
  29. package/src/models/https/index.js +18 -0
  30. package/src/models/imposter.js +243 -0
  31. package/src/models/imposterPrinter.js +120 -0
  32. package/src/models/impostersRepository.js +49 -0
  33. package/src/models/inMemoryImpostersRepository.js +418 -0
  34. package/src/models/jsonpath.js +44 -0
  35. package/src/models/mbConnection.js +107 -0
  36. package/src/models/predicates.js +438 -0
  37. package/src/models/protocols.js +242 -0
  38. package/src/models/responseResolver.js +398 -0
  39. package/src/models/smtp/index.js +16 -0
  40. package/src/models/smtp/smtpRequest.js +60 -0
  41. package/src/models/smtp/smtpServer.js +109 -0
  42. package/src/models/tcp/index.js +18 -0
  43. package/src/models/tcp/tcpProxy.js +110 -0
  44. package/src/models/tcp/tcpRequest.js +23 -0
  45. package/src/models/tcp/tcpServer.js +156 -0
  46. package/src/models/tcp/tcpValidator.js +19 -0
  47. package/src/models/xpath.js +95 -0
  48. package/src/mountebank.js +245 -0
  49. package/src/public/images/arrow_down.png +0 -0
  50. package/src/public/images/arrow_up.png +0 -0
  51. package/src/public/images/book.jpg +0 -0
  52. package/src/public/images/dataflow.png +0 -0
  53. package/src/public/images/favicon.ico +0 -0
  54. package/src/public/images/forkme_right_orange_ff7600.png +0 -0
  55. package/src/public/images/mountebank.png +0 -0
  56. package/src/public/images/overview.gif +0 -0
  57. package/src/public/images/quote.png +0 -0
  58. package/src/public/images/tw-logo.png +0 -0
  59. package/src/public/scripts/jquery/jquery-3.6.1.min.js +2 -0
  60. package/src/public/scripts/urlHashHandler.js +31 -0
  61. package/src/public/stylesheets/application.css +424 -0
  62. package/src/public/stylesheets/ie.css +14 -0
  63. package/src/public/stylesheets/imposters.css +121 -0
  64. package/src/public/stylesheets/jqueryui/1.10.4/themes/smoothness/jquery-ui.css +1178 -0
  65. package/src/util/combinators.js +68 -0
  66. package/src/util/date.js +51 -0
  67. package/src/util/errors.js +55 -0
  68. package/src/util/helpers.js +131 -0
  69. package/src/util/inherit.js +28 -0
  70. package/src/util/ip.js +54 -0
  71. package/src/util/logger.js +83 -0
  72. package/src/util/middleware.js +256 -0
  73. package/src/util/scopedLogger.js +47 -0
  74. package/src/views/_footer.ejs +20 -0
  75. package/src/views/_header.ejs +113 -0
  76. package/src/views/_imposter.ejs +8 -0
  77. package/src/views/config.ejs +71 -0
  78. package/src/views/docs/api/behaviors/copy.ejs +427 -0
  79. package/src/views/docs/api/behaviors/decorate.ejs +182 -0
  80. package/src/views/docs/api/behaviors/lookup.ejs +220 -0
  81. package/src/views/docs/api/behaviors/shellTransform.ejs +153 -0
  82. package/src/views/docs/api/behaviors/wait.ejs +121 -0
  83. package/src/views/docs/api/behaviors.ejs +141 -0
  84. package/src/views/docs/api/contracts/addStub-description.ejs +10 -0
  85. package/src/views/docs/api/contracts/addStub.ejs +10 -0
  86. package/src/views/docs/api/contracts/config-description.ejs +32 -0
  87. package/src/views/docs/api/contracts/config.ejs +23 -0
  88. package/src/views/docs/api/contracts/home-description.ejs +18 -0
  89. package/src/views/docs/api/contracts/home.ejs +13 -0
  90. package/src/views/docs/api/contracts/imposter-description.ejs +439 -0
  91. package/src/views/docs/api/contracts/imposter.ejs +182 -0
  92. package/src/views/docs/api/contracts/imposters-description.ejs +13 -0
  93. package/src/views/docs/api/contracts/imposters.ejs +13 -0
  94. package/src/views/docs/api/contracts/logs-description.ejs +3 -0
  95. package/src/views/docs/api/contracts/logs.ejs +14 -0
  96. package/src/views/docs/api/contracts/stub-description.ejs +4 -0
  97. package/src/views/docs/api/contracts/stub.ejs +7 -0
  98. package/src/views/docs/api/contracts/stubs-description.ejs +4 -0
  99. package/src/views/docs/api/contracts/stubs.ejs +11 -0
  100. package/src/views/docs/api/contracts.ejs +133 -0
  101. package/src/views/docs/api/errors.ejs +64 -0
  102. package/src/views/docs/api/fault/connectionReset.ejs +31 -0
  103. package/src/views/docs/api/fault/randomDataThenClose.ejs +31 -0
  104. package/src/views/docs/api/faults.ejs +57 -0
  105. package/src/views/docs/api/injection.ejs +426 -0
  106. package/src/views/docs/api/json.ejs +205 -0
  107. package/src/views/docs/api/jsonpath.ejs +210 -0
  108. package/src/views/docs/api/mocks.ejs +130 -0
  109. package/src/views/docs/api/overview.ejs +968 -0
  110. package/src/views/docs/api/predicates/and.ejs +62 -0
  111. package/src/views/docs/api/predicates/contains.ejs +64 -0
  112. package/src/views/docs/api/predicates/deepEquals.ejs +114 -0
  113. package/src/views/docs/api/predicates/endsWith.ejs +66 -0
  114. package/src/views/docs/api/predicates/equals.ejs +125 -0
  115. package/src/views/docs/api/predicates/exists.ejs +118 -0
  116. package/src/views/docs/api/predicates/inject.ejs +67 -0
  117. package/src/views/docs/api/predicates/matches.ejs +66 -0
  118. package/src/views/docs/api/predicates/not.ejs +52 -0
  119. package/src/views/docs/api/predicates/or.ejs +79 -0
  120. package/src/views/docs/api/predicates/startsWith.ejs +62 -0
  121. package/src/views/docs/api/predicates.ejs +382 -0
  122. package/src/views/docs/api/proxies.ejs +191 -0
  123. package/src/views/docs/api/proxy/addDecorateBehavior.ejs +115 -0
  124. package/src/views/docs/api/proxy/addWaitBehavior.ejs +96 -0
  125. package/src/views/docs/api/proxy/injectHeaders.ejs +91 -0
  126. package/src/views/docs/api/proxy/predicateGenerators.ejs +600 -0
  127. package/src/views/docs/api/proxy/proxyModes.ejs +495 -0
  128. package/src/views/docs/api/stubs.ejs +391 -0
  129. package/src/views/docs/api/xpath.ejs +281 -0
  130. package/src/views/docs/cli/configFiles.ejs +133 -0
  131. package/src/views/docs/cli/customFormatters.ejs +53 -0
  132. package/src/views/docs/cli/help.ejs +6 -0
  133. package/src/views/docs/cli/replay.ejs +42 -0
  134. package/src/views/docs/cli/restart.ejs +10 -0
  135. package/src/views/docs/cli/save.ejs +68 -0
  136. package/src/views/docs/cli/start.ejs +234 -0
  137. package/src/views/docs/cli/stop.ejs +32 -0
  138. package/src/views/docs/commandLine.ejs +93 -0
  139. package/src/views/docs/communityExtensions.ejs +233 -0
  140. package/src/views/docs/gettingStarted.ejs +146 -0
  141. package/src/views/docs/mentalModel.ejs +51 -0
  142. package/src/views/docs/protocols/custom.ejs +231 -0
  143. package/src/views/docs/protocols/http.ejs +238 -0
  144. package/src/views/docs/protocols/https.ejs +246 -0
  145. package/src/views/docs/protocols/smtp.ejs +142 -0
  146. package/src/views/docs/protocols/tcp.ejs +431 -0
  147. package/src/views/docs/security.ejs +38 -0
  148. package/src/views/faqs.ejs +65 -0
  149. package/src/views/feed.ejs +33 -0
  150. package/src/views/imposter.ejs +22 -0
  151. package/src/views/imposters.ejs +33 -0
  152. package/src/views/index.ejs +89 -0
  153. package/src/views/license.ejs +30 -0
  154. package/src/views/logs.ejs +77 -0
  155. package/src/views/releases/v1.1.0.ejs +55 -0
  156. package/src/views/releases/v1.1.36.ejs +84 -0
  157. package/src/views/releases/v1.1.72.ejs +92 -0
  158. package/src/views/releases/v1.10.0.ejs +108 -0
  159. package/src/views/releases/v1.11.0.ejs +109 -0
  160. package/src/views/releases/v1.12.0.ejs +96 -0
  161. package/src/views/releases/v1.13.0.ejs +118 -0
  162. package/src/views/releases/v1.14.0.ejs +107 -0
  163. package/src/views/releases/v1.14.1.ejs +94 -0
  164. package/src/views/releases/v1.15.0.ejs +113 -0
  165. package/src/views/releases/v1.16.0.ejs +104 -0
  166. package/src/views/releases/v1.2.0.ejs +78 -0
  167. package/src/views/releases/v1.2.103.ejs +86 -0
  168. package/src/views/releases/v1.2.122.ejs +86 -0
  169. package/src/views/releases/v1.2.30.ejs +84 -0
  170. package/src/views/releases/v1.2.45.ejs +84 -0
  171. package/src/views/releases/v1.2.56.ejs +79 -0
  172. package/src/views/releases/v1.3.0.ejs +86 -0
  173. package/src/views/releases/v1.3.1.ejs +100 -0
  174. package/src/views/releases/v1.4.0.ejs +96 -0
  175. package/src/views/releases/v1.4.1.ejs +103 -0
  176. package/src/views/releases/v1.4.2.ejs +100 -0
  177. package/src/views/releases/v1.4.3.ejs +113 -0
  178. package/src/views/releases/v1.5.0.ejs +104 -0
  179. package/src/views/releases/v1.5.1.ejs +91 -0
  180. package/src/views/releases/v1.6.0.ejs +109 -0
  181. package/src/views/releases/v1.7.0.ejs +113 -0
  182. package/src/views/releases/v1.7.1.ejs +90 -0
  183. package/src/views/releases/v1.7.2.ejs +96 -0
  184. package/src/views/releases/v1.8.0.ejs +121 -0
  185. package/src/views/releases/v1.9.0.ejs +111 -0
  186. package/src/views/releases/v2.0.0.ejs +159 -0
  187. package/src/views/releases/v2.1.0.ejs +121 -0
  188. package/src/views/releases/v2.1.1.ejs +106 -0
  189. package/src/views/releases/v2.1.2.ejs +84 -0
  190. package/src/views/releases/v2.2.0.ejs +115 -0
  191. package/src/views/releases/v2.2.1.ejs +102 -0
  192. package/src/views/releases/v2.3.0.ejs +121 -0
  193. package/src/views/releases/v2.3.1.ejs +100 -0
  194. package/src/views/releases/v2.3.2.ejs +102 -0
  195. package/src/views/releases/v2.3.3.ejs +97 -0
  196. package/src/views/releases/v2.4.0.ejs +114 -0
  197. package/src/views/releases/v2.5.0.ejs +51 -0
  198. package/src/views/releases/v2.6.0.ejs +35 -0
  199. package/src/views/releases/v2.7.0.ejs +32 -0
  200. package/src/views/releases/v2.8.0.ejs +36 -0
  201. package/src/views/releases/v2.8.1.ejs +7 -0
  202. package/src/views/releases/v2.8.2.ejs +26 -0
  203. package/src/views/releases/v2.9.0.ejs +32 -0
  204. package/src/views/releases/v2.9.1.ejs +10 -0
  205. package/src/views/releases.ejs +26 -0
  206. package/src/views/sitemap.ejs +36 -0
  207. package/src/views/support.ejs +14 -0
@@ -0,0 +1,256 @@
1
+ 'use strict';
2
+
3
+ const helpers = require('../util/helpers.js'),
4
+ errors = require('./errors.js');
5
+
6
+ /**
7
+ * Express middleware functions to inject into the HTTP processing
8
+ * @module
9
+ */
10
+
11
+ /**
12
+ * Returns a middleware function to transforms all outgoing relative links in the response body
13
+ * to absolute URLs, incorporating the current host name and port
14
+ * @param {number} port - The port of the current instance
15
+ * @returns {Function}
16
+ */
17
+ function useAbsoluteUrls (port) {
18
+ return function (request, response, next) {
19
+ const setHeaderOriginal = response.setHeader,
20
+ sendOriginal = response.send,
21
+ host = request.headers.host || `localhost:${port}`,
22
+ absolutize = link => `http://${host}${link}`,
23
+ isObject = helpers.isObject;
24
+
25
+ response.setHeader = function () {
26
+ const args = Array.prototype.slice.call(arguments);
27
+
28
+ if (args[0] && args[0].toLowerCase() === 'location') {
29
+ args[1] = absolutize(args[1]);
30
+ }
31
+ setHeaderOriginal.apply(this, args);
32
+ };
33
+
34
+ response.send = function () {
35
+ const args = Array.prototype.slice.call(arguments),
36
+ body = args[0],
37
+ changeLinks = function (obj) {
38
+ if (obj._links) {
39
+ Object.keys(obj._links).forEach(function (rel) {
40
+ if (obj._links[rel].href) {
41
+ obj._links[rel].href = absolutize(obj._links[rel].href);
42
+ }
43
+ });
44
+ }
45
+ },
46
+ traverse = function (obj, fn, parent) {
47
+ if (parent === 'stubs' || parent === 'response') {
48
+ // Don't change _links within stubs or within the response
49
+ // sent back to protocol implementations
50
+ return;
51
+ }
52
+ fn(obj);
53
+ Object.keys(obj).forEach(key => {
54
+ if (obj[key] && isObject(obj[key])) {
55
+ traverse(obj[key], fn, key);
56
+ }
57
+ });
58
+ };
59
+
60
+ if (isObject(body)) {
61
+ traverse(body, changeLinks);
62
+
63
+ // Special case stubs _links. Hard to manage in the traverse function because stubs is an array
64
+ // and we want to change stubs[]._links but not stubs[]._responses.is.body._links
65
+ if (Array.isArray(body.stubs)) {
66
+ body.stubs.forEach(changeLinks);
67
+ }
68
+ else if (Array.isArray(body.imposters)) {
69
+ body.imposters.forEach(imposter => {
70
+ if (Array.isArray(imposter.stubs)) {
71
+ imposter.stubs.forEach(changeLinks);
72
+ }
73
+ });
74
+ }
75
+ }
76
+ sendOriginal.apply(this, args);
77
+ };
78
+
79
+ next();
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Returns a middleware function to return a 404 if the imposter does not exist
85
+ * @param {Object} imposters - The imposters repository
86
+ * @returns {Function}
87
+ */
88
+ function createImposterValidator (imposters) {
89
+ return async function validateImposterExists (request, response, next) {
90
+ const exists = await imposters.exists(request.params.id);
91
+
92
+ if (exists) {
93
+ next();
94
+ }
95
+ else {
96
+ response.statusCode = 404;
97
+ response.send({
98
+ errors: [errors.MissingResourceError('Try POSTing to /imposters first?')]
99
+ });
100
+ }
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Returns a middleware function that logs the requests made to the server
106
+ * @param {Object} log - The logger
107
+ * @param {string} format - The log format
108
+ * @returns {Function}
109
+ */
110
+ function logger (log, format) {
111
+ function shouldLog (request) {
112
+ const isStaticAsset = (['.js', '.css', '.gif', '.png', '.ico'].some(function (fileType) {
113
+ return request.url.indexOf(fileType) >= 0;
114
+ })),
115
+ isHtmlRequest = (request.headers.accept || '').indexOf('html') >= 0,
116
+ isXHR = request.headers['x-requested-with'] === 'XMLHttpRequest';
117
+
118
+ return !(isStaticAsset || isHtmlRequest || isXHR);
119
+ }
120
+
121
+ return function (request, response, next) {
122
+ if (shouldLog(request)) {
123
+ const message = format.replace(':method', request.method).replace(':url', request.url);
124
+ if (request.url.indexOf('_requests') > 0) {
125
+ // Protocol implementations communicating with mountebank
126
+ log.debug(message);
127
+ }
128
+ else {
129
+ log.info(message);
130
+ }
131
+ }
132
+ next();
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Returns a middleware function that passes global variables to all render calls without
138
+ * having to pass them explicitly
139
+ * @param {Object} vars - the global variables to pass
140
+ * @returns {Function}
141
+ */
142
+ function globals (vars) {
143
+ return function (request, response, next) {
144
+ const originalRender = response.render;
145
+ response.render = function () {
146
+ const args = Array.prototype.slice.call(arguments),
147
+ variables = args[1] || {};
148
+
149
+ Object.keys(vars).forEach(function (name) {
150
+ variables[name] = vars[name];
151
+ });
152
+ args[1] = variables;
153
+ originalRender.apply(this, args);
154
+ };
155
+ next();
156
+ };
157
+ }
158
+
159
+ /**
160
+ * The mountebank server uses header-based content negotiation to return either HTML or JSON
161
+ * for each URL. This breaks down on IE browsers as they fail to send the correct Accept header,
162
+ * and since we default to JSON (to make the API easier to use), that leads to a poor experience
163
+ * for IE users. We special case IE to html by inspecting the user agent, making sure not to
164
+ * interfere with XHR requests that do add the Accept header
165
+ * @param {Object} request - The http request
166
+ * @param {Object} response - The http response
167
+ * @param {Function} next - The next middleware function to call
168
+ */
169
+ function defaultIEtoHTML (request, response, next) {
170
+ // IE has inconsistent Accept headers, often defaulting to */*
171
+ // Our default is JSON, which fails to render in the browser on content-negotiated pages
172
+ if (request.headers['user-agent'] && request.headers['user-agent'].indexOf('MSIE') >= 0) {
173
+ if (!(request.headers.accept && request.headers.accept.match(/application\/json/))) {
174
+ request.headers.accept = 'text/html';
175
+ }
176
+ }
177
+ next();
178
+ }
179
+
180
+ /**
181
+ * Returns a middleware function that defaults the content type to JSON if not set to make
182
+ * command line testing easier (e.g. you don't have to set the Accept header with curl) and
183
+ * parses the JSON before reaching a controller, handling errors gracefully.
184
+ * @param {Object} log - The logger
185
+ * @returns {Function}
186
+ */
187
+ function json (log) {
188
+ return function (request, response, next) {
189
+ // Disable body parsing, if already parsed
190
+ if (request.headers['content-type'] === 'application/json' && helpers.isObject(request.body)) {
191
+ next();
192
+ return;
193
+ }
194
+
195
+ request.body = '';
196
+ request.setEncoding('utf8');
197
+ request.on('data', chunk => {
198
+ request.body += chunk;
199
+ });
200
+ request.on('end', function () {
201
+ if (request.body === '') {
202
+ next();
203
+ }
204
+ else {
205
+ try {
206
+ request.body = JSON.parse(request.body);
207
+ request.headers['content-type'] = 'application/json';
208
+ next();
209
+ }
210
+ catch (e) {
211
+ log.error('Invalid JSON: ' + request.body);
212
+ response.statusCode = 400;
213
+ response.send({
214
+ errors: [errors.InvalidJSONError({ source: request.body })]
215
+ });
216
+ }
217
+ }
218
+ });
219
+ };
220
+ }
221
+
222
+ function validateApiKey (expectedApiKey, log) {
223
+ return function (request, response, next) {
224
+ if (!expectedApiKey) {
225
+ next();
226
+ return;
227
+ }
228
+
229
+ if (!request.headers['x-api-key']) {
230
+ log.error('The x-api-key header is required but was not provided');
231
+ response.statusCode = 401;
232
+ response.send({
233
+ errors: [errors.UnauthorizedError()]
234
+ });
235
+ return;
236
+ }
237
+
238
+ const crypto = require('crypto');
239
+ const hash = crypto.createHash('sha512');
240
+ if (crypto.timingSafeEqual(
241
+ hash.copy().update(request.headers['x-api-key']).digest(),
242
+ hash.copy().update(expectedApiKey).digest()
243
+ )) {
244
+ next();
245
+ }
246
+ else {
247
+ log.error('The x-api-key header value does not match the expected API key');
248
+ response.statusCode = 401;
249
+ response.send({
250
+ errors: [errors.UnauthorizedError()]
251
+ });
252
+ }
253
+ };
254
+ }
255
+
256
+ module.exports = { useAbsoluteUrls, createImposterValidator, logger, globals, defaultIEtoHTML, json, validateApiKey };
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ /** @module */
4
+
5
+ const inherit = require('./inherit.js'),
6
+ util = require('util');
7
+
8
+ function wrap (wrappedLogger, logger) {
9
+ ['debug', 'info', 'warn', 'error'].forEach(level => {
10
+ wrappedLogger[level] = function () {
11
+ const args = Array.prototype.slice.call(arguments);
12
+ args[0] = wrappedLogger.scopePrefix + args[0];
13
+
14
+ // Format here rather than use winston's splat formatter
15
+ // to get rid of inconsistent "meta" log elements
16
+ const message = util.format.apply(null, args);
17
+ logger[level](message);
18
+ };
19
+ });
20
+ wrappedLogger.baseLogger = logger;
21
+ }
22
+
23
+ /**
24
+ * Returns a logger that prefixes each message of the given logger with a given scope
25
+ * @param {Object} logger - The logger to add a scope to
26
+ * @param {string} scope - The prefix for all log messages
27
+ * @returns {Object}
28
+ */
29
+ function create (logger, scope) {
30
+ function formatScope (scopeText) {
31
+ return scopeText.indexOf('[') === 0 ? scopeText : `[${scopeText}] `;
32
+ }
33
+
34
+ const wrappedLogger = inherit.from(logger, {
35
+ scopePrefix: formatScope(scope),
36
+ withScope: nestedScopePrefix => create(logger, `${wrappedLogger.scopePrefix}${nestedScopePrefix} `),
37
+ changeScope: newScope => {
38
+ wrappedLogger.scopePrefix = formatScope(newScope);
39
+ wrap(wrappedLogger, logger);
40
+ }
41
+ });
42
+
43
+ wrap(wrappedLogger, logger);
44
+ return wrappedLogger;
45
+ }
46
+
47
+ module.exports = { create };
@@ -0,0 +1,20 @@
1
+ </div>
2
+ </div>
3
+
4
+ <hr />
5
+
6
+ <footer>
7
+ <nav class='horizontal'>
8
+ <ul>
9
+ <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
10
+ <li><a href='/releases'>releases</a></li>
11
+ <li><a href='https://github.com/mountebank-testing/mountebank/blob/master/CONTRIBUTING.md'>contributing</a></li>
12
+ <li><a href='/license'>license</a></li>
13
+ <li><a href='https://github.com/mountebank-testing/mountebank'>source</a></li>
14
+ <li><a href='https://github.com/mountebank-testing/mountebank/issues'>issues</a></li>
15
+ </ul>
16
+ </nav>
17
+ </footer>
18
+
19
+ </body>
20
+ </html>
@@ -0,0 +1,113 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>mountebank - <%= title %></title>
5
+ <meta charset='utf-8'>
6
+ <meta name='description' content='<%= description %>' />
7
+ <meta name='author' content='Brandon Byars' />
8
+
9
+ <link rel='stylesheet' href='/stylesheets/jqueryui/1.10.4/themes/smoothness/jquery-ui.css' />
10
+ <link rel='stylesheet' type='text/css' href='/stylesheets/application.css' />
11
+ <!--[if IE]>
12
+ <link rel='stylesheet' type='text/css' href='/stylesheets/ie.css' />
13
+ <![endif]-->
14
+
15
+ <link rel='shortcut icon' href='/images/favicon.ico' type='image/x-icon' />
16
+
17
+ <script src='/scripts/jquery/jquery-3.6.1.min.js'></script>
18
+ <script src='/scripts/urlHashHandler.js'></script>
19
+ </head>
20
+ <body>
21
+ <div id='main'>
22
+ <header>
23
+ <a href='/'><img src='/images/mountebank.png' alt='mountebank' /></a>
24
+ <p>mountebank - over the wire test doubles</p>
25
+
26
+ <form method='GET' action='http://www.google.com/search'>
27
+ <input type='hidden' name='domains' value='www.mbtest.dev' />
28
+ <input type='hidden' name='sitesearch' value='www.mbtest.dev' />
29
+ <input type='search' name='q' id='q' results='5' autosave='mb' placeholder='Search...'/>
30
+ <input type='submit' value='Search...' id='searchButton' />
31
+ </form>
32
+
33
+ <nav class='horizontal'>
34
+ <ul>
35
+ <li><a href='/'>home</a></li>
36
+ <li><a href='/imposters'>imposters</a></li>
37
+ <li><a href='/logs'>logs</a></li>
38
+ <li><a href='/config'>config</a></li>
39
+ <li><a href='/metrics' title='Prometheus metrics'>metrics</a></li>
40
+ <li><a href='/feed' class='feed-icon' title='subscribe for release updates'></a></li>
41
+ </ul>
42
+ </nav>
43
+ </header>
44
+
45
+ <hr />
46
+
47
+ <div id='sidenav'>
48
+ <h3>the apothecary</h3>
49
+ <nav class='vertical'>
50
+ <ul>
51
+ <li><a href='/docs/gettingStarted'>getting started</a></li>
52
+ <li><a href='/docs/mentalModel'>mental model</a></li>
53
+ <li><a href='/docs/communityExtensions'>3rd party plugins</a></li>
54
+ <li><a href='/docs/commandLine'>command line</a></li>
55
+ <li><a href='/docs/security'>security</a></li>
56
+ <li><a href='/faqs'>faqs</a></li>
57
+ <li><a href='/support'>support</a></li>
58
+ </ul>
59
+
60
+ <p>api:</p>
61
+ <ul>
62
+ <li><a href='/docs/api/overview'>overview</a></li>
63
+ <li><a href='/docs/api/contracts'>contracts</a></li>
64
+ <li><a href='/docs/api/mocks'>mock verification</a></li>
65
+ <li><a href='/docs/api/stubs'>stub responses</a></li>
66
+ <li>
67
+ <ul>
68
+ <li><a href='/docs/api/proxies'>proxies</a></li>
69
+ <li><a href='/docs/api/injection'>injection</a></li>
70
+ <li><a href='/docs/api/behaviors'>behaviors</a></li>
71
+ <li><a href='/docs/api/faults'>faults</a></li>
72
+ </ul>
73
+ </li>
74
+ <li><a href='/docs/api/predicates'>stub predicates</a></li>
75
+ <li>
76
+ <ul>
77
+ <li><a href='/docs/api/xpath'>xpath</a></li>
78
+ <li><a href='/docs/api/json'>json</a></li>
79
+ <li><a href='/docs/api/jsonpath'>jsonpath</a></li>
80
+ </ul>
81
+ </li>
82
+ <li><a href='/docs/api/errors'>errors</a></li>
83
+ </ul>
84
+
85
+ <p>builtin protocols:</p>
86
+ <ul>
87
+ <li><a href='/docs/protocols/http'>http</a></li>
88
+ <li><a href='/docs/protocols/https'>https</a></li>
89
+ <li><a href='/docs/protocols/tcp'>tcp</a></li>
90
+ <li><a href='/docs/protocols/smtp'>smtp</a></li>
91
+ </ul>
92
+
93
+ <p>community plugins:</p>
94
+ <ul>
95
+ <li><a href='https://gitlab.com/dAnjou/mountebank-ldap'>ldap</a></li>
96
+ <li><a href='https://github.com/vamsib/mountebank-ws'>websockets</a></li>
97
+ <li><a href='https://github.com/bashj79/mb-graphql'>graphql</a></li>
98
+ <li><a href='https://github.com/telekom/mb-netmgmt'>snmp</a></li>
99
+ <li><a href='https://github.com/telekom/mb-netmgmt'>telnet</a></li>
100
+ <li><a href='https://github.com/telekom/mb-netmgmt'>ssh</a></li>
101
+ <li><a href='https://github.com/telekom/mb-netmgmt'>netconf</a></li>
102
+ <li><a href='/docs/protocols/custom'>create your own</a></li>
103
+ </ul>
104
+
105
+ <p>the book:<br /><br />
106
+ <a href='https://www.manning.com/books/testing-microservices-with-mountebank?utm_source=mb&amp;utm_medium=affiliate&amp;utm_campaign=book_byars_testing_12_20_18&amp;a_aid=mb&amp;a_bid=ee3288f4'>
107
+ <img src='/images/book.jpg' alt='Testing Microservices with Mountebank' width='130' height='163' />
108
+ </a>
109
+ </p>
110
+ </nav>
111
+ </div>
112
+
113
+ <div id='content'>
@@ -0,0 +1,8 @@
1
+ <tr id='imposter-<%= imposter.port %>'>
2
+ <td style='width: 15em;'><a href='<%= imposter._links.self.href %>'>
3
+ <%= imposter.name || imposter.protocol + ':' + imposter.port %>
4
+ </a></td>
5
+ <td style='width: 6em;'><%= imposter.protocol %></td>
6
+ <td style='width: 5em;'><%= imposter.port %></td>
7
+ <td style='width: 6em;'><%= imposter.numberOfRequests %></td>
8
+ </tr>
@@ -0,0 +1,71 @@
1
+ <%
2
+ title = 'configuration'
3
+ description = 'The version, command line parameters, and process information about this running mb process'
4
+ %>
5
+
6
+ <%- include('_header') -%>
7
+
8
+ <%
9
+ function isJSONObject (value) {
10
+ return typeof value === 'object' && !Array.isArray(value);
11
+ }
12
+
13
+ function prettyPrint (value) {
14
+ return isJSONObject(value) ? JSON.stringify(value, null, 2) : value;
15
+ }
16
+ %>
17
+
18
+ <h1>Config</h1>
19
+
20
+ <table>
21
+ <tr>
22
+ <td>version</td>
23
+ <td><%= version %></td>
24
+ </tr>
25
+ <% Object.keys(options).forEach(key =>{ %>
26
+ <tr>
27
+ <td><%= key %></td>
28
+ <td><% if (isJSONObject(options[key])) { -%><pre><code><% } -%><%= prettyPrint(options[key]) %><% if (isJSONObject(options[key])) { -%></code></pre><% } -%>
29
+ </td>
30
+ </tr>
31
+ <% }); -%>
32
+ </table>
33
+
34
+ <h2>Process Information</h2>
35
+
36
+ <table>
37
+ <tr>
38
+ <td>node version</td>
39
+ <td><%= process.nodeVersion %></td>
40
+ </tr>
41
+ <tr>
42
+ <td>architecture</td>
43
+ <td><%= process.architecture %></td>
44
+ </tr>
45
+ <tr>
46
+ <td>platform</td>
47
+ <td><%= process.platform %></td>
48
+ </tr>
49
+ <tr>
50
+ <td>rss</td>
51
+ <td><%= process.rss %></td>
52
+ </tr>
53
+ <tr>
54
+ <td>heapTotal</td>
55
+ <td><%= process.heapTotal %></td>
56
+ </tr>
57
+ <tr>
58
+ <td>heapUsed</td>
59
+ <td><%= process.heapUsed %></td>
60
+ </tr>
61
+ <tr>
62
+ <td>uptime</td>
63
+ <td><%= process.uptime %></td>
64
+ </tr>
65
+ <tr>
66
+ <td>cwd</td>
67
+ <td><%= process.cwd %></td>
68
+ </tr>
69
+ </table>
70
+
71
+ <%- include('_footer') -%>