initial commit

This commit is contained in:
Zoe
2023-01-03 09:29:04 -06:00
commit 7851137d88
12889 changed files with 2557443 additions and 0 deletions

21
node_modules/h3/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Pooya Parsa <pooya@pi0.io>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

164
node_modules/h3/README.md generated vendored Normal file
View File

@@ -0,0 +1,164 @@
[![npm downloads](https://img.shields.io/npm/dm/h3.svg?style=flat-square)](https://npmjs.com/package/h3)
[![version](https://img.shields.io/npm/v/h3/latest.svg?style=flat-square)](https://npmjs.com/package/h3)
[![bundlephobia](https://img.shields.io/bundlephobia/min/h3/latest.svg?style=flat-square)](https://bundlephobia.com/result?p=h3)
[![build status](https://img.shields.io/github/workflow/status/unjs/h3/ci/main?style=flat-square)](https://github.com/unjs/h3/actions)
[![coverage](https://img.shields.io/codecov/c/gh/unjs/h3/main?style=flat-square)](https://codecov.io/gh/unjs/h3)
[![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue?style=flat-square)](https://www.jsdocs.io/package/h3)
> H3 is a minimal h(ttp) framework built for high performance and portability
<!-- ![h3 - Tiny JavaScript Server](.github/banner.svg) -->
## Features
✔️ &nbsp;**Portable:** Works perfectly in Serverless, Workers, and Node.js
✔️ &nbsp;**Minimal:** Small and tree-shakable
✔️ &nbsp;**Modern:** Native promise support
✔️ &nbsp;**Extendable:** Ships with a set of composable utilities but can be extended
✔️ &nbsp;**Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)
✔️ &nbsp;**Compatible:** Compatibility layer with node/connect/express middleware
## Install
```bash
# Using npm
npm install h3
# Using yarn
yarn add h3
# Using pnpm
pnpm add h3
```
## Usage
```ts
import { createServer } from 'http'
import { createApp, eventHandler, toNodeListener } from 'h3'
const app = createApp()
app.use('/', eventHandler(() => 'Hello world!'))
createServer(toNodeListener(app)).listen(process.env.PORT || 3000)
```
<details>
<summary>Example using <a href="https://github.com/unjs/listhen">listhen</a> for an elegant listener.</summary>
```ts
import { createApp, toNodeListener } from 'h3'
import { listen } from 'listhen'
const app = createApp()
app.use('/', eventHandler(() => 'Hello world!'))
listen(toNodeListener(app))
```
</details>
## Router
The `app` instance created by `h3` uses a middleware stack (see [how it works](#how-it-works)) with the ability to match route prefix and apply matched middleware.
To opt-in using a more advanced and convenient routing system, we can create a router instance and register it to app instance.
```ts
import { createApp, eventHandler, createRouter } from 'h3'
const app = createApp()
const router = createRouter()
.get('/', eventHandler(() => 'Hello World!'))
.get('/hello/:name', eventHandler(event => `Hello ${event.context.params.name}!`))
app.use(router)
```
**Tip:** We can register same route more than once with different methods.
Routes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree) and matched using [unjs/radix3](https://github.com/unjs/radix3).
## More app usage examples
```js
// Handle can directly return object or Promise<object> for JSON response
app.use('/api', eventHandler((event) => ({ url: event.node.req.url }))
// We can have better matching other than quick prefix match
app.use('/odd', eventHandler(() => 'Is odd!'), { match: url => url.substr(1) % 2 })
// Handle can directly return string for HTML response
app.use(eventHandler(() => '<h1>Hello world!</h1>'))
// We can chain calls to .use()
app.use('/1', eventHandler(() => '<h1>Hello world!</h1>'))
.use('/2', eventHandler(() => '<h1>Goodbye!</h1>'))
// Legacy middleware with 3rd argument are automatically promisified
app.use(fromNodeMiddleware((req, res, next) => { req.setHeader('x-foo', 'bar'); next() }))
// Lazy loaded routes using { lazy: true }
app.use('/big', () => import('./big-handler'), { lazy: true })
```
## Utilities
H3 has concept of compasable utilities that accept `event` (from `eventHandler((event) => {})`) as their first argument. This has several performance benefits over injecting them to `event` or `app` instances and global middleware commonly used in Node.js frameworks such as Express, which Only required code is evaluated and bundled and rest of utils can be tree-shaken when not used.
### Built-in
- `readRawBody(event, encoding?)`
- `readBody(event)`
- `parseCookies(event)`
- `getCookie(event, name)`
- `setCookie(event, name, value, opts?)`
- `deleteCookie(event, name, opts?)`
- `getQuery(event)`
- `getRouterParams(event)`
- `send(event, data, type?)`
- `sendRedirect(event, location, code=302)`
- `getRequestHeaders(event, headers)` (alias: `getHeaders`)
- `getRequestHeader(event, name)` (alias: `getHeader`)
- `setResponseHeaders(event, headers)` (alias: `setHeaders`)
- `setResponseHeader(event, name, value)` (alias: `setHeader`)
- `appendResponseHeaders(event, headers)` (alias: `appendHeaders`)
- `appendResponseHeader(event, name, value)` (alias: `appendHeader`)
- `writeEarlyHints(event, links, callback)`
- `sendStream(event, data)`
- `sendError(event, error, debug?)`
- `getMethod(event, default?)`
- `isMethod(event, expected, allowHead?)`
- `assertMethod(event, expected, allowHead?)`
- `createError({ statusCode, statusMessage, data? })`
- `sendProxy(event, { target, headers?, fetchOptions?, fetch?, sendStream? })`
- `proxyRequest(event, { target, headers?, fetchOptions?, fetch?, sendStream? })`
👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
## Community Packages
You can use more h3 event utilities made by the community.
Please check their READMEs for more details.
PRs are welcome to add your packages.
- [h3-cors](https://github.com/NozomuIkuta/h3-cors)
- `defineCorsEventHandler(options)`
- `isPreflight(event)`
- [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
- `validateBody(event, schema)`
- `validateQuery(event, schema)`
- [h3-zod](https://github.com/wobsoriano/h3-zod)
- `useValidatedBody(event, schema)`
- `useValidatedQuery(event, schema)`
## License
MIT

977
node_modules/h3/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,977 @@
'use strict';
const ufo = require('ufo');
const radix3 = require('radix3');
const destr = require('destr');
const cookieEs = require('cookie-es');
function useBase(base, handler) {
base = ufo.withoutTrailingSlash(base);
if (!base) {
return handler;
}
return eventHandler((event) => {
event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
event.node.req.url = ufo.withoutBase(event.node.req.url || "/", base);
return handler(event);
});
}
class H3Error extends Error {
constructor() {
super(...arguments);
this.statusCode = 500;
this.fatal = false;
this.unhandled = false;
this.statusMessage = void 0;
}
toJSON() {
const obj = {
message: this.message,
statusCode: this.statusCode
};
if (this.statusMessage) {
obj.statusMessage = this.statusMessage;
}
if (this.data !== void 0) {
obj.data = this.data;
}
return obj;
}
}
H3Error.__h3_error__ = true;
function createError(input) {
if (typeof input === "string") {
return new H3Error(input);
}
if (isError(input)) {
return input;
}
const err = new H3Error(
input.message ?? input.statusMessage,
input.cause ? { cause: input.cause } : void 0
);
if ("stack" in input) {
try {
Object.defineProperty(err, "stack", {
get() {
return input.stack;
}
});
} catch {
try {
err.stack = input.stack;
} catch {
}
}
}
if (input.data) {
err.data = input.data;
}
if (input.statusCode) {
err.statusCode = input.statusCode;
} else if (input.status) {
err.statusCode = input.status;
}
if (input.statusMessage) {
err.statusMessage = input.statusMessage;
} else if (input.statusText) {
err.statusMessage = input.statusText;
}
if (input.fatal !== void 0) {
err.fatal = input.fatal;
}
if (input.unhandled !== void 0) {
err.unhandled = input.unhandled;
}
return err;
}
function sendError(event, error, debug) {
if (event.node.res.writableEnded) {
return;
}
const h3Error = isError(error) ? error : createError(error);
const responseBody = {
statusCode: h3Error.statusCode,
statusMessage: h3Error.statusMessage,
stack: [],
data: h3Error.data
};
if (debug) {
responseBody.stack = (h3Error.stack || "").split("\n").map((l) => l.trim());
}
if (event.node.res.writableEnded) {
return;
}
const _code = Number.parseInt(h3Error.statusCode);
if (_code) {
event.node.res.statusCode = _code;
}
if (h3Error.statusMessage) {
event.node.res.statusMessage = h3Error.statusMessage;
}
event.node.res.setHeader("content-type", MIMES.json);
event.node.res.end(JSON.stringify(responseBody, void 0, 2));
}
function isError(input) {
return input?.constructor?.__h3_error__ === true;
}
function getQuery(event) {
return ufo.getQuery(event.node.req.url || "");
}
function getRouterParams(event) {
return event.context.params || {};
}
function getRouterParam(event, name) {
const params = getRouterParams(event);
return params[name];
}
function getMethod(event, defaultMethod = "GET") {
return (event.node.req.method || defaultMethod).toUpperCase();
}
function isMethod(event, expected, allowHead) {
const method = getMethod(event);
if (allowHead && method === "HEAD") {
return true;
}
if (typeof expected === "string") {
if (method === expected) {
return true;
}
} else if (expected.includes(method)) {
return true;
}
return false;
}
function assertMethod(event, expected, allowHead) {
if (!isMethod(event, expected, allowHead)) {
throw createError({
statusCode: 405,
statusMessage: "HTTP method is not allowed."
});
}
}
function getRequestHeaders(event) {
const _headers = {};
for (const key in event.node.req.headers) {
const val = event.node.req.headers[key];
_headers[key] = Array.isArray(val) ? val.filter(Boolean).join(", ") : val;
}
return _headers;
}
const getHeaders = getRequestHeaders;
function getRequestHeader(event, name) {
const headers = getRequestHeaders(event);
const value = headers[name.toLowerCase()];
return value;
}
const getHeader = getRequestHeader;
const RawBodySymbol = Symbol.for("h3RawBody");
const ParsedBodySymbol = Symbol.for("h3ParsedBody");
const PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
function readRawBody(event, encoding = "utf8") {
assertMethod(event, PayloadMethods$1);
if (RawBodySymbol in event.node.req) {
const promise2 = Promise.resolve(event.node.req[RawBodySymbol]);
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
}
if ("body" in event.node.req) {
return Promise.resolve(event.node.req.body);
}
if (!Number.parseInt(event.node.req.headers["content-length"] || "")) {
return Promise.resolve(void 0);
}
const promise = event.node.req[RawBodySymbol] = new Promise(
(resolve, reject) => {
const bodyData = [];
event.node.req.on("error", (err) => {
reject(err);
}).on("data", (chunk) => {
bodyData.push(chunk);
}).on("end", () => {
resolve(Buffer.concat(bodyData));
});
}
);
const result = encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
return result;
}
async function readBody(event) {
if (ParsedBodySymbol in event.node.req) {
return event.node.req[ParsedBodySymbol];
}
const body = await readRawBody(event);
if (event.node.req.headers["content-type"] === "application/x-www-form-urlencoded") {
const form = new URLSearchParams(body);
const parsedForm = /* @__PURE__ */ Object.create(null);
for (const [key, value] of form.entries()) {
if (key in parsedForm) {
if (!Array.isArray(parsedForm[key])) {
parsedForm[key] = [parsedForm[key]];
}
parsedForm[key].push(value);
} else {
parsedForm[key] = value;
}
}
return parsedForm;
}
const json = destr(body);
event.node.req[ParsedBodySymbol] = json;
return json;
}
function handleCacheHeaders(event, opts) {
const cacheControls = ["public", ...opts.cacheControls || []];
let cacheMatched = false;
if (opts.maxAge !== void 0) {
cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
}
if (opts.modifiedTime) {
const modifiedTime = new Date(opts.modifiedTime);
const ifModifiedSince = event.node.req.headers["if-modified-since"];
event.node.res.setHeader("last-modified", modifiedTime.toUTCString());
if (ifModifiedSince && new Date(ifModifiedSince) >= opts.modifiedTime) {
cacheMatched = true;
}
}
if (opts.etag) {
event.node.res.setHeader("etag", opts.etag);
const ifNonMatch = event.node.req.headers["if-none-match"];
if (ifNonMatch === opts.etag) {
cacheMatched = true;
}
}
event.node.res.setHeader("cache-control", cacheControls.join(", "));
if (cacheMatched) {
event.node.res.statusCode = 304;
event.node.res.end();
return true;
}
return false;
}
const MIMES = {
html: "text/html",
json: "application/json"
};
const defer = typeof setImmediate !== "undefined" ? setImmediate : (fn) => fn();
function send(event, data, type) {
if (type) {
defaultContentType(event, type);
}
return new Promise((resolve) => {
defer(() => {
event.node.res.end(data);
resolve();
});
});
}
function defaultContentType(event, type) {
if (type && !event.node.res.getHeader("content-type")) {
event.node.res.setHeader("content-type", type);
}
}
function sendRedirect(event, location, code = 302) {
event.node.res.statusCode = code;
event.node.res.setHeader("location", location);
const encodedLoc = location.replace(/"/g, "%22");
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
return send(event, html, MIMES.html);
}
function getResponseHeaders(event) {
return event.node.res.getHeaders();
}
function getResponseHeader(event, name) {
return event.node.res.getHeader(name);
}
function setResponseHeaders(event, headers) {
for (const [name, value] of Object.entries(headers)) {
event.node.res.setHeader(name, value);
}
}
const setHeaders = setResponseHeaders;
function setResponseHeader(event, name, value) {
event.node.res.setHeader(name, value);
}
const setHeader = setResponseHeader;
function appendResponseHeaders(event, headers) {
for (const [name, value] of Object.entries(headers)) {
appendResponseHeader(event, name, value);
}
}
const appendHeaders = appendResponseHeaders;
function appendResponseHeader(event, name, value) {
let current = event.node.res.getHeader(name);
if (!current) {
event.node.res.setHeader(name, value);
return;
}
if (!Array.isArray(current)) {
current = [current.toString()];
}
event.node.res.setHeader(name, [...current, value]);
}
const appendHeader = appendResponseHeader;
function isStream(data) {
return data && typeof data === "object" && typeof data.pipe === "function" && typeof data.on === "function";
}
function sendStream(event, data) {
return new Promise((resolve, reject) => {
data.pipe(event.node.res);
data.on("end", () => resolve());
data.on("error", (error) => reject(createError(error)));
});
}
const noop = () => {
};
function writeEarlyHints(event, hints, cb = noop) {
if (!event.node.res.socket) {
cb();
return;
}
if (typeof hints === "string" || Array.isArray(hints)) {
hints = { link: hints };
}
if (hints.link) {
hints.link = Array.isArray(hints.link) ? hints.link : hints.link.split(",");
}
const headers = Object.entries(hints).map(
(e) => [e[0].toLowerCase(), e[1]]
);
if (headers.length === 0) {
cb();
return;
}
let hint = "HTTP/1.1 103 Early Hints";
if (hints.link) {
hint += `\r
Link: ${hints.link.join(", ")}`;
}
for (const [header, value] of headers) {
if (header === "link") {
continue;
}
hint += `\r
${header}: ${value}`;
}
if (event.node.res.socket) {
event.node.res.socket.write(
`${hint}\r
\r
`,
"utf8",
cb
);
} else {
cb();
}
}
function parseCookies(event) {
return cookieEs.parse(event.node.req.headers.cookie || "");
}
function getCookie(event, name) {
return parseCookies(event)[name];
}
function setCookie(event, name, value, serializeOptions) {
const cookieStr = cookieEs.serialize(name, value, {
path: "/",
...serializeOptions
});
appendHeader(event, "Set-Cookie", cookieStr);
}
function deleteCookie(event, name, serializeOptions) {
setCookie(event, name, "", {
...serializeOptions,
maxAge: 0
});
}
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
const ignoredHeaders = /* @__PURE__ */ new Set([
"transfer-encoding",
"connection",
"keep-alive",
"upgrade",
"expect"
]);
async function proxyRequest(event, target, opts = {}) {
const method = getMethod(event);
let body;
if (PayloadMethods.has(method)) {
body = await readRawBody(event).catch(() => void 0);
}
const headers = /* @__PURE__ */ Object.create(null);
const reqHeaders = getRequestHeaders(event);
for (const name in reqHeaders) {
if (!ignoredHeaders.has(name)) {
headers[name] = reqHeaders[name];
}
}
if (opts.fetchOptions?.headers) {
Object.assign(headers, opts.fetchOptions.headers);
}
if (opts.headers) {
Object.assign(headers, opts.headers);
}
return sendProxy(event, target, {
...opts,
fetchOptions: {
headers,
method,
body,
...opts.fetchOptions
}
});
}
async function sendProxy(event, target, opts = {}) {
const _fetch = opts.fetch || globalThis.fetch;
if (!_fetch) {
throw new Error(
"fetch is not available. Try importing `node-fetch-native/polyfill` for Node.js."
);
}
const response = await _fetch(target, {
headers: opts.headers,
...opts.fetchOptions
});
event.node.res.statusCode = response.status;
event.node.res.statusMessage = response.statusText;
for (const [key, value] of response.headers.entries()) {
if (key === "content-encoding") {
continue;
}
if (key === "content-length") {
continue;
}
event.node.res.setHeader(key, value);
}
try {
if (response.body) {
if (opts.sendStream === false) {
const data = new Uint8Array(await response.arrayBuffer());
event.node.res.end(data);
} else {
for await (const chunk of response.body) {
event.node.res.write(chunk);
}
event.node.res.end();
}
}
} catch (error) {
event.node.res.end();
throw error;
}
}
class H3Headers {
constructor(init) {
if (!init) {
this._headers = {};
} else if (Array.isArray(init)) {
this._headers = Object.fromEntries(
init.map(([key, value]) => [key.toLowerCase(), value])
);
} else if (init && "append" in init) {
this._headers = Object.fromEntries(init.entries());
} else {
this._headers = Object.fromEntries(
Object.entries(init).map(([key, value]) => [key.toLowerCase(), value])
);
}
}
[Symbol.iterator]() {
return this.entries();
}
entries() {
throw Object.entries(this._headers)[Symbol.iterator]();
}
keys() {
return Object.keys(this._headers)[Symbol.iterator]();
}
values() {
throw Object.values(this._headers)[Symbol.iterator]();
}
append(name, value) {
const _name = name.toLowerCase();
this.set(_name, [this.get(_name), value].filter(Boolean).join(", "));
}
delete(name) {
delete this._headers[name.toLowerCase()];
}
get(name) {
return this._headers[name.toLowerCase()];
}
has(name) {
return name.toLowerCase() in this._headers;
}
set(name, value) {
this._headers[name.toLowerCase()] = String(value);
}
forEach(callbackfn) {
for (const [key, value] of Object.entries(this._headers)) {
callbackfn(value, key, this);
}
}
}
class H3Response {
constructor(body = null, init = {}) {
this.body = null;
this.type = "default";
this.bodyUsed = false;
this.headers = new H3Headers(init.headers);
this.status = init.status ?? 200;
this.statusText = init.statusText || "";
this.redirected = !!init.status && [301, 302, 307, 308].includes(init.status);
this._body = body;
this.url = "";
this.ok = this.status < 300 && this.status > 199;
}
clone() {
return new H3Response(this.body, {
headers: this.headers,
status: this.status,
statusText: this.statusText
});
}
arrayBuffer() {
return Promise.resolve(this._body);
}
blob() {
return Promise.resolve(this._body);
}
formData() {
return Promise.resolve(this._body);
}
json() {
return Promise.resolve(this._body);
}
text() {
return Promise.resolve(this._body);
}
}
class H3Event {
constructor(req, res) {
this["__is_event__"] = true;
this.context = {};
this.node = { req, res };
}
get path() {
return this.req.url;
}
get req() {
return this.node.req;
}
get res() {
return this.node.res;
}
respondWith(r) {
Promise.resolve(r).then((_response) => {
if (this.res.writableEnded) {
return;
}
const response = _response instanceof H3Response ? _response : new H3Response(_response);
for (const [key, value] of response.headers.entries()) {
this.res.setHeader(key, value);
}
if (response.status) {
this.res.statusCode = response.status;
}
if (response.statusText) {
this.res.statusMessage = response.statusText;
}
if (response.redirected) {
this.res.setHeader("location", response.url);
}
if (!response._body) {
return this.res.end();
}
if (typeof response._body === "string" || "buffer" in response._body || "byteLength" in response._body) {
return this.res.end(response._body);
}
if (!response.headers.has("content-type")) {
response.headers.set("content-type", MIMES.json);
}
this.res.end(JSON.stringify(response._body));
});
}
}
function isEvent(input) {
return "__is_event__" in input;
}
function createEvent(req, res) {
return new H3Event(req, res);
}
function defineEventHandler(handler) {
handler.__is_handler__ = true;
return handler;
}
const eventHandler = defineEventHandler;
function isEventHandler(input) {
return "__is_handler__" in input;
}
function toEventHandler(input, _, _route) {
if (!isEventHandler(input)) {
console.warn(
"[h3] Implicit event handler conversion is deprecated. Use `eventHandler()` or `fromNodeMiddleware()` to define event handlers.",
_route && _route !== "/" ? `
Route: ${_route}` : "",
`
Handler: ${input}`
);
}
return input;
}
function dynamicEventHandler(initial) {
let current = initial;
const wrapper = eventHandler((event) => {
if (current) {
return current(event);
}
});
wrapper.set = (handler) => {
current = handler;
};
return wrapper;
}
function defineLazyEventHandler(factory) {
let _promise;
let _resolved;
const resolveHandler = () => {
if (_resolved) {
return Promise.resolve(_resolved);
}
if (!_promise) {
_promise = Promise.resolve(factory()).then((r) => {
const handler = r.default || r;
if (typeof handler !== "function") {
throw new TypeError(
"Invalid lazy handler result. It should be a function:",
handler
);
}
_resolved = toEventHandler(r.default || r);
return _resolved;
});
}
return _promise;
};
return eventHandler((event) => {
if (_resolved) {
return _resolved(event);
}
return resolveHandler().then((handler) => handler(event));
});
}
const lazyEventHandler = defineLazyEventHandler;
function createApp(options = {}) {
const stack = [];
const handler = createAppEventHandler(stack, options);
const app = {
use: (arg1, arg2, arg3) => use(app, arg1, arg2, arg3),
handler,
stack,
options
};
return app;
}
function use(app, arg1, arg2, arg3) {
if (Array.isArray(arg1)) {
for (const i of arg1) {
use(app, i, arg2, arg3);
}
} else if (Array.isArray(arg2)) {
for (const i of arg2) {
use(app, arg1, i, arg3);
}
} else if (typeof arg1 === "string") {
app.stack.push(
normalizeLayer({ ...arg3, route: arg1, handler: arg2 })
);
} else if (typeof arg1 === "function") {
app.stack.push(
normalizeLayer({ ...arg2, route: "/", handler: arg1 })
);
} else {
app.stack.push(normalizeLayer({ ...arg1 }));
}
return app;
}
function createAppEventHandler(stack, options) {
const spacing = options.debug ? 2 : void 0;
return eventHandler(async (event) => {
event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
const reqUrl = event.node.req.url || "/";
for (const layer of stack) {
if (layer.route.length > 1) {
if (!reqUrl.startsWith(layer.route)) {
continue;
}
event.node.req.url = reqUrl.slice(layer.route.length) || "/";
} else {
event.node.req.url = reqUrl;
}
if (layer.match && !layer.match(event.node.req.url, event)) {
continue;
}
const val = await layer.handler(event);
if (event.node.res.writableEnded) {
return;
}
const type = typeof val;
if (type === "string") {
return send(event, val, MIMES.html);
} else if (isStream(val)) {
return sendStream(event, val);
} else if (val === null) {
event.node.res.statusCode = 204;
return send(event);
} else if (type === "object" || type === "boolean" || type === "number") {
if (val.buffer) {
return send(event, val);
} else if (val instanceof Error) {
throw createError(val);
} else {
return send(
event,
JSON.stringify(val, void 0, spacing),
MIMES.json
);
}
}
}
if (!event.node.res.writableEnded) {
throw createError({
statusCode: 404,
statusMessage: `Cannot find any route matching ${event.node.req.url || "/"}.`
});
}
});
}
function normalizeLayer(input) {
let handler = input.handler;
if (handler.handler) {
handler = handler.handler;
}
if (input.lazy) {
handler = lazyEventHandler(handler);
} else if (!isEventHandler(handler)) {
handler = toEventHandler(handler, void 0, input.route);
}
return {
route: ufo.withoutTrailingSlash(input.route),
match: input.match,
handler
};
}
const defineNodeListener = (handler) => handler;
const defineNodeMiddleware = (middleware) => middleware;
function fromNodeMiddleware(handler) {
if (isEventHandler(handler)) {
return handler;
}
if (typeof handler !== "function") {
throw new TypeError(
"Invalid handler. It should be a function:",
handler
);
}
return eventHandler((event) => {
return callNodeListener(
handler,
event.node.req,
event.node.res
);
});
}
function toNodeListener(app) {
const toNodeHandle = async function(req, res) {
const event = createEvent(req, res);
try {
await app.handler(event);
} catch (_error) {
const error = createError(_error);
if (!isError(_error)) {
error.unhandled = true;
}
if (app.options.onError) {
await app.options.onError(error, event);
} else {
if (error.unhandled || error.fatal) {
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
}
await sendError(event, error, !!app.options.debug);
}
}
};
return toNodeHandle;
}
function promisifyNodeListener(handler) {
return function(req, res) {
return callNodeListener(handler, req, res);
};
}
function callNodeListener(handler, req, res) {
const isMiddleware = handler.length > 2;
return new Promise((resolve, reject) => {
const next = (err) => {
if (isMiddleware) {
res.off("close", next);
res.off("error", next);
}
return err ? reject(createError(err)) : resolve(void 0);
};
try {
const returned = handler(req, res, next);
if (isMiddleware && returned === void 0) {
res.once("close", next);
res.once("error", next);
} else {
resolve(returned);
}
} catch (error) {
next(error);
}
});
}
const RouterMethods = [
"connect",
"delete",
"get",
"head",
"options",
"post",
"put",
"trace",
"patch"
];
function createRouter(opts = {}) {
const _router = radix3.createRouter({});
const routes = {};
const router = {};
const addRoute = (path, handler, method) => {
let route = routes[path];
if (!route) {
routes[path] = route = { handlers: {} };
_router.insert(path, route);
}
if (Array.isArray(method)) {
for (const m of method) {
addRoute(path, handler, m);
}
} else {
route.handlers[method] = toEventHandler(handler, void 0, path);
}
return router;
};
router.use = router.add = (path, handler, method) => addRoute(path, handler, method || "all");
for (const method of RouterMethods) {
router[method] = (path, handle) => router.add(path, handle, method);
}
router.handler = eventHandler((event) => {
let path = event.node.req.url || "/";
const qIndex = path.indexOf("?");
if (qIndex !== -1) {
path = path.slice(0, Math.max(0, qIndex));
}
const matched = _router.lookup(path);
if (!matched || !matched.handlers) {
if (opts.preemptive || opts.preemtive) {
throw createError({
statusCode: 404,
name: "Not Found",
statusMessage: `Cannot find any route matching ${event.node.req.url || "/"}.`
});
} else {
return;
}
}
const method = (event.node.req.method || "get").toLowerCase();
const handler = matched.handlers[method] || matched.handlers.all;
if (!handler) {
throw createError({
statusCode: 405,
name: "Method Not Allowed",
statusMessage: `Method ${method} is not allowed on this route.`
});
}
const params = matched.params || {};
event.context.params = params;
return handler(event);
});
return router;
}
exports.H3Error = H3Error;
exports.H3Event = H3Event;
exports.H3Headers = H3Headers;
exports.H3Response = H3Response;
exports.MIMES = MIMES;
exports.appendHeader = appendHeader;
exports.appendHeaders = appendHeaders;
exports.appendResponseHeader = appendResponseHeader;
exports.appendResponseHeaders = appendResponseHeaders;
exports.assertMethod = assertMethod;
exports.callNodeListener = callNodeListener;
exports.createApp = createApp;
exports.createAppEventHandler = createAppEventHandler;
exports.createError = createError;
exports.createEvent = createEvent;
exports.createRouter = createRouter;
exports.defaultContentType = defaultContentType;
exports.defineEventHandler = defineEventHandler;
exports.defineLazyEventHandler = defineLazyEventHandler;
exports.defineNodeListener = defineNodeListener;
exports.defineNodeMiddleware = defineNodeMiddleware;
exports.deleteCookie = deleteCookie;
exports.dynamicEventHandler = dynamicEventHandler;
exports.eventHandler = eventHandler;
exports.fromNodeMiddleware = fromNodeMiddleware;
exports.getCookie = getCookie;
exports.getHeader = getHeader;
exports.getHeaders = getHeaders;
exports.getMethod = getMethod;
exports.getQuery = getQuery;
exports.getRequestHeader = getRequestHeader;
exports.getRequestHeaders = getRequestHeaders;
exports.getResponseHeader = getResponseHeader;
exports.getResponseHeaders = getResponseHeaders;
exports.getRouterParam = getRouterParam;
exports.getRouterParams = getRouterParams;
exports.handleCacheHeaders = handleCacheHeaders;
exports.isError = isError;
exports.isEvent = isEvent;
exports.isEventHandler = isEventHandler;
exports.isMethod = isMethod;
exports.isStream = isStream;
exports.lazyEventHandler = lazyEventHandler;
exports.parseCookies = parseCookies;
exports.promisifyNodeListener = promisifyNodeListener;
exports.proxyRequest = proxyRequest;
exports.readBody = readBody;
exports.readRawBody = readRawBody;
exports.send = send;
exports.sendError = sendError;
exports.sendProxy = sendProxy;
exports.sendRedirect = sendRedirect;
exports.sendStream = sendStream;
exports.setCookie = setCookie;
exports.setHeader = setHeader;
exports.setHeaders = setHeaders;
exports.setResponseHeader = setResponseHeader;
exports.setResponseHeaders = setResponseHeaders;
exports.toEventHandler = toEventHandler;
exports.toNodeListener = toNodeListener;
exports.use = use;
exports.useBase = useBase;
exports.writeEarlyHints = writeEarlyHints;

306
node_modules/h3/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,306 @@
import { IncomingMessage, ServerResponse, OutgoingMessage } from 'node:http';
export { IncomingMessage as NodeIncomingMessage, ServerResponse as NodeServerResponse } from 'node:http';
import { CookieSerializeOptions } from 'cookie-es';
import * as ufo from 'ufo';
type HTTPMethod = "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
type Encoding = false | "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
interface H3EventContext extends Record<string, any> {
}
type EventHandlerResponse<T = any> = T | Promise<T>;
interface EventHandler<T = any> {
__is_handler__?: true;
(event: H3Event): EventHandlerResponse<T>;
}
type LazyEventHandler = () => EventHandler | Promise<EventHandler>;
type RequestHeaders = {
[name: string]: string | undefined;
};
type NodeListener = (req: IncomingMessage, res: ServerResponse) => void;
type NodePromisifiedHandler = (req: IncomingMessage, res: ServerResponse) => Promise<any>;
type NodeMiddleware = (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => any) => any;
declare const defineNodeListener: (handler: NodeListener) => NodeListener;
declare const defineNodeMiddleware: (middleware: NodeMiddleware) => NodeMiddleware;
declare function fromNodeMiddleware(handler: NodeListener | NodeMiddleware): EventHandler;
declare function toNodeListener(app: App): NodeListener;
declare function promisifyNodeListener(handler: NodeListener | NodeMiddleware): NodePromisifiedHandler;
declare function callNodeListener(handler: NodeMiddleware, req: IncomingMessage, res: ServerResponse): Promise<unknown>;
declare class H3Headers implements Headers {
_headers: Record<string, string>;
constructor(init?: HeadersInit);
[Symbol.iterator](): IterableIterator<[string, string]>;
entries(): IterableIterator<[string, string]>;
keys(): IterableIterator<string>;
values(): IterableIterator<string>;
append(name: string, value: string): void;
delete(name: string): void;
get(name: string): string | null;
has(name: string): boolean;
set(name: string, value: string): void;
forEach(callbackfn: (value: string, key: string, parent: Headers) => void): void;
}
declare class H3Response implements Response {
readonly headers: H3Headers;
readonly status: number;
readonly statusText: string;
readonly redirected: boolean;
readonly ok: boolean;
readonly url: string;
_body: string | ArrayBuffer | Uint8Array;
readonly body: ReadableStream<Uint8Array> | null;
readonly type: ResponseType;
readonly bodyUsed = false;
constructor(body?: BodyInit | EventHandlerResponse | null, init?: ResponseInit);
clone(): H3Response;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json<T = any>(): Promise<T>;
text(): Promise<string>;
}
interface NodeEventContext {
req: IncomingMessage;
res: ServerResponse;
}
declare class H3Event implements Pick<FetchEvent, "respondWith"> {
"__is_event__": boolean;
node: NodeEventContext;
context: H3EventContext;
constructor(req: IncomingMessage, res: ServerResponse);
get path(): string | undefined;
/** @deprecated Please use `event.node.req` instead. **/
get req(): IncomingMessage;
/** @deprecated Please use `event.node.res` instead. **/
get res(): ServerResponse<IncomingMessage>;
respondWith(r: H3Response | PromiseLike<H3Response>): void;
}
declare function isEvent(input: any): input is H3Event;
declare function createEvent(req: IncomingMessage, res: ServerResponse): H3Event;
declare function defineEventHandler<T = any>(handler: EventHandler<T>): EventHandler<T>;
declare const eventHandler: typeof defineEventHandler;
declare function isEventHandler(input: any): input is EventHandler;
declare function toEventHandler(input: any, _?: any, _route?: string): EventHandler;
interface DynamicEventHandler extends EventHandler {
set: (handler: EventHandler) => void;
}
declare function dynamicEventHandler(initial?: EventHandler): DynamicEventHandler;
declare function defineLazyEventHandler(factory: LazyEventHandler): EventHandler;
declare const lazyEventHandler: typeof defineLazyEventHandler;
interface Layer {
route: string;
match?: Matcher;
handler: EventHandler;
}
type Stack = Layer[];
interface InputLayer {
route?: string;
match?: Matcher;
handler: EventHandler;
lazy?: boolean;
}
type InputStack = InputLayer[];
type Matcher = (url: string, event?: H3Event) => boolean;
interface AppUse {
(route: string | string[], handler: EventHandler | EventHandler[], options?: Partial<InputLayer>): App;
(handler: EventHandler | EventHandler[], options?: Partial<InputLayer>): App;
(options: InputLayer): App;
}
interface AppOptions {
debug?: boolean;
onError?: (error: Error, event: H3Event) => any;
}
interface App {
stack: Stack;
handler: EventHandler;
options: AppOptions;
use: AppUse;
}
declare function createApp(options?: AppOptions): App;
declare function use(app: App, arg1: string | EventHandler | InputLayer | InputLayer[], arg2?: Partial<InputLayer> | EventHandler | EventHandler[], arg3?: Partial<InputLayer>): App;
declare function createAppEventHandler(stack: Stack, options: AppOptions): EventHandler<void>;
/**
* H3 Runtime Error
* @class
* @extends Error
* @property {Number} statusCode An Integer indicating the HTTP response status code.
* @property {String} statusMessage A String representing the HTTP status message
* @property {String} fatal Indicates if the error is a fatal error.
* @property {String} unhandled Indicates if the error was unhandled and auto captured.
* @property {Any} data An extra data that will includes in the response.<br>
* This can be used to pass additional information about the error.
* @property {Boolean} internal Setting this property to <code>true</code> will mark error as an internal error
*/
declare class H3Error extends Error {
static __h3_error__: boolean;
toJSON(): Pick<H3Error, "statusCode" | "statusMessage" | "data" | "message">;
statusCode: number;
fatal: boolean;
unhandled: boolean;
statusMessage?: string;
data?: any;
}
/**
* Creates new `Error` that can be used to handle both internal and runtime errors.
*
* @param input {Partial<H3Error>}
* @return {H3Error} An instance of the H3Error
*/
declare function createError(input: string | (Partial<H3Error> & {
status?: number;
statusText?: string;
})): H3Error;
/**
* Receive an error and return the corresponding response.<br>
* H3 internally uses this function to handle unhandled errors.<br>
* Note that calling this function will close the connection and no other data will be sent to client afterwards.
*
@param event {H3Event} H3 event or req passed by h3 handler
* @param error {H3Error|Error} Raised error
* @param debug {Boolean} Whether application is in debug mode.<br>
* In the debug mode the stack trace of errors will be return in response.
*/
declare function sendError(event: H3Event, error: Error | H3Error, debug?: boolean): void;
declare function isError(input: any): input is H3Error;
declare function useBase(base: string, handler: EventHandler): EventHandler;
/**
* Reads body of the request and returns encoded raw string (default) or `Buffer` if encoding if falsy.
* @param event {H3Event} H3 event or req passed by h3 handler
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.
*
* @return {String|Buffer} Encoded raw string or raw Buffer of the body
*/
declare function readRawBody<E extends Encoding = "utf8">(event: H3Event, encoding?: E): E extends false ? Promise<Buffer | undefined> : Promise<string | undefined>;
/**
* Reads request body and try to safely parse using [destr](https://github.com/unjs/destr)
* @param event {H3Event} H3 event or req passed by h3 handler
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.
*
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body
*
* ```ts
* const body = await useBody(req)
* ```
*/
declare function readBody<T = any>(event: H3Event): Promise<T>;
interface CacheConditions {
modifiedTime?: string | Date;
maxAge?: number;
etag?: string;
cacheControls?: string[];
}
/**
* Check request caching headers (`If-Modified-Since`) and add caching headers (Last-Modified, Cache-Control)
* Note: `public` cache control will be added by default
* @returns `true` when cache headers are matching. When `true` is returned, no reponse should be sent anymore
*/
declare function handleCacheHeaders(event: H3Event, opts: CacheConditions): boolean;
declare const MIMES: {
html: string;
json: string;
};
/**
* Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
* @param event {H3Event} H3 event or req passed by h3 handler
* @returns Object of cookie name-value pairs
* ```ts
* const cookies = parseCookies(event)
* ```
*/
declare function parseCookies(event: H3Event): Record<string, string>;
/**
* Get a cookie value by name.
* @param event {H3Event} H3 event or req passed by h3 handler
* @param name Name of the cookie to get
* @returns {*} Value of the cookie (String or undefined)
* ```ts
* const authorization = useCookie(request, 'Authorization')
* ```
*/
declare function getCookie(event: H3Event, name: string): string | undefined;
/**
* Set a cookie value by name.
* @param event {H3Event} H3 event or res passed by h3 handler
* @param name Name of the cookie to set
* @param value Value of the cookie to set
* @param serializeOptions {CookieSerializeOptions} Options for serializing the cookie
* ```ts
* setCookie(res, 'Authorization', '1234567')
* ```
*/
declare function setCookie(event: H3Event, name: string, value: string, serializeOptions?: CookieSerializeOptions): void;
/**
* Set a cookie value by name.
* @param event {H3Event} H3 event or res passed by h3 handler
* @param name Name of the cookie to delete
* @param serializeOptions {CookieSerializeOptions} Cookie options
* ```ts
* deleteCookie(res, 'SessionId')
* ```
*/
declare function deleteCookie(event: H3Event, name: string, serializeOptions?: CookieSerializeOptions): void;
interface ProxyOptions {
headers?: RequestHeaders | HeadersInit;
fetchOptions?: RequestInit;
fetch?: typeof fetch;
sendStream?: boolean;
}
declare function proxyRequest(event: H3Event, target: string, opts?: ProxyOptions): Promise<void>;
declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions): Promise<void>;
declare function getQuery(event: H3Event): ufo.QueryObject;
declare function getRouterParams(event: H3Event): H3Event["context"];
declare function getRouterParam(event: H3Event, name: string): H3Event["context"][string];
declare function getMethod(event: H3Event, defaultMethod?: HTTPMethod): HTTPMethod;
declare function isMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
declare function assertMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
declare function getRequestHeaders(event: H3Event): RequestHeaders;
declare const getHeaders: typeof getRequestHeaders;
declare function getRequestHeader(event: H3Event, name: string): RequestHeaders[string];
declare const getHeader: typeof getRequestHeader;
declare function send(event: H3Event, data?: any, type?: string): Promise<void>;
declare function defaultContentType(event: H3Event, type?: string): void;
declare function sendRedirect(event: H3Event, location: string, code?: number): Promise<void>;
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["res"]["getHeaders"]>;
declare function getResponseHeader(event: H3Event, name: string): ReturnType<H3Event["res"]["getHeader"]>;
declare function setResponseHeaders(event: H3Event, headers: Record<string, Parameters<OutgoingMessage["setHeader"]>[1]>): void;
declare const setHeaders: typeof setResponseHeaders;
declare function setResponseHeader(event: H3Event, name: string, value: Parameters<OutgoingMessage["setHeader"]>[1]): void;
declare const setHeader: typeof setResponseHeader;
declare function appendResponseHeaders(event: H3Event, headers: Record<string, string>): void;
declare const appendHeaders: typeof appendResponseHeaders;
declare function appendResponseHeader(event: H3Event, name: string, value: string): void;
declare const appendHeader: typeof appendResponseHeader;
declare function isStream(data: any): any;
declare function sendStream(event: H3Event, data: any): Promise<void>;
declare function writeEarlyHints(event: H3Event, hints: string | string[] | Record<string, string | string[]>, cb?: () => void): void;
type RouterMethod = Lowercase<HTTPMethod>;
type RouterUse = (path: string, handler: EventHandler, method?: RouterMethod | RouterMethod[]) => Router;
type AddRouteShortcuts = Record<RouterMethod, RouterUse>;
interface Router extends AddRouteShortcuts {
add: RouterUse;
use: RouterUse;
handler: EventHandler;
}
interface CreateRouterOptions {
/** @deprecated Please use `preemptive` instead. **/
preemtive?: boolean;
preemptive?: boolean;
}
declare function createRouter(opts?: CreateRouterOptions): Router;
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, ProxyOptions, RequestHeaders, Router, RouterMethod, RouterUse, Stack, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getRouterParam, getRouterParams, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readRawBody, send, sendError, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, toEventHandler, toNodeListener, use, useBase, writeEarlyHints };

913
node_modules/h3/dist/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,913 @@
import { withoutTrailingSlash, withoutBase, getQuery as getQuery$1 } from 'ufo';
import { createRouter as createRouter$1 } from 'radix3';
import destr from 'destr';
import { parse, serialize } from 'cookie-es';
function useBase(base, handler) {
base = withoutTrailingSlash(base);
if (!base) {
return handler;
}
return eventHandler((event) => {
event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
event.node.req.url = withoutBase(event.node.req.url || "/", base);
return handler(event);
});
}
class H3Error extends Error {
constructor() {
super(...arguments);
this.statusCode = 500;
this.fatal = false;
this.unhandled = false;
this.statusMessage = void 0;
}
toJSON() {
const obj = {
message: this.message,
statusCode: this.statusCode
};
if (this.statusMessage) {
obj.statusMessage = this.statusMessage;
}
if (this.data !== void 0) {
obj.data = this.data;
}
return obj;
}
}
H3Error.__h3_error__ = true;
function createError(input) {
if (typeof input === "string") {
return new H3Error(input);
}
if (isError(input)) {
return input;
}
const err = new H3Error(
input.message ?? input.statusMessage,
input.cause ? { cause: input.cause } : void 0
);
if ("stack" in input) {
try {
Object.defineProperty(err, "stack", {
get() {
return input.stack;
}
});
} catch {
try {
err.stack = input.stack;
} catch {
}
}
}
if (input.data) {
err.data = input.data;
}
if (input.statusCode) {
err.statusCode = input.statusCode;
} else if (input.status) {
err.statusCode = input.status;
}
if (input.statusMessage) {
err.statusMessage = input.statusMessage;
} else if (input.statusText) {
err.statusMessage = input.statusText;
}
if (input.fatal !== void 0) {
err.fatal = input.fatal;
}
if (input.unhandled !== void 0) {
err.unhandled = input.unhandled;
}
return err;
}
function sendError(event, error, debug) {
if (event.node.res.writableEnded) {
return;
}
const h3Error = isError(error) ? error : createError(error);
const responseBody = {
statusCode: h3Error.statusCode,
statusMessage: h3Error.statusMessage,
stack: [],
data: h3Error.data
};
if (debug) {
responseBody.stack = (h3Error.stack || "").split("\n").map((l) => l.trim());
}
if (event.node.res.writableEnded) {
return;
}
const _code = Number.parseInt(h3Error.statusCode);
if (_code) {
event.node.res.statusCode = _code;
}
if (h3Error.statusMessage) {
event.node.res.statusMessage = h3Error.statusMessage;
}
event.node.res.setHeader("content-type", MIMES.json);
event.node.res.end(JSON.stringify(responseBody, void 0, 2));
}
function isError(input) {
return input?.constructor?.__h3_error__ === true;
}
function getQuery(event) {
return getQuery$1(event.node.req.url || "");
}
function getRouterParams(event) {
return event.context.params || {};
}
function getRouterParam(event, name) {
const params = getRouterParams(event);
return params[name];
}
function getMethod(event, defaultMethod = "GET") {
return (event.node.req.method || defaultMethod).toUpperCase();
}
function isMethod(event, expected, allowHead) {
const method = getMethod(event);
if (allowHead && method === "HEAD") {
return true;
}
if (typeof expected === "string") {
if (method === expected) {
return true;
}
} else if (expected.includes(method)) {
return true;
}
return false;
}
function assertMethod(event, expected, allowHead) {
if (!isMethod(event, expected, allowHead)) {
throw createError({
statusCode: 405,
statusMessage: "HTTP method is not allowed."
});
}
}
function getRequestHeaders(event) {
const _headers = {};
for (const key in event.node.req.headers) {
const val = event.node.req.headers[key];
_headers[key] = Array.isArray(val) ? val.filter(Boolean).join(", ") : val;
}
return _headers;
}
const getHeaders = getRequestHeaders;
function getRequestHeader(event, name) {
const headers = getRequestHeaders(event);
const value = headers[name.toLowerCase()];
return value;
}
const getHeader = getRequestHeader;
const RawBodySymbol = Symbol.for("h3RawBody");
const ParsedBodySymbol = Symbol.for("h3ParsedBody");
const PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
function readRawBody(event, encoding = "utf8") {
assertMethod(event, PayloadMethods$1);
if (RawBodySymbol in event.node.req) {
const promise2 = Promise.resolve(event.node.req[RawBodySymbol]);
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
}
if ("body" in event.node.req) {
return Promise.resolve(event.node.req.body);
}
if (!Number.parseInt(event.node.req.headers["content-length"] || "")) {
return Promise.resolve(void 0);
}
const promise = event.node.req[RawBodySymbol] = new Promise(
(resolve, reject) => {
const bodyData = [];
event.node.req.on("error", (err) => {
reject(err);
}).on("data", (chunk) => {
bodyData.push(chunk);
}).on("end", () => {
resolve(Buffer.concat(bodyData));
});
}
);
const result = encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
return result;
}
async function readBody(event) {
if (ParsedBodySymbol in event.node.req) {
return event.node.req[ParsedBodySymbol];
}
const body = await readRawBody(event);
if (event.node.req.headers["content-type"] === "application/x-www-form-urlencoded") {
const form = new URLSearchParams(body);
const parsedForm = /* @__PURE__ */ Object.create(null);
for (const [key, value] of form.entries()) {
if (key in parsedForm) {
if (!Array.isArray(parsedForm[key])) {
parsedForm[key] = [parsedForm[key]];
}
parsedForm[key].push(value);
} else {
parsedForm[key] = value;
}
}
return parsedForm;
}
const json = destr(body);
event.node.req[ParsedBodySymbol] = json;
return json;
}
function handleCacheHeaders(event, opts) {
const cacheControls = ["public", ...opts.cacheControls || []];
let cacheMatched = false;
if (opts.maxAge !== void 0) {
cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
}
if (opts.modifiedTime) {
const modifiedTime = new Date(opts.modifiedTime);
const ifModifiedSince = event.node.req.headers["if-modified-since"];
event.node.res.setHeader("last-modified", modifiedTime.toUTCString());
if (ifModifiedSince && new Date(ifModifiedSince) >= opts.modifiedTime) {
cacheMatched = true;
}
}
if (opts.etag) {
event.node.res.setHeader("etag", opts.etag);
const ifNonMatch = event.node.req.headers["if-none-match"];
if (ifNonMatch === opts.etag) {
cacheMatched = true;
}
}
event.node.res.setHeader("cache-control", cacheControls.join(", "));
if (cacheMatched) {
event.node.res.statusCode = 304;
event.node.res.end();
return true;
}
return false;
}
const MIMES = {
html: "text/html",
json: "application/json"
};
const defer = typeof setImmediate !== "undefined" ? setImmediate : (fn) => fn();
function send(event, data, type) {
if (type) {
defaultContentType(event, type);
}
return new Promise((resolve) => {
defer(() => {
event.node.res.end(data);
resolve();
});
});
}
function defaultContentType(event, type) {
if (type && !event.node.res.getHeader("content-type")) {
event.node.res.setHeader("content-type", type);
}
}
function sendRedirect(event, location, code = 302) {
event.node.res.statusCode = code;
event.node.res.setHeader("location", location);
const encodedLoc = location.replace(/"/g, "%22");
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
return send(event, html, MIMES.html);
}
function getResponseHeaders(event) {
return event.node.res.getHeaders();
}
function getResponseHeader(event, name) {
return event.node.res.getHeader(name);
}
function setResponseHeaders(event, headers) {
for (const [name, value] of Object.entries(headers)) {
event.node.res.setHeader(name, value);
}
}
const setHeaders = setResponseHeaders;
function setResponseHeader(event, name, value) {
event.node.res.setHeader(name, value);
}
const setHeader = setResponseHeader;
function appendResponseHeaders(event, headers) {
for (const [name, value] of Object.entries(headers)) {
appendResponseHeader(event, name, value);
}
}
const appendHeaders = appendResponseHeaders;
function appendResponseHeader(event, name, value) {
let current = event.node.res.getHeader(name);
if (!current) {
event.node.res.setHeader(name, value);
return;
}
if (!Array.isArray(current)) {
current = [current.toString()];
}
event.node.res.setHeader(name, [...current, value]);
}
const appendHeader = appendResponseHeader;
function isStream(data) {
return data && typeof data === "object" && typeof data.pipe === "function" && typeof data.on === "function";
}
function sendStream(event, data) {
return new Promise((resolve, reject) => {
data.pipe(event.node.res);
data.on("end", () => resolve());
data.on("error", (error) => reject(createError(error)));
});
}
const noop = () => {
};
function writeEarlyHints(event, hints, cb = noop) {
if (!event.node.res.socket) {
cb();
return;
}
if (typeof hints === "string" || Array.isArray(hints)) {
hints = { link: hints };
}
if (hints.link) {
hints.link = Array.isArray(hints.link) ? hints.link : hints.link.split(",");
}
const headers = Object.entries(hints).map(
(e) => [e[0].toLowerCase(), e[1]]
);
if (headers.length === 0) {
cb();
return;
}
let hint = "HTTP/1.1 103 Early Hints";
if (hints.link) {
hint += `\r
Link: ${hints.link.join(", ")}`;
}
for (const [header, value] of headers) {
if (header === "link") {
continue;
}
hint += `\r
${header}: ${value}`;
}
if (event.node.res.socket) {
event.node.res.socket.write(
`${hint}\r
\r
`,
"utf8",
cb
);
} else {
cb();
}
}
function parseCookies(event) {
return parse(event.node.req.headers.cookie || "");
}
function getCookie(event, name) {
return parseCookies(event)[name];
}
function setCookie(event, name, value, serializeOptions) {
const cookieStr = serialize(name, value, {
path: "/",
...serializeOptions
});
appendHeader(event, "Set-Cookie", cookieStr);
}
function deleteCookie(event, name, serializeOptions) {
setCookie(event, name, "", {
...serializeOptions,
maxAge: 0
});
}
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
const ignoredHeaders = /* @__PURE__ */ new Set([
"transfer-encoding",
"connection",
"keep-alive",
"upgrade",
"expect"
]);
async function proxyRequest(event, target, opts = {}) {
const method = getMethod(event);
let body;
if (PayloadMethods.has(method)) {
body = await readRawBody(event).catch(() => void 0);
}
const headers = /* @__PURE__ */ Object.create(null);
const reqHeaders = getRequestHeaders(event);
for (const name in reqHeaders) {
if (!ignoredHeaders.has(name)) {
headers[name] = reqHeaders[name];
}
}
if (opts.fetchOptions?.headers) {
Object.assign(headers, opts.fetchOptions.headers);
}
if (opts.headers) {
Object.assign(headers, opts.headers);
}
return sendProxy(event, target, {
...opts,
fetchOptions: {
headers,
method,
body,
...opts.fetchOptions
}
});
}
async function sendProxy(event, target, opts = {}) {
const _fetch = opts.fetch || globalThis.fetch;
if (!_fetch) {
throw new Error(
"fetch is not available. Try importing `node-fetch-native/polyfill` for Node.js."
);
}
const response = await _fetch(target, {
headers: opts.headers,
...opts.fetchOptions
});
event.node.res.statusCode = response.status;
event.node.res.statusMessage = response.statusText;
for (const [key, value] of response.headers.entries()) {
if (key === "content-encoding") {
continue;
}
if (key === "content-length") {
continue;
}
event.node.res.setHeader(key, value);
}
try {
if (response.body) {
if (opts.sendStream === false) {
const data = new Uint8Array(await response.arrayBuffer());
event.node.res.end(data);
} else {
for await (const chunk of response.body) {
event.node.res.write(chunk);
}
event.node.res.end();
}
}
} catch (error) {
event.node.res.end();
throw error;
}
}
class H3Headers {
constructor(init) {
if (!init) {
this._headers = {};
} else if (Array.isArray(init)) {
this._headers = Object.fromEntries(
init.map(([key, value]) => [key.toLowerCase(), value])
);
} else if (init && "append" in init) {
this._headers = Object.fromEntries(init.entries());
} else {
this._headers = Object.fromEntries(
Object.entries(init).map(([key, value]) => [key.toLowerCase(), value])
);
}
}
[Symbol.iterator]() {
return this.entries();
}
entries() {
throw Object.entries(this._headers)[Symbol.iterator]();
}
keys() {
return Object.keys(this._headers)[Symbol.iterator]();
}
values() {
throw Object.values(this._headers)[Symbol.iterator]();
}
append(name, value) {
const _name = name.toLowerCase();
this.set(_name, [this.get(_name), value].filter(Boolean).join(", "));
}
delete(name) {
delete this._headers[name.toLowerCase()];
}
get(name) {
return this._headers[name.toLowerCase()];
}
has(name) {
return name.toLowerCase() in this._headers;
}
set(name, value) {
this._headers[name.toLowerCase()] = String(value);
}
forEach(callbackfn) {
for (const [key, value] of Object.entries(this._headers)) {
callbackfn(value, key, this);
}
}
}
class H3Response {
constructor(body = null, init = {}) {
this.body = null;
this.type = "default";
this.bodyUsed = false;
this.headers = new H3Headers(init.headers);
this.status = init.status ?? 200;
this.statusText = init.statusText || "";
this.redirected = !!init.status && [301, 302, 307, 308].includes(init.status);
this._body = body;
this.url = "";
this.ok = this.status < 300 && this.status > 199;
}
clone() {
return new H3Response(this.body, {
headers: this.headers,
status: this.status,
statusText: this.statusText
});
}
arrayBuffer() {
return Promise.resolve(this._body);
}
blob() {
return Promise.resolve(this._body);
}
formData() {
return Promise.resolve(this._body);
}
json() {
return Promise.resolve(this._body);
}
text() {
return Promise.resolve(this._body);
}
}
class H3Event {
constructor(req, res) {
this["__is_event__"] = true;
this.context = {};
this.node = { req, res };
}
get path() {
return this.req.url;
}
get req() {
return this.node.req;
}
get res() {
return this.node.res;
}
respondWith(r) {
Promise.resolve(r).then((_response) => {
if (this.res.writableEnded) {
return;
}
const response = _response instanceof H3Response ? _response : new H3Response(_response);
for (const [key, value] of response.headers.entries()) {
this.res.setHeader(key, value);
}
if (response.status) {
this.res.statusCode = response.status;
}
if (response.statusText) {
this.res.statusMessage = response.statusText;
}
if (response.redirected) {
this.res.setHeader("location", response.url);
}
if (!response._body) {
return this.res.end();
}
if (typeof response._body === "string" || "buffer" in response._body || "byteLength" in response._body) {
return this.res.end(response._body);
}
if (!response.headers.has("content-type")) {
response.headers.set("content-type", MIMES.json);
}
this.res.end(JSON.stringify(response._body));
});
}
}
function isEvent(input) {
return "__is_event__" in input;
}
function createEvent(req, res) {
return new H3Event(req, res);
}
function defineEventHandler(handler) {
handler.__is_handler__ = true;
return handler;
}
const eventHandler = defineEventHandler;
function isEventHandler(input) {
return "__is_handler__" in input;
}
function toEventHandler(input, _, _route) {
if (!isEventHandler(input)) {
console.warn(
"[h3] Implicit event handler conversion is deprecated. Use `eventHandler()` or `fromNodeMiddleware()` to define event handlers.",
_route && _route !== "/" ? `
Route: ${_route}` : "",
`
Handler: ${input}`
);
}
return input;
}
function dynamicEventHandler(initial) {
let current = initial;
const wrapper = eventHandler((event) => {
if (current) {
return current(event);
}
});
wrapper.set = (handler) => {
current = handler;
};
return wrapper;
}
function defineLazyEventHandler(factory) {
let _promise;
let _resolved;
const resolveHandler = () => {
if (_resolved) {
return Promise.resolve(_resolved);
}
if (!_promise) {
_promise = Promise.resolve(factory()).then((r) => {
const handler = r.default || r;
if (typeof handler !== "function") {
throw new TypeError(
"Invalid lazy handler result. It should be a function:",
handler
);
}
_resolved = toEventHandler(r.default || r);
return _resolved;
});
}
return _promise;
};
return eventHandler((event) => {
if (_resolved) {
return _resolved(event);
}
return resolveHandler().then((handler) => handler(event));
});
}
const lazyEventHandler = defineLazyEventHandler;
function createApp(options = {}) {
const stack = [];
const handler = createAppEventHandler(stack, options);
const app = {
use: (arg1, arg2, arg3) => use(app, arg1, arg2, arg3),
handler,
stack,
options
};
return app;
}
function use(app, arg1, arg2, arg3) {
if (Array.isArray(arg1)) {
for (const i of arg1) {
use(app, i, arg2, arg3);
}
} else if (Array.isArray(arg2)) {
for (const i of arg2) {
use(app, arg1, i, arg3);
}
} else if (typeof arg1 === "string") {
app.stack.push(
normalizeLayer({ ...arg3, route: arg1, handler: arg2 })
);
} else if (typeof arg1 === "function") {
app.stack.push(
normalizeLayer({ ...arg2, route: "/", handler: arg1 })
);
} else {
app.stack.push(normalizeLayer({ ...arg1 }));
}
return app;
}
function createAppEventHandler(stack, options) {
const spacing = options.debug ? 2 : void 0;
return eventHandler(async (event) => {
event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
const reqUrl = event.node.req.url || "/";
for (const layer of stack) {
if (layer.route.length > 1) {
if (!reqUrl.startsWith(layer.route)) {
continue;
}
event.node.req.url = reqUrl.slice(layer.route.length) || "/";
} else {
event.node.req.url = reqUrl;
}
if (layer.match && !layer.match(event.node.req.url, event)) {
continue;
}
const val = await layer.handler(event);
if (event.node.res.writableEnded) {
return;
}
const type = typeof val;
if (type === "string") {
return send(event, val, MIMES.html);
} else if (isStream(val)) {
return sendStream(event, val);
} else if (val === null) {
event.node.res.statusCode = 204;
return send(event);
} else if (type === "object" || type === "boolean" || type === "number") {
if (val.buffer) {
return send(event, val);
} else if (val instanceof Error) {
throw createError(val);
} else {
return send(
event,
JSON.stringify(val, void 0, spacing),
MIMES.json
);
}
}
}
if (!event.node.res.writableEnded) {
throw createError({
statusCode: 404,
statusMessage: `Cannot find any route matching ${event.node.req.url || "/"}.`
});
}
});
}
function normalizeLayer(input) {
let handler = input.handler;
if (handler.handler) {
handler = handler.handler;
}
if (input.lazy) {
handler = lazyEventHandler(handler);
} else if (!isEventHandler(handler)) {
handler = toEventHandler(handler, void 0, input.route);
}
return {
route: withoutTrailingSlash(input.route),
match: input.match,
handler
};
}
const defineNodeListener = (handler) => handler;
const defineNodeMiddleware = (middleware) => middleware;
function fromNodeMiddleware(handler) {
if (isEventHandler(handler)) {
return handler;
}
if (typeof handler !== "function") {
throw new TypeError(
"Invalid handler. It should be a function:",
handler
);
}
return eventHandler((event) => {
return callNodeListener(
handler,
event.node.req,
event.node.res
);
});
}
function toNodeListener(app) {
const toNodeHandle = async function(req, res) {
const event = createEvent(req, res);
try {
await app.handler(event);
} catch (_error) {
const error = createError(_error);
if (!isError(_error)) {
error.unhandled = true;
}
if (app.options.onError) {
await app.options.onError(error, event);
} else {
if (error.unhandled || error.fatal) {
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
}
await sendError(event, error, !!app.options.debug);
}
}
};
return toNodeHandle;
}
function promisifyNodeListener(handler) {
return function(req, res) {
return callNodeListener(handler, req, res);
};
}
function callNodeListener(handler, req, res) {
const isMiddleware = handler.length > 2;
return new Promise((resolve, reject) => {
const next = (err) => {
if (isMiddleware) {
res.off("close", next);
res.off("error", next);
}
return err ? reject(createError(err)) : resolve(void 0);
};
try {
const returned = handler(req, res, next);
if (isMiddleware && returned === void 0) {
res.once("close", next);
res.once("error", next);
} else {
resolve(returned);
}
} catch (error) {
next(error);
}
});
}
const RouterMethods = [
"connect",
"delete",
"get",
"head",
"options",
"post",
"put",
"trace",
"patch"
];
function createRouter(opts = {}) {
const _router = createRouter$1({});
const routes = {};
const router = {};
const addRoute = (path, handler, method) => {
let route = routes[path];
if (!route) {
routes[path] = route = { handlers: {} };
_router.insert(path, route);
}
if (Array.isArray(method)) {
for (const m of method) {
addRoute(path, handler, m);
}
} else {
route.handlers[method] = toEventHandler(handler, void 0, path);
}
return router;
};
router.use = router.add = (path, handler, method) => addRoute(path, handler, method || "all");
for (const method of RouterMethods) {
router[method] = (path, handle) => router.add(path, handle, method);
}
router.handler = eventHandler((event) => {
let path = event.node.req.url || "/";
const qIndex = path.indexOf("?");
if (qIndex !== -1) {
path = path.slice(0, Math.max(0, qIndex));
}
const matched = _router.lookup(path);
if (!matched || !matched.handlers) {
if (opts.preemptive || opts.preemtive) {
throw createError({
statusCode: 404,
name: "Not Found",
statusMessage: `Cannot find any route matching ${event.node.req.url || "/"}.`
});
} else {
return;
}
}
const method = (event.node.req.method || "get").toLowerCase();
const handler = matched.handlers[method] || matched.handlers.all;
if (!handler) {
throw createError({
statusCode: 405,
name: "Method Not Allowed",
statusMessage: `Method ${method} is not allowed on this route.`
});
}
const params = matched.params || {};
event.context.params = params;
return handler(event);
});
return router;
}
export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getRouterParam, getRouterParams, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readRawBody, send, sendError, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, toEventHandler, toNodeListener, use, useBase, writeEarlyHints };

60
node_modules/h3/package.json generated vendored Normal file
View File

@@ -0,0 +1,60 @@
{
"name": "h3",
"version": "1.0.2",
"description": "Tiny JavaScript Server",
"repository": "unjs/h3",
"license": "MIT",
"sideEffects": false,
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"dependencies": {
"cookie-es": "^0.5.0",
"destr": "^1.2.2",
"radix3": "^1.0.0",
"ufo": "^1.0.1"
},
"devDependencies": {
"0x": "^5.4.1",
"@types/express": "^4.17.14",
"@types/node": "^18.11.14",
"@types/supertest": "^2.0.12",
"@vitest/coverage-c8": "^0.25.8",
"autocannon": "^7.10.0",
"changelogen": "^0.4.0",
"connect": "^3.7.0",
"eslint": "^8.29.0",
"eslint-config-unjs": "^0.0.3",
"express": "^4.18.2",
"get-port": "^6.1.2",
"jiti": "^1.16.0",
"listhen": "^1.0.1",
"node-fetch-native": "^1.0.1",
"prettier": "^2.8.1",
"supertest": "^6.3.3",
"typescript": "^4.9.4",
"unbuild": "^1.0.2",
"vitest": "^0.25.8"
},
"packageManager": "pnpm@7.18.2",
"scripts": {
"build": "unbuild",
"dev": "vitest",
"lint": "eslint --ext ts,mjs,cjs . && prettier -c src test playground",
"play": "jiti ./playground/index.ts",
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
"release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
"test": "pnpm lint && vitest run --coverage"
}
}