feat: init
This commit is contained in:
56
node_modules/srvx/dist/_chunks/_plugins.mjs
generated
vendored
Normal file
56
node_modules/srvx/dist/_chunks/_plugins.mjs
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import { a as green, i as gray, n as bold, s as red } from "./_utils.mjs";
|
||||
function wrapFetch(server) {
|
||||
const fetchHandler = server.options.fetch;
|
||||
const middleware = server.options.middleware || [];
|
||||
return middleware.length === 0 ? fetchHandler : (request) => callMiddleware(request, fetchHandler, middleware, 0);
|
||||
}
|
||||
function callMiddleware(request, fetchHandler, middleware, index) {
|
||||
if (index === middleware.length) return fetchHandler(request);
|
||||
return middleware[index](request, () => callMiddleware(request, fetchHandler, middleware, index + 1));
|
||||
}
|
||||
const errorPlugin = (server) => {
|
||||
const errorHandler = server.options.error;
|
||||
if (!errorHandler) return;
|
||||
server.options.middleware.unshift((_req, next) => {
|
||||
try {
|
||||
const res = next();
|
||||
return res instanceof Promise ? res.catch((error) => errorHandler(error)) : res;
|
||||
} catch (error) {
|
||||
return errorHandler(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
const gracefulShutdownPlugin = (server) => {
|
||||
const config = server.options?.gracefulShutdown;
|
||||
if (!globalThis.process?.on || config === false || config === void 0 && (process.env.CI || process.env.TEST)) return;
|
||||
const gracefulTimeout = config === true || !config?.gracefulTimeout ? Number.parseInt(process.env.SERVER_SHUTDOWN_TIMEOUT || "") || 5 : config.gracefulTimeout;
|
||||
let isClosing = false;
|
||||
let isClosed = false;
|
||||
const w = server.options.silent ? () => {} : process.stderr.write.bind(process.stderr);
|
||||
const forceClose = async () => {
|
||||
if (isClosed) return;
|
||||
w(red("\x1B[2K\rForcibly closing connections...\n"));
|
||||
isClosed = true;
|
||||
await server.close(true);
|
||||
};
|
||||
const shutdown = async () => {
|
||||
if (isClosing || isClosed) return;
|
||||
setTimeout(() => {
|
||||
globalThis.process.once("SIGINT", forceClose);
|
||||
}, 100);
|
||||
isClosing = true;
|
||||
const closePromise = server.close();
|
||||
for (let remaining = gracefulTimeout; remaining > 0; remaining--) {
|
||||
w(gray(`\rStopping server gracefully (${remaining}s)... Press ${bold("Ctrl+C")} again to force close.`));
|
||||
if (await Promise.race([closePromise.then(() => true), new Promise((r) => setTimeout(() => r(false), 1e3))])) {
|
||||
w("\x1B[2K\r" + green("Server closed successfully.\n"));
|
||||
isClosed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
w("\x1B[2K\rGraceful shutdown timed out.\n");
|
||||
await forceClose();
|
||||
};
|
||||
for (const sig of ["SIGINT", "SIGTERM"]) globalThis.process.on(sig, shutdown);
|
||||
};
|
||||
export { gracefulShutdownPlugin as n, wrapFetch as r, errorPlugin as t };
|
||||
28
node_modules/srvx/dist/_chunks/_url.d.mts
generated
vendored
Normal file
28
node_modules/srvx/dist/_chunks/_url.d.mts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
//#region src/_url.d.ts
|
||||
type URLInit = {
|
||||
protocol: string;
|
||||
host: string;
|
||||
pathname: string;
|
||||
search: string;
|
||||
};
|
||||
/**
|
||||
* URL wrapper with fast paths to access to the following props:
|
||||
*
|
||||
* - `url.pathname`
|
||||
* - `url.search`
|
||||
* - `url.searchParams`
|
||||
* - `url.protocol`
|
||||
*
|
||||
* **NOTES:**
|
||||
*
|
||||
* - It is assumed that the input URL is **already encoded** and formatted from an HTTP request and contains no hash.
|
||||
* - Triggering the setters or getters on other props will deoptimize to full URL parsing.
|
||||
* - Changes to `searchParams` will be discarded as we don't track them.
|
||||
*/
|
||||
declare const FastURL: {
|
||||
new (url: string | URLInit): URL & {
|
||||
_url: URL;
|
||||
};
|
||||
};
|
||||
//#endregion
|
||||
export { FastURL as t };
|
||||
126
node_modules/srvx/dist/_chunks/_url.mjs
generated
vendored
Normal file
126
node_modules/srvx/dist/_chunks/_url.mjs
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
function lazyInherit(target, source, sourceKey) {
|
||||
for (const key of [...Object.getOwnPropertyNames(source), ...Object.getOwnPropertySymbols(source)]) {
|
||||
if (key === "constructor") continue;
|
||||
const targetDesc = Object.getOwnPropertyDescriptor(target, key);
|
||||
const desc = Object.getOwnPropertyDescriptor(source, key);
|
||||
let modified = false;
|
||||
if (desc.get) {
|
||||
modified = true;
|
||||
desc.get = targetDesc?.get || function() {
|
||||
return this[sourceKey][key];
|
||||
};
|
||||
}
|
||||
if (desc.set) {
|
||||
modified = true;
|
||||
desc.set = targetDesc?.set || function(value) {
|
||||
this[sourceKey][key] = value;
|
||||
};
|
||||
}
|
||||
if (!targetDesc?.value && typeof desc.value === "function") {
|
||||
modified = true;
|
||||
desc.value = function(...args) {
|
||||
return this[sourceKey][key](...args);
|
||||
};
|
||||
}
|
||||
if (modified) Object.defineProperty(target, key, desc);
|
||||
}
|
||||
}
|
||||
const FastURL = /* @__PURE__ */ (() => {
|
||||
const NativeURL = globalThis.URL;
|
||||
const FastURL = class URL {
|
||||
#url;
|
||||
#href;
|
||||
#protocol;
|
||||
#host;
|
||||
#pathname;
|
||||
#search;
|
||||
#searchParams;
|
||||
#pos;
|
||||
constructor(url) {
|
||||
if (typeof url === "string") this.#href = url;
|
||||
else {
|
||||
this.#protocol = url.protocol;
|
||||
this.#host = url.host;
|
||||
this.#pathname = url.pathname;
|
||||
this.#search = url.search;
|
||||
}
|
||||
}
|
||||
static [Symbol.hasInstance](val) {
|
||||
return val instanceof NativeURL;
|
||||
}
|
||||
get _url() {
|
||||
if (this.#url) return this.#url;
|
||||
this.#url = new NativeURL(this.href);
|
||||
this.#href = void 0;
|
||||
this.#protocol = void 0;
|
||||
this.#host = void 0;
|
||||
this.#pathname = void 0;
|
||||
this.#search = void 0;
|
||||
this.#searchParams = void 0;
|
||||
this.#pos = void 0;
|
||||
return this.#url;
|
||||
}
|
||||
get href() {
|
||||
if (this.#url) return this.#url.href;
|
||||
if (!this.#href) this.#href = `${this.#protocol || "http:"}//${this.#host || "localhost"}${this.#pathname || "/"}${this.#search || ""}`;
|
||||
return this.#href;
|
||||
}
|
||||
#getPos() {
|
||||
if (!this.#pos) {
|
||||
const url = this.href;
|
||||
const protoIndex = url.indexOf("://");
|
||||
const pathnameIndex = protoIndex === -1 ? -1 : url.indexOf("/", protoIndex + 4);
|
||||
this.#pos = [
|
||||
protoIndex,
|
||||
pathnameIndex,
|
||||
pathnameIndex === -1 ? -1 : url.indexOf("?", pathnameIndex)
|
||||
];
|
||||
}
|
||||
return this.#pos;
|
||||
}
|
||||
get pathname() {
|
||||
if (this.#url) return this.#url.pathname;
|
||||
if (this.#pathname === void 0) {
|
||||
const [, pathnameIndex, queryIndex] = this.#getPos();
|
||||
if (pathnameIndex === -1) return this._url.pathname;
|
||||
this.#pathname = this.href.slice(pathnameIndex, queryIndex === -1 ? void 0 : queryIndex);
|
||||
}
|
||||
return this.#pathname;
|
||||
}
|
||||
get search() {
|
||||
if (this.#url) return this.#url.search;
|
||||
if (this.#search === void 0) {
|
||||
const [, pathnameIndex, queryIndex] = this.#getPos();
|
||||
if (pathnameIndex === -1) return this._url.search;
|
||||
const url = this.href;
|
||||
this.#search = queryIndex === -1 || queryIndex === url.length - 1 ? "" : url.slice(queryIndex);
|
||||
}
|
||||
return this.#search;
|
||||
}
|
||||
get searchParams() {
|
||||
if (this.#url) return this.#url.searchParams;
|
||||
if (!this.#searchParams) this.#searchParams = new URLSearchParams(this.search);
|
||||
return this.#searchParams;
|
||||
}
|
||||
get protocol() {
|
||||
if (this.#url) return this.#url.protocol;
|
||||
if (this.#protocol === void 0) {
|
||||
const [protocolIndex] = this.#getPos();
|
||||
if (protocolIndex === -1) return this._url.protocol;
|
||||
this.#protocol = this.href.slice(0, protocolIndex + 1);
|
||||
}
|
||||
return this.#protocol;
|
||||
}
|
||||
toString() {
|
||||
return this.href;
|
||||
}
|
||||
toJSON() {
|
||||
return this.href;
|
||||
}
|
||||
};
|
||||
lazyInherit(FastURL.prototype, NativeURL.prototype, "_url");
|
||||
Object.setPrototypeOf(FastURL.prototype, NativeURL.prototype);
|
||||
Object.setPrototypeOf(FastURL, NativeURL);
|
||||
return FastURL;
|
||||
})();
|
||||
export { lazyInherit as n, FastURL as t };
|
||||
15
node_modules/srvx/dist/_chunks/_utils.mjs
generated
vendored
Normal file
15
node_modules/srvx/dist/_chunks/_utils.mjs
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
const noColor = /* @__PURE__ */ (() => {
|
||||
const env = globalThis.process?.env ?? {};
|
||||
return env.NO_COLOR === "1" || env.TERM === "dumb";
|
||||
})();
|
||||
const _c = (c, r = 39) => (t) => noColor ? t : `\u001B[${c}m${t}\u001B[${r}m`;
|
||||
const bold = /* @__PURE__ */ _c(1, 22);
|
||||
const red = /* @__PURE__ */ _c(31);
|
||||
const green = /* @__PURE__ */ _c(32);
|
||||
const yellow = /* @__PURE__ */ _c(33);
|
||||
const blue = /* @__PURE__ */ _c(34);
|
||||
const magenta = /* @__PURE__ */ _c(35);
|
||||
const cyan = /* @__PURE__ */ _c(36);
|
||||
const gray = /* @__PURE__ */ _c(90);
|
||||
const url = (title, url) => noColor ? `[${title}](${url})` : `\u001B]8;;${url}\u001B\\${title}\u001B]8;;\u001B\\`;
|
||||
export { green as a, url as c, gray as i, yellow as l, bold as n, magenta as o, cyan as r, red as s, blue as t };
|
||||
70
node_modules/srvx/dist/_chunks/_utils2.mjs
generated
vendored
Normal file
70
node_modules/srvx/dist/_chunks/_utils2.mjs
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
function resolvePortAndHost(opts) {
|
||||
const _port = opts.port ?? globalThis.process?.env.PORT ?? 3e3;
|
||||
const port = typeof _port === "number" ? _port : Number.parseInt(_port, 10);
|
||||
if (port < 0 || port > 65535) throw new RangeError(`Port must be between 0 and 65535 (got "${port}").`);
|
||||
return {
|
||||
port,
|
||||
hostname: opts.hostname ?? globalThis.process?.env.HOST
|
||||
};
|
||||
}
|
||||
function fmtURL(host, port, secure) {
|
||||
if (!host || !port) return;
|
||||
if (host.includes(":")) host = `[${host}]`;
|
||||
return `http${secure ? "s" : ""}://${host}:${port}/`;
|
||||
}
|
||||
function printListening(opts, url) {
|
||||
if (!url || (opts.silent ?? globalThis.process?.env?.TEST)) return;
|
||||
let additionalInfo = "";
|
||||
try {
|
||||
const _url = new URL(url);
|
||||
if (_url.hostname === "[::]" || _url.hostname === "0.0.0.0") {
|
||||
_url.hostname = "localhost";
|
||||
url = _url.href;
|
||||
additionalInfo = " (all interfaces)";
|
||||
}
|
||||
} catch {}
|
||||
let listeningOn = `➜ Listening on:`;
|
||||
if (globalThis.process.stdout?.isTTY) {
|
||||
listeningOn = `\u001B[32m${listeningOn}\u001B[0m`;
|
||||
url = `\u001B[36m${url}\u001B[0m`;
|
||||
additionalInfo = `\u001B[2m${additionalInfo}\u001B[0m`;
|
||||
}
|
||||
console.log(`${listeningOn} ${url}${additionalInfo}`);
|
||||
}
|
||||
function resolveTLSOptions(opts) {
|
||||
if (!opts.tls || opts.protocol === "http") return;
|
||||
const cert = resolveCertOrKey(opts.tls.cert);
|
||||
const key = resolveCertOrKey(opts.tls.key);
|
||||
if (!cert && !key) {
|
||||
if (opts.protocol === "https") throw new TypeError("TLS `cert` and `key` must be provided for `https` protocol.");
|
||||
return;
|
||||
}
|
||||
if (!cert || !key) throw new TypeError("TLS `cert` and `key` must be provided together.");
|
||||
return {
|
||||
cert,
|
||||
key,
|
||||
passphrase: opts.tls.passphrase
|
||||
};
|
||||
}
|
||||
function resolveCertOrKey(value) {
|
||||
if (!value) return;
|
||||
if (typeof value !== "string") throw new TypeError("TLS certificate and key must be strings in PEM format or file paths.");
|
||||
if (value.startsWith("-----BEGIN ")) return value;
|
||||
const { readFileSync } = process.getBuiltinModule("node:fs");
|
||||
return readFileSync(value, "utf8");
|
||||
}
|
||||
function createWaitUntil() {
|
||||
const promises = /* @__PURE__ */ new Set();
|
||||
return {
|
||||
waitUntil: (promise) => {
|
||||
if (typeof promise?.then !== "function") return;
|
||||
promises.add(Promise.resolve(promise).catch(console.error).finally(() => {
|
||||
promises.delete(promise);
|
||||
}));
|
||||
},
|
||||
wait: () => {
|
||||
return Promise.all(promises);
|
||||
}
|
||||
};
|
||||
}
|
||||
export { resolveTLSOptions as a, resolvePortAndHost as i, fmtURL as n, printListening as r, createWaitUntil as t };
|
||||
Reference in New Issue
Block a user