@jaredwray/mockhttp 1.5.1 → 1.6.1

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 (3) hide show
  1. package/README.md +18 -2
  2. package/dist/index.mjs +49 -12
  3. package/package.json +17 -26
package/README.md CHANGED
@@ -8,11 +8,11 @@
8
8
  [![Docker Pulls](https://img.shields.io/docker/pulls/jaredwray/mockhttp)](https://hub.docker.com/r/jaredwray/mockhttp)
9
9
  [![mockhttp.org](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fjaredwray.com%2Fapi%2Fmockhttp-traffic&query=%24.message&label=mockhttp.org)](https://mockhttp.org)
10
10
 
11
- A 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`.
11
+ A 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`.
12
12
 
13
13
  # Features
14
14
  * All the features of [httpbin](https://httpbin.org/)
15
- * Taps - Inject custom responses for testing and develepment
15
+ * Taps - Inject custom responses for testing and development
16
16
  * `@fastify/helmet` built in by default
17
17
  * Built with `nodejs`, `typescript`, and `fastify`
18
18
  * Deploy via `docker` or `nodejs`
@@ -30,6 +30,7 @@ A simple HTTP server that can be used to mock HTTP responses for testing purpose
30
30
  - [Response Injection (Tap Feature)](#response-injection-tap-feature)
31
31
  - [Rate Limiting](#rate-limiting)
32
32
  - [Logging](#logging)
33
+ - [Flexible URL Matching](#flexible-url-matching)
33
34
  - [API Reference](#api-reference)
34
35
  - [About mockhttp.org](#about-mockhttporg)
35
36
  - [Contributing](#contributing)
@@ -608,6 +609,21 @@ You can also disable logging via the `LOGGING` environment variable:
608
609
  LOGGING=false node your-app.js
609
610
  ```
610
611
 
612
+ # Flexible URL Matching
613
+
614
+ MockHttp ignores trailing path segments that come after the parsable portion of a URL. This is useful when a client appends extra data to a known endpoint — instead of returning 404, MockHttp serves the closest matching route.
615
+
616
+ For example, all of these are served by `/status/:code`:
617
+
618
+ ```
619
+ GET /status/429
620
+ GET /status/429/
621
+ GET /status/429/foo
622
+ GET /status/429/foo/bar
623
+ ```
624
+
625
+ The rewrite preserves the query string and only triggers when a more specific route exists; URLs whose first path segment doesn't correspond to a registered route still return 404.
626
+
611
627
  # API Reference
612
628
 
613
629
  ## MockHttp Class
package/dist/index.mjs CHANGED
@@ -246,16 +246,47 @@ async function generateCertificateFiles(options) {
246
246
  }
247
247
  //#endregion
248
248
  //#region src/fastify-config.ts
249
+ function isSpecificMatch(route) {
250
+ if (!route) return false;
251
+ const params = route.params;
252
+ return params === void 0 || params["*"] === void 0;
253
+ }
254
+ function rewriteUrl(req) {
255
+ const originalUrl = req.url ?? "/";
256
+ const method = req.method;
257
+ if (!method) return originalUrl;
258
+ const queryIdx = originalUrl.indexOf("?");
259
+ const path = queryIdx >= 0 ? originalUrl.slice(0, queryIdx) : originalUrl;
260
+ const query = queryIdx >= 0 ? originalUrl.slice(queryIdx) : "";
261
+ if (isSpecificMatch(this.findRoute({
262
+ method,
263
+ url: path
264
+ }))) return originalUrl;
265
+ const segments = path.split("/").filter(Boolean);
266
+ while (segments.length >= 1) {
267
+ const candidatePath = `/${segments.join("/")}`;
268
+ if (candidatePath !== path && isSpecificMatch(this.findRoute({
269
+ method,
270
+ url: candidatePath
271
+ }))) return candidatePath + query;
272
+ if (segments.length === 1) break;
273
+ segments.pop();
274
+ }
275
+ return originalUrl;
276
+ }
249
277
  function getFastifyConfig(logging = true) {
250
- return { logger: logging ? { transport: {
251
- target: "pino-pretty",
252
- options: {
253
- colorize: true,
254
- translateTime: true,
255
- ignore: "pid,hostname",
256
- singleLine: true
257
- }
258
- } } : false };
278
+ return {
279
+ logger: logging ? { transport: {
280
+ target: "pino-pretty",
281
+ options: {
282
+ colorize: true,
283
+ translateTime: true,
284
+ ignore: "pid,hostname",
285
+ singleLine: true
286
+ }
287
+ } } : false,
288
+ rewriteUrl
289
+ };
259
290
  }
260
291
  //#endregion
261
292
  //#region src/routes/anything/index.ts
@@ -328,6 +359,7 @@ const anythingRoute = (fastify) => {
328
359
  };
329
360
  const noValidation = {
330
361
  schema: anythingSchema,
362
+ /* v8 ignore next -- @preserve */
331
363
  validatorCompiler: () => () => true
332
364
  };
333
365
  fastify.get("/anything", noValidation, handler);
@@ -869,6 +901,7 @@ const delayRoute = (fastify) => {
869
901
  /* v8 ignore next -- @preserve */
870
902
  const host = request.headers.host || "localhost";
871
903
  return {
904
+ /* v8 ignore next -- @preserve */
872
905
  args: request.query || {},
873
906
  data: "",
874
907
  files: {},
@@ -1176,6 +1209,7 @@ const streamRoute = (fastify) => {
1176
1209
  for (let i = 0; i < lines; i++) {
1177
1210
  const data = {
1178
1211
  id: i,
1212
+ /* v8 ignore next -- @preserve */
1179
1213
  args: request.query || {},
1180
1214
  headers: request.headers,
1181
1215
  origin: request.ip,
@@ -2867,17 +2901,17 @@ const fastifySwaggerConfig = { openapi: {
2867
2901
  info: {
2868
2902
  title: "Mock HTTP API",
2869
2903
  description: `
2870
- A 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\`.
2904
+ A 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\`.
2871
2905
 
2872
2906
  * [GitHub Repository](https://github.com/jaredwray/mockhttp)
2873
2907
  * [Docker Image](https://hub.docker.com/r/jaredwray/mockhttp)
2874
- * [NPM Package](https://www.npmjs.com/package/jaredwray/mockhttp)
2908
+ * [NPM Package](https://www.npmjs.com/package/@jaredwray/mockhttp)
2875
2909
 
2876
2910
  # About mockhttp.org
2877
2911
 
2878
2912
  [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.
2879
2913
  `,
2880
- version: "1.5.1"
2914
+ version: "1.6.1"
2881
2915
  },
2882
2916
  consumes: ["application/json"],
2883
2917
  produces: ["application/json"]
@@ -2890,14 +2924,17 @@ const registerSwaggerUi = async (fastify) => {
2890
2924
  deepLinking: false
2891
2925
  },
2892
2926
  uiHooks: {
2927
+ /* v8 ignore next -- @preserve */
2893
2928
  onRequest(_request, _reply, next) {
2894
2929
  next();
2895
2930
  },
2931
+ /* v8 ignore next -- @preserve */
2896
2932
  preHandler(_request, _reply, next) {
2897
2933
  next();
2898
2934
  }
2899
2935
  },
2900
2936
  staticCSP: true,
2937
+ /* v8 ignore next -- @preserve */
2901
2938
  transformSpecification: (swaggerObject, _request, _reply) => swaggerObject,
2902
2939
  transformSpecificationClone: true
2903
2940
  });
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@jaredwray/mockhttp",
3
- "version": "1.5.1",
3
+ "version": "1.6.1",
4
4
  "description": "Mock Http - Easy way to mock http with httpbin replacement",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
7
7
  "types": "dist/index.d.mts",
8
+ "packageManager": "pnpm@11.1.3",
9
+ "engines": {
10
+ "node": ">=22.18.0"
11
+ },
8
12
  "directories": {
9
13
  "test": "test"
10
14
  },
@@ -53,27 +57,27 @@
53
57
  },
54
58
  "homepage": "https://github.com/jaredwray/mockhttp#readme",
55
59
  "devDependencies": {
56
- "@biomejs/biome": "^2.4.11",
57
- "@swc/core": "^1.15.24",
60
+ "@biomejs/biome": "^2.4.15",
61
+ "@swc/core": "^1.15.33",
58
62
  "@types/html-escaper": "^3.0.4",
59
- "@vitest/coverage-v8": "^4.1.4",
63
+ "@vitest/coverage-v8": "^4.1.6",
60
64
  "rimraf": "^6.1.3",
61
- "tsdown": "^0.21.7",
65
+ "tsdown": "^0.22.0",
62
66
  "tsx": "^4.21.0",
63
- "typescript": "6.0.2",
64
- "vitest": "^4.1.4"
67
+ "typescript": "6.0.3",
68
+ "vitest": "^4.1.6"
65
69
  },
66
70
  "dependencies": {
67
71
  "@fastify/cookie": "^11.0.2",
68
72
  "@fastify/helmet": "^13.0.2",
69
73
  "@fastify/rate-limit": "^10.3.0",
70
- "@fastify/static": "^9.1.0",
74
+ "@fastify/static": "^9.1.3",
71
75
  "@fastify/swagger": "^9.7.0",
72
- "@fastify/swagger-ui": "^5.2.5",
73
- "@scalar/api-reference": "^1.52.1",
76
+ "@fastify/swagger-ui": "^5.2.6",
77
+ "@scalar/api-reference": "^1.55.3",
74
78
  "detect-port": "^2.1.0",
75
- "fastify": "^5.8.4",
76
- "hookified": "^2.1.1",
79
+ "fastify": "^5.8.5",
80
+ "hookified": "^2.2.0",
77
81
  "html-escaper": "^3.0.3",
78
82
  "pino": "^10.3.1",
79
83
  "pino-pretty": "^13.1.3"
@@ -82,18 +86,5 @@
82
86
  "dist",
83
87
  "public",
84
88
  "LICENCE"
85
- ],
86
- "pnpm": {
87
- "overrides": {
88
- "set-cookie-parser": "2.7.2"
89
- },
90
- "onlyBuiltDependencies": [
91
- "@swc/core",
92
- "core-js",
93
- "esbuild",
94
- "protobufjs",
95
- "unrs-resolver",
96
- "vue-demi"
97
- ]
98
- }
89
+ ]
99
90
  }