@jaredwray/mockhttp 0.4.0 → 0.4.2

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.
package/README.md CHANGED
@@ -16,6 +16,7 @@ A simple HTTP server that can be used to mock HTTP responses for testing purpose
16
16
  * Deploy via `docker` or `nodejs`
17
17
  * Global deployment via [mockhttp.org](https://mockhttp.org) (free service)
18
18
  * Better API documentation and examples
19
+ * Auto detect the port that is not in use
19
20
  * Maintained and updated regularly!
20
21
 
21
22
  # Deploy via Docker
@@ -23,6 +24,29 @@ A simple HTTP server that can be used to mock HTTP responses for testing purpose
23
24
  docker run -d -p 3000:3000 jaredwray/mockhttp
24
25
  ```
25
26
 
27
+ # Deploy via Docker Compose
28
+ ```yaml
29
+ services:
30
+ mockhttp:
31
+ image: jaredwray/mockhttp:latest
32
+ ports:
33
+ - "3000:3000"
34
+ ```
35
+
36
+ If you want to run it on a different port, just change the `3000` to whatever port you want and add in the environment variable `PORT` to the environment.
37
+
38
+ ```yaml
39
+ services:
40
+ mockhttp:
41
+ image: jaredwray/mockhttp:latest
42
+ ports:
43
+ - "3001:3001"
44
+ environment:
45
+ - PORT=3001
46
+ ```
47
+
48
+ You can see an example of this in the [docker-compose.yaml](docker-compose.yaml) file.
49
+
26
50
  # Deploy via NodeJS
27
51
  ```bash
28
52
  npm install @jaredwray/mockhttp --save
@@ -34,12 +58,13 @@ then run `mockhttp` in your code.
34
58
  import { mockhttp } from '@jaredwray/mockhttp';
35
59
  await mockhttp.start(); // start the server
36
60
  const response = await fetch('http://localhost:3000/get');
61
+ console.log(reaponse);
37
62
  await mockhttp.stop(); // stop the server
38
63
  ```
39
64
 
40
65
  # About mockhttp.org
41
66
 
42
- [mockhttp.org](https://mockhttp.org) is a free service that runs this codebase and allows you to use it for testing purposes. It is a simple way to mock HTTP responses for testing purposes. It is globally available has some limitations on it to prevent abuse but many people will not see it. It is ran via [Cloudflare](https://cloudflare.com) and [Google Cloud Run](https://cloud.google.com/run/) across 7 regions globally and can do millions of requests per second.
67
+ [mockhttp.org](https://mockhttp.org) is a free service that runs this codebase and allows you to use it for testing purposes. It is a simple way to mock HTTP responses for testing purposes. It is globally available has some limitations on it to prevent abuse such as requests per second. It is ran via [Cloudflare](https://cloudflare.com) and [Google Cloud Run](https://cloud.google.com/run/) across 7 regions globally and can do millions of requests per second.
43
68
 
44
69
  # Contributing
45
70
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Hookified, HookifiedOptions } from 'hookified';
2
1
  import { FastifyInstance } from 'fastify';
2
+ import { Hookified, HookifiedOptions } from 'hookified';
3
3
 
4
4
  type HttpBinOptions = {
5
5
  httpMethods?: boolean;
@@ -10,13 +10,18 @@ type HttpBinOptions = {
10
10
  };
11
11
  type MockHttpOptions = {
12
12
  /**
13
- * The port to listen on. If not provided, defaults to 3000 and falls back to 3001 if the PORT is in use.
13
+ * The port to listen on. If not provided, defaults to 3000 and detects the next available port if in use.
14
14
  */
15
15
  port?: number;
16
16
  /**
17
17
  * The host to listen on. If not provided, defaults to '0.0.0.0'.
18
18
  */
19
19
  host?: string;
20
+ /**
21
+ * Whether to automatically detect the next available port if the provided port is in use. Defaults
22
+ * to true.
23
+ */
24
+ autoDetectPort?: boolean;
20
25
  /**
21
26
  * Whether to use Helmet for security headers. Defaults to true.
22
27
  */
@@ -37,30 +42,120 @@ type MockHttpOptions = {
37
42
  declare class MockHttp extends Hookified {
38
43
  private _port;
39
44
  private _host;
45
+ private _autoDetectPort;
40
46
  private _helmet;
41
47
  private _apiDocs;
42
48
  private _httpBin;
43
49
  private _server;
44
50
  constructor(options?: MockHttpOptions);
51
+ /**
52
+ * The port to listen on. If not provided, defaults to 3000 and detects the next available port if in use.
53
+ * @default 3000
54
+ */
45
55
  get port(): number;
56
+ /**
57
+ * The port to listen on. If not provided, defaults to 3000 and detects the next available port if in use.
58
+ * @default 3000
59
+ */
46
60
  set port(port: number);
61
+ /**
62
+ * The host to listen on. If not provided, defaults to 'localhost'.
63
+ * @default 'localhost'
64
+ */
47
65
  get host(): string;
66
+ /**
67
+ * The host to listen on. If not provided, defaults to 'localhost'.
68
+ * @default 'localhost'
69
+ */
48
70
  set host(host: string);
71
+ /**
72
+ * Whether to automatically detect the next available port if the provided port is in use. Defaults to true.
73
+ * @default true
74
+ */
75
+ get autoDetectPort(): boolean;
76
+ /**
77
+ * Whether to automatically detect the next available port if the provided port is in use. Defaults to true.
78
+ * @default true
79
+ */
80
+ set autoDetectPort(autoDetectPort: boolean);
81
+ /**
82
+ * Whether to use Helmet for security headers. Defaults to true.
83
+ * @default true
84
+ */
49
85
  get helmet(): boolean;
86
+ /**
87
+ * Whether to use Helmet for security headers. Defaults to true.
88
+ * @default true
89
+ */
50
90
  set helmet(helmet: boolean);
91
+ /**
92
+ * Whether to use Swagger for API documentation. Defaults to true.
93
+ * @default true
94
+ */
51
95
  get apiDocs(): boolean;
96
+ /**
97
+ * Whether to use Swagger for API documentation. Defaults to true.
98
+ * @default true
99
+ */
52
100
  set apiDocs(apiDocs: boolean);
101
+ /**
102
+ * HTTP Bin options. Defaults to all enabled.
103
+ */
53
104
  get httpBin(): HttpBinOptions;
105
+ /**
106
+ * HTTP Bin options. Defaults to all enabled.
107
+ */
54
108
  set httpBin(httpBinary: HttpBinOptions);
109
+ /**
110
+ * The Fastify server instance.
111
+ */
55
112
  get server(): FastifyInstance;
113
+ /**
114
+ * The Fastify server instance.
115
+ */
56
116
  set server(server: FastifyInstance);
117
+ /**
118
+ * Start the Fastify server. If the server is already running, it will be closed and restarted.
119
+ */
57
120
  start(): Promise<void>;
121
+ /**
122
+ * Close the Fastify server.
123
+ */
58
124
  close(): Promise<void>;
125
+ /**
126
+ * Detect the next available port to run on.
127
+ * @returns The port that is available to run on
128
+ */
129
+ detectPort(): Promise<number>;
130
+ /**
131
+ * This will register the API documentation routes including openapi and swagger ui.
132
+ * @param fastifyInstance - the server instance to register the routes on.
133
+ */
59
134
  registerApiDocs(fastifyInstance?: FastifyInstance): Promise<void>;
135
+ /**
136
+ * Register the HTTP methods routes.
137
+ * @param fastifyInstance - the server instance to register the routes on.
138
+ */
60
139
  registerHttpMethods(fastifyInstance?: FastifyInstance): Promise<void>;
140
+ /**
141
+ * Register the status code routes.
142
+ * @param fastifyInstance - the server instance to register the routes on.
143
+ */
61
144
  registerStatusCodeRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
145
+ /**
146
+ * Register the request inspection routes.
147
+ * @param fastifyInstance - the server instance to register the routes on.
148
+ */
62
149
  registerRequestInspectionRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
150
+ /**
151
+ * Register the response inspection routes.
152
+ * @param fastifyInstance - the server instance to register the routes on.
153
+ */
63
154
  registerResponseInspectionRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
155
+ /**
156
+ * Register the redirect routes.
157
+ * @param fastifyInstance - the server instance to register the routes on.
158
+ */
64
159
  registerRedirectRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
65
160
  }
66
161
 
package/dist/index.js CHANGED
@@ -9,8 +9,9 @@ import path from "node:path";
9
9
  import fastifyStatic from "@fastify/static";
10
10
  import fastifyHelmet from "@fastify/helmet";
11
11
  import { fastifySwagger } from "@fastify/swagger";
12
- import { Hookified } from "hookified";
13
12
  import Fastify from "fastify";
13
+ import { Hookified } from "hookified";
14
+ import { detect } from "detect-port";
14
15
 
15
16
  // src/swagger.ts
16
17
  import { fastifySwaggerUi } from "@fastify/swagger-ui";
@@ -18,7 +19,7 @@ import { fastifySwaggerUi } from "@fastify/swagger-ui";
18
19
  // package.json
19
20
  var package_default = {
20
21
  name: "@jaredwray/mockhttp",
21
- version: "0.4.0",
22
+ version: "0.4.2",
22
23
  description: "Mock Http - Easy way to mock http with httpbin replacement",
23
24
  type: "module",
24
25
  main: "dist/index.js",
@@ -34,7 +35,9 @@ var package_default = {
34
35
  "docker:push": "docker push jaredwray/mockhttp",
35
36
  "docker:stop": 'docker stop $(docker ps -a -q --filter ancestor=jaredwray/mockhttp --format="{{.ID}}")',
36
37
  "docker:readme": "tsx ./scripts/create-docker-readme.ts",
37
- prepare: "npm run build",
38
+ "docker:compose:up": "docker-compose up -d",
39
+ "docker:compose:down": "docker-compose down",
40
+ prepare: "pnpm build",
38
41
  start: "node dist/index.js"
39
42
  },
40
43
  repository: {
@@ -54,24 +57,25 @@ var package_default = {
54
57
  },
55
58
  homepage: "https://github.com/jaredwray/mockhttp#readme",
56
59
  devDependencies: {
57
- "@swc/core": "^1.10.9",
58
- "@types/html-escaper": "^3.0.2",
59
- "@vitest/coverage-v8": "^3.0.4",
60
+ "@swc/core": "^1.11.16",
61
+ "@types/html-escaper": "^3.0.4",
62
+ "@vitest/coverage-v8": "^3.1.1",
60
63
  rimraf: "^6.0.1",
61
- tsup: "^8.3.6",
62
- tsx: "^4.19.2",
63
- typescript: "^5.7.3",
64
- vitest: "^3.0.4",
64
+ tsup: "^8.4.0",
65
+ tsx: "^4.19.3",
66
+ typescript: "^5.8.3",
67
+ vitest: "^3.1.1",
65
68
  xo: "^0.60.0"
66
69
  },
67
70
  dependencies: {
68
71
  "@fastify/helmet": "^13.0.1",
69
- "@fastify/static": "^8.0.4",
72
+ "@fastify/static": "^8.1.1",
70
73
  "@fastify/swagger": "^9.4.2",
71
- "@fastify/swagger-ui": "^5.2.1",
72
- "@scalar/api-reference": "^1.25.108",
73
- fastify: "^5.2.1",
74
- hookified: "^1.7.0",
74
+ "@fastify/swagger-ui": "^5.2.2",
75
+ "@scalar/api-reference": "^1.28.12",
76
+ "detect-port": "^2.1.0",
77
+ fastify: "^5.2.2",
78
+ hookified: "^1.8.1",
75
79
  "html-escaper": "^3.0.3",
76
80
  pino: "^9.6.0",
77
81
  "pino-pretty": "^13.0.0"
@@ -80,7 +84,14 @@ var package_default = {
80
84
  "dist",
81
85
  "public",
82
86
  "LICENCE"
83
- ]
87
+ ],
88
+ pnpm: {
89
+ onlyBuiltDependencies: [
90
+ "@swc/core",
91
+ "esbuild",
92
+ "vue-demi"
93
+ ]
94
+ }
84
95
  };
85
96
 
86
97
  // src/swagger.ts
@@ -93,7 +104,7 @@ A simple HTTP server that can be used to mock HTTP responses for testing purpose
93
104
 
94
105
  # About mockhttp.org
95
106
 
96
- [mockhttp.org](https://mockhttp.org) is a free service that runs this codebase and allows you to use it for testing purposes. It is a simple way to mock HTTP responses for testing purposes. It is globally available has some limitations on it to prevent abuse but many people will not see it. It is ran via [Cloudflare](https://cloudflare.com) and [Google Cloud Run](https://cloud.google.com/run/) across 7 regions globally and can do millions of requests per second.
107
+ [mockhttp.org](https://mockhttp.org) is a free service that runs this codebase and allows you to use it for testing purposes. It is a simple way to mock HTTP responses for testing purposes. Ran via [Cloudflare](https://cloudflare.com) and [Google Cloud Run](https://cloud.google.com/run/) across 7 regions globally and can do millions of requests per second.
97
108
  `;
98
109
  var fastifySwaggerConfig = {
99
110
  openapi: {
@@ -1266,6 +1277,7 @@ var MockHttp = class extends Hookified {
1266
1277
  }
1267
1278
  _port = 3e3;
1268
1279
  _host = "0.0.0.0";
1280
+ _autoDetectPort = true;
1269
1281
  _helmet = true;
1270
1282
  _apiDocs = true;
1271
1283
  _httpBin = {
@@ -1295,46 +1307,106 @@ var MockHttp = class extends Hookified {
1295
1307
  this._httpBin = options.httpBin;
1296
1308
  }
1297
1309
  }
1310
+ /**
1311
+ * The port to listen on. If not provided, defaults to 3000 and detects the next available port if in use.
1312
+ * @default 3000
1313
+ */
1298
1314
  get port() {
1299
1315
  return this._port;
1300
1316
  }
1317
+ /**
1318
+ * The port to listen on. If not provided, defaults to 3000 and detects the next available port if in use.
1319
+ * @default 3000
1320
+ */
1301
1321
  set port(port) {
1302
1322
  this._port = port;
1303
1323
  }
1324
+ /**
1325
+ * The host to listen on. If not provided, defaults to 'localhost'.
1326
+ * @default 'localhost'
1327
+ */
1304
1328
  get host() {
1305
1329
  return this._host;
1306
1330
  }
1331
+ /**
1332
+ * The host to listen on. If not provided, defaults to 'localhost'.
1333
+ * @default 'localhost'
1334
+ */
1307
1335
  set host(host) {
1308
1336
  this._host = host;
1309
1337
  }
1338
+ /**
1339
+ * Whether to automatically detect the next available port if the provided port is in use. Defaults to true.
1340
+ * @default true
1341
+ */
1342
+ get autoDetectPort() {
1343
+ return this._autoDetectPort;
1344
+ }
1345
+ /**
1346
+ * Whether to automatically detect the next available port if the provided port is in use. Defaults to true.
1347
+ * @default true
1348
+ */
1349
+ set autoDetectPort(autoDetectPort) {
1350
+ this._autoDetectPort = autoDetectPort;
1351
+ }
1352
+ /**
1353
+ * Whether to use Helmet for security headers. Defaults to true.
1354
+ * @default true
1355
+ */
1310
1356
  get helmet() {
1311
1357
  return this._helmet;
1312
1358
  }
1359
+ /**
1360
+ * Whether to use Helmet for security headers. Defaults to true.
1361
+ * @default true
1362
+ */
1313
1363
  set helmet(helmet) {
1314
1364
  this._helmet = helmet;
1315
1365
  }
1366
+ /**
1367
+ * Whether to use Swagger for API documentation. Defaults to true.
1368
+ * @default true
1369
+ */
1316
1370
  get apiDocs() {
1317
1371
  return this._apiDocs;
1318
1372
  }
1373
+ /**
1374
+ * Whether to use Swagger for API documentation. Defaults to true.
1375
+ * @default true
1376
+ */
1319
1377
  // eslint-disable-next-line unicorn/prevent-abbreviations
1320
1378
  set apiDocs(apiDocs) {
1321
1379
  this._apiDocs = apiDocs;
1322
1380
  }
1381
+ /**
1382
+ * HTTP Bin options. Defaults to all enabled.
1383
+ */
1323
1384
  get httpBin() {
1324
1385
  return this._httpBin;
1325
1386
  }
1387
+ /**
1388
+ * HTTP Bin options. Defaults to all enabled.
1389
+ */
1326
1390
  set httpBin(httpBinary) {
1327
1391
  this._httpBin = httpBinary;
1328
1392
  }
1393
+ /**
1394
+ * The Fastify server instance.
1395
+ */
1329
1396
  get server() {
1330
1397
  return this._server;
1331
1398
  }
1399
+ /**
1400
+ * The Fastify server instance.
1401
+ */
1332
1402
  set server(server) {
1333
1403
  this._server = server;
1334
1404
  }
1405
+ /**
1406
+ * Start the Fastify server. If the server is already running, it will be closed and restarted.
1407
+ */
1335
1408
  async start() {
1336
1409
  try {
1337
- const { port, host } = this;
1338
1410
  if (this._server) {
1339
1411
  await this._server.close();
1340
1412
  }
@@ -1370,23 +1442,49 @@ var MockHttp = class extends Hookified {
1370
1442
  if (redirects) {
1371
1443
  await this.registerRedirectRoutes();
1372
1444
  }
1445
+ if (this._autoDetectPort) {
1446
+ const originalPort = this._port;
1447
+ this._port = await this.detectPort();
1448
+ if (originalPort !== this._port) {
1449
+ this._server.log.info(`Port ${originalPort} is in use, detected next available port: ${this._port}`);
1450
+ }
1451
+ }
1373
1452
  await this._server.listen({
1374
- port,
1375
- host
1453
+ port: this._port,
1454
+ host: this._host
1376
1455
  });
1377
1456
  } catch (error) {
1378
1457
  this._server.log.error(error);
1379
1458
  }
1380
1459
  }
1460
+ /**
1461
+ * Close the Fastify server.
1462
+ */
1381
1463
  async close() {
1382
1464
  await this._server.close();
1383
1465
  }
1466
+ /**
1467
+ * Detect the next available port to run on.
1468
+ * @returns The port that is available to run on
1469
+ */
1470
+ async detectPort() {
1471
+ const { port } = this;
1472
+ return detect(port);
1473
+ }
1474
+ /**
1475
+ * This will register the API documentation routes including openapi and swagger ui.
1476
+ * @param fastifyInstance - the server instance to register the routes on.
1477
+ */
1384
1478
  async registerApiDocs(fastifyInstance) {
1385
1479
  const fastify = fastifyInstance ?? this._server;
1386
1480
  await fastify.register(fastifySwagger, fastifySwaggerConfig);
1387
1481
  await registerSwaggerUi(fastify);
1388
1482
  await fastify.register(indexRoute);
1389
1483
  }
1484
+ /**
1485
+ * Register the HTTP methods routes.
1486
+ * @param fastifyInstance - the server instance to register the routes on.
1487
+ */
1390
1488
  async registerHttpMethods(fastifyInstance) {
1391
1489
  const fastify = fastifyInstance ?? this._server;
1392
1490
  await fastify.register(getRoute);
@@ -1395,22 +1493,38 @@ var MockHttp = class extends Hookified {
1395
1493
  await fastify.register(putRoute);
1396
1494
  await fastify.register(patchRoute);
1397
1495
  }
1496
+ /**
1497
+ * Register the status code routes.
1498
+ * @param fastifyInstance - the server instance to register the routes on.
1499
+ */
1398
1500
  async registerStatusCodeRoutes(fastifyInstance) {
1399
1501
  const fastify = fastifyInstance ?? this._server;
1400
1502
  await fastify.register(statusCodeRoute);
1401
1503
  }
1504
+ /**
1505
+ * Register the request inspection routes.
1506
+ * @param fastifyInstance - the server instance to register the routes on.
1507
+ */
1402
1508
  async registerRequestInspectionRoutes(fastifyInstance) {
1403
1509
  const fastify = fastifyInstance ?? this._server;
1404
1510
  await fastify.register(ipRoute);
1405
1511
  await fastify.register(headersRoute);
1406
1512
  await fastify.register(userAgentRoute);
1407
1513
  }
1514
+ /**
1515
+ * Register the response inspection routes.
1516
+ * @param fastifyInstance - the server instance to register the routes on.
1517
+ */
1408
1518
  async registerResponseInspectionRoutes(fastifyInstance) {
1409
1519
  const fastify = fastifyInstance ?? this._server;
1410
1520
  await fastify.register(cacheRoutes);
1411
1521
  await fastify.register(etagRoutes);
1412
1522
  await fastify.register(responseHeadersRoutes);
1413
1523
  }
1524
+ /**
1525
+ * Register the redirect routes.
1526
+ * @param fastifyInstance - the server instance to register the routes on.
1527
+ */
1414
1528
  async registerRedirectRoutes(fastifyInstance) {
1415
1529
  const fastify = fastifyInstance ?? this._server;
1416
1530
  await fastify.register(absoluteRedirectRoute);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaredwray/mockhttp",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Mock Http - Easy way to mock http with httpbin replacement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -16,7 +16,9 @@
16
16
  "docker:push": "docker push jaredwray/mockhttp",
17
17
  "docker:stop": "docker stop $(docker ps -a -q --filter ancestor=jaredwray/mockhttp --format=\"{{.ID}}\")",
18
18
  "docker:readme": "tsx ./scripts/create-docker-readme.ts",
19
- "prepare": "npm run build",
19
+ "docker:compose:up": "docker-compose up -d",
20
+ "docker:compose:down": "docker-compose down",
21
+ "prepare": "pnpm build",
20
22
  "start": "node dist/index.js"
21
23
  },
22
24
  "repository": {
@@ -36,24 +38,25 @@
36
38
  },
37
39
  "homepage": "https://github.com/jaredwray/mockhttp#readme",
38
40
  "devDependencies": {
39
- "@swc/core": "^1.10.9",
40
- "@types/html-escaper": "^3.0.2",
41
- "@vitest/coverage-v8": "^3.0.4",
41
+ "@swc/core": "^1.11.16",
42
+ "@types/html-escaper": "^3.0.4",
43
+ "@vitest/coverage-v8": "^3.1.1",
42
44
  "rimraf": "^6.0.1",
43
- "tsup": "^8.3.6",
44
- "tsx": "^4.19.2",
45
- "typescript": "^5.7.3",
46
- "vitest": "^3.0.4",
45
+ "tsup": "^8.4.0",
46
+ "tsx": "^4.19.3",
47
+ "typescript": "^5.8.3",
48
+ "vitest": "^3.1.1",
47
49
  "xo": "^0.60.0"
48
50
  },
49
51
  "dependencies": {
50
52
  "@fastify/helmet": "^13.0.1",
51
- "@fastify/static": "^8.0.4",
53
+ "@fastify/static": "^8.1.1",
52
54
  "@fastify/swagger": "^9.4.2",
53
- "@fastify/swagger-ui": "^5.2.1",
54
- "@scalar/api-reference": "^1.25.108",
55
- "fastify": "^5.2.1",
56
- "hookified": "^1.7.0",
55
+ "@fastify/swagger-ui": "^5.2.2",
56
+ "@scalar/api-reference": "^1.28.12",
57
+ "detect-port": "^2.1.0",
58
+ "fastify": "^5.2.2",
59
+ "hookified": "^1.8.1",
57
60
  "html-escaper": "^3.0.3",
58
61
  "pino": "^9.6.0",
59
62
  "pino-pretty": "^13.0.0"
@@ -62,5 +65,12 @@
62
65
  "dist",
63
66
  "public",
64
67
  "LICENCE"
65
- ]
68
+ ],
69
+ "pnpm": {
70
+ "onlyBuiltDependencies": [
71
+ "@swc/core",
72
+ "esbuild",
73
+ "vue-demi"
74
+ ]
75
+ }
66
76
  }