srvx 0.9.3 → 0.9.5
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/dist/_chunks/_color-Dtg6hRMg.mjs +18 -0
- package/dist/_chunks/{_plugins-DBERsPAu.mjs → _plugins-CPeJORNN.mjs} +9 -11
- package/dist/_chunks/{_utils-dqVgpDNy.mjs → _utils-DS1d5FUa.mjs} +3 -1
- package/dist/adapters/bun.mjs +3 -3
- package/dist/adapters/cloudflare.mjs +2 -2
- package/dist/adapters/deno.mjs +3 -3
- package/dist/adapters/generic.mjs +3 -3
- package/dist/adapters/node.mjs +3 -3
- package/dist/adapters/service-worker.mjs +2 -2
- package/dist/cli.mjs +45 -45
- package/dist/log.mjs +6 -6
- package/package.json +1 -1
- package/dist/_chunks/_utils.cli-B2YzwlOv.mjs +0 -31
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/_color.ts
|
|
2
|
+
const noColor = /* @__PURE__ */ (() => {
|
|
3
|
+
const env = globalThis.process?.env;
|
|
4
|
+
return env.NO_COLOR === "1" || env.TERM === "dumb";
|
|
5
|
+
})();
|
|
6
|
+
const _c = (c, r = 39) => (t) => noColor ? t : `\u001B[${c}m${t}\u001B[${r}m`;
|
|
7
|
+
const bold = /* @__PURE__ */ _c(1, 22);
|
|
8
|
+
const red = /* @__PURE__ */ _c(31);
|
|
9
|
+
const green = /* @__PURE__ */ _c(32);
|
|
10
|
+
const yellow = /* @__PURE__ */ _c(33);
|
|
11
|
+
const blue = /* @__PURE__ */ _c(34);
|
|
12
|
+
const magenta = /* @__PURE__ */ _c(35);
|
|
13
|
+
const cyan = /* @__PURE__ */ _c(36);
|
|
14
|
+
const gray = /* @__PURE__ */ _c(90);
|
|
15
|
+
const url = (title, url$1) => noColor ? `[${title}](${url$1})` : `\u001B]8;;${url$1}\u001B\\${title}\u001B]8;;\u001B\\`;
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { blue, bold, cyan, gray, green, magenta, red, url, yellow };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gray, red } from "./_color-Dtg6hRMg.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/_middleware.ts
|
|
4
4
|
function wrapFetch(server) {
|
|
@@ -34,23 +34,21 @@ const gracefulShutdownPlugin = (server) => {
|
|
|
34
34
|
const shutdown = async () => {
|
|
35
35
|
if (isShuttingDown) return;
|
|
36
36
|
isShuttingDown = true;
|
|
37
|
-
|
|
37
|
+
const w = process.stderr.write.bind(process.stderr);
|
|
38
|
+
w(gray(`\nShutting down server in ${gracefulShutdown}s...`));
|
|
38
39
|
let timeout;
|
|
39
40
|
await Promise.race([server.close().finally(() => {
|
|
40
41
|
clearTimeout(timeout);
|
|
41
|
-
|
|
42
|
+
w(gray(" Server closed.\n"));
|
|
42
43
|
}), new Promise((resolve) => {
|
|
43
44
|
timeout = setTimeout(() => {
|
|
44
|
-
|
|
45
|
+
w(gray(`\nForce closing connections in ${forceShutdown}s...`));
|
|
45
46
|
timeout = setTimeout(() => {
|
|
46
|
-
|
|
47
|
+
w(red("\nCould not close connections in time, force exiting."));
|
|
47
48
|
resolve();
|
|
48
|
-
}, 1e3);
|
|
49
|
-
return server.close(true)
|
|
50
|
-
|
|
51
|
-
resolve();
|
|
52
|
-
});
|
|
53
|
-
}, 1e3);
|
|
49
|
+
}, forceShutdown * 1e3);
|
|
50
|
+
return server.close(true);
|
|
51
|
+
}, gracefulShutdown * 1e3);
|
|
54
52
|
})]);
|
|
55
53
|
globalThis.process.exit(0);
|
|
56
54
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
function resolvePortAndHost(opts) {
|
|
3
3
|
const _port = opts.port ?? globalThis.process?.env.PORT ?? 3e3;
|
|
4
4
|
const port = typeof _port === "number" ? _port : Number.parseInt(_port, 10);
|
|
5
|
+
if (port < 0 || port > 65535) throw new RangeError(`Port must be between 0 and 65535 (got "${port}").`);
|
|
5
6
|
const hostname = opts.hostname ?? globalThis.process?.env.HOST;
|
|
6
7
|
return {
|
|
7
8
|
port,
|
|
@@ -56,7 +57,8 @@ function createWaitUntil() {
|
|
|
56
57
|
const promises = new Set();
|
|
57
58
|
return {
|
|
58
59
|
waitUntil: (promise) => {
|
|
59
|
-
|
|
60
|
+
if (typeof promise?.then !== "function") return;
|
|
61
|
+
promises.add(Promise.resolve(promise).catch(console.error).finally(() => {
|
|
60
62
|
promises.delete(promise);
|
|
61
63
|
}));
|
|
62
64
|
},
|
package/dist/adapters/bun.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "../_chunks/
|
|
1
|
+
import "../_chunks/_color-Dtg6hRMg.mjs";
|
|
2
2
|
import "../_chunks/_inherit-B9eAGP_O.mjs";
|
|
3
3
|
import { FastURL$1 as FastURL } from "../_chunks/_url-DF-_pEPn.mjs";
|
|
4
|
-
import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-
|
|
5
|
-
import { gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-
|
|
4
|
+
import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-DS1d5FUa.mjs";
|
|
5
|
+
import { gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-CPeJORNN.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/adapters/bun.ts
|
|
8
8
|
const FastResponse = Response;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../_chunks/
|
|
2
|
-
import { errorPlugin, wrapFetch } from "../_chunks/_plugins-
|
|
1
|
+
import "../_chunks/_color-Dtg6hRMg.mjs";
|
|
2
|
+
import { errorPlugin, wrapFetch } from "../_chunks/_plugins-CPeJORNN.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/adapters/cloudflare.ts
|
|
5
5
|
const FastURL = URL;
|
package/dist/adapters/deno.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "../_chunks/
|
|
1
|
+
import "../_chunks/_color-Dtg6hRMg.mjs";
|
|
2
2
|
import "../_chunks/_inherit-B9eAGP_O.mjs";
|
|
3
3
|
import { FastURL$1 as FastURL } from "../_chunks/_url-DF-_pEPn.mjs";
|
|
4
|
-
import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-
|
|
5
|
-
import { gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-
|
|
4
|
+
import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-DS1d5FUa.mjs";
|
|
5
|
+
import { gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-CPeJORNN.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/adapters/deno.ts
|
|
8
8
|
const FastResponse = Response;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "../_chunks/
|
|
2
|
-
import { createWaitUntil } from "../_chunks/_utils-
|
|
3
|
-
import { errorPlugin, wrapFetch } from "../_chunks/_plugins-
|
|
1
|
+
import "../_chunks/_color-Dtg6hRMg.mjs";
|
|
2
|
+
import { createWaitUntil } from "../_chunks/_utils-DS1d5FUa.mjs";
|
|
3
|
+
import { errorPlugin, wrapFetch } from "../_chunks/_plugins-CPeJORNN.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/adapters/generic.ts
|
|
6
6
|
const FastURL = URL;
|
package/dist/adapters/node.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "../_chunks/
|
|
1
|
+
import "../_chunks/_color-Dtg6hRMg.mjs";
|
|
2
2
|
import { lazyInherit } from "../_chunks/_inherit-B9eAGP_O.mjs";
|
|
3
3
|
import { FastURL$1 as FastURL } from "../_chunks/_url-DF-_pEPn.mjs";
|
|
4
|
-
import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-
|
|
5
|
-
import { errorPlugin, gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-
|
|
4
|
+
import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-DS1d5FUa.mjs";
|
|
5
|
+
import { errorPlugin, gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-CPeJORNN.mjs";
|
|
6
6
|
import { NodeResponse, callNodeHandler } from "../_chunks/call-BUTAdRs1.mjs";
|
|
7
7
|
import nodeHTTP, { IncomingMessage, ServerResponse } from "node:http";
|
|
8
8
|
import { Duplex, Readable } from "node:stream";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../_chunks/
|
|
2
|
-
import { errorPlugin, wrapFetch } from "../_chunks/_plugins-
|
|
1
|
+
import "../_chunks/_color-Dtg6hRMg.mjs";
|
|
2
|
+
import { errorPlugin, wrapFetch } from "../_chunks/_plugins-CPeJORNN.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/adapters/service-worker.ts
|
|
5
5
|
const FastURL = URL;
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bold, cyan, gray, green, magenta, red, url, yellow } from "./_chunks/_color-Dtg6hRMg.mjs";
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
4
|
import * as nodeHTTP$1 from "node:http";
|
|
@@ -156,8 +156,8 @@ async function loadEntry(opts) {
|
|
|
156
156
|
} catch (error) {
|
|
157
157
|
if (error?.code === "ERR_UNKNOWN_FILE_EXTENSION") {
|
|
158
158
|
const message = String(error);
|
|
159
|
-
if (/"\.(m|c)?ts"/g.test(message)) console.error(
|
|
160
|
-
else if (/"\.(m|c)?tsx"/g.test(message)) console.error(
|
|
159
|
+
if (/"\.(m|c)?ts"/g.test(message)) console.error(red(`\nMake sure you're using Node.js v22.18+ or v24+ for TypeScript support (current version: ${process.versions.node})\n\n`));
|
|
160
|
+
else if (/"\.(m|c)?tsx"/g.test(message)) console.error(red(`\nYou need a compatible loader for JSX support (Deno, Bun or srvx --register jiti/register)\n\n`));
|
|
161
161
|
}
|
|
162
162
|
if (error instanceof Error) Error.captureStackTrace?.(error, serve);
|
|
163
163
|
throw error;
|
|
@@ -183,14 +183,14 @@ function renderError(error, status = 500, title = "Server Error") {
|
|
|
183
183
|
}
|
|
184
184
|
function printInfo(entry) {
|
|
185
185
|
let entryInfo;
|
|
186
|
-
if (options._entry) entryInfo =
|
|
187
|
-
else entryInfo =
|
|
188
|
-
console.log(
|
|
189
|
-
if (options._entry && entry._error) console.error(
|
|
186
|
+
if (options._entry) entryInfo = cyan("./" + relative(".", options._entry));
|
|
187
|
+
else entryInfo = gray(`(create ${bold(`server.ts`)} to enable)`);
|
|
188
|
+
console.log(gray(`${bold(gray("λ"))} Server handler: ${entryInfo}`));
|
|
189
|
+
if (options._entry && entry._error) console.error(red(` ${entry._error}`));
|
|
190
190
|
let staticInfo;
|
|
191
|
-
if (options._static) staticInfo =
|
|
192
|
-
else staticInfo =
|
|
193
|
-
console.log(
|
|
191
|
+
if (options._static) staticInfo = cyan("./" + relative(".", options._static) + "/");
|
|
192
|
+
else staticInfo = gray(`(add ${bold("public/")} dir to enable)`);
|
|
193
|
+
console.log(gray(`${bold(gray("∘"))} Static files: ${staticInfo}`));
|
|
194
194
|
}
|
|
195
195
|
async function interceptListen(cb) {
|
|
196
196
|
const originalListen = nodeHTTP$1.Server.prototype.listen;
|
|
@@ -217,7 +217,7 @@ async function interceptListen(cb) {
|
|
|
217
217
|
};
|
|
218
218
|
}
|
|
219
219
|
async function version() {
|
|
220
|
-
const version$1 = "0.9.
|
|
220
|
+
const version$1 = "0.9.4";
|
|
221
221
|
return `srvx ${version$1}\n${runtime()}`;
|
|
222
222
|
}
|
|
223
223
|
function runtime() {
|
|
@@ -266,7 +266,7 @@ function parseArgs$1(args$1) {
|
|
|
266
266
|
dir = dirname(entry);
|
|
267
267
|
}
|
|
268
268
|
if (!existsSync(dir)) {
|
|
269
|
-
console.error(
|
|
269
|
+
console.error(red(`Directory "${dir}" does not exist.\n`));
|
|
270
270
|
process.exit(1);
|
|
271
271
|
}
|
|
272
272
|
return {
|
|
@@ -287,55 +287,55 @@ function parseArgs$1(args$1) {
|
|
|
287
287
|
}
|
|
288
288
|
function example() {
|
|
289
289
|
const useTs = !options._entry || options._entry.endsWith(".ts");
|
|
290
|
-
return `${
|
|
291
|
-
${
|
|
292
|
-
${
|
|
293
|
-
${
|
|
290
|
+
return `${bold(gray("// server.ts"))}
|
|
291
|
+
${magenta("export default")} {
|
|
292
|
+
${cyan("fetch")}(req${useTs ? ": Request" : ""}) {
|
|
293
|
+
${magenta("return")} new Response(${green("\"Hello, World!\"")});
|
|
294
294
|
}
|
|
295
295
|
}`;
|
|
296
296
|
}
|
|
297
297
|
function usage(mainOpts) {
|
|
298
298
|
const command = mainOpts.command;
|
|
299
299
|
return `
|
|
300
|
-
${
|
|
300
|
+
${cyan(command)} - Start an HTTP server with the specified entry path.
|
|
301
301
|
|
|
302
|
-
${
|
|
302
|
+
${bold("USAGE")}
|
|
303
303
|
${existsSync(options._entry) ? "" : `\n${example()}\n`}
|
|
304
|
-
${
|
|
305
|
-
${
|
|
306
|
-
${
|
|
307
|
-
${
|
|
308
|
-
${
|
|
309
|
-
${
|
|
310
|
-
${
|
|
304
|
+
${gray("# srvx [options] [entry]")}
|
|
305
|
+
${gray("$")} ${cyan(command)} ${gray("./server.ts")} ${gray("# Start development server")}
|
|
306
|
+
${gray("$")} ${cyan(command)} --prod ${gray("# Start production server")}
|
|
307
|
+
${gray("$")} ${cyan(command)} --port=8080 ${gray("# Listen on port 8080")}
|
|
308
|
+
${gray("$")} ${cyan(command)} --host=localhost ${gray("# Bind to localhost only")}
|
|
309
|
+
${gray("$")} ${cyan(command)} --import=jiti/register ${gray(`# Enable ${url("jiti", "https://github.com/unjs/jiti")} loader`)}
|
|
310
|
+
${gray("$")} ${cyan(command)} --tls --cert=cert.pem --key=key.pem ${gray("# Enable TLS (HTTPS/HTTP2)")}
|
|
311
311
|
|
|
312
312
|
|
|
313
|
-
${
|
|
313
|
+
${bold("ARGUMENTS")}
|
|
314
314
|
|
|
315
|
-
${
|
|
316
|
-
Default: ${defaultEntries.map((e) =>
|
|
315
|
+
${yellow("<entry>")} Server entry path to serve.
|
|
316
|
+
Default: ${defaultEntries.map((e) => cyan(e)).join(", ")} ${gray(`(${defaultExts.join(",")})`)}
|
|
317
317
|
|
|
318
|
-
${
|
|
318
|
+
${bold("OPTIONS")}
|
|
319
319
|
|
|
320
|
-
${
|
|
321
|
-
${
|
|
322
|
-
${
|
|
323
|
-
${
|
|
324
|
-
${
|
|
325
|
-
${
|
|
326
|
-
${
|
|
327
|
-
${
|
|
328
|
-
${
|
|
329
|
-
${
|
|
320
|
+
${green("-p, --port")} ${yellow("<port>")} Port to listen on (default: ${yellow("3000")})
|
|
321
|
+
${green("--host")} ${yellow("<host>")} Host to bind to (default: all interfaces)
|
|
322
|
+
${green("-s, --static")} ${yellow("<dir>")} Serve static files from the specified directory (default: ${yellow("public")})
|
|
323
|
+
${green("--prod")} Run in production mode (no watch, no debug)
|
|
324
|
+
${green("--import")} ${yellow("<loader>")} ES module to preload
|
|
325
|
+
${green("--tls")} Enable TLS (HTTPS/HTTP2)
|
|
326
|
+
${green("--cert")} ${yellow("<file>")} TLS certificate file
|
|
327
|
+
${green("--key")} ${yellow("<file>")} TLS private key file
|
|
328
|
+
${green("-h, --help")} Show this help message
|
|
329
|
+
${green("-v, --version")} Show server and runtime versions
|
|
330
330
|
|
|
331
|
-
${
|
|
331
|
+
${bold("ENVIRONMENT")}
|
|
332
332
|
|
|
333
|
-
${
|
|
334
|
-
${
|
|
335
|
-
${
|
|
333
|
+
${green("PORT")} Override port
|
|
334
|
+
${green("HOST")} Override host
|
|
335
|
+
${green("NODE_ENV")} Set to ${yellow("production")} for production mode.
|
|
336
336
|
|
|
337
|
-
➤ ${
|
|
338
|
-
➤ ${
|
|
337
|
+
➤ ${url("Documentation", mainOpts.docs || "https://srvx.h3.dev")}
|
|
338
|
+
➤ ${url("Report issues", mainOpts.issues || "https://github.com/h3js/srvx/issues")}
|
|
339
339
|
`.trim();
|
|
340
340
|
}
|
|
341
341
|
function setupProcessErrorHandlers() {
|
package/dist/log.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { blue, bold, gray, green, red, yellow } from "./_chunks/_color-Dtg6hRMg.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/log.ts
|
|
4
4
|
const statusColors = {
|
|
5
|
-
1:
|
|
6
|
-
2:
|
|
7
|
-
3:
|
|
5
|
+
1: blue,
|
|
6
|
+
2: green,
|
|
7
|
+
3: yellow
|
|
8
8
|
};
|
|
9
9
|
const log = (_options = {}) => {
|
|
10
10
|
return async (req, next) => {
|
|
11
11
|
const start = performance.now();
|
|
12
12
|
const res = await next();
|
|
13
13
|
const duration = performance.now() - start;
|
|
14
|
-
const statusColor = statusColors[Math.floor(res.status / 100)] ||
|
|
15
|
-
console.log(`${
|
|
14
|
+
const statusColor = statusColors[Math.floor(res.status / 100)] || red;
|
|
15
|
+
console.log(`${gray(`[${new Date().toLocaleTimeString()}]`)} ${bold(req.method)} ${blue(req.url)} [${statusColor(res.status + "")}] ${gray(`(${duration.toFixed(2)}ms)`)}`);
|
|
16
16
|
return res;
|
|
17
17
|
};
|
|
18
18
|
};
|
package/package.json
CHANGED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
//#region src/_utils.cli.ts
|
|
2
|
-
const noColor = globalThis.process?.env?.NO_COLOR === "1" || globalThis.process?.env?.TERM === "dumb";
|
|
3
|
-
const resets = {
|
|
4
|
-
1: 22,
|
|
5
|
-
31: 39,
|
|
6
|
-
32: 39,
|
|
7
|
-
33: 39,
|
|
8
|
-
34: 39,
|
|
9
|
-
35: 39,
|
|
10
|
-
36: 39,
|
|
11
|
-
90: 39
|
|
12
|
-
};
|
|
13
|
-
const _c = (c) => (text) => {
|
|
14
|
-
if (noColor) return text;
|
|
15
|
-
const off = resets[c] ?? 0;
|
|
16
|
-
return `\u001B[${c}m${text}\u001B[${off}m`;
|
|
17
|
-
};
|
|
18
|
-
const Colors = {
|
|
19
|
-
bold: _c(1),
|
|
20
|
-
red: _c(31),
|
|
21
|
-
green: _c(32),
|
|
22
|
-
yellow: _c(33),
|
|
23
|
-
blue: _c(34),
|
|
24
|
-
magenta: _c(35),
|
|
25
|
-
cyan: _c(36),
|
|
26
|
-
gray: _c(90),
|
|
27
|
-
url: (title, url) => noColor ? `[${title}](${url})` : `\u001B]8;;${url}\u001B\\${title}\u001B]8;;\u001B\\`
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
//#endregion
|
|
31
|
-
export { Colors };
|