initial commit
This commit is contained in:
21
node_modules/h3/LICENSE
generated
vendored
Normal file
21
node_modules/h3/LICENSE
generated
vendored
Normal 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
164
node_modules/h3/README.md
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
[](https://npmjs.com/package/h3)
|
||||
[](https://npmjs.com/package/h3)
|
||||
[](https://bundlephobia.com/result?p=h3)
|
||||
[](https://github.com/unjs/h3/actions)
|
||||
[](https://codecov.io/gh/unjs/h3)
|
||||
[](https://www.jsdocs.io/package/h3)
|
||||
|
||||
> H3 is a minimal h(ttp) framework built for high performance and portability
|
||||
|
||||
<!--  -->
|
||||
|
||||
## Features
|
||||
|
||||
✔️ **Portable:** Works perfectly in Serverless, Workers, and Node.js
|
||||
|
||||
✔️ **Minimal:** Small and tree-shakable
|
||||
|
||||
✔️ **Modern:** Native promise support
|
||||
|
||||
✔️ **Extendable:** Ships with a set of composable utilities but can be extended
|
||||
|
||||
✔️ **Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)
|
||||
|
||||
✔️ **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
977
node_modules/h3/dist/index.cjs
generated
vendored
Normal 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
306
node_modules/h3/dist/index.d.ts
generated
vendored
Normal 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
913
node_modules/h3/dist/index.mjs
generated
vendored
Normal 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
60
node_modules/h3/package.json
generated
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user