@jaredwray/mockhttp 2.1.0 → 3.0.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.
@@ -617,13 +617,13 @@ curl -s "http://localhost:3000/bins/$ID/requests" \
617
617
 
618
618
  ### Truncation
619
619
 
620
- Bodies larger than `maxBodySize` (1 MiB by default) are cut off and flagged:
620
+ Bodies larger than `maxBodySize` (128 KiB by default) are cut off and flagged:
621
621
 
622
622
  ```javascript
623
623
  // In test setup
624
- import { MockHttp, BinManager } from '@jaredwray/mockhttp';
624
+ import { MockHttp, MockHttpBins } from '@jaredwray/mockhttp';
625
625
  const mock = new MockHttp();
626
- mock.bins = new BinManager({ maxBodySize: 1024 }); // 1 KiB cap
626
+ mock.bins = new MockHttpBins({ maxBodySize: 1024 }); // 1 KiB cap
627
627
  await mock.start();
628
628
  ```
629
629
 
@@ -663,8 +663,7 @@ curl -s "http://localhost:3000/bins/$ID/requests" | jq '.requests[0].path'
663
663
 
664
664
  ## Programmatic Access
665
665
 
666
- The bin manager is exposed on the `MockHttp` instance as `mock.bins`. This
667
- makes it easy to drive bins from a test suite without going through HTTP:
666
+ Use `mock.bins` to control request bins from a test. You do not need an HTTP call:
668
667
 
669
668
  ```javascript
670
669
  import { MockHttp } from '@jaredwray/mockhttp';
@@ -673,13 +672,13 @@ const mock = new MockHttp({ logging: false });
673
672
  await mock.start();
674
673
 
675
674
  // Create a bin
676
- const bin = mock.bins.createBin();
675
+ const bin = await mock.bins.createBin();
677
676
  console.log(`Webhook target: http://localhost:${mock.port}/b/${bin.id}`);
678
677
 
679
678
  // ... point your code-under-test at that URL ...
680
679
 
681
680
  // Read captured requests (newest first)
682
- const requests = mock.bins.getRequests(bin.id);
681
+ const requests = await mock.bins.getRequests(bin.id);
683
682
  console.log(`Captured ${requests.length} requests`);
684
683
 
685
684
  for (const req of requests) {
@@ -687,8 +686,8 @@ for (const req of requests) {
687
686
  }
688
687
 
689
688
  // Clean up
690
- mock.bins.deleteBin(bin.id);
691
- await mock.close(); // also stops the bin cleanup timer
689
+ await mock.bins.deleteBin(bin.id);
690
+ await mock.close();
692
691
  ```
693
692
 
694
693
  ### Using Bins in a Vitest Test
@@ -709,14 +708,14 @@ afterAll(async () => {
709
708
  });
710
709
 
711
710
  test('my SDK sends the right webhook payload', async () => {
712
- const bin = mock.bins.createBin();
711
+ const bin = await mock.bins.createBin();
713
712
  const webhookUrl = `http://localhost:${mock.port}/b/${bin.id}`;
714
713
 
715
714
  // Drive your SDK at the bin
716
715
  await mySdk.notify(webhookUrl, { event: 'user.created', id: 42 });
717
716
 
718
717
  // Assert on what actually arrived
719
- const [captured] = mock.bins.getRequests(bin.id);
718
+ const [captured] = await mock.bins.getRequests(bin.id);
720
719
  expect(captured.method).toBe('POST');
721
720
  expect(captured.contentType).toBe('application/json');
722
721
  expect(JSON.parse(captured.body!)).toEqual({
@@ -737,18 +736,17 @@ const mock = new MockHttp({
737
736
  });
738
737
  ```
739
738
 
740
- To tune limits, replace the default `BinManager` before starting:
739
+ To change the limits, replace the default `MockHttpBins` before you start the server:
741
740
 
742
741
  ```javascript
743
- import { MockHttp, BinManager } from '@jaredwray/mockhttp';
742
+ import { MockHttp, MockHttpBins } from '@jaredwray/mockhttp';
744
743
 
745
744
  const mock = new MockHttp();
746
- mock.bins = new BinManager({
745
+ mock.bins = new MockHttpBins({
747
746
  defaultTtlMs: 60 * 60 * 1000, // 1 hour (default: 24h)
748
747
  maxRequestsPerBin: 500, // (default: 100)
749
- maxBodySize: 5 * 1024 * 1024, // 5 MiB (default: 1 MiB)
748
+ maxBodySize: 512 * 1024, // 512 KiB (default: 128 KiB)
750
749
  idLength: 16, // (default: 12)
751
- cleanupIntervalMs: 30 * 1000, // sweep every 30s (default: 60s)
752
750
  });
753
751
 
754
752
  await mock.start();
@@ -758,44 +756,40 @@ await mock.start();
758
756
 
759
757
  | Option | Default | Description |
760
758
  |--------|---------|-------------|
761
- | `defaultTtlMs` | `86400000` (24h) | Bin lifetime. Expired bins return 404 and are lazily removed. |
759
+ | `defaultTtlMs` | `86400000` (24h) | Bin lifetime, set as the Keyv TTL. An expired bin returns 404. |
762
760
  | `maxRequestsPerBin` | `100` | When exceeded, oldest captures are dropped (FIFO). |
763
- | `maxBodySize` | `1048576` (1 MiB) | Larger bodies are truncated; `truncated: true` is set on the capture. |
761
+ | `maxBodySize` | `131072` (128 KiB) | Larger bodies are truncated; `truncated: true` is set on the capture. |
764
762
  | `idLength` | `12` | Length of generated bin and request ids. |
765
- | `cleanupIntervalMs` | `60000` (1 min) | How often expired bins are swept. The timer is `unref()`'d so it never keeps the process alive. |
763
+ | `keyv` | `new Keyv()` | Keyv store for bins. The default keeps bins in memory. |
764
+
765
+ ### Storage
766
766
 
767
- ### Pluggable Storage
767
+ `MockHttpBins` stores each bin in [Keyv](https://github.com/jaredwray/keyv) 6. The default is `new Keyv()`. That store keeps the data in memory for this process.
768
768
 
769
- `BinManager` accepts a `store: BinStore` so you can plug in alternative
770
- backends (Redis, SQLite, etc.) without changing the rest of the codebase. The
771
- default `InMemoryBinStore` keeps state in process memory.
769
+ Pass a Keyv 6 instance when you want a different adapter. Install the adapter in your project. This package does not include an adapter. `@keyv/redis` 6 matches this Keyv version.
772
770
 
773
771
  ```typescript
774
- import {
775
- BinManager,
776
- InMemoryBinStore,
777
- type Bin,
778
- type BinStore,
779
- type CapturedRequest,
780
- } from '@jaredwray/mockhttp';
781
-
782
- class RedisBinStore implements BinStore {
783
- createBin(bin: Bin): void { /* SET bin:${bin.id} ... */ }
784
- getBin(id: string): Bin | undefined { /* GET ... */ }
785
- listBins(): Bin[] { /* SCAN ... */ }
786
- deleteBin(id: string): boolean { /* DEL ... */ }
787
- addRequest(binId: string, req: CapturedRequest, max: number): void {
788
- /* LPUSH bin:${binId}:requests + LTRIM to max */
789
- }
790
- getRequests(binId: string): CapturedRequest[] { /* LRANGE ... */ }
791
- getRequest(binId: string, reqId: string): CapturedRequest | undefined { /* ... */ }
792
- clearRequests(binId: string): void { /* DEL bin:${binId}:requests */ }
793
- cleanupExpired(now: number): string[] { /* scan + delete */ return []; }
794
- }
772
+ import Keyv from 'keyv';
773
+ import KeyvRedis from '@keyv/redis'; // pnpm add @keyv/redis
774
+ import { MockHttpBins } from '@jaredwray/mockhttp';
795
775
 
796
- mock.bins = new BinManager({ store: new RedisBinStore() });
776
+ mock.bins = new MockHttpBins({
777
+ keyv: new Keyv({ store: new KeyvRedis('redis://localhost:6379') }),
778
+ });
797
779
  ```
798
780
 
781
+ Each capture writes the full bin again. A large body or a high request limit makes that write large. Set `maxBodySize` and `maxRequestsPerBin` to limit the size. With the defaults, a full bin of binary bodies is about 17 MB.
782
+
783
+ Two processes that share one Keyv can lose a capture. This occurs when both processes write the same bin at the same time.
784
+
785
+ If Keyv does not store a write, the bin route returns `500` with the standard Fastify error body: `statusCode`, `error`, and `message`.
786
+
787
+ A failed read depends on the Keyv `error` listener. Without a listener, Keyv throws the store error and the route returns `500`. With a listener, Keyv does not throw. A failed read then looks like a missing bin, and the route returns `404`. `listBins()` returns only the bins that it read before the error.
788
+
789
+ `listBins()` throws an error when the adapter has no iterator.
790
+
791
+ An expired bin returns 404. The in-memory Keyv store deletes an expired bin only when a read or `listBins()` reaches it. Until then, the bin stays in memory.
792
+
799
793
  ### Configuration
800
794
  URL: https://mockhttp.org/docs/configuration/
801
795
 
@@ -1017,7 +1011,6 @@ new MockHttp(options?)
1017
1011
  - `logging?`: boolean - Enable logging (default: true)
1018
1012
  - `staticFiles?`: boolean - Serve files from the package `public/` directory (default: true)
1019
1013
  - `pluginTimeout?`: number - Fastify plugin boot timeout in milliseconds; `0` disables it (default: Fastify's timeout)
1020
- - `startBins?`: boolean - Start the request-bin cleanup timer during `initialize()` (default: true)
1021
1014
  - `httpBin?`: HttpBinOptions - Configure which httpbin routes to enable
1022
1015
  - `httpMethods?`: boolean - Enable HTTP method routes (default: true)
1023
1016
  - `redirects?`: boolean - Enable redirect routes (default: true)
@@ -1046,7 +1039,6 @@ new MockHttp(options?)
1046
1039
  - `logging`: boolean - Get/set logging enabled state
1047
1040
  - `staticFiles`: boolean - Get/set whether files from `public/` are served
1048
1041
  - `pluginTimeout`: number | undefined - Get/set Fastify plugin boot timeout
1049
- - `startBins`: boolean - Get/set whether bin cleanup starts during `initialize()`
1050
1042
  - `rateLimit`: RateLimitPluginOptions | undefined - Get/set rate limiting options
1051
1043
  - `httpBin`: HttpBinOptions - Get/set httpbin route options
1052
1044
  - `https`: HttpsOptions | undefined - Get/set HTTPS configuration
@@ -1055,7 +1047,7 @@ new MockHttp(options?)
1055
1047
  - `http1`: boolean - Get/set HTTP/1.1 fallback for HTTP/2 with HTTPS
1056
1048
  - `server`: FastifyInstance - Get/set the Fastify server instance
1057
1049
  - `taps`: TapManager - Get/set the TapManager instance
1058
- - `bins`: BinManager - Get/set the BinManager instance for request bins
1050
+ - `bins`: MockHttpBins - Get or set the request bins
1059
1051
 
1060
1052
  ### Methods
1061
1053
 
@@ -1135,57 +1127,55 @@ Register the request bin routes — management at `/bins` and capture at `/b/:id
1135
1127
 
1136
1128
  ## Bins (Request Capture)
1137
1129
 
1138
- Access the BinManager via `mockHttp.bins` to manage request bins programmatically. See [Request Bins](#request-bins) for usage examples.
1130
+ Use `mockHttp.bins` to control request bins. See [Request Bins](#request-bins) for usage examples.
1139
1131
 
1140
1132
  ### `bins.createBin()`
1141
1133
 
1142
- Create a new bin with the configured TTL.
1134
+ Create a new bin with the configured TTL. Throws when Keyv does not store the bin.
1143
1135
 
1144
- **Returns:** `Bin` — `{ id, createdAt, expiresAt, requestCount }`
1136
+ **Returns:** `Promise<Bin>` — `{ id, createdAt, expiresAt, requestCount }`
1145
1137
 
1146
1138
  ### `bins.getBin(id)`
1147
1139
 
1148
- Look up a bin by id. Returns `undefined` if the bin does not exist or has expired (and lazily removes the expired entry).
1140
+ Look up a bin by id. Returns `undefined` if the bin does not exist or Keyv has expired it. When the Keyv instance has an `error` listener, a failed read also returns `undefined`.
1149
1141
 
1150
- **Returns:** `Bin | undefined`
1142
+ **Returns:** `Promise<Bin | undefined>`
1151
1143
 
1152
1144
  ### `bins.listBins()`
1153
1145
 
1154
- List all non-expired bins.
1146
+ List the bins that Keyv still holds.
1155
1147
 
1156
- **Returns:** `Bin[]`
1148
+ **Returns:** `Promise<Bin[]>`
1157
1149
 
1158
1150
  ### `bins.deleteBin(id)`
1159
1151
 
1160
- Delete a bin and all its captured requests.
1152
+ Delete a bin and all its captured requests. The delete waits for captures already queued for that bin.
1161
1153
 
1162
- **Returns:** `boolean` — `true` if the bin existed
1154
+ **Returns:** `Promise<boolean>` — `true` when the bin existed
1163
1155
 
1164
1156
  ### `bins.getRequests(binId)`
1165
1157
 
1166
1158
  List captured requests for a bin, newest first.
1167
1159
 
1168
- **Returns:** `CapturedRequest[]`
1160
+ **Returns:** `Promise<CapturedRequest[]>`
1169
1161
 
1170
1162
  ### `bins.getRequest(binId, reqId)`
1171
1163
 
1172
1164
  Look up a single captured request.
1173
1165
 
1174
- **Returns:** `CapturedRequest | undefined`
1166
+ **Returns:** `Promise<CapturedRequest | undefined>`
1175
1167
 
1176
1168
  ### `bins.clearRequests(binId)`
1177
1169
 
1178
- Clear all captured requests in a bin (the bin itself is preserved).
1179
-
1180
- ### `bins.recordRequest(binId, raw)`
1170
+ Clear all captured requests in a bin. The bin stays. Throws when Keyv does not store the change.
1181
1171
 
1182
- Manually record a captured request. Returns `undefined` if the bin does not exist or is expired. Normally invoked by the capture route, but available for programmatic use.
1172
+ **Returns:** `Promise<boolean>` — `false` when the bin does not exist
1183
1173
 
1184
- **Returns:** `CapturedRequest | undefined`
1174
+ ### `bins.recordRequest(binId, raw)`
1185
1175
 
1186
- ### `bins.start()` / `bins.stop()`
1176
+ Manually record a captured request. Returns `undefined` if the bin does not exist. Throws when Keyv does not store the capture. Normally invoked by the capture route, but available for programmatic use.
1187
1177
 
1188
- Start or stop the periodic cleanup of expired bins. `MockHttp.start()` and `MockHttp.close()` call these automatically. The interval is `unref()`'d so it never keeps the Node process alive.
1178
+ **Returns:** `Promise<CapturedRequest | undefined>`
1189
1179
 
1190
1180
  ### `bins.maxBodySize` / `bins.maxRequestsPerBin` / `bins.defaultTtlMs`
1191
1181
 
@@ -1248,7 +1238,7 @@ URL: https://mockhttp.org/docs/hosted/
1248
1238
 
1249
1239
  # About mockhttp.org
1250
1240
 
1251
- [mockhttp.org](https://mockhttp.org) is a free hosted instance of this codebase for testing. It runs on a [Cloudflare Worker](/docs/how-to-deploy/cloudflare/) (no containers): documentation is served from Workers Assets, and mock APIs such as `/get` and `/post` run in the Worker. The service is globally available and rate-limited (1000 requests per minute per IP) to prevent abuse.
1241
+ [mockhttp.org](https://mockhttp.org) is a free hosted instance of this codebase for testing. It runs on a [Cloudflare Worker](/docs/how-to-deploy/cloudflare/) (no containers): documentation is served from Workers Assets, and mock APIs such as `/get` and `/post` run in the Worker. The service is globally available and rate-limited (1000 requests per minute per IP) to prevent abuse. Request bins on this service are stored in MongoDB Atlas, in the `bins` collection, so they are shared across isolates.
1252
1242
 
1253
1243
  All [mockhttp.org](https://mockhttp.org) traffic stays on Cloudflare. A separate test app runs the Node server on [Wasmer Edge](/docs/how-to-deploy/wasmer/) at [mockhttp.wasmer.app](https://mockhttp.wasmer.app).
1254
1244
 
@@ -1273,7 +1263,6 @@ The Worker starts the same MockHTTP app as Node.js, with a few options set for t
1273
1263
  | `rateLimit` | `false` | [`@fastify/rate-limit`](https://github.com/fastify/fastify-rate-limit) is off. A Cloudflare rate limiting binding allows 1000 requests per 60 seconds per IP. |
1274
1264
  | `siteDistPath` | unused path | Fastify does not serve the docs. Workers Assets serve `site/dist`. |
1275
1265
  | `staticFiles` | `false` | Logos and other `public/` files are copied into `site/dist` and read through the `ASSETS` binding. |
1276
- | `startBins` | `false` | The bin cleanup timer uses `setInterval`, which can hang a Worker isolate during startup. Bin routes still register. Expired bins are removed when that bin is read, not by a sweep of every bin. |
1277
1266
  | `pluginTimeout` | `0` | Disables Fastify's plugin boot timeout. Those timers are unreliable on Workers. |
1278
1267
  | `logging` | `false` | Request logging is off. |
1279
1268
  | `autoDetectPort` | `false` | The app always listens on port 3000 inside the isolate. |
@@ -1422,7 +1411,7 @@ Change `name` and `owner` before you deploy your own app. The environment variab
1422
1411
 
1423
1412
  [`Anybuild`](https://github.com/jaredwray/mockhttp/blob/main/Anybuild) tells Wasmer how to build the package on a remote builder:
1424
1413
 
1425
- - Node.js 24 and pnpm `12.4.1`
1414
+ - Node.js 24 and pnpm `12.12.1`
1426
1415
  - Build command: `pnpm run build && pnpm website:build`
1427
1416
  - Start command: `node dist/index.mjs`
1428
1417
 
@@ -1448,7 +1437,7 @@ wasmer deploy --non-interactive --build-remote
1448
1437
 
1449
1438
  ## Runtime behavior
1450
1439
 
1451
- Bins use the default in-memory store, so a bin exists only on the instance that created it. Taps are a library API (`mock.taps.inject`) and have no HTTP routes, so a deployed app cannot inject one.
1440
+ Bins use `new Keyv()` by default. The store keeps each bin in memory on the instance that created it. Give `MockHttpBins` a shared Keyv when bins must be visible on more than one instance. Two processes can lose a capture when they write the same bin at the same time. Taps are a library API (`mock.taps.inject`) and have no HTTP routes, so a deployed app cannot inject one.
1452
1441
 
1453
1442
  `@fastify/rate-limit` is on at 1000 requests per minute. It keys on the address that connects to the process. The server does not trust proxy headers, and the allow list is only `127.0.0.1` and `::1`. On the test app, `/ip` reports `127.0.0.100`, which is the edge proxy rather than the caller, and the response includes `x-ratelimit-limit: 1000`. Clients that share that proxy address share one limit on that instance. This is not the Cloudflare limiter used by [mockhttp.org](https://mockhttp.org).
1454
1443
 
@@ -1464,7 +1453,7 @@ OpenAPI Spec Source: /home/runner/work/mockhttp/mockhttp/site/api/swagger.json
1464
1453
  "info": {
1465
1454
  "title": "Mock HTTP API",
1466
1455
  "description": "\nA simple HTTP server that can be used to mock HTTP responses for testing purposes. Inspired by [httpbin](https://httpbin.org/) and built using `nodejs` and `fastify` with the idea of running it via https://mockhttp.org, via docker `jaredwray/mockhttp`, or nodejs `npm install @jaredwray/mockhttp`.\n\n* [GitHub Repository](https://github.com/jaredwray/mockhttp)\n* [Docker Image](https://hub.docker.com/r/jaredwray/mockhttp)\n* [NPM Package](https://www.npmjs.com/package/@jaredwray/mockhttp)\n\n# About mockhttp.org\n\n[mockhttp.org](https://mockhttp.org) is a free hosted instance of this codebase for testing. It runs on a Cloudflare Worker (no containers): documentation is served from Workers Assets, and mock APIs such as `/get` and `/post` run in the Worker. The service is globally available and rate-limited (1000 requests per minute per IP) to prevent abuse.\n",
1467
- "version": "2.1.0"
1456
+ "version": "3.0.0"
1468
1457
  },
1469
1458
  "components": {
1470
1459
  "schemas": {}
@@ -1598,7 +1587,11 @@ OpenAPI Spec Source: /home/runner/work/mockhttp/mockhttp/site/api/swagger.json
1598
1587
  "type": "string"
1599
1588
  },
1600
1589
  {
1601
- "type": "null"
1590
+ "type": "object",
1591
+ "nullable": true,
1592
+ "enum": [
1593
+ null
1594
+ ]
1602
1595
  }
1603
1596
  ]
1604
1597
  }
@@ -5840,10 +5833,8 @@ OpenAPI Spec Source: /home/runner/work/mockhttp/mockhttp/site/api/swagger.json
5840
5833
  "type": "integer"
5841
5834
  },
5842
5835
  "body": {
5843
- "type": [
5844
- "null",
5845
- "string"
5846
- ]
5836
+ "type": "string",
5837
+ "nullable": true
5847
5838
  },
5848
5839
  "bodyEncoding": {
5849
5840
  "type": "string",
@@ -6010,10 +6001,8 @@ OpenAPI Spec Source: /home/runner/work/mockhttp/mockhttp/site/api/swagger.json
6010
6001
  "type": "integer"
6011
6002
  },
6012
6003
  "body": {
6013
- "type": [
6014
- "null",
6015
- "string"
6016
- ]
6004
+ "type": "string",
6005
+ "nullable": true
6017
6006
  },
6018
6007
  "bodyEncoding": {
6019
6008
  "type": "string",
@@ -6950,6 +6939,78 @@ OpenAPI Spec Source: /home/runner/work/mockhttp/mockhttp/site/api/swagger.json
6950
6939
  ## Changelog
6951
6940
  URL: https://mockhttp.org/changelog
6952
6941
 
6942
+ ### v3.0.0
6943
+ URL: https://mockhttp.org/changelog/v3-0-0
6944
+ Date: October 20, 2026
6945
+ Tag: Release
6946
+
6947
+ ## @jaredwray/mockhttp@3.0.0 — 2026-10-19
6948
+
6949
+ Request bins now use Keyv via MockHttpBins, and the Worker can store them in MongoDB Atlas.
6950
+
6951
+ ### ⚠ BREAKING CHANGES
6952
+ - Replace `BinManager`, `BinStore`, and `InMemoryBinStore` with async `MockHttpBins`. `mock.bins.start()` and `mock.bins.stop()` are removed. The default `maxBodySize` is 128 KiB (was 1 MiB). Node engines are now `>=22.19.0` (was `>=22.18.0`). (`b1ddcc0`, #246)
6953
+ Migration: assign `mock.bins = new MockHttpBins({ keyv })` before `start()` (default store is `new Keyv()`) and `await` the bin methods.
6954
+
6955
+ ```ts
6956
+ import Keyv from "keyv";
6957
+ import { MockHttp, MockHttpBins } from "@jaredwray/mockhttp";
6958
+
6959
+ const mock = new MockHttp();
6960
+ mock.bins = new MockHttpBins({ keyv: new Keyv(), maxBodySize: 128 * 1024 });
6961
+ await mock.start();
6962
+ const bin = await mock.bins.createBin();
6963
+ ```
6964
+
6965
+ ### Features
6966
+ - Store Worker request bins in MongoDB Atlas when `MONGODB_URI` is set (`266157b`, #247)
6967
+
6968
+ ```bash
6969
+ # Cloudflare Worker secret. Bins go in the Atlas `bins` collection.
6970
+ # Leave MONGODB_URI unset to keep the in-memory Keyv.
6971
+ wrangler secret put MONGODB_URI
6972
+ ```
6973
+
6974
+ ### Bug Fixes
6975
+ - security - upgrade fastify proxy-addr, fast-uri, find-my-way, undici (`9c52869`, #233)
6976
+ - security - upgrade handlebars, source-map-js (`28aa662`, #236)
6977
+
6978
+ ### Internal
6979
+ - sync defense-in-depth files from agentic (`7fb3ce4`, #234)
6980
+ - upgrade code quality dependencies (`a57b990`, #235)
6981
+ - upgrade TypeScript and build tooling (`b11fa0f`, #237)
6982
+ - upgrade monorepo tooling (`58e8596`, #238)
6983
+ - upgrade GitHub Actions (`58bc448`, #239)
6984
+ - upgrade Dev Container images (`2047c3c`, #240)
6985
+ - upgrade Fastify dependencies (`3e93bea`, #241)
6986
+ - upgrade hookified (`d938e6e`, #242)
6987
+ - upgrade pino and pino-pretty (`c2a94ad`, #243)
6988
+ - upgrade Docker Node.js runtime image (`cd5decf`, #244)
6989
+ - pin the Compose image (`74ad4ea`, #245)
6990
+
6991
+ ### Contributors
6992
+ - @jaredwray (11)
6993
+ - @cursoragent (5)
6994
+
6995
+ ### Full List of Changes
6996
+ - fix: security - upgrade fastify proxy-addr, fast-uri, find-my-way, undici by @jaredwray in #233
6997
+ - mono - chore: sync defense-in-depth files from agentic by @jaredwray in #234
6998
+ - mono - chore: upgrade code quality dependencies by @jaredwray in #235
6999
+ - fix: security - upgrade handlebars, source-map-js by @jaredwray in #236
7000
+ - mono - chore: upgrade TypeScript and build tooling by @jaredwray in #237
7001
+ - mono - chore: upgrade monorepo tooling by @jaredwray in #238
7002
+ - mono - chore: upgrade GitHub Actions by @jaredwray in #239
7003
+ - mono - chore: upgrade Dev Container images by @jaredwray in #240
7004
+ - mono - chore: upgrade Fastify dependencies by @jaredwray in #241
7005
+ - mono - chore: upgrade hookified by @jaredwray in #242
7006
+ - mono - chore: upgrade pino and pino-pretty by @jaredwray in #243
7007
+ - mono - chore: upgrade Docker Node.js runtime image by @jaredwray in #244
7008
+ - mono - chore: pin the Compose image by @jaredwray in #245
7009
+ - Store request bins in Keyv by @jaredwray in #246
7010
+ - Store Worker request bins in MongoDB Atlas by @jaredwray in #247
7011
+
7012
+ **Full diff:** [https://github.com/jaredwray/mockhttp/compare/v2.1.0...v3.0.0](https://github.com/jaredwray/mockhttp/compare/v2.1.0...v3.0.0)
7013
+
6953
7014
  ### v2.1.0
6954
7015
  URL: https://mockhttp.org/changelog/v2-1-0
6955
7016
  Date: October 3, 2026
@@ -7627,14 +7688,3 @@ Tag: Release
7627
7688
 
7628
7689
 
7629
7690
  **Full Changelog**: [https://github.com/jaredwray/mockhttp/compare/v0.2.0...v0.2.1](https://github.com/jaredwray/mockhttp/compare/v0.2.0...v0.2.1)
7630
-
7631
- ### v0.2.0
7632
- URL: https://mockhttp.org/changelog/v0-2-0
7633
- Date: December 13, 2024
7634
- Tag: Release
7635
-
7636
- ## What's Changed
7637
- * response inspection by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/14](https://github.com/jaredwray/mockhttp/pull/14)
7638
-
7639
-
7640
- **Full Changelog**: [https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0](https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0)
@@ -21,6 +21,7 @@ HTTP mock server and httpbin replacement for API testing. Run it at mockhttp.org
21
21
 
22
22
  ## Changelog
23
23
  - [Changelog](https://mockhttp.org/changelog)
24
+ - [v3.0.0](https://mockhttp.org/changelog/v3-0-0) (October 20, 2026)
24
25
  - [v2.1.0](https://mockhttp.org/changelog/v2-1-0) (October 3, 2026)
25
26
  - [v2.0.0](https://mockhttp.org/changelog/v2-0-0) (September 18, 2026)
26
27
  - [v1.9.0](https://mockhttp.org/changelog/v1-9-0) (August 19, 2026)
@@ -40,4 +41,3 @@ HTTP mock server and httpbin replacement for API testing. Run it at mockhttp.org
40
41
  - [v0.8.0](https://mockhttp.org/changelog/v0-8-0) (August 27, 2025)
41
42
  - [v0.7.0](https://mockhttp.org/changelog/v0-7-0) (August 23, 2025)
42
43
  - [v0.6.1](https://mockhttp.org/changelog/v0-6-1) (July 19, 2025)
43
- - [v0.6.0](https://mockhttp.org/changelog/v0-6-0) (June 14, 2025)