@jaredwray/mockhttp 0.2.3 → 0.4.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
@@ -7,9 +7,17 @@
7
7
  [![npm](https://img.shields.io/npm/v/@jaredwray/mockhttp)](https://npmjs.com/package/@jaredwray/mockhttp)
8
8
  [![Docker Pulls](https://img.shields.io/docker/pulls/jaredwray/mockhttp)](https://hub.docker.com/r/jaredwray/mockhttp)
9
9
 
10
-
11
10
  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
11
 
12
+ # Features
13
+ * All the features of [httpbin](https://httpbin.org/)
14
+ * `@fastify/helmet` built in by default
15
+ * Built with `nodejs`, `typescript`, and `fastify`
16
+ * Deploy via `docker` or `nodejs`
17
+ * Global deployment via [mockhttp.org](https://mockhttp.org) (free service)
18
+ * Better API documentation and examples
19
+ * Maintained and updated regularly!
20
+
13
21
  # Deploy via Docker
14
22
  ```bash
15
23
  docker run -d -p 3000:3000 jaredwray/mockhttp
@@ -24,14 +32,14 @@ then run `mockhttp` in your code.
24
32
 
25
33
  ```javascript
26
34
  import { mockhttp } from '@jaredwray/mockhttp';
27
- mockhttp.start(); // start the server
28
- const response = await fetch('http://localhost:8080/ip');
29
- mockhttp.stop(); // stop the server
35
+ await mockhttp.start(); // start the server
36
+ const response = await fetch('http://localhost:3000/get');
37
+ await mockhttp.stop(); // stop the server
30
38
  ```
31
39
 
32
40
  # About mockhttp.org
33
41
 
34
- [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.
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.
35
43
 
36
44
  # Contributing
37
45
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,69 @@
1
- declare const start: () => Promise<void>;
1
+ import { Hookified, HookifiedOptions } from 'hookified';
2
+ import { FastifyInstance } from 'fastify';
2
3
 
3
- export { start };
4
+ type HttpBinOptions = {
5
+ httpMethods?: boolean;
6
+ redirects?: boolean;
7
+ requestInspection?: boolean;
8
+ responseInspection?: boolean;
9
+ statusCodes?: boolean;
10
+ };
11
+ type MockHttpOptions = {
12
+ /**
13
+ * The port to listen on. If not provided, defaults to 3000 and falls back to 3001 if the PORT is in use.
14
+ */
15
+ port?: number;
16
+ /**
17
+ * The host to listen on. If not provided, defaults to '0.0.0.0'.
18
+ */
19
+ host?: string;
20
+ /**
21
+ * Whether to use Helmet for security headers. Defaults to true.
22
+ */
23
+ helmet?: boolean;
24
+ /**
25
+ * Whether to use Swagger for API documentation. Defaults to true.
26
+ */
27
+ apiDocs?: boolean;
28
+ /**
29
+ * Whether to use Swagger UI. Defaults to true.
30
+ */
31
+ httpBin?: HttpBinOptions;
32
+ /**
33
+ * Hookified options.
34
+ */
35
+ hookOptions?: HookifiedOptions;
36
+ };
37
+ declare class MockHttp extends Hookified {
38
+ private _port;
39
+ private _host;
40
+ private _helmet;
41
+ private _apiDocs;
42
+ private _httpBin;
43
+ private _server;
44
+ constructor(options?: MockHttpOptions);
45
+ get port(): number;
46
+ set port(port: number);
47
+ get host(): string;
48
+ set host(host: string);
49
+ get helmet(): boolean;
50
+ set helmet(helmet: boolean);
51
+ get apiDocs(): boolean;
52
+ set apiDocs(apiDocs: boolean);
53
+ get httpBin(): HttpBinOptions;
54
+ set httpBin(httpBinary: HttpBinOptions);
55
+ get server(): FastifyInstance;
56
+ set server(server: FastifyInstance);
57
+ start(): Promise<void>;
58
+ close(): Promise<void>;
59
+ registerApiDocs(fastifyInstance?: FastifyInstance): Promise<void>;
60
+ registerHttpMethods(fastifyInstance?: FastifyInstance): Promise<void>;
61
+ registerStatusCodeRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
62
+ registerRequestInspectionRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
63
+ registerResponseInspectionRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
64
+ registerRedirectRoutes(fastifyInstance?: FastifyInstance): Promise<void>;
65
+ }
66
+
67
+ declare const start: () => Promise<MockHttp>;
68
+
69
+ export { MockHttp as default, MockHttp as mockhttp, start };
package/dist/index.js CHANGED
@@ -3,128 +3,14 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
 
4
4
  // src/index.ts
5
5
  import process from "node:process";
6
+
7
+ // src/mock-http.ts
6
8
  import path from "node:path";
7
- import Fastify from "fastify";
8
9
  import fastifyStatic from "@fastify/static";
9
- import { fastifySwagger } from "@fastify/swagger";
10
10
  import fastifyHelmet from "@fastify/helmet";
11
-
12
- // src/routes/index.ts
13
- var indexRoute = /* @__PURE__ */ __name((fastify2) => {
14
- fastify2.get("/", {
15
- schema: {
16
- hide: true
17
- }
18
- }, async (_request, reply) => {
19
- const redocHtml = `
20
- <!doctype html>
21
- <html>
22
- <head>
23
- <title>{ mockhttp }</title>
24
- <meta charset="utf-8" />
25
- <meta
26
- name="viewport"
27
- content="width=device-width, initial-scale=1" />
28
- <style>
29
- :root {
30
- --scalar-custom-header-height: 70px;
31
- }
32
- .custom-header {
33
- height: var(--scalar-custom-header-height);
34
- background-color: var(--scalar-background-1);
35
- box-shadow: inset 0 -1px 0 var(--scalar-border-color);
36
- color: var(--scalar-color-1);
37
- font-size: var(--scalar-font-size-2);
38
- padding: 0 18px;
39
- position: sticky;
40
- justify-content: space-between;
41
- top: 0;
42
- z-index: 100;
43
- }
44
- .custom-header,
45
- .custom-header nav {
46
- display: flex;
47
- align-items: center;
48
- gap: 18px;
49
- }
50
-
51
- .custom-header img {
52
- height: var(--scalar-custom-header-height);
53
- object-fit: contain;
54
- }
55
-
56
- .custom-header a:hover {
57
- color: var(--scalar-color-2);
58
- }
59
-
60
- .github-corner {
61
- fill: var(--scalar-border-color) !important;
62
- }
63
-
64
- </style>
65
- </head>
66
- <body>
67
- <header class="custom-header scalar-app">
68
- <a href="/"><img src="/logo.svg" alt="{ mockhttp }" /></a>
69
- <a href="https://github.com/jaredwray/mockhttp" class="github-corner" aria-label="View source on GitHub">
70
- <svg width="70" height="70" viewBox="0 0 250 250" style="color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
71
- </header>
72
-
73
- <script
74
- id="api-reference"
75
- data-url="/docs/json"></script>
76
-
77
- <script src="/scalar/browser/standalone.js"></script>
78
- </body>
79
- </html>
80
- `;
81
- await reply.type("text/html").send(redocHtml);
82
- });
83
- }, "indexRoute");
84
-
85
- // src/routes/sitemap.ts
86
- var sitemapRoute = /* @__PURE__ */ __name((fastify2) => {
87
- fastify2.get("/sitemap.xml", {
88
- schema: {
89
- hide: true
90
- }
91
- }, async (_request, reply) => {
92
- try {
93
- const host = _request.headers.host ?? "mockhttp.org";
94
- const isSecure = _request.headers["x-forwarded-proto"]?.includes("https");
95
- const protocol = isSecure ? "https" : "http";
96
- const xml = `<?xml version="1.0" encoding="UTF-8"?>
97
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
98
- <url>
99
- <loc>${protocol}://${host}/</loc>
100
- <changefreq>monthly</changefreq>
101
- <priority>1.0</priority>
102
- </url>
103
- </urlset>`;
104
- await reply.type("text/xml").send(xml);
105
- } catch (error) {
106
- fastify2.log.error(error);
107
- await reply.status(500).send({
108
- error: "Internal Server Error"
109
- });
110
- }
111
- });
112
- }, "sitemapRoute");
113
-
114
- // src/fastify-config.ts
115
- var fastifyConfig = {
116
- logger: {
117
- transport: {
118
- target: "pino-pretty",
119
- options: {
120
- colorize: true,
121
- translateTime: true,
122
- ignore: "pid,hostname",
123
- singleLine: true
124
- }
125
- }
126
- }
127
- };
11
+ import { fastifySwagger } from "@fastify/swagger";
12
+ import { Hookified } from "hookified";
13
+ import Fastify from "fastify";
128
14
 
129
15
  // src/swagger.ts
130
16
  import { fastifySwaggerUi } from "@fastify/swagger-ui";
@@ -132,7 +18,7 @@ import { fastifySwaggerUi } from "@fastify/swagger-ui";
132
18
  // package.json
133
19
  var package_default = {
134
20
  name: "@jaredwray/mockhttp",
135
- version: "0.2.3",
21
+ version: "0.4.0",
136
22
  description: "Mock Http - Easy way to mock http with httpbin replacement",
137
23
  type: "module",
138
24
  main: "dist/index.js",
@@ -168,23 +54,24 @@ var package_default = {
168
54
  },
169
55
  homepage: "https://github.com/jaredwray/mockhttp#readme",
170
56
  devDependencies: {
171
- "@swc/core": "^1.10.4",
57
+ "@swc/core": "^1.10.9",
172
58
  "@types/html-escaper": "^3.0.2",
173
- "@vitest/coverage-v8": "^2.1.8",
59
+ "@vitest/coverage-v8": "^3.0.4",
174
60
  rimraf: "^6.0.1",
175
- tsup: "^8.3.5",
61
+ tsup: "^8.3.6",
176
62
  tsx: "^4.19.2",
177
- typescript: "^5.7.2",
178
- vitest: "^2.1.8",
63
+ typescript: "^5.7.3",
64
+ vitest: "^3.0.4",
179
65
  xo: "^0.60.0"
180
66
  },
181
67
  dependencies: {
182
- "@fastify/helmet": "^13.0.0",
183
- "@fastify/static": "^8.0.3",
184
- "@fastify/swagger": "^9.4.0",
185
- "@fastify/swagger-ui": "^5.2.0",
186
- "@scalar/api-reference": "^1.25.99",
187
- fastify: "^5.2.0",
68
+ "@fastify/helmet": "^13.0.1",
69
+ "@fastify/static": "^8.0.4",
70
+ "@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",
188
75
  "html-escaper": "^3.0.3",
189
76
  pino: "^9.6.0",
190
77
  "pino-pretty": "^13.0.0"
@@ -197,11 +84,22 @@ var package_default = {
197
84
  };
198
85
 
199
86
  // src/swagger.ts
87
+ var description = `
88
+ 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\`.
89
+
90
+ * [GitHub Repository](https://github.com/jaredwray/mockhttp)
91
+ * [Docker Image](https://hub.docker.com/r/jaredwray/mockhttp)
92
+ * [NPM Package](https://www.npmjs.com/package/jaredwray/mockhttp)
93
+
94
+ # About mockhttp.org
95
+
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.
97
+ `;
200
98
  var fastifySwaggerConfig = {
201
99
  openapi: {
202
100
  info: {
203
101
  title: "Mock HTTP API",
204
- description: "A replacement for httpbin built using Fastify and Typescript",
102
+ description,
205
103
  version: package_default.version
206
104
  },
207
105
  consumes: [
@@ -212,8 +110,8 @@ var fastifySwaggerConfig = {
212
110
  ]
213
111
  }
214
112
  };
215
- var registerSwaggerUi = /* @__PURE__ */ __name(async (fastify2) => {
216
- await fastify2.register(fastifySwaggerUi, {
113
+ var registerSwaggerUi = /* @__PURE__ */ __name(async (fastify) => {
114
+ await fastify.register(fastifySwaggerUi, {
217
115
  routePrefix: "/docs",
218
116
  uiConfig: {
219
117
  docExpansion: "none",
@@ -235,110 +133,122 @@ var registerSwaggerUi = /* @__PURE__ */ __name(async (fastify2) => {
235
133
  });
236
134
  }, "registerSwaggerUi");
237
135
 
238
- // src/routes/request-inspection/ip.ts
239
- var ipSchema = {
240
- description: "Returns the IP address of the client",
241
- tags: [
242
- "Request Inspection"
243
- ],
244
- response: {
245
- // eslint-disable-next-line @typescript-eslint/naming-convention
246
- 200: {
247
- type: "object",
248
- properties: {
249
- ip: {
250
- type: "string",
251
- description: "The IP address of the client"
252
- }
253
- },
254
- required: [
255
- "ip"
256
- ]
136
+ // src/fastify-config.ts
137
+ var fastifyConfig = {
138
+ logger: {
139
+ transport: {
140
+ target: "pino-pretty",
141
+ options: {
142
+ colorize: true,
143
+ translateTime: true,
144
+ ignore: "pid,hostname",
145
+ singleLine: true
146
+ }
257
147
  }
258
148
  }
259
149
  };
260
- var ipRoute = /* @__PURE__ */ __name((fastify2) => {
261
- fastify2.get("/ip", {
262
- schema: ipSchema
263
- }, async (request) => {
264
- const cloudflareIp = request.headers["cf-connecting-ip"];
265
- const forwardedIp = request.headers["x-forwarded-for"];
266
- const remoteIp = request.ip;
267
- const ip = cloudflareIp ?? (typeof forwardedIp === "string" ? forwardedIp.split(",")[0].trim() : remoteIp);
268
- return {
269
- ip
270
- };
271
- });
272
- }, "ipRoute");
273
150
 
274
- // src/routes/request-inspection/headers.ts
275
- var headersSchema = {
276
- description: "Returns all headers of the client request",
277
- tags: [
278
- "Request Inspection"
279
- ],
280
- response: {
281
- // eslint-disable-next-line @typescript-eslint/naming-convention
282
- 200: {
283
- type: "object",
284
- properties: {
285
- headers: {
286
- type: "object",
287
- additionalProperties: {
288
- type: "string"
289
- },
290
- description: "All headers of the client request"
291
- }
292
- },
293
- required: [
294
- "headers"
295
- ]
151
+ // src/routes/index.ts
152
+ var indexRoute = /* @__PURE__ */ __name((fastify) => {
153
+ fastify.get("/", {
154
+ schema: {
155
+ hide: true
296
156
  }
297
- }
298
- };
299
- var headersRoute = /* @__PURE__ */ __name((fastify2) => {
300
- fastify2.get("/headers", {
301
- schema: headersSchema
302
- }, async (request) => {
303
- const headers = request.headers;
304
- return {
305
- headers
306
- };
157
+ }, async (_request, reply) => {
158
+ const redocHtml = `
159
+ <!doctype html>
160
+ <html>
161
+ <head>
162
+ <title>{ mockhttp }</title>
163
+ <meta charset="utf-8" />
164
+ <meta
165
+ name="viewport"
166
+ content="width=device-width, initial-scale=1" />
167
+ <style>
168
+ :root {
169
+ --scalar-custom-header-height: 70px;
170
+ }
171
+ .custom-header {
172
+ height: var(--scalar-custom-header-height);
173
+ background-color: var(--scalar-background-1);
174
+ box-shadow: inset 0 -1px 0 var(--scalar-border-color);
175
+ color: var(--scalar-color-1);
176
+ font-size: var(--scalar-font-size-2);
177
+ padding: 0 18px;
178
+ position: sticky;
179
+ justify-content: space-between;
180
+ top: 0;
181
+ z-index: 100;
182
+ }
183
+ .custom-header,
184
+ .custom-header nav {
185
+ display: flex;
186
+ align-items: center;
187
+ gap: 18px;
188
+ }
189
+
190
+ .custom-header img {
191
+ height: var(--scalar-custom-header-height);
192
+ object-fit: contain;
193
+ }
194
+
195
+ .custom-header a:hover {
196
+ color: var(--scalar-color-2);
197
+ }
198
+
199
+ .github-corner {
200
+ fill: var(--scalar-border-color) !important;
201
+ }
202
+
203
+ </style>
204
+ </head>
205
+ <body>
206
+ <header class="custom-header scalar-app">
207
+ <a href="/"><img src="/logo.svg" alt="{ mockhttp }" /></a>
208
+ <a href="https://github.com/jaredwray/mockhttp" class="github-corner" aria-label="View source on GitHub">
209
+ <svg width="70" height="70" viewBox="0 0 250 250" style="color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
210
+ </header>
211
+
212
+ <script
213
+ id="api-reference"
214
+ data-url="/docs/json"></script>
215
+
216
+ <script src="/scalar/browser/standalone.js"></script>
217
+ </body>
218
+ </html>
219
+ `;
220
+ await reply.type("text/html").send(redocHtml);
307
221
  });
308
- }, "headersRoute");
222
+ }, "indexRoute");
309
223
 
310
- // src/routes/request-inspection/user-agent.ts
311
- var userAgentSchema = {
312
- description: "Returns the User-Agent header of the client request",
313
- tags: [
314
- "Request Inspection"
315
- ],
316
- response: {
317
- // eslint-disable-next-line @typescript-eslint/naming-convention
318
- 200: {
319
- type: "object",
320
- properties: {
321
- userAgent: {
322
- type: "string",
323
- description: "The User-Agent header of the client request"
324
- }
325
- },
326
- required: [
327
- "userAgent"
328
- ]
224
+ // src/routes/sitemap.ts
225
+ var sitemapRoute = /* @__PURE__ */ __name((fastify) => {
226
+ fastify.get("/sitemap.xml", {
227
+ schema: {
228
+ hide: true
229
+ }
230
+ }, async (_request, reply) => {
231
+ try {
232
+ const host = _request.headers.host ?? "mockhttp.org";
233
+ const isSecure = _request.headers["x-forwarded-proto"]?.includes("https");
234
+ const protocol = isSecure ? "https" : "http";
235
+ const xml = `<?xml version="1.0" encoding="UTF-8"?>
236
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
237
+ <url>
238
+ <loc>${protocol}://${host}/</loc>
239
+ <changefreq>monthly</changefreq>
240
+ <priority>1.0</priority>
241
+ </url>
242
+ </urlset>`;
243
+ await reply.type("text/xml").send(xml);
244
+ } catch (error) {
245
+ fastify.log.error(error);
246
+ await reply.status(500).send({
247
+ error: "Internal Server Error"
248
+ });
329
249
  }
330
- }
331
- };
332
- var userAgentRoute = /* @__PURE__ */ __name((fastify2) => {
333
- fastify2.get("/user-agent", {
334
- schema: userAgentSchema
335
- }, async (request) => {
336
- const userAgent = request.headers["user-agent"];
337
- return {
338
- userAgent
339
- };
340
250
  });
341
- }, "userAgentRoute");
251
+ }, "sitemapRoute");
342
252
 
343
253
  // src/routes/http-methods/get.ts
344
254
  var getSchema = {
@@ -387,8 +297,8 @@ var getSchema = {
387
297
  }
388
298
  }
389
299
  };
390
- var getRoute = /* @__PURE__ */ __name((fastify2) => {
391
- fastify2.get("/get", {
300
+ var getRoute = /* @__PURE__ */ __name((fastify) => {
301
+ fastify.get("/get", {
392
302
  schema: getSchema
393
303
  }, async (request, _reply) => ({
394
304
  method: "GET",
@@ -435,8 +345,8 @@ var postSchema = {
435
345
  }
436
346
  }
437
347
  };
438
- var postRoute = /* @__PURE__ */ __name((fastify2) => {
439
- fastify2.post("/post", {
348
+ var postRoute = /* @__PURE__ */ __name((fastify) => {
349
+ fastify.post("/post", {
440
350
  schema: postSchema
441
351
  }, async (request) => ({
442
352
  method: "POST",
@@ -483,8 +393,8 @@ var deleteSchema = {
483
393
  }
484
394
  }
485
395
  };
486
- var deleteRoute = /* @__PURE__ */ __name((fastify2) => {
487
- fastify2.delete("/delete", {
396
+ var deleteRoute = /* @__PURE__ */ __name((fastify) => {
397
+ fastify.delete("/delete", {
488
398
  schema: deleteSchema
489
399
  }, async (request) => ({
490
400
  method: "DELETE",
@@ -531,8 +441,8 @@ var putSchema = {
531
441
  }
532
442
  }
533
443
  };
534
- var putRoute = /* @__PURE__ */ __name((fastify2) => {
535
- fastify2.put("/put", {
444
+ var putRoute = /* @__PURE__ */ __name((fastify) => {
445
+ fastify.put("/put", {
536
446
  schema: putSchema
537
447
  }, async (request) => ({
538
448
  method: "PUT",
@@ -579,8 +489,8 @@ var patchSchema = {
579
489
  }
580
490
  }
581
491
  };
582
- var patchRoute = /* @__PURE__ */ __name((fastify2) => {
583
- fastify2.patch("/patch", {
492
+ var patchRoute = /* @__PURE__ */ __name((fastify) => {
493
+ fastify.patch("/patch", {
584
494
  schema: patchSchema
585
495
  }, async (request) => ({
586
496
  method: "PATCH",
@@ -871,7 +781,7 @@ var statusSchema = {
871
781
  }
872
782
  }
873
783
  };
874
- var statusCodeRoute = /* @__PURE__ */ __name((fastify2) => {
784
+ var statusCodeRoute = /* @__PURE__ */ __name((fastify) => {
875
785
  const handler = /* @__PURE__ */ __name(async (request, reply) => {
876
786
  let { code } = request.params;
877
787
  if (!code || !statusCodes.map((status) => status.code).includes(Number(code))) {
@@ -881,23 +791,128 @@ var statusCodeRoute = /* @__PURE__ */ __name((fastify2) => {
881
791
  status: `Response with status code ${code}`
882
792
  });
883
793
  }, "handler");
884
- fastify2.get("/status/:code?", {
794
+ fastify.get("/status/:code?", {
885
795
  schema: statusSchema
886
796
  }, handler);
887
- fastify2.post("/status/:code?", {
797
+ fastify.post("/status/:code?", {
888
798
  schema: statusSchema
889
799
  }, handler);
890
- fastify2.put("/status/:code?", {
800
+ fastify.put("/status/:code?", {
891
801
  schema: statusSchema
892
802
  }, handler);
893
- fastify2.patch("/status/:code?", {
803
+ fastify.patch("/status/:code?", {
894
804
  schema: statusSchema
895
805
  }, handler);
896
- fastify2.delete("/status/:code?", {
806
+ fastify.delete("/status/:code?", {
897
807
  schema: statusSchema
898
808
  }, handler);
899
809
  }, "statusCodeRoute");
900
810
 
811
+ // src/routes/request-inspection/ip.ts
812
+ var ipSchema = {
813
+ description: "Returns the IP address of the client",
814
+ tags: [
815
+ "Request Inspection"
816
+ ],
817
+ response: {
818
+ // eslint-disable-next-line @typescript-eslint/naming-convention
819
+ 200: {
820
+ type: "object",
821
+ properties: {
822
+ ip: {
823
+ type: "string",
824
+ description: "The IP address of the client"
825
+ }
826
+ },
827
+ required: [
828
+ "ip"
829
+ ]
830
+ }
831
+ }
832
+ };
833
+ var ipRoute = /* @__PURE__ */ __name((fastify) => {
834
+ fastify.get("/ip", {
835
+ schema: ipSchema
836
+ }, async (request) => {
837
+ const cloudflareIp = request.headers["cf-connecting-ip"];
838
+ const forwardedIp = request.headers["x-forwarded-for"];
839
+ const remoteIp = request.ip;
840
+ const ip = cloudflareIp ?? (typeof forwardedIp === "string" ? forwardedIp.split(",")[0].trim() : remoteIp);
841
+ return {
842
+ ip
843
+ };
844
+ });
845
+ }, "ipRoute");
846
+
847
+ // src/routes/request-inspection/headers.ts
848
+ var headersSchema = {
849
+ description: "Returns all headers of the client request",
850
+ tags: [
851
+ "Request Inspection"
852
+ ],
853
+ response: {
854
+ // eslint-disable-next-line @typescript-eslint/naming-convention
855
+ 200: {
856
+ type: "object",
857
+ properties: {
858
+ headers: {
859
+ type: "object",
860
+ additionalProperties: {
861
+ type: "string"
862
+ },
863
+ description: "All headers of the client request"
864
+ }
865
+ },
866
+ required: [
867
+ "headers"
868
+ ]
869
+ }
870
+ }
871
+ };
872
+ var headersRoute = /* @__PURE__ */ __name((fastify) => {
873
+ fastify.get("/headers", {
874
+ schema: headersSchema
875
+ }, async (request) => {
876
+ const headers = request.headers;
877
+ return {
878
+ headers
879
+ };
880
+ });
881
+ }, "headersRoute");
882
+
883
+ // src/routes/request-inspection/user-agent.ts
884
+ var userAgentSchema = {
885
+ description: "Returns the User-Agent header of the client request",
886
+ tags: [
887
+ "Request Inspection"
888
+ ],
889
+ response: {
890
+ // eslint-disable-next-line @typescript-eslint/naming-convention
891
+ 200: {
892
+ type: "object",
893
+ properties: {
894
+ userAgent: {
895
+ type: "string",
896
+ description: "The User-Agent header of the client request"
897
+ }
898
+ },
899
+ required: [
900
+ "userAgent"
901
+ ]
902
+ }
903
+ }
904
+ };
905
+ var userAgentRoute = /* @__PURE__ */ __name((fastify) => {
906
+ fastify.get("/user-agent", {
907
+ schema: userAgentSchema
908
+ }, async (request) => {
909
+ const userAgent = request.headers["user-agent"];
910
+ return {
911
+ userAgent
912
+ };
913
+ });
914
+ }, "userAgentRoute");
915
+
901
916
  // src/routes/response-inspection/cache.ts
902
917
  var cacheGetSchema = {
903
918
  description: "Handles cache validation and retrieval.",
@@ -942,8 +957,8 @@ var cacheSetSchema = {
942
957
  }
943
958
  }
944
959
  };
945
- var cacheRoutes = /* @__PURE__ */ __name((fastify2) => {
946
- fastify2.get("/cache", {
960
+ var cacheRoutes = /* @__PURE__ */ __name((fastify) => {
961
+ fastify.get("/cache", {
947
962
  schema: cacheGetSchema
948
963
  }, async (request, reply) => {
949
964
  const ifModifiedSince = request.headers["if-modified-since"];
@@ -954,7 +969,7 @@ var cacheRoutes = /* @__PURE__ */ __name((fastify2) => {
954
969
  }
955
970
  await reply.send("Cache content or resource response here.");
956
971
  });
957
- fastify2.get("/cache/:value", {
972
+ fastify.get("/cache/:value", {
958
973
  schema: cacheSetSchema
959
974
  }, async (request, reply) => {
960
975
  const { value } = request.params;
@@ -998,8 +1013,8 @@ var etagSchema = {
998
1013
  }
999
1014
  }
1000
1015
  };
1001
- var etagRoutes = /* @__PURE__ */ __name((fastify2) => {
1002
- fastify2.get("/etag/:etag", {
1016
+ var etagRoutes = /* @__PURE__ */ __name((fastify) => {
1017
+ fastify.get("/etag/:etag", {
1003
1018
  schema: etagSchema
1004
1019
  }, async (request, reply) => {
1005
1020
  const { etag } = request.params;
@@ -1038,8 +1053,8 @@ var responseHeadersSchema = {
1038
1053
  }
1039
1054
  }
1040
1055
  };
1041
- var responseHeadersRoutes = /* @__PURE__ */ __name((fastify2) => {
1042
- fastify2.get("/response-headers", {
1056
+ var responseHeadersRoutes = /* @__PURE__ */ __name((fastify) => {
1057
+ fastify.get("/response-headers", {
1043
1058
  schema: responseHeadersSchema
1044
1059
  }, async (request, reply) => {
1045
1060
  const queryParameters = request.query;
@@ -1052,7 +1067,7 @@ var responseHeadersRoutes = /* @__PURE__ */ __name((fastify2) => {
1052
1067
  ]));
1053
1068
  await reply.send(cleanedResponse);
1054
1069
  });
1055
- fastify2.post("/response-headers", {
1070
+ fastify.post("/response-headers", {
1056
1071
  schema: responseHeadersSchema
1057
1072
  }, async (request, reply) => {
1058
1073
  const queryParameters = request.query ?? {};
@@ -1074,53 +1089,351 @@ var responseHeadersRoutes = /* @__PURE__ */ __name((fastify2) => {
1074
1089
  });
1075
1090
  }, "responseHeadersRoutes");
1076
1091
 
1077
- // src/index.ts
1078
- var fastify = Fastify(fastifyConfig);
1079
- await fastify.register(fastifyStatic, {
1080
- root: path.resolve("./node_modules/@scalar/api-reference/dist"),
1081
- prefix: "/scalar"
1082
- });
1083
- await fastify.register(fastifyStatic, {
1084
- root: path.resolve("./public"),
1085
- decorateReply: false
1086
- });
1087
- await fastify.register(fastifyHelmet);
1088
- await fastify.register(fastifySwagger, fastifySwaggerConfig);
1089
- await registerSwaggerUi(fastify);
1090
- await fastify.register(indexRoute);
1091
- await fastify.register(sitemapRoute);
1092
- await fastify.register(getRoute);
1093
- await fastify.register(postRoute);
1094
- await fastify.register(deleteRoute);
1095
- await fastify.register(putRoute);
1096
- await fastify.register(patchRoute);
1097
- await fastify.register(statusCodeRoute);
1098
- await fastify.register(ipRoute);
1099
- await fastify.register(headersRoute);
1100
- await fastify.register(userAgentRoute);
1101
- await fastify.register(cacheRoutes);
1102
- await fastify.register(etagRoutes);
1103
- await fastify.register(responseHeadersRoutes);
1104
- var start = /* @__PURE__ */ __name(async () => {
1105
- try {
1106
- let port = 3e3;
1107
- if (process.env.PORT) {
1108
- port = Number.parseInt(process.env.PORT, 10);
1092
+ // src/routes/redirects/absolute-redirect.ts
1093
+ var absoluteRedirectSchema = {
1094
+ tags: [
1095
+ "Redirects"
1096
+ ],
1097
+ description: "Redirects the request to the target URL using an absolute URL",
1098
+ params: {
1099
+ type: "object",
1100
+ properties: {
1101
+ value: {
1102
+ type: "integer",
1103
+ minimum: 1
1104
+ }
1105
+ },
1106
+ required: [
1107
+ "value"
1108
+ ]
1109
+ },
1110
+ headers: {
1111
+ type: "object",
1112
+ properties: {
1113
+ host: {
1114
+ type: "string"
1115
+ }
1116
+ },
1117
+ required: [
1118
+ "host"
1119
+ ]
1120
+ },
1121
+ response: {
1122
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1123
+ 302: {
1124
+ type: "string"
1109
1125
  }
1110
- let host = "0.0.0.0";
1111
- if (process.env.HOST) {
1112
- host = process.env.HOST;
1126
+ }
1127
+ };
1128
+ var absoluteRedirectRoute = /* @__PURE__ */ __name((fastify) => {
1129
+ fastify.get("/absolute-redirect/:value", {
1130
+ schema: absoluteRedirectSchema
1131
+ }, async (request, reply) => {
1132
+ const value = request.params.value;
1133
+ const { host } = request.headers;
1134
+ const protocol = request.protocol;
1135
+ let url = `${protocol}://${host}/get`;
1136
+ let html = `
1137
+ <title>Redirecting...</title>
1138
+ <h1>Redirecting...</h1>
1139
+ <p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
1140
+ `;
1141
+ if (value > 1) {
1142
+ url = `${protocol}://${host}/absolute-redirect/${value - 1}`;
1143
+ html = `
1144
+ <title>Redirecting...</title>
1145
+ <h1>Redirecting...</h1>
1146
+ <p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
1147
+ `;
1113
1148
  }
1114
- await fastify.listen({
1115
- port,
1116
- host
1117
- });
1118
- } catch (error) {
1119
- fastify.log.error(error);
1120
- process.exit(1);
1149
+ await reply.header("Location", url).status(302).type("text/html").send(html);
1150
+ });
1151
+ }, "absoluteRedirectRoute");
1152
+
1153
+ // src/routes/redirects/relative-redirect.ts
1154
+ var relativeRedirectSchema = {
1155
+ tags: [
1156
+ "Redirects"
1157
+ ],
1158
+ description: "Redirects the request to the target URL using an relative URL",
1159
+ params: {
1160
+ type: "object",
1161
+ properties: {
1162
+ value: {
1163
+ type: "integer",
1164
+ minimum: 1
1165
+ }
1166
+ },
1167
+ required: [
1168
+ "value"
1169
+ ]
1170
+ },
1171
+ headers: {
1172
+ type: "object",
1173
+ properties: {
1174
+ host: {
1175
+ type: "string"
1176
+ }
1177
+ },
1178
+ required: [
1179
+ "host"
1180
+ ]
1181
+ },
1182
+ response: {
1183
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1184
+ 302: {
1185
+ type: "string"
1186
+ }
1187
+ }
1188
+ };
1189
+ var relativeRedirectRoute = /* @__PURE__ */ __name((fastify) => {
1190
+ fastify.get("/relative-redirect/:value", {
1191
+ schema: relativeRedirectSchema
1192
+ }, async (request, reply) => {
1193
+ const value = request.params.value;
1194
+ let url = "/get";
1195
+ let html = `
1196
+ <title>Redirecting...</title>
1197
+ <h1>Redirecting...</h1>
1198
+ <p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
1199
+ `;
1200
+ if (value > 1) {
1201
+ url = `/relative-redirect/${value - 1}`;
1202
+ html = `
1203
+ <title>Redirecting...</title>
1204
+ <h1>Redirecting...</h1>
1205
+ <p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
1206
+ `;
1207
+ }
1208
+ await reply.header("Location", url).status(302).type("text/html").send(html);
1209
+ });
1210
+ }, "relativeRedirectRoute");
1211
+
1212
+ // src/routes/redirects/redirect-to.ts
1213
+ var redirectToSchema = {
1214
+ tags: [
1215
+ "Redirects"
1216
+ ],
1217
+ description: "Redirects the request to the target URL",
1218
+ querystring: {
1219
+ type: "object",
1220
+ properties: {
1221
+ url: {
1222
+ type: "string",
1223
+ format: "uri",
1224
+ description: "The URL to redirect to"
1225
+ },
1226
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1227
+ status_code: {
1228
+ type: "string",
1229
+ pattern: "^[1-5][0-9][0-9]$",
1230
+ description: "The HTTP status code to use for redirection"
1231
+ }
1232
+ },
1233
+ required: [
1234
+ "url"
1235
+ ],
1236
+ additionalProperties: false
1237
+ }
1238
+ };
1239
+ var redirectToRoute = /* @__PURE__ */ __name((fastify) => {
1240
+ const handler = /* @__PURE__ */ __name(async (request, reply) => {
1241
+ const { url, status_code } = request.query;
1242
+ const statusCode = status_code ? Number(status_code) : 302;
1243
+ await reply.redirect(url, statusCode);
1244
+ }, "handler");
1245
+ fastify.get("/redirect-to", {
1246
+ schema: redirectToSchema
1247
+ }, handler);
1248
+ fastify.post("/redirect-to", {
1249
+ schema: redirectToSchema
1250
+ }, handler);
1251
+ fastify.put("/redirect-to", {
1252
+ schema: redirectToSchema
1253
+ }, handler);
1254
+ fastify.patch("/redirect-to", {
1255
+ schema: redirectToSchema
1256
+ }, handler);
1257
+ fastify.delete("/redirect-to", {
1258
+ schema: redirectToSchema
1259
+ }, handler);
1260
+ }, "redirectToRoute");
1261
+
1262
+ // src/mock-http.ts
1263
+ var MockHttp = class extends Hookified {
1264
+ static {
1265
+ __name(this, "MockHttp");
1266
+ }
1267
+ _port = 3e3;
1268
+ _host = "0.0.0.0";
1269
+ _helmet = true;
1270
+ _apiDocs = true;
1271
+ _httpBin = {
1272
+ httpMethods: true,
1273
+ redirects: true,
1274
+ requestInspection: true,
1275
+ responseInspection: true,
1276
+ statusCodes: true
1277
+ };
1278
+ // eslint-disable-next-line new-cap
1279
+ _server = Fastify();
1280
+ constructor(options) {
1281
+ super(options?.hookOptions);
1282
+ if (options?.port) {
1283
+ this._port = options.port;
1284
+ }
1285
+ if (options?.host) {
1286
+ this._host = options.host;
1287
+ }
1288
+ if (options?.helmet !== void 0) {
1289
+ this._helmet = options.helmet;
1290
+ }
1291
+ if (options?.apiDocs !== void 0) {
1292
+ this._apiDocs = options.apiDocs;
1293
+ }
1294
+ if (options?.httpBin !== void 0) {
1295
+ this._httpBin = options.httpBin;
1296
+ }
1297
+ }
1298
+ get port() {
1299
+ return this._port;
1300
+ }
1301
+ set port(port) {
1302
+ this._port = port;
1303
+ }
1304
+ get host() {
1305
+ return this._host;
1306
+ }
1307
+ set host(host) {
1308
+ this._host = host;
1309
+ }
1310
+ get helmet() {
1311
+ return this._helmet;
1312
+ }
1313
+ set helmet(helmet) {
1314
+ this._helmet = helmet;
1315
+ }
1316
+ get apiDocs() {
1317
+ return this._apiDocs;
1318
+ }
1319
+ // eslint-disable-next-line unicorn/prevent-abbreviations
1320
+ set apiDocs(apiDocs) {
1321
+ this._apiDocs = apiDocs;
1322
+ }
1323
+ get httpBin() {
1324
+ return this._httpBin;
1325
+ }
1326
+ set httpBin(httpBinary) {
1327
+ this._httpBin = httpBinary;
1328
+ }
1329
+ get server() {
1330
+ return this._server;
1331
+ }
1332
+ set server(server) {
1333
+ this._server = server;
1334
+ }
1335
+ async start() {
1336
+ try {
1337
+ const { port, host } = this;
1338
+ if (this._server) {
1339
+ await this._server.close();
1340
+ }
1341
+ this._server = Fastify(fastifyConfig);
1342
+ await this._server.register(fastifyStatic, {
1343
+ root: path.resolve("./node_modules/@scalar/api-reference/dist"),
1344
+ prefix: "/scalar"
1345
+ });
1346
+ await this.server.register(fastifyStatic, {
1347
+ root: path.resolve("./public"),
1348
+ decorateReply: false
1349
+ });
1350
+ await this._server.register(sitemapRoute);
1351
+ if (this._helmet) {
1352
+ await this._server.register(fastifyHelmet);
1353
+ }
1354
+ if (this._apiDocs) {
1355
+ await this.registerApiDocs();
1356
+ }
1357
+ const { httpMethods, redirects, requestInspection, responseInspection, statusCodes: statusCodes2 } = this._httpBin;
1358
+ if (httpMethods) {
1359
+ await this.registerHttpMethods();
1360
+ }
1361
+ if (statusCodes2) {
1362
+ await this.registerStatusCodeRoutes();
1363
+ }
1364
+ if (requestInspection) {
1365
+ await this.registerRequestInspectionRoutes();
1366
+ }
1367
+ if (responseInspection) {
1368
+ await this.registerResponseInspectionRoutes();
1369
+ }
1370
+ if (redirects) {
1371
+ await this.registerRedirectRoutes();
1372
+ }
1373
+ await this._server.listen({
1374
+ port,
1375
+ host
1376
+ });
1377
+ } catch (error) {
1378
+ this._server.log.error(error);
1379
+ }
1380
+ }
1381
+ async close() {
1382
+ await this._server.close();
1383
+ }
1384
+ async registerApiDocs(fastifyInstance) {
1385
+ const fastify = fastifyInstance ?? this._server;
1386
+ await fastify.register(fastifySwagger, fastifySwaggerConfig);
1387
+ await registerSwaggerUi(fastify);
1388
+ await fastify.register(indexRoute);
1389
+ }
1390
+ async registerHttpMethods(fastifyInstance) {
1391
+ const fastify = fastifyInstance ?? this._server;
1392
+ await fastify.register(getRoute);
1393
+ await fastify.register(postRoute);
1394
+ await fastify.register(deleteRoute);
1395
+ await fastify.register(putRoute);
1396
+ await fastify.register(patchRoute);
1397
+ }
1398
+ async registerStatusCodeRoutes(fastifyInstance) {
1399
+ const fastify = fastifyInstance ?? this._server;
1400
+ await fastify.register(statusCodeRoute);
1401
+ }
1402
+ async registerRequestInspectionRoutes(fastifyInstance) {
1403
+ const fastify = fastifyInstance ?? this._server;
1404
+ await fastify.register(ipRoute);
1405
+ await fastify.register(headersRoute);
1406
+ await fastify.register(userAgentRoute);
1407
+ }
1408
+ async registerResponseInspectionRoutes(fastifyInstance) {
1409
+ const fastify = fastifyInstance ?? this._server;
1410
+ await fastify.register(cacheRoutes);
1411
+ await fastify.register(etagRoutes);
1412
+ await fastify.register(responseHeadersRoutes);
1413
+ }
1414
+ async registerRedirectRoutes(fastifyInstance) {
1415
+ const fastify = fastifyInstance ?? this._server;
1416
+ await fastify.register(absoluteRedirectRoute);
1417
+ await fastify.register(relativeRedirectRoute);
1418
+ await fastify.register(redirectToRoute);
1419
+ }
1420
+ };
1421
+
1422
+ // src/index.ts
1423
+ var start = /* @__PURE__ */ __name(async () => {
1424
+ const mockHttp = new MockHttp();
1425
+ if (process.env.PORT) {
1426
+ mockHttp.port = Number.parseInt(process.env.PORT, 10);
1427
+ }
1428
+ if (process.env.HOST) {
1429
+ mockHttp.host = process.env.HOST;
1121
1430
  }
1431
+ await mockHttp.start();
1432
+ return mockHttp;
1122
1433
  }, "start");
1123
1434
  await start();
1124
1435
  export {
1436
+ MockHttp as default,
1437
+ MockHttp as mockhttp,
1125
1438
  start
1126
1439
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaredwray/mockhttp",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "Mock Http - Easy way to mock http with httpbin replacement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,23 +36,24 @@
36
36
  },
37
37
  "homepage": "https://github.com/jaredwray/mockhttp#readme",
38
38
  "devDependencies": {
39
- "@swc/core": "^1.10.4",
39
+ "@swc/core": "^1.10.9",
40
40
  "@types/html-escaper": "^3.0.2",
41
- "@vitest/coverage-v8": "^2.1.8",
41
+ "@vitest/coverage-v8": "^3.0.4",
42
42
  "rimraf": "^6.0.1",
43
- "tsup": "^8.3.5",
43
+ "tsup": "^8.3.6",
44
44
  "tsx": "^4.19.2",
45
- "typescript": "^5.7.2",
46
- "vitest": "^2.1.8",
45
+ "typescript": "^5.7.3",
46
+ "vitest": "^3.0.4",
47
47
  "xo": "^0.60.0"
48
48
  },
49
49
  "dependencies": {
50
- "@fastify/helmet": "^13.0.0",
51
- "@fastify/static": "^8.0.3",
52
- "@fastify/swagger": "^9.4.0",
53
- "@fastify/swagger-ui": "^5.2.0",
54
- "@scalar/api-reference": "^1.25.99",
55
- "fastify": "^5.2.0",
50
+ "@fastify/helmet": "^13.0.1",
51
+ "@fastify/static": "^8.0.4",
52
+ "@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",
56
57
  "html-escaper": "^3.0.3",
57
58
  "pino": "^9.6.0",
58
59
  "pino-pretty": "^13.0.0"