@jaredwray/mockhttp 0.2.2 → 0.3.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 +12 -4
- package/dist/index.js +230 -21
- package/package.json +14 -15
- package/public/robots.txt +2 -0
package/README.md
CHANGED
|
@@ -7,9 +7,17 @@
|
|
|
7
7
|
[](https://npmjs.com/package/@jaredwray/mockhttp)
|
|
8
8
|
[](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
|
+
* CORS and Helmet support
|
|
15
|
+
* Built with `nodejs` 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
|
|
35
|
+
await mockhttp.start(); // start the server
|
|
28
36
|
const response = await fetch('http://localhost:8080/ip');
|
|
29
|
-
mockhttp.stop(); // stop the server
|
|
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.js
CHANGED
|
@@ -8,9 +8,8 @@ import Fastify from "fastify";
|
|
|
8
8
|
import fastifyStatic from "@fastify/static";
|
|
9
9
|
import { fastifySwagger } from "@fastify/swagger";
|
|
10
10
|
import fastifyHelmet from "@fastify/helmet";
|
|
11
|
-
import fastifyCors from "@fastify/cors";
|
|
12
11
|
|
|
13
|
-
// src/routes/index
|
|
12
|
+
// src/routes/index.ts
|
|
14
13
|
var indexRoute = /* @__PURE__ */ __name((fastify2) => {
|
|
15
14
|
fastify2.get("/", {
|
|
16
15
|
schema: {
|
|
@@ -83,6 +82,35 @@ var indexRoute = /* @__PURE__ */ __name((fastify2) => {
|
|
|
83
82
|
});
|
|
84
83
|
}, "indexRoute");
|
|
85
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
|
+
|
|
86
114
|
// src/fastify-config.ts
|
|
87
115
|
var fastifyConfig = {
|
|
88
116
|
logger: {
|
|
@@ -104,7 +132,7 @@ import { fastifySwaggerUi } from "@fastify/swagger-ui";
|
|
|
104
132
|
// package.json
|
|
105
133
|
var package_default = {
|
|
106
134
|
name: "@jaredwray/mockhttp",
|
|
107
|
-
version: "0.
|
|
135
|
+
version: "0.3.0",
|
|
108
136
|
description: "Mock Http - Easy way to mock http with httpbin replacement",
|
|
109
137
|
type: "module",
|
|
110
138
|
main: "dist/index.js",
|
|
@@ -113,7 +141,7 @@ var package_default = {
|
|
|
113
141
|
},
|
|
114
142
|
scripts: {
|
|
115
143
|
test: "xo --fix && vitest run --coverage",
|
|
116
|
-
dev: "xo --fix &&
|
|
144
|
+
dev: "xo --fix && tsx src/index.ts --watch",
|
|
117
145
|
build: "rimraf ./dist && tsup src/index.ts --format esm --dts --clean",
|
|
118
146
|
"docker:build": "docker build -t jaredwray/mockhttp .",
|
|
119
147
|
"docker:run": "docker run -p 3000:3000 jaredwray/mockhttp",
|
|
@@ -140,26 +168,25 @@ var package_default = {
|
|
|
140
168
|
},
|
|
141
169
|
homepage: "https://github.com/jaredwray/mockhttp#readme",
|
|
142
170
|
devDependencies: {
|
|
143
|
-
"@swc/core": "^1.10.
|
|
171
|
+
"@swc/core": "^1.10.9",
|
|
144
172
|
"@types/html-escaper": "^3.0.2",
|
|
145
|
-
"@vitest/coverage-v8": "^
|
|
173
|
+
"@vitest/coverage-v8": "^3.0.4",
|
|
146
174
|
rimraf: "^6.0.1",
|
|
147
|
-
tsup: "^8.3.
|
|
175
|
+
tsup: "^8.3.6",
|
|
148
176
|
tsx: "^4.19.2",
|
|
149
|
-
typescript: "^5.7.
|
|
150
|
-
vitest: "^
|
|
177
|
+
typescript: "^5.7.3",
|
|
178
|
+
vitest: "^3.0.4",
|
|
151
179
|
xo: "^0.60.0"
|
|
152
180
|
},
|
|
153
181
|
dependencies: {
|
|
154
|
-
"@fastify/
|
|
155
|
-
"@fastify/
|
|
156
|
-
"@fastify/
|
|
157
|
-
"@fastify/swagger": "^
|
|
158
|
-
"@
|
|
159
|
-
|
|
160
|
-
fastify: "^5.1.0",
|
|
182
|
+
"@fastify/helmet": "^13.0.1",
|
|
183
|
+
"@fastify/static": "^8.0.4",
|
|
184
|
+
"@fastify/swagger": "^9.4.2",
|
|
185
|
+
"@fastify/swagger-ui": "^5.2.1",
|
|
186
|
+
"@scalar/api-reference": "^1.25.108",
|
|
187
|
+
fastify: "^5.2.1",
|
|
161
188
|
"html-escaper": "^3.0.3",
|
|
162
|
-
pino: "^9.
|
|
189
|
+
pino: "^9.6.0",
|
|
163
190
|
"pino-pretty": "^13.0.0"
|
|
164
191
|
},
|
|
165
192
|
files: [
|
|
@@ -170,11 +197,22 @@ var package_default = {
|
|
|
170
197
|
};
|
|
171
198
|
|
|
172
199
|
// src/swagger.ts
|
|
200
|
+
var description = `
|
|
201
|
+
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\`.
|
|
202
|
+
|
|
203
|
+
* [GitHub Repository](https://github.com/jaredwray/mockhttp)
|
|
204
|
+
* [Docker Image](https://hub.docker.com/r/jaredwray/mockhttp)
|
|
205
|
+
* [NPM Package](https://www.npmjs.com/package/jaredwray/mockhttp)
|
|
206
|
+
|
|
207
|
+
# About mockhttp.org
|
|
208
|
+
|
|
209
|
+
[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.
|
|
210
|
+
`;
|
|
173
211
|
var fastifySwaggerConfig = {
|
|
174
212
|
openapi: {
|
|
175
213
|
info: {
|
|
176
214
|
title: "Mock HTTP API",
|
|
177
|
-
description
|
|
215
|
+
description,
|
|
178
216
|
version: package_default.version
|
|
179
217
|
},
|
|
180
218
|
consumes: [
|
|
@@ -1047,6 +1085,176 @@ var responseHeadersRoutes = /* @__PURE__ */ __name((fastify2) => {
|
|
|
1047
1085
|
});
|
|
1048
1086
|
}, "responseHeadersRoutes");
|
|
1049
1087
|
|
|
1088
|
+
// src/routes/redirects/absolute-redirect.ts
|
|
1089
|
+
var absoluteRedirectSchema = {
|
|
1090
|
+
tags: [
|
|
1091
|
+
"Redirects"
|
|
1092
|
+
],
|
|
1093
|
+
description: "Redirects the request to the target URL using an absolute URL",
|
|
1094
|
+
params: {
|
|
1095
|
+
type: "object",
|
|
1096
|
+
properties: {
|
|
1097
|
+
value: {
|
|
1098
|
+
type: "integer",
|
|
1099
|
+
minimum: 1
|
|
1100
|
+
}
|
|
1101
|
+
},
|
|
1102
|
+
required: [
|
|
1103
|
+
"value"
|
|
1104
|
+
]
|
|
1105
|
+
},
|
|
1106
|
+
headers: {
|
|
1107
|
+
type: "object",
|
|
1108
|
+
properties: {
|
|
1109
|
+
host: {
|
|
1110
|
+
type: "string"
|
|
1111
|
+
}
|
|
1112
|
+
},
|
|
1113
|
+
required: [
|
|
1114
|
+
"host"
|
|
1115
|
+
]
|
|
1116
|
+
},
|
|
1117
|
+
response: {
|
|
1118
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1119
|
+
302: {
|
|
1120
|
+
type: "string"
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
var absoluteRedirectRoute = /* @__PURE__ */ __name((fastify2) => {
|
|
1125
|
+
fastify2.get("/absolute-redirect/:value", {
|
|
1126
|
+
schema: absoluteRedirectSchema
|
|
1127
|
+
}, async (request, reply) => {
|
|
1128
|
+
const value = request.params.value;
|
|
1129
|
+
const { host } = request.headers;
|
|
1130
|
+
const protocol = request.protocol;
|
|
1131
|
+
let url = `${protocol}://${host}/get`;
|
|
1132
|
+
let html = `
|
|
1133
|
+
<title>Redirecting...</title>
|
|
1134
|
+
<h1>Redirecting...</h1>
|
|
1135
|
+
<p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
|
|
1136
|
+
`;
|
|
1137
|
+
if (value > 1) {
|
|
1138
|
+
url = `${protocol}://${host}/absolute-redirect/${value - 1}`;
|
|
1139
|
+
html = `
|
|
1140
|
+
<title>Redirecting...</title>
|
|
1141
|
+
<h1>Redirecting...</h1>
|
|
1142
|
+
<p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
|
|
1143
|
+
`;
|
|
1144
|
+
}
|
|
1145
|
+
await reply.header("Location", url).status(302).type("text/html").send(html);
|
|
1146
|
+
});
|
|
1147
|
+
}, "absoluteRedirectRoute");
|
|
1148
|
+
|
|
1149
|
+
// src/routes/redirects/relative-redirect.ts
|
|
1150
|
+
var relativeRedirectSchema = {
|
|
1151
|
+
tags: [
|
|
1152
|
+
"Redirects"
|
|
1153
|
+
],
|
|
1154
|
+
description: "Redirects the request to the target URL using an relative URL",
|
|
1155
|
+
params: {
|
|
1156
|
+
type: "object",
|
|
1157
|
+
properties: {
|
|
1158
|
+
value: {
|
|
1159
|
+
type: "integer",
|
|
1160
|
+
minimum: 1
|
|
1161
|
+
}
|
|
1162
|
+
},
|
|
1163
|
+
required: [
|
|
1164
|
+
"value"
|
|
1165
|
+
]
|
|
1166
|
+
},
|
|
1167
|
+
headers: {
|
|
1168
|
+
type: "object",
|
|
1169
|
+
properties: {
|
|
1170
|
+
host: {
|
|
1171
|
+
type: "string"
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
required: [
|
|
1175
|
+
"host"
|
|
1176
|
+
]
|
|
1177
|
+
},
|
|
1178
|
+
response: {
|
|
1179
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1180
|
+
302: {
|
|
1181
|
+
type: "string"
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
var relativeRedirectRoute = /* @__PURE__ */ __name((fastify2) => {
|
|
1186
|
+
fastify2.get("/relative-redirect/:value", {
|
|
1187
|
+
schema: relativeRedirectSchema
|
|
1188
|
+
}, async (request, reply) => {
|
|
1189
|
+
const value = request.params.value;
|
|
1190
|
+
let url = "/get";
|
|
1191
|
+
let html = `
|
|
1192
|
+
<title>Redirecting...</title>
|
|
1193
|
+
<h1>Redirecting...</h1>
|
|
1194
|
+
<p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
|
|
1195
|
+
`;
|
|
1196
|
+
if (value > 1) {
|
|
1197
|
+
url = `/relative-redirect/${value - 1}`;
|
|
1198
|
+
html = `
|
|
1199
|
+
<title>Redirecting...</title>
|
|
1200
|
+
<h1>Redirecting...</h1>
|
|
1201
|
+
<p>You should be redirected automatically to target URL: <a href="${url}">${url}</a>. If not click the link.</p>
|
|
1202
|
+
`;
|
|
1203
|
+
}
|
|
1204
|
+
await reply.header("Location", url).status(302).type("text/html").send(html);
|
|
1205
|
+
});
|
|
1206
|
+
}, "relativeRedirectRoute");
|
|
1207
|
+
|
|
1208
|
+
// src/routes/redirects/redirect-to.ts
|
|
1209
|
+
var redirectToSchema = {
|
|
1210
|
+
tags: [
|
|
1211
|
+
"Redirects"
|
|
1212
|
+
],
|
|
1213
|
+
description: "Redirects the request to the target URL",
|
|
1214
|
+
querystring: {
|
|
1215
|
+
type: "object",
|
|
1216
|
+
properties: {
|
|
1217
|
+
url: {
|
|
1218
|
+
type: "string",
|
|
1219
|
+
format: "uri",
|
|
1220
|
+
description: "The URL to redirect to"
|
|
1221
|
+
},
|
|
1222
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1223
|
+
status_code: {
|
|
1224
|
+
type: "string",
|
|
1225
|
+
pattern: "^[1-5][0-9][0-9]$",
|
|
1226
|
+
description: "The HTTP status code to use for redirection"
|
|
1227
|
+
}
|
|
1228
|
+
},
|
|
1229
|
+
required: [
|
|
1230
|
+
"url"
|
|
1231
|
+
],
|
|
1232
|
+
additionalProperties: false
|
|
1233
|
+
}
|
|
1234
|
+
};
|
|
1235
|
+
var redirectToRoute = /* @__PURE__ */ __name((fastify2) => {
|
|
1236
|
+
const handler = /* @__PURE__ */ __name(async (request, reply) => {
|
|
1237
|
+
const { url, status_code } = request.query;
|
|
1238
|
+
const statusCode = status_code ? Number(status_code) : 302;
|
|
1239
|
+
await reply.redirect(url, statusCode);
|
|
1240
|
+
}, "handler");
|
|
1241
|
+
fastify2.get("/redirect-to", {
|
|
1242
|
+
schema: redirectToSchema
|
|
1243
|
+
}, handler);
|
|
1244
|
+
fastify2.post("/redirect-to", {
|
|
1245
|
+
schema: redirectToSchema
|
|
1246
|
+
}, handler);
|
|
1247
|
+
fastify2.put("/redirect-to", {
|
|
1248
|
+
schema: redirectToSchema
|
|
1249
|
+
}, handler);
|
|
1250
|
+
fastify2.patch("/redirect-to", {
|
|
1251
|
+
schema: redirectToSchema
|
|
1252
|
+
}, handler);
|
|
1253
|
+
fastify2.delete("/redirect-to", {
|
|
1254
|
+
schema: redirectToSchema
|
|
1255
|
+
}, handler);
|
|
1256
|
+
}, "redirectToRoute");
|
|
1257
|
+
|
|
1050
1258
|
// src/index.ts
|
|
1051
1259
|
var fastify = Fastify(fastifyConfig);
|
|
1052
1260
|
await fastify.register(fastifyStatic, {
|
|
@@ -1057,13 +1265,11 @@ await fastify.register(fastifyStatic, {
|
|
|
1057
1265
|
root: path.resolve("./public"),
|
|
1058
1266
|
decorateReply: false
|
|
1059
1267
|
});
|
|
1060
|
-
await fastify.register(fastifyCors, {
|
|
1061
|
-
origin: "*"
|
|
1062
|
-
});
|
|
1063
1268
|
await fastify.register(fastifyHelmet);
|
|
1064
1269
|
await fastify.register(fastifySwagger, fastifySwaggerConfig);
|
|
1065
1270
|
await registerSwaggerUi(fastify);
|
|
1066
1271
|
await fastify.register(indexRoute);
|
|
1272
|
+
await fastify.register(sitemapRoute);
|
|
1067
1273
|
await fastify.register(getRoute);
|
|
1068
1274
|
await fastify.register(postRoute);
|
|
1069
1275
|
await fastify.register(deleteRoute);
|
|
@@ -1076,6 +1282,9 @@ await fastify.register(userAgentRoute);
|
|
|
1076
1282
|
await fastify.register(cacheRoutes);
|
|
1077
1283
|
await fastify.register(etagRoutes);
|
|
1078
1284
|
await fastify.register(responseHeadersRoutes);
|
|
1285
|
+
await fastify.register(absoluteRedirectRoute);
|
|
1286
|
+
await fastify.register(relativeRedirectRoute);
|
|
1287
|
+
await fastify.register(redirectToRoute);
|
|
1079
1288
|
var start = /* @__PURE__ */ __name(async () => {
|
|
1080
1289
|
try {
|
|
1081
1290
|
let port = 3e3;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaredwray/mockhttp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Mock Http - Easy way to mock http with httpbin replacement",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "xo --fix && vitest run --coverage",
|
|
12
|
-
"dev": "xo --fix &&
|
|
12
|
+
"dev": "xo --fix && tsx src/index.ts --watch",
|
|
13
13
|
"build": "rimraf ./dist && tsup src/index.ts --format esm --dts --clean",
|
|
14
14
|
"docker:build": "docker build -t jaredwray/mockhttp .",
|
|
15
15
|
"docker:run": "docker run -p 3000:3000 jaredwray/mockhttp",
|
|
@@ -36,26 +36,25 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://github.com/jaredwray/mockhttp#readme",
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@swc/core": "^1.10.
|
|
39
|
+
"@swc/core": "^1.10.9",
|
|
40
40
|
"@types/html-escaper": "^3.0.2",
|
|
41
|
-
"@vitest/coverage-v8": "^
|
|
41
|
+
"@vitest/coverage-v8": "^3.0.4",
|
|
42
42
|
"rimraf": "^6.0.1",
|
|
43
|
-
"tsup": "^8.3.
|
|
43
|
+
"tsup": "^8.3.6",
|
|
44
44
|
"tsx": "^4.19.2",
|
|
45
|
-
"typescript": "^5.7.
|
|
46
|
-
"vitest": "^
|
|
45
|
+
"typescript": "^5.7.3",
|
|
46
|
+
"vitest": "^3.0.4",
|
|
47
47
|
"xo": "^0.60.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@fastify/
|
|
51
|
-
"@fastify/
|
|
52
|
-
"@fastify/
|
|
53
|
-
"@fastify/swagger": "^
|
|
54
|
-
"@
|
|
55
|
-
"
|
|
56
|
-
"fastify": "^5.1.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",
|
|
57
56
|
"html-escaper": "^3.0.3",
|
|
58
|
-
"pino": "^9.
|
|
57
|
+
"pino": "^9.6.0",
|
|
59
58
|
"pino-pretty": "^13.0.0"
|
|
60
59
|
},
|
|
61
60
|
"files": [
|