@jaredwray/mockhttp 1.4.0 → 1.5.0

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
@@ -26,6 +26,7 @@ A simple HTTP server that can be used to mock HTTP responses for testing purpose
26
26
  - [Deploy via Docker Compose](#deploy-via-docker-compose)
27
27
  - [Deploy via NodeJS](#deploy-via-nodejs)
28
28
  - [HTTPS Support](#https-support)
29
+ - [HTTP/2 Support](#http2-support)
29
30
  - [Response Injection (Tap Feature)](#response-injection-tap-feature)
30
31
  - [Rate Limiting](#rate-limiting)
31
32
  - [Logging](#logging)
@@ -197,6 +198,55 @@ const result = await generateCertificateFiles({
197
198
  | `validityDays` | number | `365` | Certificate validity period in days |
198
199
  | `keySize` | number | `2048` | RSA key size in bits |
199
200
 
201
+ # HTTP/2 Support
202
+
203
+ MockHttp supports HTTP/2 in two modes:
204
+ - **h2** — HTTP/2 over TLS (used by browsers), enabled with both `http2: true` and `https: true`
205
+ - **h2c** — HTTP/2 cleartext (no TLS), enabled with just `http2: true`, useful for service-to-service testing
206
+
207
+ ## HTTP/2 over TLS (h2)
208
+
209
+ ```javascript
210
+ import { MockHttp } from '@jaredwray/mockhttp';
211
+
212
+ const mock = new MockHttp({ http2: true, https: true });
213
+ await mock.start();
214
+
215
+ console.log(mock.http2); // true
216
+ console.log(mock.isHttps); // true
217
+
218
+ const response = await mock.server.inject({ method: 'GET', url: '/get' });
219
+ console.log(response.statusCode); // 200
220
+
221
+ await mock.close();
222
+ ```
223
+
224
+ By default, HTTP/1.1 clients can still connect via ALPN negotiation (`http1` defaults to `true`). To disable HTTP/1.1 fallback:
225
+
226
+ ```javascript
227
+ const mock = new MockHttp({ http2: true, https: true, http1: false });
228
+ await mock.start();
229
+ ```
230
+
231
+ ## HTTP/2 Cleartext (h2c)
232
+
233
+ ```javascript
234
+ const mock = new MockHttp({ http2: true });
235
+ await mock.start();
236
+
237
+ console.log(mock.http2); // true
238
+
239
+ await mock.close();
240
+ ```
241
+
242
+ > **Note:** Browsers do not support h2c. This mode is useful for testing gRPC or service-to-service communication.
243
+
244
+ ## HTTP/2 via Environment Variable
245
+
246
+ ```bash
247
+ HTTP2=true node your-app.js
248
+ ```
249
+
200
250
  # Response Injection (Tap Feature)
201
251
 
202
252
  The injection/tap feature allows you to "tap into" the request flow and inject custom responses for specific requests. This is particularly useful for:
@@ -589,6 +639,8 @@ new MockHttp(options?)
589
639
  - `auth?`: boolean - Enable authentication routes (default: true)
590
640
  - `images?`: boolean - Enable image routes (default: true)
591
641
  - `https?`: boolean | HttpsOptions - Enable HTTPS with auto-generated or custom certificates (default: undefined/disabled)
642
+ - `http2?`: boolean - Enable HTTP/2 support (default: false)
643
+ - `http1?`: boolean - Allow HTTP/1.1 fallback when using HTTP/2 with HTTPS (default: true)
592
644
  - `hookOptions?`: HookifiedOptions - Hookified options
593
645
 
594
646
  ### Properties
@@ -603,6 +655,8 @@ new MockHttp(options?)
603
655
  - `httpBin`: HttpBinOptions - Get/set httpbin route options
604
656
  - `https`: HttpsOptions | undefined - Get/set HTTPS configuration
605
657
  - `isHttps`: boolean - Whether the server is running with HTTPS
658
+ - `http2`: boolean - Get/set HTTP/2 support
659
+ - `http1`: boolean - Get/set HTTP/1.1 fallback for HTTP/2 with HTTPS
606
660
  - `server`: FastifyInstance - Get/set the Fastify server instance
607
661
  - `taps`: TapManager - Get/set the TapManager instance
608
662
 
package/dist/index.d.ts CHANGED
@@ -251,6 +251,18 @@ type MockHttpOptions = {
251
251
  * or provide an object with cert/key strings/paths or auto-generation options.
252
252
  */
253
253
  https?: boolean | HttpsOptions;
254
+ /**
255
+ * Whether to enable HTTP/2 support. When used with `https`, enables h2 (HTTP/2 over TLS).
256
+ * When used without `https`, enables h2c (HTTP/2 cleartext).
257
+ * Defaults to false.
258
+ */
259
+ http2?: boolean;
260
+ /**
261
+ * Whether to allow HTTP/1.1 fallback when using HTTP/2 with HTTPS (ALPN negotiation).
262
+ * Only applies when both `http2` and `https` are enabled.
263
+ * Defaults to true.
264
+ */
265
+ http1?: boolean;
254
266
  };
255
267
  declare class MockHttp extends Hookified {
256
268
  private _port;
@@ -261,6 +273,8 @@ declare class MockHttp extends Hookified {
261
273
  private _logging;
262
274
  private _httpBin;
263
275
  private _rateLimit?;
276
+ private _http2;
277
+ private _http1;
264
278
  private _https;
265
279
  private _httpsCredentials;
266
280
  private _server;
@@ -340,6 +354,26 @@ declare class MockHttp extends Hookified {
340
354
  * Whether the server is running in HTTPS mode.
341
355
  */
342
356
  get isHttps(): boolean;
357
+ /**
358
+ * Whether HTTP/2 support is enabled.
359
+ * @default false
360
+ */
361
+ get http2(): boolean;
362
+ /**
363
+ * Whether HTTP/2 support is enabled.
364
+ * @default false
365
+ */
366
+ set http2(http2: boolean);
367
+ /**
368
+ * Whether to allow HTTP/1.1 fallback when using HTTP/2 with HTTPS.
369
+ * @default true
370
+ */
371
+ get http1(): boolean;
372
+ /**
373
+ * Whether to allow HTTP/1.1 fallback when using HTTP/2 with HTTPS.
374
+ * @default true
375
+ */
376
+ set http1(http1: boolean);
343
377
  /**
344
378
  * HTTP Bin options. Defaults to all enabled.
345
379
  */
package/dist/index.js CHANGED
@@ -3832,7 +3832,7 @@ import { fastifySwaggerUi } from "@fastify/swagger-ui";
3832
3832
  // package.json
3833
3833
  var package_default = {
3834
3834
  name: "@jaredwray/mockhttp",
3835
- version: "1.4.0",
3835
+ version: "1.5.0",
3836
3836
  description: "Mock Http - Easy way to mock http with httpbin replacement",
3837
3837
  type: "module",
3838
3838
  main: "dist/index.js",
@@ -3883,15 +3883,15 @@ var package_default = {
3883
3883
  },
3884
3884
  homepage: "https://github.com/jaredwray/mockhttp#readme",
3885
3885
  devDependencies: {
3886
- "@biomejs/biome": "^2.3.14",
3887
- "@swc/core": "^1.15.11",
3886
+ "@biomejs/biome": "^2.4.7",
3887
+ "@swc/core": "^1.15.18",
3888
3888
  "@types/html-escaper": "^3.0.4",
3889
- "@vitest/coverage-v8": "^4.0.18",
3890
- rimraf: "^6.1.2",
3889
+ "@vitest/coverage-v8": "^4.1.0",
3890
+ rimraf: "^6.1.3",
3891
3891
  tsup: "^8.5.1",
3892
3892
  tsx: "^4.21.0",
3893
3893
  typescript: "^5.9.3",
3894
- vitest: "^4.0.18"
3894
+ vitest: "^4.1.0"
3895
3895
  },
3896
3896
  dependencies: {
3897
3897
  "@fastify/cookie": "^11.0.2",
@@ -3900,10 +3900,10 @@ var package_default = {
3900
3900
  "@fastify/static": "^9.0.0",
3901
3901
  "@fastify/swagger": "^9.7.0",
3902
3902
  "@fastify/swagger-ui": "^5.2.5",
3903
- "@scalar/api-reference": "^1.44.16",
3903
+ "@scalar/api-reference": "^1.48.7",
3904
3904
  "detect-port": "^2.1.0",
3905
- fastify: "^5.7.4",
3906
- hookified: "^1.15.1",
3905
+ fastify: "^5.8.2",
3906
+ hookified: "^2.1.0",
3907
3907
  "html-escaper": "^3.0.3",
3908
3908
  pino: "^10.3.1",
3909
3909
  "pino-pretty": "^13.1.3"
@@ -4124,6 +4124,8 @@ var MockHttp = class extends Hookified {
4124
4124
  "::1"
4125
4125
  ]
4126
4126
  };
4127
+ _http2 = false;
4128
+ _http1 = true;
4127
4129
  _https;
4128
4130
  _httpsCredentials;
4129
4131
  _server = Fastify();
@@ -4155,6 +4157,12 @@ var MockHttp = class extends Hookified {
4155
4157
  if (options?.logging !== void 0) {
4156
4158
  this._logging = options.logging;
4157
4159
  }
4160
+ if (options?.http2 !== void 0) {
4161
+ this._http2 = options.http2;
4162
+ }
4163
+ if (options?.http1 !== void 0) {
4164
+ this._http1 = options.http1;
4165
+ }
4158
4166
  if (options?.https !== void 0) {
4159
4167
  if (options.https === true) {
4160
4168
  this._https = {
@@ -4280,6 +4288,34 @@ var MockHttp = class extends Hookified {
4280
4288
  return this._httpsCredentials !== void 0;
4281
4289
  }
4282
4290
  /**
4291
+ * Whether HTTP/2 support is enabled.
4292
+ * @default false
4293
+ */
4294
+ get http2() {
4295
+ return this._http2;
4296
+ }
4297
+ /**
4298
+ * Whether HTTP/2 support is enabled.
4299
+ * @default false
4300
+ */
4301
+ set http2(http2) {
4302
+ this._http2 = http2;
4303
+ }
4304
+ /**
4305
+ * Whether to allow HTTP/1.1 fallback when using HTTP/2 with HTTPS.
4306
+ * @default true
4307
+ */
4308
+ get http1() {
4309
+ return this._http1;
4310
+ }
4311
+ /**
4312
+ * Whether to allow HTTP/1.1 fallback when using HTTP/2 with HTTPS.
4313
+ * @default true
4314
+ */
4315
+ set http1(http1) {
4316
+ this._http1 = http1;
4317
+ }
4318
+ /**
4283
4319
  * HTTP Bin options. Defaults to all enabled.
4284
4320
  */
4285
4321
  get httpBin() {
@@ -4345,17 +4381,23 @@ var MockHttp = class extends Hookified {
4345
4381
  if (this._server) {
4346
4382
  await this._server.close();
4347
4383
  }
4384
+ const fastifyOptions = {
4385
+ ...getFastifyConfig(this._logging)
4386
+ };
4387
+ if (this._http2) {
4388
+ fastifyOptions.http2 = true;
4389
+ }
4348
4390
  if (this._httpsCredentials) {
4349
- this._server = Fastify({
4350
- ...getFastifyConfig(this._logging),
4351
- https: {
4352
- key: this._httpsCredentials.key,
4353
- cert: this._httpsCredentials.cert
4354
- }
4355
- });
4356
- } else {
4357
- this._server = Fastify(getFastifyConfig(this._logging));
4391
+ const httpsOptions = {
4392
+ key: this._httpsCredentials.key,
4393
+ cert: this._httpsCredentials.cert
4394
+ };
4395
+ if (this._http2) {
4396
+ httpsOptions.allowHTTP1 = this._http1;
4397
+ }
4398
+ fastifyOptions.https = httpsOptions;
4358
4399
  }
4400
+ this._server = Fastify(fastifyOptions);
4359
4401
  this._server.addHook("onRequest", async (request, reply) => {
4360
4402
  const matchedTap = this._taps.matchRequest(request);
4361
4403
  if (matchedTap) {
@@ -4646,6 +4688,9 @@ var start = /* @__PURE__ */ __name(async () => {
4646
4688
  if (process2.env.LOGGING === "false") {
4647
4689
  mockHttp.logging = false;
4648
4690
  }
4691
+ if (process2.env.HTTP2 === "true") {
4692
+ mockHttp.http2 = true;
4693
+ }
4649
4694
  await mockHttp.start();
4650
4695
  return mockHttp;
4651
4696
  }, "start");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaredwray/mockhttp",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Mock Http - Easy way to mock http with httpbin replacement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -51,15 +51,15 @@
51
51
  },
52
52
  "homepage": "https://github.com/jaredwray/mockhttp#readme",
53
53
  "devDependencies": {
54
- "@biomejs/biome": "^2.3.14",
55
- "@swc/core": "^1.15.11",
54
+ "@biomejs/biome": "^2.4.7",
55
+ "@swc/core": "^1.15.18",
56
56
  "@types/html-escaper": "^3.0.4",
57
- "@vitest/coverage-v8": "^4.0.18",
58
- "rimraf": "^6.1.2",
57
+ "@vitest/coverage-v8": "^4.1.0",
58
+ "rimraf": "^6.1.3",
59
59
  "tsup": "^8.5.1",
60
60
  "tsx": "^4.21.0",
61
61
  "typescript": "^5.9.3",
62
- "vitest": "^4.0.18"
62
+ "vitest": "^4.1.0"
63
63
  },
64
64
  "dependencies": {
65
65
  "@fastify/cookie": "^11.0.2",
@@ -68,10 +68,10 @@
68
68
  "@fastify/static": "^9.0.0",
69
69
  "@fastify/swagger": "^9.7.0",
70
70
  "@fastify/swagger-ui": "^5.2.5",
71
- "@scalar/api-reference": "^1.44.16",
71
+ "@scalar/api-reference": "^1.48.7",
72
72
  "detect-port": "^2.1.0",
73
- "fastify": "^5.7.4",
74
- "hookified": "^1.15.1",
73
+ "fastify": "^5.8.2",
74
+ "hookified": "^2.1.0",
75
75
  "html-escaper": "^3.0.3",
76
76
  "pino": "^10.3.1",
77
77
  "pino-pretty": "^13.1.3"