+```
+
+### Local testing
+
+You can test adapter using any compatible JavaScript runtime by passing a Request object.
+
+```js [web.test.mjs]
+import { handler } from "./web.mjs";
+
+const response = await handler(new Request(new URL("/", "http://localhost")));
+
+console.log(await response.text()); // Hello world!
+```
+
+Run with `node ./web.test.mjs`.
diff --git a/docs/3.adapters/3.plain.md b/docs/3.adapters/3.plain.md
new file mode 100644
index 00000000..ae0b35bd
--- /dev/null
+++ b/docs/3.adapters/3.plain.md
@@ -0,0 +1,62 @@
+---
+icon: material-symbols-light:data-object
+---
+
+# Plain
+
+> Run h3 servers into any unknown runtime!
+
+There might be cases where your runtime is nither Node.js or Web compatible. Using plain adapter you can have an object input/output interface.
+
+> [!NOTE]
+> This can be also be particulary useful for testing your server or running inside lambda-like environments.
+
+## Usage
+
+First, create app entry:
+
+```js [app.mjs]
+import { createApp, defineEventHandler } from "h3";
+
+export const app = createApp();
+
+app.use(defineEventHandler(() => "Hello world!"));
+```
+
+Create plain entry:
+
+```js [plain.mjs]
+import { toPlainHandler } from "h3";
+import { app } from "./app.mjs";
+
+export const handler = toPlainHandler(app);
+```
+
+### Local testing
+
+You can test adapter using any JavaScript runtime.
+
+```js [plain.test.mjs]
+import { handler } from "./plain.mjs";
+
+const response = await handlerRequest({
+ method: "GET",
+ path: "/",
+ headers: {
+ "x-test": "test",
+ },
+ body: undefined,
+ context: {},
+});
+```
+
+Example response:
+
+```js
+{
+ status: 200,
+ statusText: '',
+ headers: [ [ 'content-type', 'text/html' ] ],
+ body: 'Hello world!'
+}
+```
diff --git a/docs/3.adapters/bun.md b/docs/3.adapters/bun.md
new file mode 100644
index 00000000..18a39d3c
--- /dev/null
+++ b/docs/3.adapters/bun.md
@@ -0,0 +1,66 @@
+---
+icon: simple-icons:bun
+---
+
+# Bun
+
+> Run your h3 apps with Bun
+
+In order to run h3 apps in [Bun](https://bun.sh/), use the [Web Adapter](/adapters/web).
+
+> [!NOTE]
+> Alternatively you can use [Node.js adapter](/adapters/node) as Bun is fully compatible with Node.js API!
+
+## Usage
+
+Create app entry:
+
+```js [app.mjs]
+import { createApp, defineEventHandler } from "h3";
+
+export const app = createApp();
+
+app.use(defineEventHandler(() => "Hello world!"));
+```
+
+Create Bun server entry:
+
+```js [server.mjs]
+import { toWebHandler } from "h3";
+import { app } from "./app.mjs";
+
+const server = Bun.serve({
+ port: 3000,
+ fetch: toWebHandler(app),
+});
+```
+
+Now, your can run Bun server:
+
+```bash
+bun --bun ./server.mjs
+```
+
+## WebSocket support
+
+:read-more{to="https://crossws.unjs.io/adapters/bun"}
+
+```ts
+import wsAdapter from "crossws/adapters/bun";
+
+const { websocket, handleUpgrade } = wsAdapter(app.websocket);
+
+const handler = toWebHandler(app)
+
+const server = Bun.serve({
+ port: 3000,
+ websocket,
+ fetch(req, server) {
+ if (await handleUpgrade(req, server)) {
+ return;
+ }
+ return handler(req)
+ }
+});
+```
+
diff --git a/docs/3.adapters/cloudflare.md b/docs/3.adapters/cloudflare.md
new file mode 100644
index 00000000..14e10f7f
--- /dev/null
+++ b/docs/3.adapters/cloudflare.md
@@ -0,0 +1,85 @@
+---
+icon: devicon-plain:cloudflareworkers
+---
+
+# Cloudflare
+
+> Run your h3 apps in Cloudflare Workers
+
+You can directly host your h3 applications to [Cloudflare Workers](https://workers.cloudflare.com/) using [Web Adapter](/adapters/web).
+
+## Usage
+
+Create app entry:
+
+```js [app.mjs]
+import { createApp, defineEventHandler } from "h3";
+
+export const app = createApp();
+
+app.use(defineEventHandler(() => "Hello world!"));
+```
+
+Create entry for a Cloudflare Worker:
+
+```js [cloudflare.mjs]
+import { toWebHandler } from "h3";
+import { app } from "./app.mjs";
+
+const handler = toWebHandler(app);
+
+export default {
+ async fetch(request, env, ctx) {
+ return handler(request, {
+ cloudflare: { env, ctx },
+ });
+ },
+};
+```
+
+Then, create a simple `wrangler.toml`:
+
+```ini [wrangler.toml]
+name = "h3-app"
+main = "cloudflare.mjs"
+compatibility_date = "2023-08-01"
+```
+
+Finally, use `wrangler dev` to locally preview:
+
+```bash
+npx wrangler dev
+```
+
+To deploy, use `wrangler deploy`:
+
+```bash
+npx wrangler deploy
+```
+
+## WebSocket support
+
+:read-more{to="https://crossws.unjs.io/adapters/cloudflare"}
+
+```ts
+import wsAdapter from "crossws/adapters/cloudflare";
+
+const { handleUpgrade } = wsAdapter(app.websocket);
+
+export default {
+ async fetch(request, env, ctx) {
+ if (request.headers.get("upgrade") === "websocket") {
+ return handleUpgrade(request, env, context);
+ }
+ return handler(request, {
+ cloudflare: { env, ctx },
+ });
+ },
+};
+```
+
+---
+
+::read-more
+👉 See [pi0/h3-on-edge](https://github.com/pi0/h3-on-edge) demo for a fully working example ([deployment](https://h3-on-edge.pi0.workers.dev/)).
+::
diff --git a/docs/3.adapters/deno.md b/docs/3.adapters/deno.md
new file mode 100644
index 00000000..d22064d1
--- /dev/null
+++ b/docs/3.adapters/deno.md
@@ -0,0 +1,77 @@
+---
+icon: teenyicons:deno-solid
+---
+
+# Deno
+
+> Run your h3 apps in Deno Deploy
+
+You can directly host your h3 applications to [Deno Deploy](https://deno.com/deploy) using [Web Adapter](/adapters/web).
+
+## Usage
+
+Create app entry:
+
+```js [app.mjs]
+import { createApp, defineEventHandler } from "h3";
+
+export const app = createApp();
+
+app.use(defineEventHandler(() => "Hello world!"));
+```
+
+Create entry for Deno Deploy:
+
+```js [deno.mjs]
+import { toWebHandler } from "h3";
+import { app } from "./app.mjs";
+
+Deno.serve(toWebHandler(app));
+```
+
+Create an `import_map.json`:
+
+```json [import_map.json]
+{
+ "imports": {
+ "h3": "https://esm.sh/h3@latest"
+ }
+}
+```
+
+Finally, use `deno run` to locally preview:
+
+```bash [terminal]
+deno run --allow-net ./deno.mjs
+```
+
+To deploy, use `deployctl deploy`:
+
+```bash [terminal]
+deployctl deploy --prod --exclude=node_modules --import-map=./import_map.json ./deno.mjs
+```
+
+## WebSocket support
+
+:read-more{to="https://crossws.unjs.io/adapters/deno"}
+
+```ts
+import wsAdapter from "crossws/adapters/deno";
+
+const handler = toWebHandler(app)
+
+const { handleUpgrade } = wsAdapter(app.websocket);
+
+Deno.serve(request => {
+ if (request.headers.get("upgrade") === "websocket") {
+ return handleUpgrade(request);
+ }
+ return handler(request)
+})
+```
+
+---
+
+::read-more
+See [pi0/h3-on-edge](https://github.com/pi0/h3-on-edge) demo for a fully working example ([deployment](https://h3-on-edge.deno.dev/)).
+::
diff --git a/docs/3.adapters/netlify.md b/docs/3.adapters/netlify.md
new file mode 100644
index 00000000..3b2f30f0
--- /dev/null
+++ b/docs/3.adapters/netlify.md
@@ -0,0 +1,68 @@
+---
+icon: teenyicons:netlify-outline
+---
+
+# Netlify
+
+> Run your h3 apps in Netlify Edge
+
+You can directly host your h3 applications to [Netlify Edge](https://www.netlify.com/platform/core/edge/) using [Web Adapter](/adapters/web).
+
+## Usage
+
+Create app entry:
+
+```js [app.mjs]
+import { createApp, defineEventHandler } from "h3";
+
+export const app = createApp();
+
+app.use(defineEventHandler(() => "Hello world!"));
+```
+
+Create entry for netlify-edge:
+
+```js [netlify/index.mjs]
+import { toWebHandler } from "h3";
+import { app } from "./app.mjs";
+
+export const handler = toWebHandler(app);
+```
+
+Then, create `import_map.json`:
+
+```json [import_map.json]
+{
+ "imports": {
+ "h3": "https://esm.sh/h3@latest"
+ }
+}
+```
+
+Create `netlify.toml`:
+
+```ini [netlify.toml]
+[build]
+ edge_functions = "netlify"
+
+[functions]
+ deno_import_map = "./import_map.json"
+```
+
+Finally, use `netlify dev` to locally preview:
+
+```bash [terminal]
+npx netlify dev
+```
+
+To deploy, use `netlify deploy`:
+
+```bash [terminal]
+npx netlify deploy --prod
+```
+
+---
+
+::read-more
+See [pi0/h3-on-edge](https://github.com/pi0/h3-on-edge) demo for a fully working example.
+::
diff --git a/docs/4.examples/0.index.md b/docs/4.examples/0.index.md
new file mode 100644
index 00000000..b4197cbe
--- /dev/null
+++ b/docs/4.examples/0.index.md
@@ -0,0 +1,11 @@
+---
+icon: ph:code
+---
+
+# Examples
+
+> Common examples for h3.
+
+::read-more{to="https://github.com/unjs/h3/tree/main/examples"}
+Check [`examples/` dir](https://github.com/unjs/h3/tree/main/examples) for more examples.
+::
diff --git a/docs/4.examples/from-expressjs-to-h3.md b/docs/4.examples/from-expressjs-to-h3.md
new file mode 100644
index 00000000..5de7abb3
--- /dev/null
+++ b/docs/4.examples/from-expressjs-to-h3.md
@@ -0,0 +1,434 @@
+# From Express.js to h3
+
+> Through various examples, let's see how easy it is to use h3 if you are familiar with Express.js.
+
+During this guide, we will reproduce many examples from the [Express.js documentation](https://expressjs.com/en/starter/examples.html) to show you how to do the same thing with h3.
+
+> [!NOTE]
+> If you are not familiar with Express.js, you can safely skip this guide.
+
+The idea is to show you how similar h3 is to Express.js. Once you understand the similarities, you will be able to use h3 without any problem if you are familiar with Express.js.
+
+> [!CAUTION]
+> Even if h3 seems to be similar to Express.js, it does not mean that Express.js is still viable. Express.js is an old framework that has not evolved for a long time. It's not a good choice for new projects since it can easily lead to security issues and memory leaks.
+
+With h3, you also have reloading out-of-the-box without any configuration using [unjs/listhen](https://listhen.unjs.io).
+
+> [!NOTE]
+> You can run every h3 examples using `npx --yes listhen -w ./app.ts`.
+
+## Hello World
+
+The first example from the Express.js documentation is the [Hello World](https://github.com/expressjs/express/blob/master/examples/hello-world/index.js).
+
+The code is pretty simple:
+
+```js [index.js]
+/**
+ * Express.js example app.
+ */
+var express = require("express");
+var app = express();
+
+app.get("/", function (req, res) {
+ res.send("Hello World");
+});
+
+app.listen(3000);
+console.log("Express started on port 3000");
+```
+
+Let's see how to do the same thing with h3:
+
+```ts [app.ts]
+/**
+ * h3 example app.
+ */
+import { createApp, defineEventHandler } from "h3";
+
+export const app = createApp();
+
+app.use(
+ "/",
+ defineEventHandler((event) => {
+ return "Hello World";
+ }),
+);
+```
+
+Then, you can use `npx --yes listhen -w ./app.ts` to start the server and go to http://localhost:3000 to see the result.
+
+:read-more{to="/guide/app"}
+
+## Multi Router
+
+The second example is the [Multi Router](https://github.com/expressjs/express/blob/master/examples/multi-router/index.js). In this example, we create many routers to split the logic.
+
+```js [index.js]
+/**
+ * Express.js example app.
+ */
+var express = require("express");
+
+var app = express();
+
+var apiv1 = express.Router();
+
+apiv1.get("/", function (req, res) {
+ res.send("Hello from APIv1 root route.");
+});
+
+apiv1.get("/users", function (req, res) {
+ res.send("List of APIv1 users.");
+});
+
+var apiv2 = express.Router();
+
+apiv2.get("/", function (req, res) {
+ res.send("Hello from APIv2 root route.");
+});
+
+apiv2.get("/users", function (req, res) {
+ res.send("List of APIv2 users.");
+});
+
+app.use("/api/v1", apiv1);
+app.use("/api/v2", apiv2);
+
+app.get("/", function (req, res) {
+ res.send("Hello from root route.");
+});
+
+app.listen(3000);
+console.log("Express started on port 3000");
+```
+
+> [!NOTE]
+> For some facilities, we group every files in the same one.
+
+Using h3, we can do the same thing:
+
+```ts [app.ts]
+/**
+ * h3 example app.
+ */
+import { createApp, createRouter, defineEventHandler, useBase } from "h3";
+
+export const app = createApp();
+
+const apiv1 = createRouter()
+ .get(
+ "/",
+ defineEventHandler(() => {
+ return "Hello from APIv1 root route.";
+ }),
+ )
+ .get(
+ "/users",
+ defineEventHandler(() => {
+ return "List of APIv1 users.";
+ }),
+ );
+
+const apiv2 = createRouter()
+ .get(
+ "/",
+ defineEventHandler(() => {
+ return "Hello from APIv2 root route.";
+ }),
+ )
+ .get(
+ "/users",
+ defineEventHandler(() => {
+ return "List of APIv2 users.";
+ }),
+ );
+
+app.use("/api/v1/**", useBase("/api/v1", apiv1.handler));
+app.use("/api/v2/**", useBase("/api/v2", apiv2.handler));
+```
+
+It's quite similar. The main difference is that we have to use `useBase` to define a base path for a router.
+
+:read-more{to="/guide/router"}
+
+## Params
+
+The third example is the [Params](https://github.com/expressjs/express/tree/master/examples/params/index.js). In this example, we use parameters in the route.
+
+```js [index.js]
+/**
+ * Express.js example app.
+ */
+var createError = require("http-errors");
+var express = require("express");
+var app = express();
+
+var users = [
+ { name: "tj" },
+ { name: "tobi" },
+ { name: "loki" },
+ { name: "jane" },
+ { name: "bandit" },
+];
+
+app.param(["to", "from"], function (req, res, next, num, name) {
+ req.params[name] = parseInt(num, 10);
+ if (isNaN(req.params[name])) {
+ next(createError(400, "failed to parseInt " + num));
+ } else {
+ next();
+ }
+});
+
+app.param("user", function (req, res, next, id) {
+ if ((req.user = users[id])) {
+ next();
+ } else {
+ next(createError(404, "failed to find user"));
+ }
+});
+
+app.get("/", function (req, res) {
+ res.send("Visit /user/0 or /users/0-2");
+});
+
+app.get("/user/:user", function (req, res) {
+ res.send("user " + req.user.name);
+});
+
+app.get("/users/:from-:to", function (req, res) {
+ var from = req.params.from;
+ var to = req.params.to;
+ var names = users.map(function (user) {
+ return user.name;
+ });
+ res.send("users " + names.slice(from, to + 1).join(", "));
+});
+
+app.listen(3000);
+console.log("Express started on port 3000");
+```
+
+Using h3, we can do the same thing:
+
+```ts [app.ts]
+/**
+ * h3 example app.
+ */
+import {
+ createApp,
+ createError,
+ createRouter,
+ defineEventHandler,
+ getRouterParam,
+ getValidatedRouterParams,
+} from "h3";
+import { z } from "zod";
+
+const users = [
+ { name: "tj" },
+ { name: "tobi" },
+ { name: "loki" },
+ { name: "jane" },
+ { name: "bandit" },
+];
+
+export const app = createApp();
+const router = createRouter();
+
+router.get(
+ "/",
+ defineEventHandler(() => {
+ return "Visit /users/0 or /users/0/2";
+ }),
+);
+
+router.get(
+ "/user/:user",
+ defineEventHandler(async (event) => {
+ const { user } = await getValidatedRouterParams(
+ event,
+ z.object({
+ user: z.number({ coerce: true }),
+ }).parse,
+ );
+
+ if (!users[user])
+ throw createError({
+ status: 404,
+ statusMessage: "User Not Found",
+ });
+
+ return `user ${user}`;
+ }),
+);
+
+router.get(
+ "/users/:from/:to",
+ defineEventHandler(async (event) => {
+ const { from, to } = await getValidatedRouterParams(
+ event,
+ z.object({
+ from: z.number({ coerce: true }),
+ to: z.number({ coerce: true }),
+ }).parse,
+ );
+
+ const names = users.map((user) => {
+ return user.name;
+ });
+
+ return `users ${names.slice(from, to).join(", ")}`;
+ }),
+);
+
+app.use(router);
+```
+
+With h3, we do not have a `param` method. Instead, we use `getRouterParam` or `getValidatedRouterParams` to validate the params. It's more explicit and easier to use. In this example, we use `Zod` but you are free to use any other validation library.
+
+## Cookies
+
+The fourth example is the [Cookies](https://github.com/expressjs/express/blob/master/examples/cookies/index.js). In this example, we use cookies.
+
+```js [index.js]
+/**
+ * Express.js example app.
+ */
+var express = require("express");
+var app = express();
+var cookieParser = require("cookie-parser");
+
+app.use(cookieParser("my secret here"));
+
+app.use(express.urlencoded({ extended: false }));
+
+app.get("/", function (req, res) {
+ if (req.cookies.remember) {
+ res.send('Remembered :). Click to forget!.');
+ } else {
+ res.send(
+ '',
+ );
+ }
+});
+
+app.get("/forget", function (req, res) {
+ res.clearCookie("remember");
+ res.redirect("back");
+});
+
+app.post("/", function (req, res) {
+ var minute = 60000;
+ if (req.body.remember) res.cookie("remember", 1, { maxAge: minute });
+ res.redirect("back");
+});
+
+app.listen(3000);
+console.log("Express started on port 3000");
+```
+
+Using h3, we can do the same thing:
+
+```ts [app.ts]
+import {
+ createApp,
+ createRouter,
+ defineEventHandler,
+ getCookie,
+ getHeader,
+ readBody,
+ sendRedirect,
+ setCookie,
+} from "h3";
+
+export const app = createApp();
+const router = createRouter();
+
+router.get(
+ "/",
+ defineEventHandler((event) => {
+ const remember = getCookie(event, "remember");
+
+ if (remember) {
+ return 'Remembered :). Click to forget!.';
+ } else {
+ return ``;
+ }
+ }),
+);
+
+router.get(
+ "/forget",
+ defineEventHandler((event) => {
+ deleteCookie(event, "remember");
+
+ const back = getHeader(event, "referer") || "/";
+ return sendRedirect(event, back);
+ }),
+);
+
+router.post(
+ "/",
+ defineEventHandler(async (event) => {
+ const body = await readBody(event);
+
+ if (body.remember)
+ setCookie(event, "remember", "1", { maxAge: 60 * 60 * 24 * 7 });
+
+ const back = getHeader(event, "referer") || "/";
+ return sendRedirect(event, back);
+ }),
+);
+
+app.use(router);
+```
+
+With h3, we do not have a `cookieParser` middleware. Instead, we use `getCookie` and `setCookie` to get and set cookies. It's more explicit and easier to use.
+
+## Middleware
+
+When using `express`, we usually handle requests with `middleware`.
+
+For instance, here we use `morgan` to handle request logging.
+
+```js [index.js]
+var express = require("express");
+var morgan = require("morgan");
+
+var app = express();
+
+app.use(morgan("combined"));
+
+app.get("/", function (req, res) {
+ res.send("hello, world!");
+});
+
+app.listen(3000);
+console.log("Express started on port 3000");
+```
+
+In `h3`, we can also directly use middleware from the `express` ecosystem.
+
+This can be easily achieved by wrapping with `fromNodeMiddleware`.
+
+```ts [app.ts]
+import morgan from "morgan";
+import { defineEventHandler, createApp, fromNodeMiddleware } from "h3";
+
+export const app = createApp();
+
+app.use(fromNodeMiddleware(morgan()));
+
+app.use(
+ "/",
+ defineEventHandler((event) => {
+ return "Hello World";
+ }),
+);
+```
diff --git a/docs/4.examples/handle-cookie.md b/docs/4.examples/handle-cookie.md
new file mode 100644
index 00000000..9171b944
--- /dev/null
+++ b/docs/4.examples/handle-cookie.md
@@ -0,0 +1,71 @@
+# Handle Cookie
+
+> Use cookies to store data on the client.
+
+Handling cookies with h3 is straightforward. There is three utilities to handle cookies:
+
+- `setCookie` to attach a cookie to the response.
+- `getCookie` to get a cookie from the request.
+- `deleteCookie` to clear a cookie from the response.
+
+## Set a Cookie
+
+To set a cookie, you need to use `setCookie` in an event handler:
+
+```ts
+import { defineEventHandler, setCookie } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ setCookie(event, "name", "value", { maxAge: 60 * 60 * 24 * 7 });
+ }),
+);
+```
+
+In the options, you can configure the [cookie flags](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie):
+
+- `maxAge` to set the expiration date of the cookie in seconds.
+- `expires` to set the expiration date of the cookie in a `Date` object.
+- `path` to set the path of the cookie.
+- `domain` to set the domain of the cookie.
+- `secure` to set the `Secure` flag of the cookie.
+- `httpOnly` to set the `HttpOnly` flag of the cookie.
+- `sameSite` to set the `SameSite` flag of the cookie.
+
+:read-more{to="/utils"}
+
+## Get a Cookie
+
+To get a cookie, you need to use `getCookie` in an event handler.
+
+```ts
+import { defineEventHandler, getCookie } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const name = getCookie(event, "name");
+
+ // do something...
+ }),
+);
+```
+
+This will return the value of the cookie if it exists, or `undefined` otherwise.
+
+## Delete a Cookie
+
+To delete a cookie, you need to use `deleteCookie` in an event handler:
+
+```ts
+import { defineEventHandler, deleteCookie } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ deleteCookie(event, "name");
+ }),
+);
+```
+
+The utility `deleteCookie` is a wrapper around `setCookie` with the value set to `""` and the `maxAge` set to `0`.
+
+This will erase the cookie from the client.
diff --git a/docs/4.examples/handle-session.md b/docs/4.examples/handle-session.md
new file mode 100644
index 00000000..99aea85b
--- /dev/null
+++ b/docs/4.examples/handle-session.md
@@ -0,0 +1,144 @@
+# Handle Session
+
+> Remember your users using a session.
+
+A session is a way to remember users using cookies. It is a very common way to authenticate users or save data about them such as their language or their preferences on the web.
+
+h3 provide many utilities to handle sessions:
+
+- `useSession` to initializes a session and returns a wrapper to control it.
+- `getSession` to initializes or gets the current user session.
+- `updateSession` to updates data of the current session.
+- `clearSession` to clears the current session.
+
+Most of the time, you will use `useSession` to manipulate the session.
+
+## Initialize a Session
+
+To initialize a session, you need to use `useSession` in an [event handler](/guide/event-handler):
+
+```js
+import { defineEventHandler, useSession } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const session = await useSession(event, {
+ password: "80d42cfb-1cd2-462c-8f17-e3237d9027e9",
+ });
+
+ // do something...
+ }),
+);
+```
+
+> [!WARNING]
+> You must provide a password to encrypt the session.
+
+This will initialize a session and return an header `Set-Cookie` with a cookie named `h3` and an encrypted content.
+
+If the request contains a cookie named `h3` or a header named `x-h3-session`, the session will be initialized with the content of the cookie or the header.
+
+> [!NOTE]
+> The header take precedence over the cookie.
+
+## Get Data from a Session
+
+To get data from a session, we will still use `useSession`. Under the hood, it will use [`getSession` to get the session.
+
+```js
+import { defineEventHandler, useSession } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const session = await useSession(event, {
+ password: "80d42cfb-1cd2-462c-8f17-e3237d9027e9",
+ });
+
+ return session.data;
+ }),
+);
+```
+
+Data are stored in the `data` property of the session. If there is no data, it will be an empty object.
+
+## Add Data to a Session
+
+To add data to a session, we will still use `useSession`. Under the hood, it will use `updateSession` to update the session.
+
+```js
+import { defineEventHandler, useSession } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const session = await useSession(event, {
+ password: "80d42cfb-1cd2-462c-8f17-e3237d9027e9",
+ });
+
+ const count = (session.data.count || 0) + 1;
+ await session.update({
+ count: count,
+ });
+
+ return count === 0
+ ? "Hello world!"
+ : `Hello world! You have visited this page ${count} times.`;
+ }),
+);
+```
+
+What is happening here?
+
+We try to get a session from the request. If there is no session, a new one will be created. Then, we increment the `count` property of the session and we update the session with the new value. Finally, we return a message with the number of times the user visited the page.
+
+Try to visit the page multiple times and you will see the number of times you visited the page.
+
+> [!NOTE]
+> If you use a CLI tool like `curl` to test this example, you will not see the number of times you visited the page because the CLI tool does not save cookies. You must get the cookie from the response and send it back to the server.
+
+## Clear a Session
+
+To clear a session, we will still use `useSession`. Under the hood, it will use `clearSession` to clear the session.
+
+```js
+import { defineEventHandler, useSession } from "h3";
+
+app.use(
+ "/clear",
+ defineEventHandler(async (event) => {
+ const session = await useSession(event, {
+ password: "80d42cfb-1cd2-462c-8f17-e3237d9027e9",
+ });
+
+ await session.clear();
+
+ return "Session cleared";
+ }),
+);
+```
+
+h3 will send a header `Set-Cookie` with an empty cookie named `h3` to clear the session.
+
+## Options
+
+When to use `useSession`, you can pass an object with options as the second argument to configure the session:
+
+```js
+import { defineEventHandler, useSession } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const session = await useSession(event, {
+ password: "80d42cfb-1cd2-462c-8f17-e3237d9027e9",
+ cookie: {
+ name: "my-session",
+ httpOnly: true,
+ secure: true,
+ sameSite: "strict",
+ },
+ maxAge: 60 * 60 * 24 * 7, // 7 days
+ });
+
+ return session.data;
+ }),
+);
+```
diff --git a/docs/4.examples/serve-static-assets.md b/docs/4.examples/serve-static-assets.md
new file mode 100644
index 00000000..d18c78b8
--- /dev/null
+++ b/docs/4.examples/serve-static-assets.md
@@ -0,0 +1,107 @@
+# Serve Static Assets
+
+> Serve static assets such as HMTL, images, CSS, JavaScript, etc.
+
+h3 can serve static assets such as HTML, images, CSS, JavaScript, etc.
+
+> [!NOTE]
+> If you use [`unjs/listhen`](https://listhen.unjs.io), you've just to create a `public` directory in your project root and put your static assets in it. They will be served automatically.
+
+## Usage
+
+To serve a static directory, you can use the `serveStatic` utility.
+
+```ts
+import { createApp, defineEventHandler, serveStatic } from "h3";
+
+export const app = createApp();
+
+app.use(
+ defineEventHandler((event) => {
+ return serveStatic(event, {
+ getContents: (id) => {
+ return undefined;
+ },
+ getMeta: (id) => {
+ return undefined;
+ },
+ });
+ }),
+);
+```
+
+This does not serve any files yet. You need to implement the `getContents` and `getMeta` methods.
+
+- `getContents` is used to read the contents of a file. It should return a `Promise` that resolves to the contents of the file or `undefined` if the file does not exist.
+- `getMeta` is used to get the metadata of a file. It should return a `Promise` that resolves to the metadata of the file or `undefined` if the file does not exist.
+
+They are separated to allow h3 to respond to `HEAD` requests without reading the contents of the file and to use the `Last-Modified` header.
+
+## Read files
+
+Now, create a `index.html` file in the `public` directory with a simple message and open your browser to http://localhost:3000. You should see the message.
+
+> [!NOTE]
+> Usage of `public` is a convention but you can use any directory name you want.
+
+> [!NOTE]
+> If you're are using [`unjs/listhen`](https://listhen.unjs.io) and want to try this example, create a directory with another name than `public` because it's the default directory used by `listhen`.
+
+Then, we can create the `getContents` and `getMeta` methods:
+
+```ts
+import { createApp, defineEventHandler, serveStatic } from "h3";
+import { stat, readFile } from "node:fs/promises";
+import { join } from "pathe";
+
+export const app = createApp();
+
+const publicDir = "assets";
+
+app.use(
+ defineEventHandler((event) => {
+ return serveStatic(event, {
+ getContents: (id) => readFile(join(publicDir, id)),
+ getMeta: async (id) => {
+ const stats = await stat(join(publicDir, id)).catch(() => {});
+
+ if (!stats || !stats.isFile()) {
+ return;
+ }
+
+ return {
+ size: stats.size,
+ mtime: stats.mtimeMs,
+ };
+ },
+ });
+ }),
+);
+```
+
+The `getContents` read the file and returns its contents, pretty simple. The `getMeta` uses `fs.stat` to get the file metadata. If the file does not exist or is not a file, it returns `undefined`. Otherwise, it returns the file size and the last modification time.
+
+The file size and last modification time are used to create an etag to send a `304 Not Modified` response if the file has not been modified since the last request. This is useful to avoid sending the same file multiple times if it has not changed.
+
+## Resolving Assets
+
+If the path does not match a file, h3 will try to add `index.html` to the path and try again. If it still does not match, it will return a 404 error.
+
+You can change this behavior by passing a `indexNames` option to `serveStatic`:
+
+```ts
+import { createApp, serveStatic } from "h3";
+
+const app = createApp();
+
+app.use(
+ serveStatic({
+ indexNames: ["/app.html", "/index.html"],
+ }),
+);
+```
+
+With this option, h3 will try to match `/app.html` first, then `/index.html` and finally return a 404 error.
+
+> [!IMPORTANT]
+> Do not forget `/` at the beginning of the h3 concatenates the path with the index name. For example, `/index.html` will be concatenated with `/hello` to form `hello/index.html`.
diff --git a/docs/4.examples/stream-response.md b/docs/4.examples/stream-response.md
new file mode 100644
index 00000000..9bec64ef
--- /dev/null
+++ b/docs/4.examples/stream-response.md
@@ -0,0 +1,103 @@
+# Stream Response
+
+> Stream response to the client.
+
+Streaming is a powerful feature of h3. It allows you to send data to the client as soon as you have it. This is useful for large files or long running tasks.
+
+> [!WARNING]
+> Steaming is complicated and can become an overhead if you don't need it.
+
+## Create a Stream
+
+To stream a response, you first need to create a stream using the [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) API:
+
+```ts
+const steam = new ReadableStream();
+```
+
+For the example, we will create a start function that will send a random number every 100 milliseconds. After 1000 milliseconds, it will close the stream:
+
+```ts
+let interval: NodeJS.Timeout;
+const stream = new ReadableStream({
+ start(controller) {
+ controller.enqueue("");
+
+ interval = setInterval(() => {
+ controller.enqueue("- " + Math.random() + "
");
+ }, 100);
+
+ setTimeout(() => {
+ clearInterval(interval);
+ controller.close();
+ }, 1000);
+ },
+ cancel() {
+ clearInterval(interval);
+ },
+});
+```
+
+## Send a Stream
+
+In your event handler, you will need to set to response header to tell to the client that we are sending a stream. Otherwise, it will wait for the response to be completed before rendering it:
+
+```ts
+import { defineEventHandler } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ setResponseHeader(event, "Content-Type", "text/html");
+ setResponseHeader(event, "Cache-Control", "no-cache");
+ setResponseHeader(event, "Transfer-Encoding", "chunked");
+
+ return null;
+ }),
+);
+```
+
+Then, you can send the stream using the `sendStream` utility:
+
+```ts
+import {
+ createApp,
+ defineEventHandler,
+ sendStream,
+ setResponseHeader,
+} from "h3";
+
+export const app = createApp();
+
+app.use(
+ defineEventHandler((event) => {
+ setResponseHeader(event, "Content-Type", "text/html");
+ setResponseHeader(event, "Cache-Control", "no-cache");
+ setResponseHeader(event, "Transfer-Encoding", "chunked");
+
+ let interval: NodeJS.Timeout;
+ const stream = new ReadableStream({
+ start(controller) {
+ controller.enqueue("");
+
+ interval = setInterval(() => {
+ controller.enqueue("- " + Math.random() + "
");
+ }, 100);
+
+ setTimeout(() => {
+ clearInterval(interval);
+ controller.close();
+ }, 1000);
+ },
+ cancel() {
+ clearInterval(interval);
+ },
+ });
+
+ return sendStream(event, stream);
+ }),
+);
+```
+
+Open your browser to http://localhost:3000 and you should see a list of random numbers appearing every 100 milliseconds.
+
+Magic! 🎉
diff --git a/docs/4.examples/validate-data.md b/docs/4.examples/validate-data.md
new file mode 100644
index 00000000..6e677465
--- /dev/null
+++ b/docs/4.examples/validate-data.md
@@ -0,0 +1,117 @@
+# Validate Data
+
+> Ensure that your data are valid and safe before processing them.
+
+When you receive data from user on your server, you must validate them. By validate, we mean that the shape of the received data must match the expected shape. It's important because you can't trust user input.
+
+> [!WARNING]
+> Do not use a generic as a validation. Providing an interface to a utility like `readBody` is not a validation. You must validate the data before using them.
+
+## Utilities for Validation
+
+h3 provide some utilities to help you to handle data validation. You will be able to validate:
+
+- query with `getValidatedQuery`
+- params with `getValidatedRouterParams`.
+- body with `readValidatedBody`
+
+To validate data, you can use any validation library you want. h3 doesn't provide any validation library like [Zod](https://zod.dev), [joi](https://joi.dev) or [myzod](https://github.com/davidmdm/myzod).
+
+> [!WARNING]
+> h3 is runtime agnostic. This means that you can use it in [any runtime](/adapters). But some validation libraries are not compatible with all runtimes.
+
+Let's see how to validate data with [Zod](https://zod.dev).
+
+For the following examples, we will use the following schema:
+
+```js
+import { z } from "zod";
+
+const userSchema = z.object({
+ name: z.string().min(3).max(20),
+ age: z.number({ coerce: true }).positive().int(),
+});
+```
+
+## Validate Query
+
+You can use `getValidatedQuery` to validate query and get the result, as a replacement of `getQuery`:
+
+```js
+import { defineEventHandler, getValidatedQuery } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const query = await getValidatedQuery(event, userSchema.parse);
+
+ return `Hello ${query.name}! You are ${query.age} years old.`;
+ }),
+);
+```
+
+> [!NOTE]
+> You could use `safeParse` instead of `parse` to get a partial query object and to not throw an error if the query is invalid.
+
+If you send a valid request like `/?name=John&age=42` to this event handler, you will get a response like this:
+
+```txt
+Hello John! You are 42 years old.
+```
+
+If you send an invalid request and the validation fails, h3 will throw a `400 Validation Error` error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.
+
+## Validate Params
+
+You can use `getValidatedRouterParams` to validate params and get the result, as a replacement of `getRouterParams`:
+
+```js
+import { defineEventHandler, getValidatedRouterParams } from "h3";
+
+router.use(
+ // You must use a router to use params
+ "/hello/:name/:age",
+ defineEventHandler(async (event) => {
+ const params = await getValidatedRouterParams(event, userSchema.parse);
+
+ return `Hello ${params.name}! You are ${params.age} years old!`;
+ }),
+);
+```
+
+> [!NOTE]
+> You could use `safeParse` instead of `parse` to get a partial params object and to not throw an error if the params is invalid.
+
+If you send a valid request like `/hello/John/42` to this event handler, you will get a response like this:
+
+```txt
+Hello John! You are 42 years old.
+```
+
+If you send an invalid request and the validation fails, h3 will throw a `400 Validation Error` error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.
+
+## Validate Body
+
+You can use `readValidatedBody` to validate body and get the result, as a replacement of `readBody`:
+
+```js
+import { defineEventHandler, readValidatedBody } from "h3";
+
+app.use(
+ defineEventHandler(async (event) => {
+ const body = await readValidatedBody(event, userSchema.parse);
+
+ return `Hello ${body.name}! You are ${body.age} years old.`;
+ }),
+);
+```
+
+> [!NOTE]
+> You could use `safeParse` instead of `parse` to get a partial body object and to not throw an error if the body is invalid.
+
+If you send a valid POST request to this event handler, you will get a response like this:
+
+```txt
+Hello John! You are 42 years old.
+```
+
+If you send an invalid request and the validation fails, h3 will throw a `400 Validation Error` error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.
diff --git a/docs/bun.lockb b/docs/bun.lockb
new file mode 100755
index 00000000..c3004914
Binary files /dev/null and b/docs/bun.lockb differ
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 00000000..26b20ece
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,11 @@
+{
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "undocs build",
+ "dev": "undocs dev"
+ },
+ "devDependencies": {
+ "undocs": "^0.2.17"
+ }
+}
diff --git a/examples/first-server.ts b/examples/first-server.ts
index 3c108f79..4f21160d 100644
--- a/examples/first-server.ts
+++ b/examples/first-server.ts
@@ -1,4 +1,4 @@
-import { createApp, defineEventHandler, toNodeListener } from "h3";
+import { createApp, defineEventHandler } from "h3";
export const app = createApp();
diff --git a/examples/nested-router.ts b/examples/nested-router.ts
index bd3478b0..e94ba800 100644
--- a/examples/nested-router.ts
+++ b/examples/nested-router.ts
@@ -1,7 +1,6 @@
import {
createApp,
defineEventHandler,
- toNodeListener,
createRouter,
useBase,
sendRedirect,
diff --git a/examples/server-sent-events.ts b/examples/server-sent-events.ts
new file mode 100644
index 00000000..5902f4ca
--- /dev/null
+++ b/examples/server-sent-events.ts
@@ -0,0 +1,26 @@
+import { createApp, createRouter, eventHandler, createEventStream } from "h3";
+
+export const app = createApp();
+
+const router = createRouter();
+app.use(router);
+
+router.get(
+ "/",
+ eventHandler((event) => {
+ const eventStream = createEventStream(event);
+
+ // Send a message every second
+ const interval = setInterval(async () => {
+ await eventStream.push("Hello world");
+ }, 1000);
+
+ // cleanup the interval and close the stream when the connection is terminated
+ eventStream.onClosed(async () => {
+ clearInterval(interval);
+ await eventStream.close();
+ });
+
+ return eventStream.send();
+ }),
+);
diff --git a/examples/websocket.ts b/examples/websocket.ts
new file mode 100644
index 00000000..e50947ea
--- /dev/null
+++ b/examples/websocket.ts
@@ -0,0 +1,35 @@
+import { createApp, defineEventHandler, defineWebSocketHandler } from "h3";
+
+export const app = createApp();
+
+app.use(
+ defineEventHandler(() =>
+ fetch(
+ "https://raw.githubusercontent.com/unjs/crossws/main/examples/h3/public/index.html",
+ ).then((r) => r.text()),
+ ),
+);
+
+app.use(
+ "/_ws",
+ defineWebSocketHandler({
+ open(peer) {
+ console.log("[ws] open", peer);
+ },
+
+ message(peer, message) {
+ console.log("[ws] message", peer, message);
+ if (message.text().includes("ping")) {
+ peer.send("pong");
+ }
+ },
+
+ close(peer, event) {
+ console.log("[ws] close", peer, event);
+ },
+
+ error(peer, error) {
+ console.log("[ws] error", peer, error);
+ },
+ }),
+);
diff --git a/package.json b/package.json
index fb21b352..49e6e8ca 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "h3",
- "version": "1.10.1",
+ "version": "1.11.1",
"description": "Minimal H(TTP) framework built for high performance and portability.",
"repository": "unjs/h3",
"license": "MIT",
@@ -22,8 +22,8 @@
"scripts": {
"build": "unbuild",
"dev": "vitest",
- "lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground examples",
- "lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground examples -w",
+ "lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground examples docs",
+ "lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground examples docs -w",
"play": "listhen -w ./playground/app.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",
@@ -32,39 +32,41 @@
},
"dependencies": {
"cookie-es": "^1.0.0",
+ "crossws": "^0.2.4",
"defu": "^6.1.4",
- "destr": "^2.0.2",
+ "destr": "^2.0.3",
"iron-webcrypto": "^1.0.0",
"ohash": "^1.1.3",
"radix3": "^1.1.0",
- "ufo": "^1.3.2",
+ "ufo": "^1.4.0",
"uncrypto": "^0.1.3",
"unenv": "^1.9.0"
},
"devDependencies": {
"0x": "^5.7.0",
"@types/express": "^4.17.21",
- "@types/node": "^20.11.6",
+ "@types/node": "^20.11.24",
"@types/supertest": "^6.0.2",
- "@vitest/coverage-v8": "^1.2.1",
- "autocannon": "^7.14.0",
+ "@vitest/coverage-v8": "^1.3.1",
+ "autocannon": "^7.15.0",
+ "automd": "^0.3.6",
"changelogen": "^0.5.5",
"connect": "^3.7.0",
- "eslint": "^8.56.0",
+ "eslint": "^8.57.0",
"eslint-config-unjs": "^0.2.1",
- "express": "^4.18.2",
+ "express": "^4.18.3",
"get-port": "^7.0.0",
"jiti": "^1.21.0",
- "listhen": "^1.5.6",
- "node-fetch-native": "^1.6.1",
- "prettier": "^3.2.4",
+ "listhen": "^1.7.2",
+ "node-fetch-native": "^1.6.2",
+ "prettier": "^3.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"supertest": "^6.3.4",
"typescript": "^5.3.3",
"unbuild": "^2.0.0",
- "vitest": "^1.2.1",
+ "vitest": "^1.3.1",
"zod": "^3.22.4"
},
- "packageManager": "pnpm@8.14.3"
+ "packageManager": "pnpm@8.15.4"
}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 908eb060..50fcd23b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,12 +11,15 @@ importers:
cookie-es:
specifier: ^1.0.0
version: 1.0.0
+ crossws:
+ specifier: ^0.2.4
+ version: 0.2.4
defu:
specifier: ^6.1.4
version: 6.1.4
destr:
- specifier: ^2.0.2
- version: 2.0.2
+ specifier: ^2.0.3
+ version: 2.0.3
iron-webcrypto:
specifier: ^1.0.0
version: 1.0.0
@@ -27,8 +30,8 @@ importers:
specifier: ^1.1.0
version: 1.1.0
ufo:
- specifier: ^1.3.2
- version: 1.3.2
+ specifier: ^1.4.0
+ version: 1.4.0
uncrypto:
specifier: ^0.1.3
version: 0.1.3
@@ -43,17 +46,20 @@ importers:
specifier: ^4.17.21
version: 4.17.21
'@types/node':
- specifier: ^20.11.6
- version: 20.11.6
+ specifier: ^20.11.24
+ version: 20.11.24
'@types/supertest':
specifier: ^6.0.2
version: 6.0.2
'@vitest/coverage-v8':
- specifier: ^1.2.1
- version: 1.2.1(vitest@1.2.1)
+ specifier: ^1.3.1
+ version: 1.3.1(vitest@1.3.1)
autocannon:
- specifier: ^7.14.0
- version: 7.14.0
+ specifier: ^7.15.0
+ version: 7.15.0
+ automd:
+ specifier: ^0.3.6
+ version: 0.3.6
changelogen:
specifier: ^0.5.5
version: 0.5.5
@@ -61,14 +67,14 @@ importers:
specifier: ^3.7.0
version: 3.7.0
eslint:
- specifier: ^8.56.0
- version: 8.56.0
+ specifier: ^8.57.0
+ version: 8.57.0
eslint-config-unjs:
specifier: ^0.2.1
- version: 0.2.1(eslint@8.56.0)(typescript@5.3.3)
+ version: 0.2.1(eslint@8.57.0)(typescript@5.3.3)
express:
- specifier: ^4.18.2
- version: 4.18.2
+ specifier: ^4.18.3
+ version: 4.18.3
get-port:
specifier: ^7.0.0
version: 7.0.0
@@ -76,14 +82,14 @@ importers:
specifier: ^1.21.0
version: 1.21.0
listhen:
- specifier: ^1.5.6
- version: 1.5.6
+ specifier: ^1.7.2
+ version: 1.7.2
node-fetch-native:
- specifier: ^1.6.1
- version: 1.6.1
+ specifier: ^1.6.2
+ version: 1.6.2
prettier:
- specifier: ^3.2.4
- version: 3.2.4
+ specifier: ^3.2.5
+ version: 3.2.5
react:
specifier: ^18.2.0
version: 18.2.0
@@ -100,8 +106,8 @@ importers:
specifier: ^2.0.0
version: 2.0.0(typescript@5.3.3)
vitest:
- specifier: ^1.2.1
- version: 1.2.1(@types/node@20.11.6)
+ specifier: ^1.3.1
+ version: 1.3.1(@types/node@20.11.24)
zod:
specifier: ^3.22.4
version: 3.22.4
@@ -116,7 +122,7 @@ importers:
version: link:..
listhen:
specifier: latest
- version: 1.5.6
+ version: 1.7.1
playground:
dependencies:
@@ -125,7 +131,7 @@ importers:
version: link:..
listhen:
specifier: latest
- version: 1.5.6
+ version: 1.7.1
packages:
@@ -156,7 +162,7 @@ packages:
opn: 5.5.0
pump: 3.0.0
pumpify: 2.0.1
- semver: 7.5.4
+ semver: 7.6.0
single-line-log: 1.1.2
split2: 4.2.0
tachyons: 4.12.0
@@ -175,8 +181,8 @@ packages:
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
engines: {node: '>=6.0.0'}
dependencies:
- '@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.22
+ '@jridgewell/gen-mapping': 0.3.4
+ '@jridgewell/trace-mapping': 0.3.23
dev: true
/@assemblyscript/loader@0.19.23:
@@ -224,8 +230,8 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.9
- '@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.22
+ '@jridgewell/gen-mapping': 0.3.4
+ '@jridgewell/trace-mapping': 0.3.23
jsesc: 2.5.2
dev: true
@@ -235,7 +241,7 @@ packages:
dependencies:
'@babel/compat-data': 7.23.5
'@babel/helper-validator-option': 7.23.5
- browserslist: 4.22.2
+ browserslist: 4.23.0
lru-cache: 5.1.1
semver: 6.3.1
dev: true
@@ -339,8 +345,15 @@ packages:
'@babel/types': 7.23.9
dev: true
- /@babel/standalone@7.23.9:
- resolution: {integrity: sha512-89NGhVfgKDqDQrtNPxqfnhIReKvp2CR80ofPNEAUpbtnouFelq33hQFURLralD9I+eFS7s5zVK61JRg/D1nLWg==}
+ /@babel/runtime@7.23.9:
+ resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ regenerator-runtime: 0.14.1
+ dev: true
+
+ /@babel/standalone@7.23.10:
+ resolution: {integrity: sha512-xqWviI/pt1Zb/d+6ilWa5IDL2mkDzsBnlHbreqnfyP3/QB/ofQ1bNVcHj8YQX154Rf/xZKR6y0s1ydVF3nAS8g==}
engines: {node: '>=6.9.0'}
dev: true
@@ -598,13 +611,13 @@ packages:
dev: true
optional: true
- /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0):
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-visitor-keys: 3.4.3
dev: true
@@ -621,7 +634,7 @@ packages:
debug: 4.3.4
espree: 9.6.1
globals: 13.24.0
- ignore: 5.3.0
+ ignore: 5.3.1
import-fresh: 3.3.0
js-yaml: 4.1.0
minimatch: 3.1.2
@@ -630,8 +643,8 @@ packages:
- supports-color
dev: true
- /@eslint/js@8.56.0:
- resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==}
+ /@eslint/js@8.57.0:
+ resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
@@ -667,17 +680,17 @@ packages:
'@sinclair/typebox': 0.27.8
dev: true
- /@jridgewell/gen-mapping@0.3.3:
- resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
+ /@jridgewell/gen-mapping@0.3.4:
+ resolution: {integrity: sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==}
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.15
- '@jridgewell/trace-mapping': 0.3.22
+ '@jridgewell/trace-mapping': 0.3.23
dev: true
- /@jridgewell/resolve-uri@3.1.1:
- resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
+ /@jridgewell/resolve-uri@3.1.2:
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
dev: true
@@ -690,10 +703,10 @@ packages:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
dev: true
- /@jridgewell/trace-mapping@0.3.22:
- resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==}
+ /@jridgewell/trace-mapping@0.3.23:
+ resolution: {integrity: sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==}
dependencies:
- '@jridgewell/resolve-uri': 3.1.1
+ '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
@@ -715,83 +728,83 @@ packages:
engines: {node: '>= 8'}
dependencies:
'@nodelib/fs.scandir': 2.1.5
- fastq: 1.16.0
+ fastq: 1.17.1
dev: true
- /@parcel/watcher-android-arm64@2.4.0:
- resolution: {integrity: sha512-+fPtO/GsbYX1LJnCYCaDVT3EOBjvSFdQN9Mrzh9zWAOOfvidPWyScTrHIZHHfJBvlHzNA0Gy0U3NXFA/M7PHUA==}
+ /@parcel/watcher-android-arm64@2.4.1:
+ resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [android]
requiresBuild: true
optional: true
- /@parcel/watcher-darwin-arm64@2.4.0:
- resolution: {integrity: sha512-T/At5pansFuQ8VJLRx0C6C87cgfqIYhW2N/kBfLCUvDhCah0EnLLwaD/6MW3ux+rpgkpQAnMELOCTKlbwncwiA==}
+ /@parcel/watcher-darwin-arm64@2.4.1:
+ resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
optional: true
- /@parcel/watcher-darwin-x64@2.4.0:
- resolution: {integrity: sha512-vZMv9jl+szz5YLsSqEGCMSllBl1gU1snfbRL5ysJU03MEa6gkVy9OMcvXV1j4g0++jHEcvzhs3Z3LpeEbVmY6Q==}
+ /@parcel/watcher-darwin-x64@2.4.1:
+ resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [darwin]
requiresBuild: true
optional: true
- /@parcel/watcher-freebsd-x64@2.4.0:
- resolution: {integrity: sha512-dHTRMIplPDT1M0+BkXjtMN+qLtqq24sLDUhmU+UxxLP2TEY2k8GIoqIJiVrGWGomdWsy5IO27aDV1vWyQ6gfHA==}
+ /@parcel/watcher-freebsd-x64@2.4.1:
+ resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
optional: true
- /@parcel/watcher-linux-arm-glibc@2.4.0:
- resolution: {integrity: sha512-9NQXD+qk46RwATNC3/UB7HWurscY18CnAPMTFcI9Y8CTbtm63/eex1SNt+BHFinEQuLBjaZwR2Lp+n7pmEJPpQ==}
+ /@parcel/watcher-linux-arm-glibc@2.4.1:
+ resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
requiresBuild: true
optional: true
- /@parcel/watcher-linux-arm64-glibc@2.4.0:
- resolution: {integrity: sha512-QuJTAQdsd7PFW9jNGaV9Pw+ZMWV9wKThEzzlY3Lhnnwy7iW23qtQFPql8iEaSFMCVI5StNNmONUopk+MFKpiKg==}
+ /@parcel/watcher-linux-arm64-glibc@2.4.1:
+ resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
requiresBuild: true
optional: true
- /@parcel/watcher-linux-arm64-musl@2.4.0:
- resolution: {integrity: sha512-oyN+uA9xcTDo/45bwsd6TFHa7Lc7hKujyMlvwrCLvSckvWogndCEoVYFNfZ6JJ2KNL/6fFiGPcbjp8jJmEh5Ng==}
+ /@parcel/watcher-linux-arm64-musl@2.4.1:
+ resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
requiresBuild: true
optional: true
- /@parcel/watcher-linux-x64-glibc@2.4.0:
- resolution: {integrity: sha512-KphV8awJmxU3q52JQvJot0QMu07CIyEjV+2Tb2ZtbucEgqyRcxOBDMsqp1JNq5nuDXtcCC0uHQICeiEz38dPBQ==}
+ /@parcel/watcher-linux-x64-glibc@2.4.1:
+ resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
requiresBuild: true
optional: true
- /@parcel/watcher-linux-x64-musl@2.4.0:
- resolution: {integrity: sha512-7jzcOonpXNWcSijPpKD5IbC6xC7yTibjJw9jviVzZostYLGxbz8LDJLUnLzLzhASPlPGgpeKLtFUMjAAzM+gSA==}
+ /@parcel/watcher-linux-x64-musl@2.4.1:
+ resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
requiresBuild: true
optional: true
- /@parcel/watcher-wasm@2.3.0:
- resolution: {integrity: sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA==}
+ /@parcel/watcher-wasm@2.4.1:
+ resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==}
engines: {node: '>= 10.0.0'}
dependencies:
is-glob: 4.0.3
@@ -799,32 +812,32 @@ packages:
bundledDependencies:
- napi-wasm
- /@parcel/watcher-win32-arm64@2.4.0:
- resolution: {integrity: sha512-NOej2lqlq8bQNYhUMnOD0nwvNql8ToQF+1Zhi9ULZoG+XTtJ9hNnCFfyICxoZLXor4bBPTOnzs/aVVoefYnjIg==}
+ /@parcel/watcher-win32-arm64@2.4.1:
+ resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [win32]
requiresBuild: true
optional: true
- /@parcel/watcher-win32-ia32@2.4.0:
- resolution: {integrity: sha512-IO/nM+K2YD/iwjWAfHFMBPz4Zqn6qBDqZxY4j2n9s+4+OuTSRM/y/irksnuqcspom5DjkSeF9d0YbO+qpys+JA==}
+ /@parcel/watcher-win32-ia32@2.4.1:
+ resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==}
engines: {node: '>= 10.0.0'}
cpu: [ia32]
os: [win32]
requiresBuild: true
optional: true
- /@parcel/watcher-win32-x64@2.4.0:
- resolution: {integrity: sha512-pAUyUVjfFjWaf/pShmJpJmNxZhbMvJASUpdes9jL6bTEJ+gDxPRSpXTIemNyNsb9AtbiGXs9XduP1reThmd+dA==}
+ /@parcel/watcher-win32-x64@2.4.1:
+ resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [win32]
requiresBuild: true
optional: true
- /@parcel/watcher@2.4.0:
- resolution: {integrity: sha512-XJLGVL0DEclX5pcWa2N9SX1jCGTDd8l972biNooLFtjneuGqodupPQh6XseXIBBeVIMaaJ7bTcs3qGvXwsp4vg==}
+ /@parcel/watcher@2.4.1:
+ resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==}
engines: {node: '>= 10.0.0'}
dependencies:
detect-libc: 1.0.3
@@ -832,18 +845,18 @@ packages:
micromatch: 4.0.5
node-addon-api: 7.1.0
optionalDependencies:
- '@parcel/watcher-android-arm64': 2.4.0
- '@parcel/watcher-darwin-arm64': 2.4.0
- '@parcel/watcher-darwin-x64': 2.4.0
- '@parcel/watcher-freebsd-x64': 2.4.0
- '@parcel/watcher-linux-arm-glibc': 2.4.0
- '@parcel/watcher-linux-arm64-glibc': 2.4.0
- '@parcel/watcher-linux-arm64-musl': 2.4.0
- '@parcel/watcher-linux-x64-glibc': 2.4.0
- '@parcel/watcher-linux-x64-musl': 2.4.0
- '@parcel/watcher-win32-arm64': 2.4.0
- '@parcel/watcher-win32-ia32': 2.4.0
- '@parcel/watcher-win32-x64': 2.4.0
+ '@parcel/watcher-android-arm64': 2.4.1
+ '@parcel/watcher-darwin-arm64': 2.4.1
+ '@parcel/watcher-darwin-x64': 2.4.1
+ '@parcel/watcher-freebsd-x64': 2.4.1
+ '@parcel/watcher-linux-arm-glibc': 2.4.1
+ '@parcel/watcher-linux-arm64-glibc': 2.4.1
+ '@parcel/watcher-linux-arm64-musl': 2.4.1
+ '@parcel/watcher-linux-x64-glibc': 2.4.1
+ '@parcel/watcher-linux-x64-musl': 2.4.1
+ '@parcel/watcher-win32-arm64': 2.4.1
+ '@parcel/watcher-win32-ia32': 2.4.1
+ '@parcel/watcher-win32-x64': 2.4.1
/@rollup/plugin-alias@5.1.0(rollup@3.29.4):
resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==}
@@ -872,7 +885,7 @@ packages:
estree-walker: 2.0.2
glob: 8.1.0
is-reference: 1.2.1
- magic-string: 0.30.5
+ magic-string: 0.30.7
rollup: 3.29.4
dev: true
@@ -917,7 +930,7 @@ packages:
optional: true
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@3.29.4)
- magic-string: 0.30.5
+ magic-string: 0.30.7
rollup: 3.29.4
dev: true
@@ -936,104 +949,104 @@ packages:
rollup: 3.29.4
dev: true
- /@rollup/rollup-android-arm-eabi@4.9.6:
- resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==}
+ /@rollup/rollup-android-arm-eabi@4.12.0:
+ resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-android-arm64@4.9.6:
- resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==}
+ /@rollup/rollup-android-arm64@4.12.0:
+ resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-darwin-arm64@4.9.6:
- resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==}
+ /@rollup/rollup-darwin-arm64@4.12.0:
+ resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-darwin-x64@4.9.6:
- resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==}
+ /@rollup/rollup-darwin-x64@4.12.0:
+ resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-linux-arm-gnueabihf@4.9.6:
- resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==}
+ /@rollup/rollup-linux-arm-gnueabihf@4.12.0:
+ resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-linux-arm64-gnu@4.9.6:
- resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==}
+ /@rollup/rollup-linux-arm64-gnu@4.12.0:
+ resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-linux-arm64-musl@4.9.6:
- resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==}
+ /@rollup/rollup-linux-arm64-musl@4.12.0:
+ resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-linux-riscv64-gnu@4.9.6:
- resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==}
+ /@rollup/rollup-linux-riscv64-gnu@4.12.0:
+ resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-linux-x64-gnu@4.9.6:
- resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==}
+ /@rollup/rollup-linux-x64-gnu@4.12.0:
+ resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-linux-x64-musl@4.9.6:
- resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==}
+ /@rollup/rollup-linux-x64-musl@4.12.0:
+ resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-win32-arm64-msvc@4.9.6:
- resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==}
+ /@rollup/rollup-win32-arm64-msvc@4.12.0:
+ resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-win32-ia32-msvc@4.9.6:
- resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==}
+ /@rollup/rollup-win32-ia32-msvc@4.12.0:
+ resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
- /@rollup/rollup-win32-x64-msvc@4.9.6:
- resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==}
+ /@rollup/rollup-win32-x64-msvc@4.12.0:
+ resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==}
cpu: [x64]
os: [win32]
requiresBuild: true
@@ -1044,6 +1057,11 @@ packages:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true
+ /@sindresorhus/merge-streams@2.3.0:
+ resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+ engines: {node: '>=18'}
+ dev: true
+
/@trysound/sax@0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@@ -1053,13 +1071,13 @@ packages:
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
dependencies:
'@types/connect': 3.4.38
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
dev: true
/@types/connect@3.4.38:
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
dependencies:
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
dev: true
/@types/cookiejar@2.1.5:
@@ -1070,10 +1088,10 @@ packages:
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
dev: true
- /@types/express-serve-static-core@4.17.41:
- resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==}
+ /@types/express-serve-static-core@4.17.43:
+ resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==}
dependencies:
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
'@types/qs': 6.9.11
'@types/range-parser': 1.2.7
'@types/send': 0.17.4
@@ -1083,7 +1101,7 @@ packages:
resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
dependencies:
'@types/body-parser': 1.19.5
- '@types/express-serve-static-core': 4.17.41
+ '@types/express-serve-static-core': 4.17.43
'@types/qs': 6.9.11
'@types/serve-static': 1.15.5
dev: true
@@ -1116,8 +1134,8 @@ packages:
resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==}
dev: true
- /@types/node@20.11.6:
- resolution: {integrity: sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==}
+ /@types/node@20.11.24:
+ resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==}
dependencies:
undici-types: 5.26.5
dev: true
@@ -1138,15 +1156,15 @@ packages:
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
dev: true
- /@types/semver@7.5.6:
- resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==}
+ /@types/semver@7.5.8:
+ resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
dev: true
/@types/send@0.17.4:
resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
dependencies:
'@types/mime': 1.3.5
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
dev: true
/@types/serve-static@1.15.5:
@@ -1154,7 +1172,7 @@ packages:
dependencies:
'@types/http-errors': 2.0.4
'@types/mime': 3.0.4
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
dev: true
/@types/superagent@8.1.3:
@@ -1162,7 +1180,7 @@ packages:
dependencies:
'@types/cookiejar': 2.1.5
'@types/methods': 1.1.4
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
dev: true
/@types/supertest@6.0.2:
@@ -1172,7 +1190,7 @@ packages:
'@types/superagent': 8.1.3
dev: true
- /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.3.3):
+ /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.3.3):
resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -1184,23 +1202,23 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.10.0
- '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/scope-manager': 5.62.0
- '@typescript-eslint/type-utils': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
- '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
debug: 4.3.4
- eslint: 8.56.0
+ eslint: 8.57.0
graphemer: 1.4.0
- ignore: 5.3.0
+ ignore: 5.3.1
natural-compare-lite: 1.4.0
- semver: 7.5.4
+ semver: 7.6.0
tsutils: 3.21.0(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.3.3):
+ /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.3.3):
resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -1214,7 +1232,7 @@ packages:
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3)
debug: 4.3.4
- eslint: 8.56.0
+ eslint: 8.57.0
typescript: 5.3.3
transitivePeerDependencies:
- supports-color
@@ -1228,7 +1246,7 @@ packages:
'@typescript-eslint/visitor-keys': 5.62.0
dev: true
- /@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@5.3.3):
+ /@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@5.3.3):
resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -1239,9 +1257,9 @@ packages:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3)
- '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
debug: 4.3.4
- eslint: 8.56.0
+ eslint: 8.57.0
tsutils: 3.21.0(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -1267,28 +1285,28 @@ packages:
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
- semver: 7.5.4
+ semver: 7.6.0
tsutils: 3.21.0(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.3.3):
+ /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.3.3):
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.15
- '@types/semver': 7.5.6
+ '@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3)
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-scope: 5.1.1
- semver: 7.5.4
+ semver: 7.6.0
transitivePeerDependencies:
- supports-color
- typescript
@@ -1306,10 +1324,10 @@ packages:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: true
- /@vitest/coverage-v8@1.2.1(vitest@1.2.1):
- resolution: {integrity: sha512-fJEhKaDwGMZtJUX7BRcGxooGwg1Hl0qt53mVup/ZJeznhvL5EodteVnb/mcByhEcvVWbK83ZF31c7nPEDi4LOQ==}
+ /@vitest/coverage-v8@1.3.1(vitest@1.3.1):
+ resolution: {integrity: sha512-UuBnkSJUNE9rdHjDCPyJ4fYuMkoMtnghes1XohYa4At0MS3OQSAo97FrbwSLRshYsXThMZy1+ybD/byK5llyIg==}
peerDependencies:
- vitest: ^1.0.0
+ vitest: 1.3.1
dependencies:
'@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3
@@ -1317,50 +1335,50 @@ packages:
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 4.0.1
- istanbul-reports: 3.1.6
- magic-string: 0.30.5
+ istanbul-reports: 3.1.7
+ magic-string: 0.30.7
magicast: 0.3.3
picocolors: 1.0.0
std-env: 3.7.0
test-exclude: 6.0.0
v8-to-istanbul: 9.2.0
- vitest: 1.2.1(@types/node@20.11.6)
+ vitest: 1.3.1(@types/node@20.11.24)
transitivePeerDependencies:
- supports-color
dev: true
- /@vitest/expect@1.2.1:
- resolution: {integrity: sha512-/bqGXcHfyKgFWYwIgFr1QYDaR9e64pRKxgBNWNXPefPFRhgm+K3+a/dS0cUGEreWngets3dlr8w8SBRw2fCfFQ==}
+ /@vitest/expect@1.3.1:
+ resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==}
dependencies:
- '@vitest/spy': 1.2.1
- '@vitest/utils': 1.2.1
+ '@vitest/spy': 1.3.1
+ '@vitest/utils': 1.3.1
chai: 4.4.1
dev: true
- /@vitest/runner@1.2.1:
- resolution: {integrity: sha512-zc2dP5LQpzNzbpaBt7OeYAvmIsRS1KpZQw4G3WM/yqSV1cQKNKwLGmnm79GyZZjMhQGlRcSFMImLjZaUQvNVZQ==}
+ /@vitest/runner@1.3.1:
+ resolution: {integrity: sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==}
dependencies:
- '@vitest/utils': 1.2.1
+ '@vitest/utils': 1.3.1
p-limit: 5.0.0
pathe: 1.1.2
dev: true
- /@vitest/snapshot@1.2.1:
- resolution: {integrity: sha512-Tmp/IcYEemKaqAYCS08sh0vORLJkMr0NRV76Gl8sHGxXT5151cITJCET20063wk0Yr/1koQ6dnmP6eEqezmd/Q==}
+ /@vitest/snapshot@1.3.1:
+ resolution: {integrity: sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==}
dependencies:
- magic-string: 0.30.5
+ magic-string: 0.30.7
pathe: 1.1.2
pretty-format: 29.7.0
dev: true
- /@vitest/spy@1.2.1:
- resolution: {integrity: sha512-vG3a/b7INKH7L49Lbp0IWrG6sw9j4waWAucwnksPB1r1FTJgV7nkBByd9ufzu6VWya/QTvQW4V9FShZbZIB2UQ==}
+ /@vitest/spy@1.3.1:
+ resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==}
dependencies:
- tinyspy: 2.2.0
+ tinyspy: 2.2.1
dev: true
- /@vitest/utils@1.2.1:
- resolution: {integrity: sha512-bsH6WVZYe/J2v3+81M5LDU8kW76xWObKIURpPrOXm2pjBniBu2MERI/XP60GpS4PHU3jyK50LUutOwrx4CyHUg==}
+ /@vitest/utils@1.3.1:
+ resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==}
dependencies:
diff-sequences: 29.6.3
estree-walker: 3.0.3
@@ -1486,11 +1504,12 @@ packages:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
- /array-buffer-byte-length@1.0.0:
- resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
+ /array-buffer-byte-length@1.0.1:
+ resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
+ engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- is-array-buffer: 3.0.2
+ call-bind: 1.0.7
+ is-array-buffer: 3.0.4
dev: true
/array-flatten@1.1.1:
@@ -1501,10 +1520,10 @@ packages:
resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
- get-intrinsic: 1.2.2
+ es-abstract: 1.22.4
+ get-intrinsic: 1.2.4
is-string: 1.0.7
dev: true
@@ -1513,24 +1532,35 @@ packages:
engines: {node: '>=8'}
dev: true
- /array.prototype.findlastindex@1.2.3:
- resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==}
+ /array.prototype.filter@1.0.3:
+ resolution: {integrity: sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.22.4
+ es-array-method-boxes-properly: 1.0.0
+ is-string: 1.0.7
+ dev: true
+
+ /array.prototype.findlastindex@1.2.4:
+ resolution: {integrity: sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
+ es-errors: 1.3.0
es-shim-unscopables: 1.0.2
- get-intrinsic: 1.2.2
dev: true
/array.prototype.flat@1.3.2:
resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
es-shim-unscopables: 1.0.2
dev: true
@@ -1538,23 +1568,24 @@ packages:
resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
es-shim-unscopables: 1.0.2
dev: true
- /arraybuffer.prototype.slice@1.0.2:
- resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==}
+ /arraybuffer.prototype.slice@1.0.3:
+ resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
engines: {node: '>= 0.4'}
dependencies:
- array-buffer-byte-length: 1.0.0
- call-bind: 1.0.5
+ array-buffer-byte-length: 1.0.1
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
- get-intrinsic: 1.2.2
- is-array-buffer: 3.0.2
- is-shared-array-buffer: 1.0.2
+ es-abstract: 1.22.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ is-array-buffer: 3.0.4
+ is-shared-array-buffer: 1.0.3
dev: true
/asap@2.0.6:
@@ -1585,8 +1616,8 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
- /autocannon@7.14.0:
- resolution: {integrity: sha512-lusP43BAwrTwQhihLjKwy7LceyX01eKSvFJUsBktASGqcR1g1ySYSPxCoCGDX08uLEs9oaqEKBBUFMenK3B3lQ==}
+ /autocannon@7.15.0:
+ resolution: {integrity: sha512-NaP2rQyA+tcubOJMFv2+oeW9jv2pq/t+LM6BL3cfJic0HEfscEcnWgAyU5YovE/oTHUzAgTliGdLPR+RQAWUbg==}
hasBin: true
dependencies:
chalk: 4.1.2
@@ -1609,30 +1640,57 @@ packages:
progress: 2.0.3
reinterval: 1.1.0
retimer: 3.0.0
- semver: 7.5.4
+ semver: 7.6.0
subarg: 1.0.0
timestring: 6.0.0
dev: true
- /autoprefixer@10.4.17(postcss@8.4.33):
+ /automd@0.3.6:
+ resolution: {integrity: sha512-6FmbZ6vTxFNohdU8ELwUUAee9u+ev8UNFk22A265P7g/IDviZthlWc4PTRgk1IlDJTXS1KHeMpl/PmuBgBOa+w==}
+ hasBin: true
+ dependencies:
+ '@parcel/watcher': 2.4.1
+ c12: 1.9.0
+ citty: 0.1.6
+ consola: 3.2.3
+ defu: 6.1.4
+ destr: 2.0.3
+ didyoumean2: 6.0.1
+ globby: 14.0.1
+ magic-string: 0.30.7
+ mdbox: 0.1.0
+ mlly: 1.6.1
+ ofetch: 1.3.3
+ pathe: 1.1.2
+ perfect-debounce: 1.0.0
+ pkg-types: 1.0.3
+ scule: 1.3.0
+ untyped: 1.4.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /autoprefixer@10.4.17(postcss@8.4.35):
resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
peerDependencies:
postcss: ^8.1.0
dependencies:
- browserslist: 4.22.2
- caniuse-lite: 1.0.30001580
+ browserslist: 4.23.0
+ caniuse-lite: 1.0.30001589
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.0.0
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /available-typed-arrays@1.0.5:
- resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
+ /available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
+ dependencies:
+ possible-typed-array-names: 1.0.0
dev: true
/balanced-match@1.0.2:
@@ -1661,8 +1719,8 @@ packages:
resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==}
dev: true
- /body-parser@1.20.1:
- resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==}
+ /body-parser@1.20.2:
+ resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
dependencies:
bytes: 3.1.2
@@ -1674,7 +1732,7 @@ packages:
iconv-lite: 0.4.24
on-finished: 2.4.1
qs: 6.11.0
- raw-body: 2.5.1
+ raw-body: 2.5.2
type-is: 1.6.18
unpipe: 1.0.0
transitivePeerDependencies:
@@ -1848,15 +1906,15 @@ packages:
xtend: 4.0.2
dev: true
- /browserslist@4.22.2:
- resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==}
+ /browserslist@4.23.0:
+ resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001580
- electron-to-chromium: 1.4.646
+ caniuse-lite: 1.0.30001589
+ electron-to-chromium: 1.4.681
node-releases: 2.0.14
- update-browserslist-db: 1.0.13(browserslist@4.22.2)
+ update-browserslist-db: 1.0.13(browserslist@4.23.0)
dev: true
/buffer-from@1.1.2:
@@ -1893,7 +1951,7 @@ packages:
/builtins@5.0.1:
resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==}
dependencies:
- semver: 7.5.4
+ semver: 7.6.0
dev: true
/bundle-name@3.0.0:
@@ -1908,15 +1966,16 @@ packages:
engines: {node: '>= 0.8'}
dev: true
- /c12@1.6.1:
- resolution: {integrity: sha512-fAZOi3INDvIbmjuwAVVggusyRTxwNdTAnwLay8IsXwhFzDwPPGzFxzrx6L55CPFGPulUSZI0eyFUvRDXveoE3g==}
+ /c12@1.9.0:
+ resolution: {integrity: sha512-7KTCZXdIbOA2hLRQ+1KzJ15Qp9Wn58one74dkihMVp2H6EzKTa3OYBy0BSfS1CCcmxYyqeX8L02m40zjQ+dstg==}
dependencies:
- chokidar: 3.5.3
+ chokidar: 3.6.0
+ confbox: 0.1.3
defu: 6.1.4
- dotenv: 16.4.1
+ dotenv: 16.4.5
giget: 1.2.1
jiti: 1.21.0
- mlly: 1.5.0
+ mlly: 1.6.1
ohash: 1.1.3
pathe: 1.1.2
perfect-debounce: 1.0.0
@@ -1933,12 +1992,15 @@ packages:
resolution: {integrity: sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==}
dev: true
- /call-bind@1.0.5:
- resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==}
+ /call-bind@1.0.7:
+ resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+ engines: {node: '>= 0.4'}
dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
function-bind: 1.1.2
- get-intrinsic: 1.2.2
- set-function-length: 1.2.0
+ get-intrinsic: 1.2.4
+ set-function-length: 1.2.1
dev: true
/callsites@3.1.0:
@@ -1956,14 +2018,14 @@ packages:
/caniuse-api@3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
dependencies:
- browserslist: 4.22.2
- caniuse-lite: 1.0.30001580
+ browserslist: 4.23.0
+ caniuse-lite: 1.0.30001589
lodash.memoize: 4.1.2
lodash.uniq: 4.5.0
dev: true
- /caniuse-lite@1.0.30001580:
- resolution: {integrity: sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==}
+ /caniuse-lite@1.0.30001589:
+ resolution: {integrity: sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==}
dev: true
/chai@4.4.1:
@@ -2017,21 +2079,21 @@ packages:
resolution: {integrity: sha512-IzgToIJ/R9NhVKmL+PW33ozYkv53bXvufDNUSH3GTKXq1iCHGgkbgbtqEWbo8tnWNnt7nPDpjL8PwSG2iS8RVw==}
hasBin: true
dependencies:
- c12: 1.6.1
+ c12: 1.9.0
colorette: 2.0.20
consola: 3.2.3
convert-gitmoji: 0.1.5
execa: 8.0.1
mri: 1.2.0
- node-fetch-native: 1.6.1
+ node-fetch-native: 1.6.2
ofetch: 1.3.3
open: 9.1.0
pathe: 1.1.2
pkg-types: 1.0.3
- scule: 1.2.0
- semver: 7.5.4
+ scule: 1.3.0
+ semver: 7.6.0
std-env: 3.7.0
- yaml: 2.3.4
+ yaml: 2.4.0
dev: true
/char-spinner@1.0.1:
@@ -2044,8 +2106,8 @@ packages:
get-func-name: 2.0.2
dev: true
- /chokidar@3.5.3:
- resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ /chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
dependencies:
anymatch: 3.1.3
@@ -2076,8 +2138,8 @@ packages:
safe-buffer: 5.2.1
dev: true
- /citty@0.1.5:
- resolution: {integrity: sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ==}
+ /citty@0.1.6:
+ resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
dependencies:
consola: 3.2.3
@@ -2150,7 +2212,7 @@ packages:
resolution: {integrity: sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==}
dependencies:
convert-source-map: 1.1.3
- inline-source-map: 0.6.2
+ inline-source-map: 0.6.3
lodash.memoize: 3.0.4
source-map: 0.5.7
dev: true
@@ -2199,6 +2261,10 @@ packages:
typedarray: 0.0.6
dev: true
+ /confbox@0.1.3:
+ resolution: {integrity: sha512-eH3ZxAihl1PhKfpr4VfEN6/vUd87fmgb6JkldHgg/YR6aEBhW63qUDgzP2Y6WM0UumdsYp5H3kibalXAdHfbgg==}
+ dev: true
+
/connect@3.7.0:
resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==}
engines: {node: '>= 0.10.0'}
@@ -2311,6 +2377,23 @@ packages:
shebang-command: 2.0.0
which: 2.0.2
+ /crossws@0.2.0:
+ resolution: {integrity: sha512-WW4qfY5ylZDzTPplWcMVh6dj3IXUme2yb1hGC4wWnAKEwL0txtiRrWdIctSAsDlcfm2udmH7GcH60IT5esY2Zw==}
+ peerDependencies:
+ uWebSockets.js: '*'
+ peerDependenciesMeta:
+ uWebSockets.js:
+ optional: true
+ dev: false
+
+ /crossws@0.2.4:
+ resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==}
+ peerDependencies:
+ uWebSockets.js: '*'
+ peerDependenciesMeta:
+ uWebSockets.js:
+ optional: true
+
/crypto-browserify@3.12.0:
resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==}
dependencies:
@@ -2327,13 +2410,13 @@ packages:
randomfill: 1.0.4
dev: true
- /css-declaration-sorter@7.1.1(postcss@8.4.33):
+ /css-declaration-sorter@7.1.1(postcss@8.4.35):
resolution: {integrity: sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ==}
engines: {node: ^14 || ^16 || >=18}
peerDependencies:
postcss: ^8.0.9
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
/css-select@5.1.0:
@@ -2373,62 +2456,62 @@ packages:
hasBin: true
dev: true
- /cssnano-preset-default@6.0.3(postcss@8.4.33):
- resolution: {integrity: sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA==}
+ /cssnano-preset-default@6.0.5(postcss@8.4.35):
+ resolution: {integrity: sha512-M+qRDEr5QZrfNl0B2ySdbTLGyNb8kBcSjuwR7WBamYBOEREH9t2efnB/nblekqhdGLZdkf4oZNetykG2JWRdZQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- css-declaration-sorter: 7.1.1(postcss@8.4.33)
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
- postcss-calc: 9.0.1(postcss@8.4.33)
- postcss-colormin: 6.0.2(postcss@8.4.33)
- postcss-convert-values: 6.0.2(postcss@8.4.33)
- postcss-discard-comments: 6.0.1(postcss@8.4.33)
- postcss-discard-duplicates: 6.0.1(postcss@8.4.33)
- postcss-discard-empty: 6.0.1(postcss@8.4.33)
- postcss-discard-overridden: 6.0.1(postcss@8.4.33)
- postcss-merge-longhand: 6.0.2(postcss@8.4.33)
- postcss-merge-rules: 6.0.3(postcss@8.4.33)
- postcss-minify-font-values: 6.0.1(postcss@8.4.33)
- postcss-minify-gradients: 6.0.1(postcss@8.4.33)
- postcss-minify-params: 6.0.2(postcss@8.4.33)
- postcss-minify-selectors: 6.0.2(postcss@8.4.33)
- postcss-normalize-charset: 6.0.1(postcss@8.4.33)
- postcss-normalize-display-values: 6.0.1(postcss@8.4.33)
- postcss-normalize-positions: 6.0.1(postcss@8.4.33)
- postcss-normalize-repeat-style: 6.0.1(postcss@8.4.33)
- postcss-normalize-string: 6.0.1(postcss@8.4.33)
- postcss-normalize-timing-functions: 6.0.1(postcss@8.4.33)
- postcss-normalize-unicode: 6.0.2(postcss@8.4.33)
- postcss-normalize-url: 6.0.1(postcss@8.4.33)
- postcss-normalize-whitespace: 6.0.1(postcss@8.4.33)
- postcss-ordered-values: 6.0.1(postcss@8.4.33)
- postcss-reduce-initial: 6.0.2(postcss@8.4.33)
- postcss-reduce-transforms: 6.0.1(postcss@8.4.33)
- postcss-svgo: 6.0.2(postcss@8.4.33)
- postcss-unique-selectors: 6.0.2(postcss@8.4.33)
- dev: true
-
- /cssnano-utils@4.0.1(postcss@8.4.33):
+ css-declaration-sorter: 7.1.1(postcss@8.4.35)
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
+ postcss-calc: 9.0.1(postcss@8.4.35)
+ postcss-colormin: 6.0.3(postcss@8.4.35)
+ postcss-convert-values: 6.0.4(postcss@8.4.35)
+ postcss-discard-comments: 6.0.1(postcss@8.4.35)
+ postcss-discard-duplicates: 6.0.2(postcss@8.4.35)
+ postcss-discard-empty: 6.0.2(postcss@8.4.35)
+ postcss-discard-overridden: 6.0.1(postcss@8.4.35)
+ postcss-merge-longhand: 6.0.3(postcss@8.4.35)
+ postcss-merge-rules: 6.0.4(postcss@8.4.35)
+ postcss-minify-font-values: 6.0.2(postcss@8.4.35)
+ postcss-minify-gradients: 6.0.2(postcss@8.4.35)
+ postcss-minify-params: 6.0.3(postcss@8.4.35)
+ postcss-minify-selectors: 6.0.2(postcss@8.4.35)
+ postcss-normalize-charset: 6.0.1(postcss@8.4.35)
+ postcss-normalize-display-values: 6.0.1(postcss@8.4.35)
+ postcss-normalize-positions: 6.0.1(postcss@8.4.35)
+ postcss-normalize-repeat-style: 6.0.1(postcss@8.4.35)
+ postcss-normalize-string: 6.0.1(postcss@8.4.35)
+ postcss-normalize-timing-functions: 6.0.1(postcss@8.4.35)
+ postcss-normalize-unicode: 6.0.3(postcss@8.4.35)
+ postcss-normalize-url: 6.0.1(postcss@8.4.35)
+ postcss-normalize-whitespace: 6.0.1(postcss@8.4.35)
+ postcss-ordered-values: 6.0.1(postcss@8.4.35)
+ postcss-reduce-initial: 6.0.3(postcss@8.4.35)
+ postcss-reduce-transforms: 6.0.1(postcss@8.4.35)
+ postcss-svgo: 6.0.2(postcss@8.4.35)
+ postcss-unique-selectors: 6.0.2(postcss@8.4.35)
+ dev: true
+
+ /cssnano-utils@4.0.1(postcss@8.4.35):
resolution: {integrity: sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /cssnano@6.0.3(postcss@8.4.33):
- resolution: {integrity: sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==}
+ /cssnano@6.0.5(postcss@8.4.35):
+ resolution: {integrity: sha512-tpTp/ukgrElwu3ESFY4IvWnGn8eTt8cJhC2aAbtA3lvUlxp6t6UPv8YCLjNnEGiFreT1O0LiOM1U3QyTBVFl2A==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- cssnano-preset-default: 6.0.3(postcss@8.4.33)
- lilconfig: 3.0.0
- postcss: 8.4.33
+ cssnano-preset-default: 6.0.5(postcss@8.4.35)
+ lilconfig: 3.1.1
+ postcss: 8.4.35
dev: true
/csso@5.0.5:
@@ -2628,13 +2711,13 @@ packages:
titleize: 3.0.0
dev: true
- /define-data-property@1.1.1:
- resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
+ /define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
engines: {node: '>= 0.4'}
dependencies:
- get-intrinsic: 1.2.2
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
gopd: 1.0.1
- has-property-descriptors: 1.0.1
dev: true
/define-lazy-prop@3.0.0:
@@ -2646,8 +2729,8 @@ packages:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
dependencies:
- define-data-property: 1.1.1
- has-property-descriptors: 1.0.1
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
object-keys: 1.1.1
dev: true
@@ -2685,8 +2768,8 @@ packages:
minimalistic-assert: 1.0.1
dev: true
- /destr@2.0.2:
- resolution: {integrity: sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==}
+ /destr@2.0.3:
+ resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==}
/destroy@1.2.0:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
@@ -2715,6 +2798,15 @@ packages:
wrappy: 1.0.2
dev: true
+ /didyoumean2@6.0.1:
+ resolution: {integrity: sha512-PSy0zQwMg5O+LjT5Mz7vnKC8I7DfWLPF6M7oepqW7WP5mn2CY3hz46xZOa1GJY+KVfyXhdmz6+tdgXwrHlZc5g==}
+ engines: {node: ^16.14.0 || >=18.12.0}
+ dependencies:
+ '@babel/runtime': 7.23.9
+ fastest-levenshtein: 1.0.16
+ lodash.deburr: 4.1.0
+ dev: true
+
/diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -2781,8 +2873,8 @@ packages:
domhandler: 5.0.3
dev: true
- /dotenv@16.4.1:
- resolution: {integrity: sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==}
+ /dotenv@16.4.5:
+ resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'}
dev: true
@@ -2805,8 +2897,8 @@ packages:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
dev: true
- /electron-to-chromium@1.4.646:
- resolution: {integrity: sha512-vThkQ0JuF45qT/20KbRgM56lV7IuGt7SjhawQ719PDHzhP84KAO1WJoaxgCoAffKHK47FmVKP1Fqizx7CwK1SA==}
+ /electron-to-chromium@1.4.681:
+ resolution: {integrity: sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==}
dev: true
/elliptic@6.5.4:
@@ -2859,64 +2951,82 @@ packages:
is-arrayish: 0.2.1
dev: true
- /es-abstract@1.22.3:
- resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==}
+ /es-abstract@1.22.4:
+ resolution: {integrity: sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==}
engines: {node: '>= 0.4'}
dependencies:
- array-buffer-byte-length: 1.0.0
- arraybuffer.prototype.slice: 1.0.2
- available-typed-arrays: 1.0.5
- call-bind: 1.0.5
- es-set-tostringtag: 2.0.2
+ array-buffer-byte-length: 1.0.1
+ arraybuffer.prototype.slice: 1.0.3
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ es-set-tostringtag: 2.0.3
es-to-primitive: 1.2.1
function.prototype.name: 1.1.6
- get-intrinsic: 1.2.2
- get-symbol-description: 1.0.0
+ get-intrinsic: 1.2.4
+ get-symbol-description: 1.0.2
globalthis: 1.0.3
gopd: 1.0.1
- has-property-descriptors: 1.0.1
- has-proto: 1.0.1
+ has-property-descriptors: 1.0.2
+ has-proto: 1.0.3
has-symbols: 1.0.3
- hasown: 2.0.0
- internal-slot: 1.0.6
- is-array-buffer: 3.0.2
+ hasown: 2.0.1
+ internal-slot: 1.0.7
+ is-array-buffer: 3.0.4
is-callable: 1.2.7
- is-negative-zero: 2.0.2
+ is-negative-zero: 2.0.3
is-regex: 1.1.4
- is-shared-array-buffer: 1.0.2
+ is-shared-array-buffer: 1.0.3
is-string: 1.0.7
- is-typed-array: 1.1.12
+ is-typed-array: 1.1.13
is-weakref: 1.0.2
object-inspect: 1.13.1
object-keys: 1.1.1
object.assign: 4.1.5
- regexp.prototype.flags: 1.5.1
+ regexp.prototype.flags: 1.5.2
safe-array-concat: 1.1.0
- safe-regex-test: 1.0.2
+ safe-regex-test: 1.0.3
string.prototype.trim: 1.2.8
string.prototype.trimend: 1.0.7
string.prototype.trimstart: 1.0.7
- typed-array-buffer: 1.0.0
- typed-array-byte-length: 1.0.0
- typed-array-byte-offset: 1.0.0
- typed-array-length: 1.0.4
+ typed-array-buffer: 1.0.2
+ typed-array-byte-length: 1.0.1
+ typed-array-byte-offset: 1.0.2
+ typed-array-length: 1.0.5
unbox-primitive: 1.0.2
- which-typed-array: 1.1.13
+ which-typed-array: 1.1.14
dev: true
- /es-set-tostringtag@2.0.2:
- resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==}
+ /es-array-method-boxes-properly@1.0.0:
+ resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==}
+ dev: true
+
+ /es-define-property@1.0.0:
+ resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.4
+ dev: true
+
+ /es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /es-set-tostringtag@2.0.3:
+ resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
engines: {node: '>= 0.4'}
dependencies:
- get-intrinsic: 1.2.2
- has-tostringtag: 1.0.0
- hasown: 2.0.0
+ get-intrinsic: 1.2.4
+ has-tostringtag: 1.0.2
+ hasown: 2.0.1
dev: true
/es-shim-unscopables@1.0.2:
resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
dependencies:
- hasown: 2.0.0
+ hasown: 2.0.1
dev: true
/es-to-primitive@1.2.1:
@@ -2959,8 +3069,8 @@ packages:
'@esbuild/win32-x64': 0.19.12
dev: true
- /escalade@3.1.1:
- resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+ /escalade@3.1.2:
+ resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
engines: {node: '>=6'}
dev: true
@@ -2978,25 +3088,25 @@ packages:
engines: {node: '>=10'}
dev: true
- /eslint-compat-utils@0.1.2(eslint@8.56.0):
+ /eslint-compat-utils@0.1.2(eslint@8.57.0):
resolution: {integrity: sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==}
engines: {node: '>=12'}
peerDependencies:
eslint: '>=6.0.0'
dependencies:
- eslint: 8.56.0
+ eslint: 8.57.0
dev: true
- /eslint-config-prettier@8.10.0(eslint@8.56.0):
+ /eslint-config-prettier@8.10.0(eslint@8.57.0):
resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
- eslint: 8.56.0
+ eslint: 8.57.0
dev: true
- /eslint-config-standard@17.1.0(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.56.0):
+ /eslint-config-standard@17.1.0(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0):
resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==}
engines: {node: '>=12.0.0'}
peerDependencies:
@@ -3005,29 +3115,29 @@ packages:
eslint-plugin-n: '^15.0.0 || ^16.0.0 '
eslint-plugin-promise: ^6.0.0
dependencies:
- eslint: 8.56.0
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
- eslint-plugin-n: 16.6.2(eslint@8.56.0)
- eslint-plugin-promise: 6.1.1(eslint@8.56.0)
+ eslint: 8.57.0
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-n: 16.6.2(eslint@8.57.0)
+ eslint-plugin-promise: 6.1.1(eslint@8.57.0)
dev: true
- /eslint-config-unjs@0.2.1(eslint@8.56.0)(typescript@5.3.3):
+ /eslint-config-unjs@0.2.1(eslint@8.57.0)(typescript@5.3.3):
resolution: {integrity: sha512-h17q+WR86glq8yLFuHfEnAFfbEYqXpJAppXc0e0fQz0gsotJQ14BZVrlvIThE2a+stWyh0VT73gbBPfosl2rVA==}
peerDependencies:
eslint: '*'
typescript: '*'
dependencies:
- '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.3.3)
- '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
- eslint: 8.56.0
- eslint-config-prettier: 8.10.0(eslint@8.56.0)
- eslint-config-standard: 17.1.0(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)
- eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
- eslint-plugin-n: 16.6.2(eslint@8.56.0)
- eslint-plugin-node: 11.1.0(eslint@8.56.0)
- eslint-plugin-promise: 6.1.1(eslint@8.56.0)
- eslint-plugin-unicorn: 47.0.0(eslint@8.56.0)
+ '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
+ eslint: 8.57.0
+ eslint-config-prettier: 8.10.0(eslint@8.57.0)
+ eslint-config-standard: 17.1.0(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-n: 16.6.2(eslint@8.57.0)
+ eslint-plugin-node: 11.1.0(eslint@8.57.0)
+ eslint-plugin-promise: 6.1.1(eslint@8.57.0)
+ eslint-plugin-unicorn: 47.0.0(eslint@8.57.0)
typescript: 5.3.3
transitivePeerDependencies:
- eslint-import-resolver-node
@@ -3045,7 +3155,7 @@ packages:
- supports-color
dev: true
- /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0):
+ /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
@@ -3054,9 +3164,9 @@ packages:
dependencies:
debug: 4.3.4
enhanced-resolve: 5.15.0
- eslint: 8.56.0
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
+ eslint: 8.57.0
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.2
is-core-module: 2.13.1
@@ -3068,7 +3178,7 @@ packages:
- supports-color
dev: true
- /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0):
+ /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
@@ -3089,39 +3199,39 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
- '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
debug: 3.2.7
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
transitivePeerDependencies:
- supports-color
dev: true
- /eslint-plugin-es-x@7.5.0(eslint@8.56.0):
+ /eslint-plugin-es-x@7.5.0(eslint@8.57.0):
resolution: {integrity: sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
eslint: '>=8'
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@eslint-community/regexpp': 4.10.0
- eslint: 8.56.0
- eslint-compat-utils: 0.1.2(eslint@8.56.0)
+ eslint: 8.57.0
+ eslint-compat-utils: 0.1.2(eslint@8.57.0)
dev: true
- /eslint-plugin-es@3.0.1(eslint@8.56.0):
+ /eslint-plugin-es@3.0.1(eslint@8.57.0):
resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==}
engines: {node: '>=8.10.0'}
peerDependencies:
eslint: '>=4.19.1'
dependencies:
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-utils: 2.1.0
regexpp: 3.2.0
dev: true
- /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0):
+ /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
engines: {node: '>=4'}
peerDependencies:
@@ -3131,22 +3241,22 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
- '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.3.3)
array-includes: 3.1.7
- array.prototype.findlastindex: 1.2.3
+ array.prototype.findlastindex: 1.2.4
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7
doctrine: 2.1.0
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)
- hasown: 2.0.0
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ hasown: 2.0.1
is-core-module: 2.13.1
is-glob: 4.0.3
minimatch: 3.1.2
object.fromentries: 2.0.7
- object.groupby: 1.0.1
+ object.groupby: 1.0.2
object.values: 1.1.7
semver: 6.3.1
tsconfig-paths: 3.15.0
@@ -3156,61 +3266,61 @@ packages:
- supports-color
dev: true
- /eslint-plugin-n@16.6.2(eslint@8.56.0):
+ /eslint-plugin-n@16.6.2(eslint@8.57.0):
resolution: {integrity: sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==}
engines: {node: '>=16.0.0'}
peerDependencies:
eslint: '>=7.0.0'
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
builtins: 5.0.1
- eslint: 8.56.0
- eslint-plugin-es-x: 7.5.0(eslint@8.56.0)
+ eslint: 8.57.0
+ eslint-plugin-es-x: 7.5.0(eslint@8.57.0)
get-tsconfig: 4.7.2
globals: 13.24.0
- ignore: 5.3.0
+ ignore: 5.3.1
is-builtin-module: 3.2.1
is-core-module: 2.13.1
minimatch: 3.1.2
resolve: 1.22.8
- semver: 7.5.4
+ semver: 7.6.0
dev: true
- /eslint-plugin-node@11.1.0(eslint@8.56.0):
+ /eslint-plugin-node@11.1.0(eslint@8.57.0):
resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==}
engines: {node: '>=8.10.0'}
peerDependencies:
eslint: '>=5.16.0'
dependencies:
- eslint: 8.56.0
- eslint-plugin-es: 3.0.1(eslint@8.56.0)
+ eslint: 8.57.0
+ eslint-plugin-es: 3.0.1(eslint@8.57.0)
eslint-utils: 2.1.0
- ignore: 5.3.0
+ ignore: 5.3.1
minimatch: 3.1.2
resolve: 1.22.8
semver: 6.3.1
dev: true
- /eslint-plugin-promise@6.1.1(eslint@8.56.0):
+ /eslint-plugin-promise@6.1.1(eslint@8.57.0):
resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
dependencies:
- eslint: 8.56.0
+ eslint: 8.57.0
dev: true
- /eslint-plugin-unicorn@47.0.0(eslint@8.56.0):
+ /eslint-plugin-unicorn@47.0.0(eslint@8.57.0):
resolution: {integrity: sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==}
engines: {node: '>=16'}
peerDependencies:
eslint: '>=8.38.0'
dependencies:
'@babel/helper-validator-identifier': 7.22.20
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
ci-info: 3.9.0
clean-regexp: 1.0.0
- eslint: 8.56.0
+ eslint: 8.57.0
esquery: 1.5.0
indent-string: 4.0.0
is-builtin-module: 3.2.1
@@ -3221,7 +3331,7 @@ packages:
regexp-tree: 0.1.27
regjsparser: 0.10.0
safe-regex: 2.1.1
- semver: 7.5.4
+ semver: 7.6.0
strip-indent: 3.0.0
dev: true
@@ -3258,15 +3368,15 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /eslint@8.56.0:
- resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==}
+ /eslint@8.57.0:
+ resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@eslint-community/regexpp': 4.10.0
'@eslint/eslintrc': 2.1.4
- '@eslint/js': 8.56.0
+ '@eslint/js': 8.57.0
'@humanwhocodes/config-array': 0.11.14
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
@@ -3288,7 +3398,7 @@ packages:
glob-parent: 6.0.2
globals: 13.24.0
graphemer: 1.4.0
- ignore: 5.3.0
+ ignore: 5.3.1
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
@@ -3398,7 +3508,7 @@ packages:
human-signals: 4.3.1
is-stream: 3.0.0
merge-stream: 2.0.0
- npm-run-path: 5.2.0
+ npm-run-path: 5.3.0
onetime: 6.0.0
signal-exit: 3.0.7
strip-final-newline: 3.0.0
@@ -3413,7 +3523,7 @@ packages:
human-signals: 5.0.0
is-stream: 3.0.0
merge-stream: 2.0.0
- npm-run-path: 5.2.0
+ npm-run-path: 5.3.0
onetime: 6.0.0
signal-exit: 4.1.0
strip-final-newline: 3.0.0
@@ -3424,13 +3534,13 @@ packages:
util-extend: 1.0.3
dev: true
- /express@4.18.2:
- resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==}
+ /express@4.18.3:
+ resolution: {integrity: sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==}
engines: {node: '>= 0.10.0'}
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
- body-parser: 1.20.1
+ body-parser: 1.20.2
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.5.0
@@ -3490,8 +3600,13 @@ packages:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
dev: true
- /fastq@1.16.0:
- resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==}
+ /fastest-levenshtein@1.0.16:
+ resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
+ engines: {node: '>= 4.9.1'}
+ dev: true
+
+ /fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
dependencies:
reusify: 1.0.4
dev: true
@@ -3559,7 +3674,7 @@ packages:
resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
engines: {node: ^10.12.0 || >=12.0.0}
dependencies:
- flatted: 3.2.9
+ flatted: 3.3.1
keyv: 4.5.4
rimraf: 3.0.2
dev: true
@@ -3569,8 +3684,8 @@ packages:
hasBin: true
dev: true
- /flatted@3.2.9:
- resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
+ /flatted@3.3.1:
+ resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
dev: true
/for-each@0.3.3:
@@ -3656,9 +3771,9 @@ packages:
resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
functions-have-names: 1.2.3
dev: true
@@ -3679,13 +3794,15 @@ packages:
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
dev: true
- /get-intrinsic@1.2.2:
- resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==}
+ /get-intrinsic@1.2.4:
+ resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+ engines: {node: '>= 0.4'}
dependencies:
+ es-errors: 1.3.0
function-bind: 1.1.2
- has-proto: 1.0.1
+ has-proto: 1.0.3
has-symbols: 1.0.3
- hasown: 2.0.0
+ hasown: 2.0.1
dev: true
/get-port-please@3.1.2:
@@ -3705,12 +3822,13 @@ packages:
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
engines: {node: '>=16'}
- /get-symbol-description@1.0.0:
- resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+ /get-symbol-description@1.0.2:
+ resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- get-intrinsic: 1.2.2
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
dev: true
/get-tsconfig@4.7.2:
@@ -3723,10 +3841,10 @@ packages:
resolution: {integrity: sha512-4VG22mopWtIeHwogGSy1FViXVo0YT+m6BrqZfz0JJFwbSsePsCdOzdLIIli5BtMp7Xe8f/o2OmBpQX2NBOC24g==}
hasBin: true
dependencies:
- citty: 0.1.5
+ citty: 0.1.6
consola: 3.2.3
defu: 6.1.4
- node-fetch-native: 1.6.1
+ node-fetch-native: 1.6.2
nypm: 0.3.6
ohash: 1.1.3
pathe: 1.1.2
@@ -3795,7 +3913,7 @@ packages:
array-union: 2.1.0
dir-glob: 3.0.1
fast-glob: 3.3.2
- ignore: 5.3.0
+ ignore: 5.3.1
merge2: 1.4.1
slash: 3.0.0
dev: true
@@ -3806,15 +3924,27 @@ packages:
dependencies:
dir-glob: 3.0.1
fast-glob: 3.3.2
- ignore: 5.3.0
+ ignore: 5.3.1
merge2: 1.4.1
slash: 4.0.0
dev: true
+ /globby@14.0.1:
+ resolution: {integrity: sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==}
+ engines: {node: '>=18'}
+ dependencies:
+ '@sindresorhus/merge-streams': 2.3.0
+ fast-glob: 3.3.2
+ ignore: 5.3.1
+ path-type: 5.0.0
+ slash: 5.1.0
+ unicorn-magic: 0.1.0
+ dev: true
+
/gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
- get-intrinsic: 1.2.2
+ get-intrinsic: 1.2.4
dev: true
/graceful-fs@4.2.11:
@@ -3825,17 +3955,21 @@ packages:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true
- /h3@1.10.0:
- resolution: {integrity: sha512-Tw1kcIC+AeimwRmviiObaD5EB430Yt+lTgOxLJxNr96Vd/fGRu04EF7aKfOAcpwKCI+U2JlbxOLhycD86p3Ciw==}
+ /h3@1.11.1:
+ resolution: {integrity: sha512-AbaH6IDnZN6nmbnJOH72y3c5Wwh9P97soSVdGSBbcDACRdkC0FEWf25pzx4f/NuOCK6quHmW18yF2Wx+G4Zi1A==}
dependencies:
cookie-es: 1.0.0
+ crossws: 0.2.4
defu: 6.1.4
- destr: 2.0.2
+ destr: 2.0.3
iron-webcrypto: 1.0.0
+ ohash: 1.1.3
radix3: 1.1.0
- ufo: 1.3.2
+ ufo: 1.4.0
uncrypto: 0.1.3
unenv: 1.9.0
+ transitivePeerDependencies:
+ - uWebSockets.js
/has-ansi@2.0.0:
resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==}
@@ -3863,14 +3997,14 @@ packages:
engines: {node: '>=8'}
dev: true
- /has-property-descriptors@1.0.1:
- resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==}
+ /has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
dependencies:
- get-intrinsic: 1.2.2
+ es-define-property: 1.0.0
dev: true
- /has-proto@1.0.1:
- resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
+ /has-proto@1.0.3:
+ resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
engines: {node: '>= 0.4'}
dev: true
@@ -3879,8 +4013,8 @@ packages:
engines: {node: '>= 0.4'}
dev: true
- /has-tostringtag@1.0.0:
- resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ /has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
engines: {node: '>= 0.4'}
dependencies:
has-symbols: 1.0.3
@@ -3911,8 +4045,8 @@ packages:
minimalistic-assert: 1.0.1
dev: true
- /hasown@2.0.0:
- resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==}
+ /hasown@2.0.1:
+ resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==}
engines: {node: '>= 0.4'}
dependencies:
function-bind: 1.1.2
@@ -4031,8 +4165,8 @@ packages:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: true
- /ignore@5.3.0:
- resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==}
+ /ignore@5.3.1:
+ resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
dev: true
@@ -4069,8 +4203,8 @@ packages:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true
- /inline-source-map@0.6.2:
- resolution: {integrity: sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==}
+ /inline-source-map@0.6.3:
+ resolution: {integrity: sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==}
dependencies:
source-map: 0.5.7
dev: true
@@ -4091,13 +4225,13 @@ packages:
xtend: 4.0.2
dev: true
- /internal-slot@1.0.6:
- resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==}
+ /internal-slot@1.0.7:
+ resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
engines: {node: '>= 0.4'}
dependencies:
- get-intrinsic: 1.2.2
- hasown: 2.0.0
- side-channel: 1.0.4
+ es-errors: 1.3.0
+ hasown: 2.0.1
+ side-channel: 1.0.5
dev: true
/internmap@1.0.1:
@@ -4116,16 +4250,16 @@ packages:
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- has-tostringtag: 1.0.0
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
dev: true
- /is-array-buffer@3.0.2:
- resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
+ /is-array-buffer@3.0.4:
+ resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
+ engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- get-intrinsic: 1.2.2
- is-typed-array: 1.1.12
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
dev: true
/is-arrayish@0.2.1:
@@ -4153,8 +4287,8 @@ packages:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- has-tostringtag: 1.0.0
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
dev: true
/is-buffer@1.1.6:
@@ -4181,14 +4315,14 @@ packages:
/is-core-module@2.13.1:
resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
dependencies:
- hasown: 2.0.0
+ hasown: 2.0.1
dev: true
/is-date-object@1.0.5:
resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
engines: {node: '>= 0.4'}
dependencies:
- has-tostringtag: 1.0.0
+ has-tostringtag: 1.0.2
dev: true
/is-docker@2.2.1:
@@ -4222,7 +4356,7 @@ packages:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
engines: {node: '>= 0.4'}
dependencies:
- has-tostringtag: 1.0.0
+ has-tostringtag: 1.0.2
dev: true
/is-glob@4.0.3:
@@ -4242,8 +4376,8 @@ packages:
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
dev: true
- /is-negative-zero@2.0.2:
- resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
+ /is-negative-zero@2.0.3:
+ resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
engines: {node: '>= 0.4'}
dev: true
@@ -4251,7 +4385,7 @@ packages:
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
engines: {node: '>= 0.4'}
dependencies:
- has-tostringtag: 1.0.0
+ has-tostringtag: 1.0.2
dev: true
/is-number@7.0.0:
@@ -4273,14 +4407,15 @@ packages:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- has-tostringtag: 1.0.0
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
dev: true
- /is-shared-array-buffer@1.0.2:
- resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+ /is-shared-array-buffer@1.0.3:
+ resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
+ engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
dev: true
/is-stream@2.0.1:
@@ -4296,7 +4431,7 @@ packages:
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
engines: {node: '>= 0.4'}
dependencies:
- has-tostringtag: 1.0.0
+ has-tostringtag: 1.0.2
dev: true
/is-symbol@1.0.4:
@@ -4306,17 +4441,17 @@ packages:
has-symbols: 1.0.3
dev: true
- /is-typed-array@1.1.12:
- resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
+ /is-typed-array@1.1.13:
+ resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
engines: {node: '>= 0.4'}
dependencies:
- which-typed-array: 1.1.13
+ which-typed-array: 1.1.14
dev: true
/is-weakref@1.0.2:
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
dev: true
/is-wsl@1.1.0:
@@ -4379,8 +4514,8 @@ packages:
- supports-color
dev: true
- /istanbul-reports@3.1.6:
- resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==}
+ /istanbul-reports@3.1.7:
+ resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
engines: {node: '>=8'}
dependencies:
html-escaper: 2.0.2
@@ -4395,6 +4530,10 @@ packages:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true
+ /js-tokens@8.0.3:
+ resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==}
+ dev: true
+
/js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
@@ -4499,8 +4638,8 @@ packages:
type-check: 0.4.0
dev: true
- /lilconfig@3.0.0:
- resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==}
+ /lilconfig@3.1.1:
+ resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==}
engines: {node: '>=14'}
dev: true
@@ -4508,33 +4647,63 @@ packages:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
- /listhen@1.5.6:
- resolution: {integrity: sha512-gTpEJhT5L85L0bFgmu+Boqu5rP4DwDtEb4Exq5gdQUxWRwx4jbzdInZkmyLONo5EwIcQB0k7ZpWlpCDPdL77EQ==}
+ /listhen@1.7.1:
+ resolution: {integrity: sha512-kukvhU7W0H92lCkA9PibJ+K9GJVHfzUEerP+RllUYHoVCm0/Pveo/VeIKgaMcdLyq0ojtpbkJiybvRlvUfNGzQ==}
+ hasBin: true
+ dependencies:
+ '@parcel/watcher': 2.4.1
+ '@parcel/watcher-wasm': 2.4.1
+ citty: 0.1.6
+ clipboardy: 4.0.0
+ consola: 3.2.3
+ crossws: 0.2.0
+ defu: 6.1.4
+ get-port-please: 3.1.2
+ h3: 1.11.1
+ http-shutdown: 1.2.2
+ jiti: 1.21.0
+ mlly: 1.6.1
+ node-forge: 1.3.1
+ pathe: 1.1.2
+ std-env: 3.7.0
+ ufo: 1.4.0
+ untun: 0.1.3
+ uqr: 0.1.2
+ transitivePeerDependencies:
+ - uWebSockets.js
+ dev: false
+
+ /listhen@1.7.2:
+ resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==}
hasBin: true
dependencies:
- '@parcel/watcher': 2.4.0
- '@parcel/watcher-wasm': 2.3.0
- citty: 0.1.5
+ '@parcel/watcher': 2.4.1
+ '@parcel/watcher-wasm': 2.4.1
+ citty: 0.1.6
clipboardy: 4.0.0
consola: 3.2.3
+ crossws: 0.2.4
defu: 6.1.4
get-port-please: 3.1.2
- h3: 1.10.0
+ h3: 1.11.1
http-shutdown: 1.2.2
jiti: 1.21.0
- mlly: 1.5.0
+ mlly: 1.6.1
node-forge: 1.3.1
pathe: 1.1.2
std-env: 3.7.0
- ufo: 1.3.2
+ ufo: 1.4.0
untun: 0.1.3
uqr: 0.1.2
+ transitivePeerDependencies:
+ - uWebSockets.js
+ dev: true
/local-pkg@0.5.0:
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
engines: {node: '>=14'}
dependencies:
- mlly: 1.5.0
+ mlly: 1.6.1
pkg-types: 1.0.3
dev: true
@@ -4560,6 +4729,10 @@ packages:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
dev: true
+ /lodash.deburr@4.1.0:
+ resolution: {integrity: sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==}
+ dev: true
+
/lodash.flatten@4.4.0:
resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==}
dev: true
@@ -4620,8 +4793,8 @@ packages:
sourcemap-codec: 1.4.8
dev: true
- /magic-string@0.30.5:
- resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==}
+ /magic-string@0.30.7:
+ resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
@@ -4646,13 +4819,17 @@ packages:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
dependencies:
- semver: 7.5.4
+ semver: 7.6.0
dev: true
/manage-path@2.0.0:
resolution: {integrity: sha512-NJhyB+PJYTpxhxZJ3lecIGgh4kwIY2RAh44XvAz9UlqthlQwtPBf62uBVR8XaD8CRuSjQ6TnZH2lNJkbLPZM2A==}
dev: true
+ /md4w@0.2.2:
+ resolution: {integrity: sha512-dJwbVIueCp4HgI9Jg4I9pDVLiig1lAVXYqVmTrIVsobh3b50EtgQrXmFEzzRRR6HaK6xVqB/bd3Ac/Nt2kdwPA==}
+ dev: true
+
/md5.js@1.3.5:
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
dependencies:
@@ -4661,6 +4838,12 @@ packages:
safe-buffer: 5.2.1
dev: true
+ /mdbox@0.1.0:
+ resolution: {integrity: sha512-eQA+6vf5XM4LqdfLsfPMxqUBSU8AMzSCSFbojWLXSDL2jZeO+xgHhxTggrG2jfGPAyyIWIukj6SuoFBd9a7XZw==}
+ dependencies:
+ md4w: 0.2.2
+ dev: true
+
/mdn-data@2.0.28:
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
dev: true
@@ -4822,29 +5005,29 @@ packages:
typescript:
optional: true
dependencies:
- autoprefixer: 10.4.17(postcss@8.4.33)
- citty: 0.1.5
- cssnano: 6.0.3(postcss@8.4.33)
+ autoprefixer: 10.4.17(postcss@8.4.35)
+ citty: 0.1.6
+ cssnano: 6.0.5(postcss@8.4.35)
defu: 6.1.4
esbuild: 0.19.12
fs-extra: 11.2.0
globby: 13.2.2
jiti: 1.21.0
- mlly: 1.5.0
+ mlly: 1.6.1
mri: 1.2.0
pathe: 1.1.2
- postcss: 8.4.33
- postcss-nested: 6.0.1(postcss@8.4.33)
+ postcss: 8.4.35
+ postcss-nested: 6.0.1(postcss@8.4.35)
typescript: 5.3.3
dev: true
- /mlly@1.5.0:
- resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==}
+ /mlly@1.6.1:
+ resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==}
dependencies:
acorn: 8.11.3
pathe: 1.1.2
pkg-types: 1.0.3
- ufo: 1.3.2
+ ufo: 1.4.0
/module-deps@6.2.3:
resolution: {integrity: sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==}
@@ -4954,8 +5137,8 @@ packages:
resolution: {integrity: sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==}
engines: {node: ^16 || ^18 || >= 20}
- /node-fetch-native@1.6.1:
- resolution: {integrity: sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw==}
+ /node-fetch-native@1.6.2:
+ resolution: {integrity: sha512-69mtXOFZ6hSkYiXAVB5SqaRvrbITC/NPyqv7yuu/qw0nmgPyYbIMYYNIDhNtwPrzk0ptrimrLz/hhjvm4w5Z+w==}
/node-forge@1.3.1:
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
@@ -4996,8 +5179,8 @@ packages:
path-key: 3.1.1
dev: true
- /npm-run-path@5.2.0:
- resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==}
+ /npm-run-path@5.3.0:
+ resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
path-key: 4.0.0
@@ -5018,10 +5201,10 @@ packages:
engines: {node: ^14.16.0 || >=16.10.0}
hasBin: true
dependencies:
- citty: 0.1.5
+ citty: 0.1.6
execa: 8.0.1
pathe: 1.1.2
- ufo: 1.3.2
+ ufo: 1.4.0
dev: true
/object-inspect@1.13.1:
@@ -5037,7 +5220,7 @@ packages:
resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
has-symbols: 1.0.3
object-keys: 1.1.1
@@ -5047,35 +5230,36 @@ packages:
resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
dev: true
- /object.groupby@1.0.1:
- resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==}
+ /object.groupby@1.0.2:
+ resolution: {integrity: sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==}
dependencies:
- call-bind: 1.0.5
+ array.prototype.filter: 1.0.3
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
- get-intrinsic: 1.2.2
+ es-abstract: 1.22.4
+ es-errors: 1.3.0
dev: true
/object.values@1.1.7:
resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
dev: true
/ofetch@1.3.3:
resolution: {integrity: sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==}
dependencies:
- destr: 2.0.2
- node-fetch-native: 1.6.1
- ufo: 1.3.2
+ destr: 2.0.3
+ node-fetch-native: 1.6.2
+ ufo: 1.4.0
dev: true
/ohash@1.1.3:
@@ -5274,6 +5458,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /path-type@5.0.0:
+ resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==}
+ engines: {node: '>=12'}
+ dev: true
+
/pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
@@ -5308,7 +5497,7 @@ packages:
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
dependencies:
jsonc-parser: 3.2.1
- mlly: 1.5.0
+ mlly: 1.6.1
pathe: 1.1.2
/pluralize@8.0.0:
@@ -5316,274 +5505,279 @@ packages:
engines: {node: '>=4'}
dev: true
- /postcss-calc@9.0.1(postcss@8.4.33):
+ /possible-typed-array-names@1.0.0:
+ resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /postcss-calc@9.0.1(postcss@8.4.35):
resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.2.2
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
postcss-value-parser: 4.2.0
dev: true
- /postcss-colormin@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-TXKOxs9LWcdYo5cgmcSHPkyrLAh86hX1ijmyy6J8SbOhyv6ua053M3ZAM/0j44UsnQNIWdl8gb5L7xX2htKeLw==}
+ /postcss-colormin@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-ECpkS+UZRyAtu/kjive2/1mihP+GNtgC8kcdU8ueWZi1ZVxMNnRziCLdhrWECJhEtSWijfX2Cl9XTTCK/hjGaA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-api: 3.0.0
colord: 2.9.3
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-convert-values@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw==}
+ /postcss-convert-values@6.0.4(postcss@8.4.35):
+ resolution: {integrity: sha512-YT2yrGzPXoQD3YeA2kBo/696qNwn7vI+15AOS2puXWEvSWqdCqlOyDWRy5GNnOc9ACRGOkuQ4ESQEqPJBWt/GA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- postcss: 8.4.33
+ browserslist: 4.23.0
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-discard-comments@6.0.1(postcss@8.4.33):
+ /postcss-discard-comments@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /postcss-discard-duplicates@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==}
+ /postcss-discard-duplicates@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-U2rsj4w6pAGROCCcD13LP2eBIi1whUsXs4kgE6xkIuGfkbxCBSKhkCTWyowFd66WdVlLv0uM1euJKIgmdmZObg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /postcss-discard-empty@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==}
+ /postcss-discard-empty@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-rj6pVC2dVCJrP0Y2RkYTQEbYaCf4HEm+R/2StQgJqGHxAa3+KcYslNQhcRqjLHtl/4wpzipJluaJLqBj6d5eDQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /postcss-discard-overridden@6.0.1(postcss@8.4.33):
+ /postcss-discard-overridden@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /postcss-merge-longhand@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw==}
+ /postcss-merge-longhand@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-kF/y3DU8CRt+SX3tP/aG+2gkZI2Z7OXDsPU7FgxIJmuyhQQ1EHceIYcsp/alvzCm2P4c37Sfdu8nNrHc+YeyLg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
- stylehacks: 6.0.2(postcss@8.4.33)
+ stylehacks: 6.0.3(postcss@8.4.35)
dev: true
- /postcss-merge-rules@6.0.3(postcss@8.4.33):
- resolution: {integrity: sha512-yfkDqSHGohy8sGYIJwBmIGDv4K4/WrJPX355XrxQb/CSsT4Kc/RxDi6akqn5s9bap85AWgv21ArcUWwWdGNSHA==}
+ /postcss-merge-rules@6.0.4(postcss@8.4.35):
+ resolution: {integrity: sha512-97iF3UJ5v8N1BWy38y+0l+Z8o5/9uGlEgtWic2PJPzoRrLB6Gxg8TVG93O0EK52jcLeMsywre26AUlX1YAYeHA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-api: 3.0.0
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: true
- /postcss-minify-font-values@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w==}
+ /postcss-minify-font-values@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-IedzbVMoX0a7VZWjSYr5qJ6C37rws8kl8diPBeMZLJfWKkgXuMFY5R/OxPegn/q9tK9ztd0XRH3aR0u2t+A7uQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-minify-gradients@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w==}
+ /postcss-minify-gradients@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-vP5mF7iI6/5fcpv+rSfwWQekOE+8I1i7/7RjZPGuIjj6eUaZVeG4XZYZrroFuw1WQd51u2V32wyQFZ+oYdE7CA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
colord: 2.9.3
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-minify-params@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-zwQtbrPEBDj+ApELZ6QylLf2/c5zmASoOuA4DzolyVGdV38iR2I5QRMsZcHkcdkZzxpN8RS4cN7LPskOkTwTZw==}
+ /postcss-minify-params@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-j4S74d3AAeCK5eGdQndXSrkxusV2ekOxbXGnlnZthMyZBBvSDiU34CihTASbJxuVB3bugudmwolS7+Dgs5OyOQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ browserslist: 4.23.0
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-minify-selectors@6.0.2(postcss@8.4.33):
+ /postcss-minify-selectors@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-0b+m+w7OAvZejPQdN2GjsXLv5o0jqYHX3aoV0e7RBKPCsB7TYG5KKWBFhGnB/iP3213Ts8c5H4wLPLMm7z28Sg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: true
- /postcss-nested@6.0.1(postcss@8.4.33):
+ /postcss-nested@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: true
- /postcss-normalize-charset@6.0.1(postcss@8.4.33):
+ /postcss-normalize-charset@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /postcss-normalize-display-values@6.0.1(postcss@8.4.33):
+ /postcss-normalize-display-values@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-positions@6.0.1(postcss@8.4.33):
+ /postcss-normalize-positions@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-repeat-style@6.0.1(postcss@8.4.33):
+ /postcss-normalize-repeat-style@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-string@6.0.1(postcss@8.4.33):
+ /postcss-normalize-string@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-timing-functions@6.0.1(postcss@8.4.33):
+ /postcss-normalize-timing-functions@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-unicode@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-Ff2VdAYCTGyMUwpevTZPZ4w0+mPjbZzLLyoLh/RMpqUqeQKZ+xMm31hkxBavDcGKcxm6ACzGk0nBfZ8LZkStKA==}
+ /postcss-normalize-unicode@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-T2Bb3gXz0ASgc3ori2dzjv6j/P2IantreaC6fT8tWjqYUiqMAh5jGIkdPwEV2FaucjQlCLeFJDJh2BeSugE1ig==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- postcss: 8.4.33
+ browserslist: 4.23.0
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-url@6.0.1(postcss@8.4.33):
+ /postcss-normalize-url@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-normalize-whitespace@6.0.1(postcss@8.4.33):
+ /postcss-normalize-whitespace@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-ordered-values@6.0.1(postcss@8.4.33):
+ /postcss-ordered-values@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
- /postcss-reduce-initial@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-YGKalhNlCLcjcLvjU5nF8FyeCTkCO5UtvJEt0hrPZVCTtRLSOH4z00T1UntQPj4dUmIYZgMj8qK77JbSX95hSw==}
+ /postcss-reduce-initial@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-w4QIR9pEa1N4xMx3k30T1vLZl6udVK2RmNqrDXhBXX9L0mBj2a8ADs8zkbaEH7eUy1m30Wyr5EBgHN31Yq1JvA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-api: 3.0.0
- postcss: 8.4.33
+ postcss: 8.4.35
dev: true
- /postcss-reduce-transforms@6.0.1(postcss@8.4.33):
+ /postcss-reduce-transforms@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
@@ -5595,24 +5789,24 @@ packages:
util-deprecate: 1.0.2
dev: true
- /postcss-svgo@6.0.2(postcss@8.4.33):
+ /postcss-svgo@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ==}
engines: {node: ^14 || ^16 || >= 18}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
svgo: 3.2.0
dev: true
- /postcss-unique-selectors@6.0.2(postcss@8.4.33):
+ /postcss-unique-selectors@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-8IZGQ94nechdG7Y9Sh9FlIY2b4uS8/k8kdKRX040XHsS3B6d1HrJAkXrBSsSu4SuARruSsUjW3nlSw8BHkaAYQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: true
@@ -5620,8 +5814,8 @@ packages:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: true
- /postcss@8.4.33:
- resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==}
+ /postcss@8.4.35:
+ resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.7
@@ -5634,8 +5828,8 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
- /prettier@3.2.4:
- resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==}
+ /prettier@3.2.5:
+ resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
engines: {node: '>=14'}
hasBin: true
dev: true
@@ -5725,14 +5919,14 @@ packages:
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
engines: {node: '>=0.6'}
dependencies:
- side-channel: 1.0.4
+ side-channel: 1.0.5
dev: true
/qs@6.11.2:
resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==}
engines: {node: '>=0.6'}
dependencies:
- side-channel: 1.0.4
+ side-channel: 1.0.5
dev: true
/querystring-es3@0.2.1:
@@ -5769,8 +5963,8 @@ packages:
engines: {node: '>= 0.6'}
dev: true
- /raw-body@2.5.1:
- resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==}
+ /raw-body@2.5.2:
+ resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
engines: {node: '>= 0.8'}
dependencies:
bytes: 3.1.2
@@ -5783,7 +5977,7 @@ packages:
resolution: {integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==}
dependencies:
defu: 6.1.4
- destr: 2.0.2
+ destr: 2.0.3
flat: 5.0.2
dev: true
@@ -5861,18 +6055,23 @@ packages:
picomatch: 2.3.1
dev: true
+ /regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+ dev: true
+
/regexp-tree@0.1.27:
resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
hasBin: true
dev: true
- /regexp.prototype.flags@1.5.1:
- resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
+ /regexp.prototype.flags@1.5.2:
+ resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- set-function-name: 2.0.1
+ es-errors: 1.3.0
+ set-function-name: 2.0.2
dev: true
/regexpp@3.2.0:
@@ -5944,7 +6143,7 @@ packages:
rollup: ^3.29.4 || ^4
typescript: ^4.5 || ^5.0
dependencies:
- magic-string: 0.30.5
+ magic-string: 0.30.7
rollup: 3.29.4
typescript: 5.3.3
optionalDependencies:
@@ -5959,26 +6158,26 @@ packages:
fsevents: 2.3.3
dev: true
- /rollup@4.9.6:
- resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==}
+ /rollup@4.12.0:
+ resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
dependencies:
'@types/estree': 1.0.5
optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.9.6
- '@rollup/rollup-android-arm64': 4.9.6
- '@rollup/rollup-darwin-arm64': 4.9.6
- '@rollup/rollup-darwin-x64': 4.9.6
- '@rollup/rollup-linux-arm-gnueabihf': 4.9.6
- '@rollup/rollup-linux-arm64-gnu': 4.9.6
- '@rollup/rollup-linux-arm64-musl': 4.9.6
- '@rollup/rollup-linux-riscv64-gnu': 4.9.6
- '@rollup/rollup-linux-x64-gnu': 4.9.6
- '@rollup/rollup-linux-x64-musl': 4.9.6
- '@rollup/rollup-win32-arm64-msvc': 4.9.6
- '@rollup/rollup-win32-ia32-msvc': 4.9.6
- '@rollup/rollup-win32-x64-msvc': 4.9.6
+ '@rollup/rollup-android-arm-eabi': 4.12.0
+ '@rollup/rollup-android-arm64': 4.12.0
+ '@rollup/rollup-darwin-arm64': 4.12.0
+ '@rollup/rollup-darwin-x64': 4.12.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.12.0
+ '@rollup/rollup-linux-arm64-gnu': 4.12.0
+ '@rollup/rollup-linux-arm64-musl': 4.12.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.12.0
+ '@rollup/rollup-linux-x64-gnu': 4.12.0
+ '@rollup/rollup-linux-x64-musl': 4.12.0
+ '@rollup/rollup-win32-arm64-msvc': 4.12.0
+ '@rollup/rollup-win32-ia32-msvc': 4.12.0
+ '@rollup/rollup-win32-x64-msvc': 4.12.0
fsevents: 2.3.3
dev: true
@@ -5999,8 +6198,8 @@ packages:
resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==}
engines: {node: '>=0.4'}
dependencies:
- call-bind: 1.0.5
- get-intrinsic: 1.2.2
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
has-symbols: 1.0.3
isarray: 2.0.5
dev: true
@@ -6013,12 +6212,12 @@ packages:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: true
- /safe-regex-test@1.0.2:
- resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==}
+ /safe-regex-test@1.0.3:
+ resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- get-intrinsic: 1.2.2
+ call-bind: 1.0.7
+ es-errors: 1.3.0
is-regex: 1.1.4
dev: true
@@ -6038,8 +6237,8 @@ packages:
loose-envify: 1.4.0
dev: true
- /scule@1.2.0:
- resolution: {integrity: sha512-CRCmi5zHQnSoeCik9565PONMg0kfkvYmcSqrbOJY4txFfy1wvVULV4FDaiXhUblUgahdqz3F2NwHZ8i4eBTwUw==}
+ /scule@1.3.0:
+ resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
dev: true
/semver@5.7.2:
@@ -6052,8 +6251,8 @@ packages:
hasBin: true
dev: true
- /semver@7.5.4:
- resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
+ /semver@7.6.0:
+ resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
engines: {node: '>=10'}
hasBin: true
dependencies:
@@ -6093,24 +6292,26 @@ packages:
- supports-color
dev: true
- /set-function-length@1.2.0:
- resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==}
+ /set-function-length@1.2.1:
+ resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==}
engines: {node: '>= 0.4'}
dependencies:
- define-data-property: 1.1.1
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
function-bind: 1.1.2
- get-intrinsic: 1.2.2
+ get-intrinsic: 1.2.4
gopd: 1.0.1
- has-property-descriptors: 1.0.1
+ has-property-descriptors: 1.0.2
dev: true
- /set-function-name@2.0.1:
- resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==}
+ /set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
engines: {node: '>= 0.4'}
dependencies:
- define-data-property: 1.1.1
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
functions-have-names: 1.2.3
- has-property-descriptors: 1.0.1
+ has-property-descriptors: 1.0.2
dev: true
/setprototypeof@1.2.0:
@@ -6145,11 +6346,13 @@ packages:
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
dev: true
- /side-channel@1.0.4:
- resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ /side-channel@1.0.5:
+ resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==}
+ engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- get-intrinsic: 1.2.2
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
object-inspect: 1.13.1
dev: true
@@ -6185,6 +6388,11 @@ packages:
engines: {node: '>=12'}
dev: true
+ /slash@5.1.0:
+ resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+ engines: {node: '>=14.16'}
+ dev: true
+
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
@@ -6209,22 +6417,22 @@ packages:
resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
dependencies:
spdx-expression-parse: 3.0.1
- spdx-license-ids: 3.0.16
+ spdx-license-ids: 3.0.17
dev: true
- /spdx-exceptions@2.4.0:
- resolution: {integrity: sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==}
+ /spdx-exceptions@2.5.0:
+ resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
dev: true
/spdx-expression-parse@3.0.1:
resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
dependencies:
- spdx-exceptions: 2.4.0
- spdx-license-ids: 3.0.16
+ spdx-exceptions: 2.5.0
+ spdx-license-ids: 3.0.17
dev: true
- /spdx-license-ids@3.0.16:
- resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==}
+ /spdx-license-ids@3.0.17:
+ resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==}
dev: true
/split2@4.2.0:
@@ -6305,25 +6513,25 @@ packages:
resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
dev: true
/string.prototype.trimend@1.0.7:
resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
dev: true
/string.prototype.trimstart@1.0.7:
resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
define-properties: 1.2.1
- es-abstract: 1.22.3
+ es-abstract: 1.22.4
dev: true
/string_decoder@1.1.1:
@@ -6378,20 +6586,20 @@ packages:
engines: {node: '>=8'}
dev: true
- /strip-literal@1.3.0:
- resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
+ /strip-literal@2.0.0:
+ resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==}
dependencies:
- acorn: 8.11.3
+ js-tokens: 8.0.3
dev: true
- /stylehacks@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-00zvJGnCu64EpMjX8b5iCZ3us2Ptyw8+toEkb92VdmkEaRaSGBNKAoK6aWZckhXxmQP8zWiTaFaiMGIU8Ve8sg==}
+ /stylehacks@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-KzBqjnqktc8/I0ERCb+lGq06giF/JxDbw2r9kEVhen9noHeIDRtMWUp9r62sOk+/2bbX6sFG1GhsS7ToXG0PEg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- postcss: 8.4.33
+ browserslist: 4.23.0
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: true
@@ -6414,7 +6622,7 @@ packages:
methods: 1.1.2
mime: 2.6.0
qs: 6.11.2
- semver: 7.5.4
+ semver: 7.6.0
transitivePeerDependencies:
- supports-color
dev: true
@@ -6557,8 +6765,8 @@ packages:
engines: {node: '>=14.0.0'}
dev: true
- /tinyspy@2.2.0:
- resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==}
+ /tinyspy@2.2.1:
+ resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
engines: {node: '>=14.0.0'}
dev: true
@@ -6661,42 +6869,48 @@ packages:
mime-types: 2.1.35
dev: true
- /typed-array-buffer@1.0.0:
- resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==}
+ /typed-array-buffer@1.0.2:
+ resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
- get-intrinsic: 1.2.2
- is-typed-array: 1.1.12
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-typed-array: 1.1.13
dev: true
- /typed-array-byte-length@1.0.0:
- resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==}
+ /typed-array-byte-length@1.0.1:
+ resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==}
engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
for-each: 0.3.3
- has-proto: 1.0.1
- is-typed-array: 1.1.12
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
dev: true
- /typed-array-byte-offset@1.0.0:
- resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==}
+ /typed-array-byte-offset@1.0.2:
+ resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==}
engines: {node: '>= 0.4'}
dependencies:
- available-typed-arrays: 1.0.5
- call-bind: 1.0.5
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
for-each: 0.3.3
- has-proto: 1.0.1
- is-typed-array: 1.1.12
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
dev: true
- /typed-array-length@1.0.4:
- resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
+ /typed-array-length@1.0.5:
+ resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==}
+ engines: {node: '>= 0.4'}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
for-each: 0.3.3
- is-typed-array: 1.1.12
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+ possible-typed-array-names: 1.0.0
dev: true
/typedarray@0.0.6:
@@ -6709,8 +6923,8 @@ packages:
hasBin: true
dev: true
- /ufo@1.3.2:
- resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==}
+ /ufo@1.4.0:
+ resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==}
/umd@3.0.3:
resolution: {integrity: sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==}
@@ -6720,7 +6934,7 @@ packages:
/unbox-primitive@1.0.2:
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
dependencies:
- call-bind: 1.0.5
+ call-bind: 1.0.7
has-bigints: 1.0.2
has-symbols: 1.0.3
which-boxed-primitive: 1.0.2
@@ -6742,22 +6956,22 @@ packages:
'@rollup/plugin-replace': 5.0.5(rollup@3.29.4)
'@rollup/pluginutils': 5.1.0(rollup@3.29.4)
chalk: 5.3.0
- citty: 0.1.5
+ citty: 0.1.6
consola: 3.2.3
defu: 6.1.4
esbuild: 0.19.12
globby: 13.2.2
hookable: 5.5.3
jiti: 1.21.0
- magic-string: 0.30.5
+ magic-string: 0.30.7
mkdist: 1.4.0(typescript@5.3.3)
- mlly: 1.5.0
+ mlly: 1.6.1
pathe: 1.1.2
pkg-types: 1.0.3
pretty-bytes: 6.1.1
rollup: 3.29.4
rollup-plugin-dts: 6.1.0(rollup@3.29.4)(typescript@5.3.3)
- scule: 1.2.0
+ scule: 1.3.0
typescript: 5.3.3
untyped: 1.4.2
transitivePeerDependencies:
@@ -6789,9 +7003,14 @@ packages:
consola: 3.2.3
defu: 6.1.4
mime: 3.0.0
- node-fetch-native: 1.6.1
+ node-fetch-native: 1.6.2
pathe: 1.1.2
+ /unicorn-magic@0.1.0:
+ resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
+ engines: {node: '>=18'}
+ dev: true
+
/universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
@@ -6811,7 +7030,7 @@ packages:
resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==}
hasBin: true
dependencies:
- citty: 0.1.5
+ citty: 0.1.6
consola: 3.2.3
pathe: 1.1.2
@@ -6820,24 +7039,24 @@ packages:
hasBin: true
dependencies:
'@babel/core': 7.23.9
- '@babel/standalone': 7.23.9
+ '@babel/standalone': 7.23.10
'@babel/types': 7.23.9
defu: 6.1.4
jiti: 1.21.0
mri: 1.2.0
- scule: 1.2.0
+ scule: 1.3.0
transitivePeerDependencies:
- supports-color
dev: true
- /update-browserslist-db@1.0.13(browserslist@4.22.2):
+ /update-browserslist-db@1.0.13(browserslist@4.23.0):
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
dependencies:
- browserslist: 4.22.2
- escalade: 3.1.1
+ browserslist: 4.23.0
+ escalade: 3.1.2
picocolors: 1.0.0
dev: true
@@ -6881,8 +7100,8 @@ packages:
inherits: 2.0.4
is-arguments: 1.1.1
is-generator-function: 1.0.10
- is-typed-array: 1.1.12
- which-typed-array: 1.1.13
+ is-typed-array: 1.1.13
+ which-typed-array: 1.1.14
dev: true
/utils-merge@1.0.1:
@@ -6903,7 +7122,7 @@ packages:
resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==}
engines: {node: '>=10.12.0'}
dependencies:
- '@jridgewell/trace-mapping': 0.3.22
+ '@jridgewell/trace-mapping': 0.3.23
'@types/istanbul-lib-coverage': 2.0.6
convert-source-map: 2.0.0
dev: true
@@ -6920,8 +7139,8 @@ packages:
engines: {node: '>= 0.8'}
dev: true
- /vite-node@1.2.1(@types/node@20.11.6):
- resolution: {integrity: sha512-fNzHmQUSOY+y30naohBvSW7pPn/xn3Ib/uqm+5wAJQJiqQsU0NBR78XdRJb04l4bOFKjpTWld0XAfkKlrDbySg==}
+ /vite-node@1.3.1(@types/node@20.11.24):
+ resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
dependencies:
@@ -6929,7 +7148,7 @@ packages:
debug: 4.3.4
pathe: 1.1.2
picocolors: 1.0.0
- vite: 5.0.12(@types/node@20.11.6)
+ vite: 5.1.4(@types/node@20.11.24)
transitivePeerDependencies:
- '@types/node'
- less
@@ -6941,8 +7160,8 @@ packages:
- terser
dev: true
- /vite@5.0.12(@types/node@20.11.6):
- resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==}
+ /vite@5.1.4(@types/node@20.11.24):
+ resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@@ -6969,23 +7188,23 @@ packages:
terser:
optional: true
dependencies:
- '@types/node': 20.11.6
+ '@types/node': 20.11.24
esbuild: 0.19.12
- postcss: 8.4.33
- rollup: 4.9.6
+ postcss: 8.4.35
+ rollup: 4.12.0
optionalDependencies:
fsevents: 2.3.3
dev: true
- /vitest@1.2.1(@types/node@20.11.6):
- resolution: {integrity: sha512-TRph8N8rnSDa5M2wKWJCMnztCZS9cDcgVTQ6tsTFTG/odHJ4l5yNVqvbeDJYJRZ6is3uxaEpFs8LL6QM+YFSdA==}
+ /vitest@1.3.1(@types/node@20.11.24):
+ resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
'@edge-runtime/vm': '*'
'@types/node': ^18.0.0 || >=20.0.0
- '@vitest/browser': ^1.0.0
- '@vitest/ui': ^1.0.0
+ '@vitest/browser': 1.3.1
+ '@vitest/ui': 1.3.1
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
@@ -7002,27 +7221,26 @@ packages:
jsdom:
optional: true
dependencies:
- '@types/node': 20.11.6
- '@vitest/expect': 1.2.1
- '@vitest/runner': 1.2.1
- '@vitest/snapshot': 1.2.1
- '@vitest/spy': 1.2.1
- '@vitest/utils': 1.2.1
+ '@types/node': 20.11.24
+ '@vitest/expect': 1.3.1
+ '@vitest/runner': 1.3.1
+ '@vitest/snapshot': 1.3.1
+ '@vitest/spy': 1.3.1
+ '@vitest/utils': 1.3.1
acorn-walk: 8.3.2
- cac: 6.7.14
chai: 4.4.1
debug: 4.3.4
execa: 8.0.1
local-pkg: 0.5.0
- magic-string: 0.30.5
+ magic-string: 0.30.7
pathe: 1.1.2
picocolors: 1.0.0
std-env: 3.7.0
- strip-literal: 1.3.0
+ strip-literal: 2.0.0
tinybench: 2.6.0
tinypool: 0.8.2
- vite: 5.0.12(@types/node@20.11.6)
- vite-node: 1.2.1(@types/node@20.11.6)
+ vite: 5.1.4(@types/node@20.11.24)
+ vite-node: 1.3.1(@types/node@20.11.24)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
@@ -7048,15 +7266,15 @@ packages:
is-symbol: 1.0.4
dev: true
- /which-typed-array@1.1.13:
- resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==}
+ /which-typed-array@1.1.14:
+ resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==}
engines: {node: '>= 0.4'}
dependencies:
- available-typed-arrays: 1.0.5
- call-bind: 1.0.5
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
for-each: 0.3.3
gopd: 1.0.1
- has-tostringtag: 1.0.0
+ has-tostringtag: 1.0.2
dev: true
/which@2.0.2:
@@ -7092,9 +7310,10 @@ packages:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
- /yaml@2.3.4:
- resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
+ /yaml@2.4.0:
+ resolution: {integrity: sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==}
engines: {node: '>= 14'}
+ hasBin: true
dev: true
/yocto-queue@0.1.0:
diff --git a/src/app.ts b/src/app.ts
index b7241c93..6bd5ad20 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -1,4 +1,5 @@
-import { withoutTrailingSlash } from "ufo";
+import { joinURL, parseURL, withoutTrailingSlash } from "ufo";
+import type { AdapterOptions as WSOptions } from "crossws";
import {
lazyEventHandler,
toEventHandler,
@@ -16,7 +17,11 @@ import {
isWebResponse,
sendNoContent,
} from "./utils";
-import type { EventHandler, LazyEventHandler } from "./types";
+import type {
+ EventHandler,
+ EventHandlerResolver,
+ LazyEventHandler,
+} from "./types";
export interface Layer {
route: string;
@@ -47,6 +52,8 @@ export interface AppUse {
(options: InputLayer): App;
}
+export type WebSocketOptions = WSOptions;
+
export interface AppOptions {
debug?: boolean;
onError?: (error: H3Error, event: H3Event) => any;
@@ -59,6 +66,7 @@ export interface AppOptions {
event: H3Event,
response?: { body?: unknown },
) => void | Promise;
+ websocket?: WebSocketOptions;
}
export interface App {
@@ -66,18 +74,35 @@ export interface App {
handler: EventHandler;
options: AppOptions;
use: AppUse;
+ resolve: EventHandlerResolver;
+ readonly websocket: WebSocketOptions;
}
+/**
+ * Create a new H3 app instance.
+ */
export function createApp(options: AppOptions = {}): App {
const stack: Stack = [];
+
const handler = createAppEventHandler(stack, options);
+
+ const resolve = createResolver(stack);
+ handler.__resolve__ = resolve;
+
+ const getWebsocket = cachedFn(() => websocketOptions(resolve, options));
+
const app: App = {
- // @ts-ignore
+ // @ts-expect-error
use: (arg1, arg2, arg3) => use(app as App, arg1, arg2, arg3),
+ resolve,
handler,
stack,
options,
+ get websocket() {
+ return getWebsocket();
+ },
};
+
return app;
}
@@ -100,9 +125,7 @@ export function use(
normalizeLayer({ ...arg3, route: arg1, handler: arg2 as EventHandler }),
);
} else if (typeof arg1 === "function") {
- app.stack.push(
- normalizeLayer({ ...arg2, route: "/", handler: arg1 as EventHandler }),
- );
+ app.stack.push(normalizeLayer({ ...arg2, handler: arg1 as EventHandler }));
} else {
app.stack.push(normalizeLayer({ ...arg1 }));
}
@@ -187,6 +210,37 @@ export function createAppEventHandler(stack: Stack, options: AppOptions) {
});
}
+function createResolver(stack: Stack): EventHandlerResolver {
+ return async (path: string) => {
+ let _layerPath: string;
+ for (const layer of stack) {
+ if (layer.route === "/" && !layer.handler.__resolve__) {
+ continue;
+ }
+ if (!path.startsWith(layer.route)) {
+ continue;
+ }
+ _layerPath = path.slice(layer.route.length) || "/";
+ if (layer.match && !layer.match(_layerPath, undefined)) {
+ continue;
+ }
+ let res = { route: layer.route, handler: layer.handler };
+ if (res.handler.__resolve__) {
+ const _res = await res.handler.__resolve__(_layerPath);
+ if (!_res) {
+ continue;
+ }
+ res = {
+ ...res,
+ ..._res,
+ route: joinURL(res.route || "/", _res.route || "/"),
+ };
+ }
+ return res;
+ }
+ };
+}
+
function normalizeLayer(input: InputLayer) {
let handler = input.handler;
// @ts-ignore
@@ -271,3 +325,27 @@ function handleHandlerResponse(event: H3Event, val: any, jsonSpace?: number) {
statusMessage: `[h3] Cannot send ${valType} as response.`,
});
}
+
+function cachedFn(fn: () => T): () => T {
+ let cache: T;
+ return () => {
+ if (!cache) {
+ cache = fn();
+ }
+ return cache;
+ };
+}
+
+function websocketOptions(
+ evResolver: EventHandlerResolver,
+ appOptions: AppOptions,
+): WSOptions {
+ return {
+ ...appOptions.websocket,
+ async resolve(info) {
+ const { pathname } = parseURL(info.url || "/");
+ const resolved = await evResolver(pathname);
+ return resolved?.handler?.__websocket__ || {};
+ },
+ };
+}
diff --git a/src/event/utils.ts b/src/event/utils.ts
index 24ee2b1e..277be5bc 100644
--- a/src/event/utils.ts
+++ b/src/event/utils.ts
@@ -47,7 +47,8 @@ export function defineEventHandler<
): EventHandler {
// Function Syntax
if (typeof handler === "function") {
- return Object.assign(handler, { __is_handler__: true });
+ handler.__is_handler__ = true;
+ return handler;
}
// Object Syntax
const _hooks: _EventHandlerHooks = {
@@ -57,7 +58,10 @@ export function defineEventHandler<
const _handler: EventHandler = (event) => {
return _callHandler(event, handler.handler, _hooks);
};
- return Object.assign(_handler, { __is_handler__: true });
+ _handler.__is_handler__ = true;
+ _handler.__resolve__ = handler.handler.__resolve__;
+ _handler.__websocket__ = handler.websocket;
+ return _handler;
}
function _normalizeArray(input?: T | T[]): T[] | undefined {
@@ -148,8 +152,9 @@ export function dynamicEventHandler(
export function defineLazyEventHandler(
factory: T,
): Awaited> {
- let _promise: Promise;
- let _resolved: EventHandler;
+ let _promise: Promise;
+ let _resolved: { handler: EventHandler };
+
const resolveHandler = () => {
if (_resolved) {
return Promise.resolve(_resolved);
@@ -163,17 +168,22 @@ export function defineLazyEventHandler(
handler,
);
}
- _resolved = toEventHandler(r.default || r);
+ _resolved = { handler: toEventHandler(r.default || r) };
return _resolved;
});
}
return _promise;
};
- return eventHandler((event) => {
+
+ const handler = eventHandler((event) => {
if (_resolved) {
- return _resolved(event);
+ return _resolved.handler(event);
}
- return resolveHandler().then((handler) => handler(event));
+ return resolveHandler().then((r) => r.handler(event));
}) as Awaited>;
+
+ handler.__resolve__ = resolveHandler;
+
+ return handler;
}
export const lazyEventHandler = defineLazyEventHandler;
diff --git a/src/router.ts b/src/router.ts
index 424becca..8a691b8e 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -3,6 +3,7 @@ import {
toRouteMatcher,
RouteMatcher,
} from "radix3";
+import { withLeadingSlash } from "ufo";
import type { HTTPMethod, EventHandler } from "./types";
import { createError } from "./error";
import { eventHandler, toEventHandler } from "./event";
@@ -44,6 +45,9 @@ export interface CreateRouterOptions {
preemptive?: boolean;
}
+/**
+ * Create a new h3 router instance.
+ */
export function createRouter(opts: CreateRouterOptions = {}): Router {
const _router = _createRouter({});
const routes: Record = {};
@@ -79,10 +83,9 @@ export function createRouter(opts: CreateRouterOptions = {}): Router {
router[method] = (path, handle) => router.add(path, handle, method);
}
- // Main handle
- router.handler = eventHandler((event) => {
+ // Handler matcher
+ const matchHandler = (path = "/", method: RouterMethod = "get") => {
// Remove query parameters for matching
- let path = event.path || "/";
const qIndex = path.indexOf("?");
if (qIndex !== -1) {
path = path.slice(0, Math.max(0, qIndex));
@@ -91,26 +94,20 @@ export function createRouter(opts: CreateRouterOptions = {}): Router {
// Match route
const matched = _router.lookup(path);
if (!matched || !matched.handlers) {
- if (opts.preemptive || opts.preemtive) {
- throw createError({
+ return {
+ error: createError({
statusCode: 404,
name: "Not Found",
- statusMessage: `Cannot find any route matching ${event.path || "/"}.`,
- });
- } else {
- return; // Let app match other handlers
- }
+ statusMessage: `Cannot find any route matching ${path || "/"}.`,
+ }),
+ };
}
// Match method
- const method = (
- event.node.req.method || "get"
- ).toLowerCase() as RouterMethod;
-
let handler: EventHandler | undefined =
matched.handlers[method] || matched.handlers.all;
- // Fallback to search for shadowed routes
+ // Fallback to search for (method) shadowed routes
if (!handler) {
if (!_matcher) {
_matcher = toRouteMatcher(_router);
@@ -131,32 +128,71 @@ export function createRouter(opts: CreateRouterOptions = {}): Router {
}
}
- // Method not matched
if (!handler) {
- if (opts.preemptive || opts.preemtive) {
- throw createError({
+ return {
+ error: createError({
statusCode: 405,
name: "Method Not Allowed",
statusMessage: `Method ${method} is not allowed on this route.`,
- });
+ }),
+ };
+ }
+
+ return { matched, handler };
+ };
+
+ // Main handle
+ const isPreemptive = opts.preemptive || opts.preemtive;
+ router.handler = eventHandler((event) => {
+ // Match handler
+ const match = matchHandler(
+ event.path,
+ event.method.toLowerCase() as RouterMethod,
+ );
+
+ // No match (method or route)
+ if ("error" in match) {
+ if (isPreemptive) {
+ throw match.error;
} else {
return; // Let app match other handlers
}
}
// Add matched route and params to the context
- event.context.matchedRoute = matched;
- const params = matched.params || {};
+ event.context.matchedRoute = match.matched;
+ const params = match.matched.params || {};
event.context.params = params;
// Call handler
- return Promise.resolve(handler(event)).then((res) => {
- if (res === undefined && (opts.preemptive || opts.preemtive)) {
+ return Promise.resolve(match.handler(event)).then((res) => {
+ if (res === undefined && isPreemptive) {
return null; // Send empty content
}
return res;
});
});
+ // Resolver
+ router.handler.__resolve__ = async (path) => {
+ path = withLeadingSlash(path);
+ const match = matchHandler(path);
+ if ("error" in match) {
+ return;
+ }
+ let res = {
+ route: match.matched.path,
+ handler: match.handler,
+ };
+ if (match.handler.__resolve__) {
+ const _res = await match.handler.__resolve__(path);
+ if (!_res) {
+ return;
+ }
+ res = { ...res, ..._res };
+ }
+ return res;
+ };
+
return router;
}
diff --git a/src/types.ts b/src/types.ts
index 1c664df3..7116c475 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,4 +1,5 @@
import type { QueryObject } from "ufo";
+import type { Hooks as WSHooks } from "crossws";
import type { H3Event } from "./event";
import type { Session } from "./utils/session";
import type { RouteNode } from "./router";
@@ -62,11 +63,19 @@ export type InferEventInput<
T,
> = void extends T ? (Event extends H3Event ? E[Key] : never) : T;
+type MaybePromise = T | Promise;
+
+export type EventHandlerResolver = (
+ path: string,
+) => MaybePromise;
+
export interface EventHandler<
Request extends EventHandlerRequest = EventHandlerRequest,
Response extends EventHandlerResponse = EventHandlerResponse,
> {
__is_handler__?: true;
+ __resolve__?: EventHandlerResolver;
+ __websocket__?: Partial;
(event: H3Event): Response;
}
@@ -90,6 +99,8 @@ export type EventHandlerObject<
onBeforeResponse?:
| _ResponseMiddleware
| _ResponseMiddleware[];
+ /** @experimental */
+ websocket?: Partial;
handler: EventHandler;
};
diff --git a/src/utils/body.ts b/src/utils/body.ts
index ff7f6171..f83ee25f 100644
--- a/src/utils/body.ts
+++ b/src/utils/body.ts
@@ -25,6 +25,12 @@ const PayloadMethods: HTTPMethod[] = ["PATCH", "POST", "PUT", "DELETE"];
/**
* Reads body of the request and returns encoded raw string (default), or `Buffer` if encoding is falsy.
+ *
+ * @example
+ * export default defineEventHandler(async (event) => {
+ * const body = await readRawBody(event, "utf-8");
+ * });
+ *
* @param event {H3Event} H3 event or req passed by h3 handler
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.
*
@@ -128,14 +134,16 @@ export function readRawBody(
/**
* Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
+ *
+ * @example
+ * export default defineEventHandler(async (event) => {
+ * const body = await readBody(event);
+ * });
+ *
* @param event H3 event passed by h3 handler
* @param encoding The character encoding to use, defaults to 'utf-8'.
*
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body
- *
- * ```ts
- * const body = await readBody(event)
- * ```
*/
export async function readBody<
@@ -170,23 +178,28 @@ export async function readBody<
/**
* Tries to read the request body via `readBody`, then uses the provided validation function and either throws a validation error or returns the result.
+ *
+ * You can use a simple function to validate the body or use a library like `zod` to define a schema.
+ *
+ * @example
+ * export default defineEventHandler(async (event) => {
+ * const body = await readValidatedBody(event, (body) => {
+ * return typeof body === "object" && body !== null;
+ * });
+ * });
+ * @example
+ * import { z } from "zod";
+ *
+ * export default defineEventHandler(async (event) => {
+ * const objectSchema = z.object();
+ * const body = await readValidatedBody(event, objectSchema.safeParse);
+ * });
+ *
* @param event The H3Event passed by the handler.
* @param validate The function to use for body validation. It will be called passing the read request body. If the result is not false, the parsed body will be returned.
* @throws If the validation function returns `false` or throws, a validation error will be thrown.
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body.
* @see {readBody}
- *
- * ```ts
- * // With a custom validation function
- * const body = await readValidatedBody(event, (body) => {
- * return typeof body === "object" && body !== null
- * })
- *
- * // With a zod schema
- * import { z } from 'zod'
- * const objectSchema = z.object()
- * const body = await readValidatedBody(event, objectSchema.safeParse)
- * ```
*/
export async function readValidatedBody<
T,
@@ -199,24 +212,26 @@ export async function readValidatedBody<
/**
* Tries to read and parse the body of a an H3Event as multipart form.
+ *
+ * @example
+ * export default defineEventHandler(async (event) => {
+ * const formData = await readMultipartFormData(event);
+ * // The result could look like:
+ * // [
+ * // {
+ * // "data": "other",
+ * // "name": "baz",
+ * // },
+ * // {
+ * // "data": "something",
+ * // "name": "some-other-data",
+ * // },
+ * // ];
+ * });
+ *
* @param event The H3Event object to read multipart form from.
*
* @return The parsed form data. If no form could be detected because the content type is not multipart/form-data or no boundary could be found.
- *
- * ```ts
- * const formData = await readMultipartFormData(event)
- * // The result could look like:
- * // [
- * // {
- * // "data": "other",
- * // "name": "baz",
- * // },
- * // {
- * // "data": "something",
- * // "name": "some-other-data",
- * // },
- * // ]
- * ```
*/
export async function readMultipartFormData(
event: H3Event,
@@ -238,15 +253,15 @@ export async function readMultipartFormData(
/**
* Constructs a FormData object from an event, after converting it to a a web request.
- * @param event The H3Event object to read the form data from.
*
- * ```ts
- * const eventHandler = event => {
- * const formData = await readFormData(event)
- * const email = formData.get("email")
- * const password = formData.get("password")
- * }
- * ```
+ * @example
+ * export default defineEventHandler(async (event) => {
+ * const formData = await readFormData(event);
+ * const email = formData.get("email");
+ * const password = formData.get("password");
+ * });
+ *
+ * @param event The H3Event object to read the form data from.
*/
export async function readFormData(event: H3Event): Promise {
return await toWebRequest(event).formData();
diff --git a/src/utils/cookie.ts b/src/utils/cookie.ts
index 98ca9beb..1dc48c30 100644
--- a/src/utils/cookie.ts
+++ b/src/utils/cookie.ts
@@ -79,13 +79,16 @@ export function deleteCookie(
}
/**
- * Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
- * that are within a single set-cookie field-value, such as in the Expires portion.
+ * Set-Cookie header field-values are sometimes comma joined in one string.
+ *
+ * This splits them without choking on commas that are within a single set-cookie field-value, such as in the Expires portion.
* This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
- * Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
+ * Node.js does this for every header _except_ set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
* Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
* Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
* @source https://github.com/nfriedly/set-cookie-parser/blob/3eab8b7d5d12c8ed87832532861c1a35520cf5b3/lib/set-cookie.js#L144
+ *
+ * @internal
*/
export function splitCookiesString(cookiesString: string | string[]): string[] {
if (Array.isArray(cookiesString)) {
diff --git a/src/utils/cors/handler.ts b/src/utils/cors/handler.ts
index 82d18216..10ce3fa8 100644
--- a/src/utils/cors/handler.ts
+++ b/src/utils/cors/handler.ts
@@ -8,6 +8,13 @@ import {
} from "./utils";
import type { H3CorsOptions } from "./types";
+/**
+ * Handle CORS for the incoming request.
+ *
+ * If the incoming request is a CORS preflight request, it will append the CORS preflight headers and send a 204 response.
+ *
+ * If return value is `true`, the request is handled and no further action is needed.
+ */
export function handleCors(event: H3Event, options: H3CorsOptions): boolean {
const _options = resolveCorsOptions(options);
if (isPreflightRequest(event)) {
diff --git a/src/utils/cors/utils.ts b/src/utils/cors/utils.ts
index b8316002..b4900c63 100644
--- a/src/utils/cors/utils.ts
+++ b/src/utils/cors/utils.ts
@@ -13,6 +13,9 @@ import type {
H3AccessControlMaxAgeHeader,
} from "./types";
+/**
+ * Resolve CORS options.
+ */
export function resolveCorsOptions(
options: H3CorsOptions = {},
): H3ResolvedCorsOptions {
@@ -31,6 +34,9 @@ export function resolveCorsOptions(
return defu(options, defaultOptions);
}
+/**
+ * Check if the incoming request is a CORS preflight request.
+ */
export function isPreflightRequest(event: H3Event): boolean {
const origin = getRequestHeader(event, "origin");
const accessControlRequestMethod = getRequestHeader(
@@ -41,6 +47,9 @@ export function isPreflightRequest(event: H3Event): boolean {
return event.method === "OPTIONS" && !!origin && !!accessControlRequestMethod;
}
+/**
+ * Check if the incoming request is a CORS request.
+ */
export function isCorsOriginAllowed(
origin: ReturnType["origin"],
options: H3CorsOptions,
@@ -69,6 +78,9 @@ export function isCorsOriginAllowed(
return originOption(origin);
}
+/**
+ * Create the `access-control-allow-origin` header.
+ */
export function createOriginHeaders(
event: H3Event,
options: H3CorsOptions,
@@ -89,6 +101,9 @@ export function createOriginHeaders(
: {};
}
+/**
+ * Create the `access-control-allow-methods` header.
+ */
export function createMethodsHeaders(
options: H3CorsOptions,
): H3AccessControlAllowMethodsHeader {
@@ -107,6 +122,9 @@ export function createMethodsHeaders(
: {};
}
+/**
+ * Create the `access-control-allow-credentials` header.
+ */
export function createCredentialsHeaders(
options: H3CorsOptions,
): H3AccessControlAllowCredentialsHeader {
@@ -119,6 +137,9 @@ export function createCredentialsHeaders(
return {};
}
+/**
+ * Create the `access-control-allow-headers` and `vary` headers.
+ */
export function createAllowHeaderHeaders(
event: H3Event,
options: H3CorsOptions,
@@ -142,6 +163,9 @@ export function createAllowHeaderHeaders(
};
}
+/**
+ * Create the `access-control-expose-headers` header.
+ */
export function createExposeHeaders(
options: H3CorsOptions,
): H3AccessControlExposeHeadersHeader {
@@ -158,6 +182,9 @@ export function createExposeHeaders(
return { "access-control-expose-headers": exposeHeaders.join(",") };
}
+/**
+ * Create the `access-control-max-age` header.
+ */
export function createMaxAgeHeader(
options: H3CorsOptions,
): H3AccessControlMaxAgeHeader {
@@ -170,8 +197,9 @@ export function createMaxAgeHeader(
return {};
}
-// TODO: Implemente e2e tests to improve code coverage
-/* c8 ignore start */
+/**
+ * Append CORS preflight headers to the response.
+ */
export function appendCorsPreflightHeaders(
event: H3Event,
options: H3CorsOptions,
@@ -182,13 +210,12 @@ export function appendCorsPreflightHeaders(
appendHeaders(event, createMethodsHeaders(options));
appendHeaders(event, createAllowHeaderHeaders(event, options));
}
-/* c8 ignore end */
-// TODO: Implemente e2e tests to improve code coverage
-/* c8 ignore start */
+/**
+ * Append CORS headers to the response.
+ */
export function appendCorsHeaders(event: H3Event, options: H3CorsOptions) {
appendHeaders(event, createOriginHeaders(event, options));
appendHeaders(event, createCredentialsHeaders(options));
appendHeaders(event, createExposeHeaders(options));
}
-/* c8 ignore end */
diff --git a/src/utils/fingerprint.ts b/src/utils/fingerprint.ts
index 7cbd11df..2b729e02 100644
--- a/src/utils/fingerprint.ts
+++ b/src/utils/fingerprint.ts
@@ -22,7 +22,12 @@ export interface RequestFingerprintOptions {
userAgent?: boolean;
}
-/** @experimental Behavior of this utility might change in the future versions */
+/**
+ *
+ * Get a unique fingerprint for the incoming request.
+ *
+ * @experimental Behavior of this utility might change in the future versions
+ */
export async function getRequestFingerprint(
event: H3Event,
opts: RequestFingerprintOptions = {},
diff --git a/src/utils/index.ts b/src/utils/index.ts
index f24486b1..9e788463 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -10,4 +10,6 @@ export * from "./request";
export * from "./response";
export * from "./sanitize";
export * from "./session";
+export * from "./sse";
export * from "./static";
+export * from "./ws";
diff --git a/src/utils/internal/iteratable.ts b/src/utils/internal/iteratable.ts
new file mode 100644
index 00000000..68f9aa2b
--- /dev/null
+++ b/src/utils/internal/iteratable.ts
@@ -0,0 +1,64 @@
+export type IterationSource =
+ | Iterable
+ | AsyncIterable
+ | Iterator
+ | AsyncIterator
+ | (() =>
+ | Iterator
+ | AsyncIterator);
+
+type SendableValue = string | Buffer | Uint8Array;
+export type IteratorSerializer = (
+ value: Value,
+) => SendableValue | undefined;
+
+/**
+ * The default implementation for {@link sendIterable}'s `serializer` argument.
+ * It serializes values as follows:
+ * - Instances of {@link String}, {@link Uint8Array} and `undefined` are returned as-is.
+ * - Objects are serialized through {@link JSON.stringify}.
+ * - Functions are serialized as `undefined`.
+ * - Values of type boolean, number, bigint or symbol are serialized using their `toString` function.
+ *
+ * @param value - The value to serialize to either a string or Uint8Array.
+ */
+export function serializeIterableValue(
+ value: unknown,
+): SendableValue | undefined {
+ switch (typeof value) {
+ case "string": {
+ return value;
+ }
+ case "boolean":
+ case "number":
+ case "bigint":
+ case "symbol": {
+ return value.toString();
+ }
+ case "function":
+ case "undefined": {
+ return undefined;
+ }
+ case "object": {
+ if (value instanceof Uint8Array) {
+ return value;
+ }
+ return JSON.stringify(value);
+ }
+ }
+}
+
+export function coerceIterable(
+ iterable: IterationSource,
+): Iterator | AsyncIterator {
+ if (typeof iterable === "function") {
+ iterable = iterable();
+ }
+ if (Symbol.iterator in iterable) {
+ return iterable[Symbol.iterator]();
+ }
+ if (Symbol.asyncIterator in iterable) {
+ return iterable[Symbol.asyncIterator]();
+ }
+ return iterable;
+}
diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts
index 0ec623bc..9aded1e2 100644
--- a/src/utils/proxy.ts
+++ b/src/utils/proxy.ts
@@ -31,6 +31,9 @@ const ignoredHeaders = new Set([
"accept",
]);
+/**
+ * Proxy the incoming request to a target URL.
+ */
export async function proxyRequest(
event: H3Event,
target: string,
@@ -70,6 +73,9 @@ export async function proxyRequest(
});
}
+/**
+ * Make a proxy request to a target URL and send the response back to the client.
+ */
export async function sendProxy(
event: H3Event,
target: string,
@@ -154,6 +160,9 @@ export async function sendProxy(
return event.node.res.end();
}
+/**
+ * Get the request headers object without headers known to cause issues when proxying.
+ */
export function getProxyRequestHeaders(event: H3Event) {
const headers = Object.create(null);
const reqHeaders = getRequestHeaders(event);
@@ -165,6 +174,9 @@ export function getProxyRequestHeaders(event: H3Event) {
return headers;
}
+/**
+ * Make a fetch request with the event's context and headers.
+ */
export function fetchWithEvent<
T = unknown,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
diff --git a/src/utils/request.ts b/src/utils/request.ts
index 6f033a51..80219c68 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -10,6 +10,9 @@ import type { H3Event } from "../event";
import { validateData, ValidateFunction } from "./internal/validate";
import { getRequestWebStream } from "./body";
+/**
+ * Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
+ */
export function getQuery<
T,
Event extends H3Event = H3Event,
@@ -18,6 +21,9 @@ export function getQuery<
return _getQuery(event.path || "") as _T;
}
+/**
+ * Get the query param from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
+ */
export function getValidatedQuery<
T,
Event extends H3Event = H3Event,
@@ -27,6 +33,11 @@ export function getValidatedQuery<
return validateData(query, validate);
}
+/**
+ * Get matched route params.
+ *
+ * If `decode` option is `true`, it will decode the matched route params using `decodeURI`.
+ */
export function getRouterParams(
event: H3Event,
opts: { decode?: boolean } = {},
@@ -43,6 +54,9 @@ export function getRouterParams(
return params;
}
+/**
+ * Get matched route params and validate with validate function.
+ */
export function getValidatedRouterParams<
T,
Event extends H3Event = H3Event,
@@ -57,6 +71,9 @@ export function getValidatedRouterParams<
return validateData(routerParams, validate);
}
+/**
+ * Get a matched route param by name.
+ */
export function getRouterParam(
event: H3Event,
name: string,
@@ -77,6 +94,13 @@ export function getMethod(
return (event.node.req.method || defaultMethod).toUpperCase() as HTTPMethod;
}
+/**
+ *
+ * Checks if the incoming request method is of the expected type.
+ *
+ * If `allowHead` is `true`, it will allow `HEAD` requests to pass if the expected method is `GET`.
+ *
+ */
export function isMethod(
event: H3Event,
expected: HTTPMethod | HTTPMethod[],
@@ -97,6 +121,11 @@ export function isMethod(
return false;
}
+/**
+ * Asserts that the incoming request method is of the expected type using `isMethod`.
+ *
+ * If the method is not allowed, it will throw a 405 error with the message "HTTP method is not allowed".
+ */
export function assertMethod(
event: H3Event,
expected: HTTPMethod | HTTPMethod[],
@@ -110,6 +139,11 @@ export function assertMethod(
}
}
+/**
+ * Get the request headers object.
+ *
+ * Array headers are joined with a comma.
+ */
export function getRequestHeaders(event: H3Event): RequestHeaders {
const _headers: RequestHeaders = {};
for (const key in event.node.req.headers) {
@@ -119,8 +153,14 @@ export function getRequestHeaders(event: H3Event): RequestHeaders {
return _headers;
}
+/**
+ * Alias for `getRequestHeaders`.
+ */
export const getHeaders = getRequestHeaders;
+/**
+ * Get a request header by name.
+ */
export function getRequestHeader(
event: H3Event,
name: HTTPHeaderName,
@@ -130,8 +170,18 @@ export function getRequestHeader(
return value;
}
+/**
+ * Alias for `getRequestHeader`.
+ */
export const getHeader = getRequestHeader;
+/**
+ * Get the request hostname.
+ *
+ * If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
+ *
+ * If no host header is found, it will default to "localhost".
+ */
export function getRequestHost(
event: H3Event,
opts: { xForwardedHost?: boolean } = {},
@@ -145,6 +195,13 @@ export function getRequestHost(
return event.node.req.headers.host || "localhost";
}
+/**
+ * Get the request protocol.
+ *
+ * If `x-forwarded-proto` header is set to "https", it will return "https". You can disable this behavior by setting `xForwardedProto` to `false`.
+ *
+ * If protocol cannot be determined, it will default to "http".
+ */
export function getRequestProtocol(
event: H3Event,
opts: { xForwardedProto?: boolean } = {},
@@ -159,12 +216,20 @@ export function getRequestProtocol(
}
const DOUBLE_SLASH_RE = /[/\\]{2,}/g;
+
/** @deprecated Use `event.path` instead */
export function getRequestPath(event: H3Event): string {
const path = (event.node.req.url || "/").replace(DOUBLE_SLASH_RE, "/");
return path;
}
+/**
+ * Generated the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
+ *
+ * If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
+ *
+ * If `xForwardedProto` is `false`, it will not use the `x-forwarded-proto` header.
+ */
export function getRequestURL(
event: H3Event,
opts: { xForwardedHost?: boolean; xForwardedProto?: boolean } = {},
@@ -178,6 +243,11 @@ export function getRequestURL(
return new URL(path, `${protocol}://${host}`);
}
+/**
+ * Convert the H3Event to a WebRequest object.
+ *
+ * **NOTE:** This function is not stable and might have edge cases that are not handled properly.
+ */
export function toWebRequest(event: H3Event) {
return (
event.web?.request ||
@@ -191,6 +261,11 @@ export function toWebRequest(event: H3Event) {
);
}
+/**
+ * Try to get the client IP address from the incoming request.
+ *
+ * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.
+ */
export function getRequestIP(
event: H3Event,
opts: {
diff --git a/src/utils/response.ts b/src/utils/response.ts
index 4f2019f1..8ee1fa19 100644
--- a/src/utils/response.ts
+++ b/src/utils/response.ts
@@ -7,10 +7,22 @@ import { MIMES } from "./consts";
import { sanitizeStatusCode, sanitizeStatusMessage } from "./sanitize";
import { splitCookiesString } from "./cookie";
import { hasProp } from "./internal/object";
+import {
+ serializeIterableValue,
+ coerceIterable,
+ IterationSource,
+ IteratorSerializer,
+} from "./internal/iteratable";
const defer =
typeof setImmediate === "undefined" ? (fn: () => any) => fn() : setImmediate;
+/**
+ * Directly send a response to the client.
+ *
+ * **Note:** This function should be used only when you want to send a response directly without using the `h3` event.
+ * Normaly you can directly `return` a value inside event handlers.
+ */
export function send(event: H3Event, data?: any, type?: string): Promise {
if (type) {
defaultContentType(event, type);
@@ -27,6 +39,7 @@ export function send(event: H3Event, data?: any, type?: string): Promise {
/**
* Respond with an empty payload.
+ *
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.
*
* @param event H3 event
@@ -51,6 +64,9 @@ export function sendNoContent(event: H3Event, code?: number) {
event.node.res.end();
}
+/**
+ * Set the response status code and message.
+ */
export function setResponseStatus(
event: H3Event,
code?: number,
@@ -67,14 +83,23 @@ export function setResponseStatus(
}
}
+/**
+ * Get the current response status code.
+ */
export function getResponseStatus(event: H3Event): number {
return event.node.res.statusCode;
}
+/**
+ * Get the current response status message.
+ */
export function getResponseStatusText(event: H3Event): string {
return event.node.res.statusMessage;
}
+/**
+ * Set the response status code and message.
+ */
export function defaultContentType(event: H3Event, type?: string) {
if (
type &&
@@ -85,6 +110,13 @@ export function defaultContentType(event: H3Event, type?: string) {
}
}
+/**
+ * Send a redirect response to the client.
+ *
+ * It adds the `location` header to the response and sets the status code to 302 by default.
+ *
+ * In the body, it sends a simple HTML page with a meta refresh tag to redirect the client in case the headers are ignored.
+ */
export function sendRedirect(event: H3Event, location: string, code = 302) {
event.node.res.statusCode = sanitizeStatusCode(
code,
@@ -96,12 +128,18 @@ export function sendRedirect(event: H3Event, location: string, code = 302) {
return send(event, html, MIMES.html);
}
+/**
+ * Get the response headers object.
+ */
export function getResponseHeaders(
event: H3Event,
): ReturnType {
return event.node.res.getHeaders();
}
+/**
+ * Alias for `getResponseHeaders`.
+ */
export function getResponseHeader(
event: H3Event,
name: HTTPHeaderName,
@@ -109,6 +147,9 @@ export function getResponseHeader(
return event.node.res.getHeader(name);
}
+/**
+ * Set the response headers.
+ */
export function setResponseHeaders(
event: H3Event,
headers: Partial<
@@ -120,8 +161,14 @@ export function setResponseHeaders(
}
}
+/**
+ * Alias for `setResponseHeaders`.
+ */
export const setHeaders = setResponseHeaders;
+/**
+ * Set a response header by name.
+ */
export function setResponseHeader(
event: H3Event,
name: HTTPHeaderName,
@@ -130,8 +177,14 @@ export function setResponseHeader(
event.node.res.setHeader(name, value);
}
+/**
+ * Alias for `setResponseHeader`.
+ */
export const setHeader = setResponseHeader;
+/**
+ * Append the response headers.
+ */
export function appendResponseHeaders(
event: H3Event,
headers: Record,
@@ -141,8 +194,14 @@ export function appendResponseHeaders(
}
}
+/**
+ * Alias for `appendResponseHeaders`.
+ */
export const appendHeaders = appendResponseHeaders;
+/**
+ * Append a response header by name.
+ */
export function appendResponseHeader(
event: H3Event,
name: HTTPHeaderName,
@@ -162,6 +221,9 @@ export function appendResponseHeader(
event.node.res.setHeader(name, [...current, value]);
}
+/**
+ * Alias for `appendResponseHeader`.
+ */
export const appendHeader = appendResponseHeader;
/**
@@ -184,6 +246,9 @@ export function clearResponseHeaders(
}
}
+/**
+ * Remove a response header by name.
+ */
export function removeResponseHeader(
event: H3Event,
name: HTTPHeaderName,
@@ -191,6 +256,9 @@ export function removeResponseHeader(
return event.node.res.removeHeader(name);
}
+/**
+ * Checks if the data is a stream. (Node.js Readable Stream, React Pipeable Stream, or Web Stream)
+ */
export function isStream(data: any): data is Readable | ReadableStream {
if (!data || typeof data !== "object") {
return false;
@@ -212,10 +280,18 @@ export function isStream(data: any): data is Readable | ReadableStream {
return false;
}
+/**
+ * Checks if the data is a Response object.
+ */
export function isWebResponse(data: any): data is Response {
return typeof Response !== "undefined" && data instanceof Response;
}
+/**
+ * Send a stream response to the client.
+ *
+ * Note: You can directly `return` a stream value inside event handlers alternatively which is recommended.
+ */
export function sendStream(
event: H3Event,
stream: Readable | ReadableStream,
@@ -288,6 +364,10 @@ export function sendStream(
}
const noop = () => {};
+
+/**
+ * Write `HTTP/1.1 103 Early Hints` to the client.
+ */
export function writeEarlyHints(
event: H3Event,
hints: string | string[] | Record,
@@ -344,6 +424,9 @@ export function writeEarlyHints(
}
}
+/**
+ * Send a Response object to the client.
+ */
export function sendWebResponse(
event: H3Event,
response: Response,
@@ -374,3 +457,67 @@ export function sendWebResponse(
}
return sendStream(event, response.body);
}
+
+/**
+ * Iterate a source of chunks and send back each chunk in order.
+ * Supports mixing async work toghether with emitting chunks.
+ *
+ * Each chunk must be a string or a buffer.
+ *
+ * For generator (yielding) functions, the returned value is treated the same as yielded values.
+ *
+ * @param event - H3 event
+ * @param iterable - Iterator that produces chunks of the response.
+ * @param serializer - Function that converts values from the iterable into stream-compatible values.
+ * @template Value - Test
+ *
+ * @example
+ * sendIterable(event, work());
+ * async function* work() {
+ * // Open document body
+ * yield "\nExecuting...
\n";
+ * // Do work ...
+ * for (let i = 0; i < 1000) {
+ * await delay(1000);
+ * // Report progress
+ * yield `- Completed job #`;
+ * yield i;
+ * yield `
\n`;
+ * }
+ * // Close out the report
+ * return `
`;
+ * }
+ * async function delay(ms) {
+ * return new Promise(resolve => setTimeout(resolve, ms));
+ * }
+ */
+export function sendIterable(
+ event: H3Event,
+ iterable: IterationSource,
+ options?: {
+ serializer: IteratorSerializer;
+ },
+): Promise {
+ const serializer = options?.serializer ?? serializeIterableValue;
+ const iterator = coerceIterable(iterable);
+ return sendStream(
+ event,
+ new ReadableStream({
+ async pull(controller) {
+ const { value, done } = await iterator.next();
+ if (value !== undefined) {
+ const chunk = serializer(value);
+ if (chunk !== undefined) {
+ controller.enqueue(chunk);
+ }
+ }
+ if (done) {
+ controller.close();
+ }
+ },
+ cancel() {
+ iterator.return?.();
+ },
+ }),
+ );
+}
diff --git a/src/utils/route.ts b/src/utils/route.ts
index 6dd74550..cba359f9 100644
--- a/src/utils/route.ts
+++ b/src/utils/route.ts
@@ -4,6 +4,22 @@ import { eventHandler } from "../event";
/**
* Prefixes and executes a handler with a base path.
+ *
+ * @example
+ * const app = createApp();
+ * const router = createRouter();
+ *
+ * const apiRouter = createRouter().get(
+ * "/hello",
+ * defineEventHandler((event) => {
+ * return "Hello API!";
+ * }),
+ * );
+ *
+ * router.use("/api/**", useBase("/api", apiRouter.handler));
+ *
+ * app.use(router.handler);
+ *
* @param base The base path to prefix. When set to an empty string, the handler will be run as is.
* @param handler The event handler to use with the adapted path.
*/
diff --git a/src/utils/sanitize.ts b/src/utils/sanitize.ts
index 278b4c18..21986519 100644
--- a/src/utils/sanitize.ts
+++ b/src/utils/sanitize.ts
@@ -2,10 +2,18 @@
// eslint-disable-next-line no-control-regex
const DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
+/**
+ * Make sure the status message is safe to use in a response.
+ *
+ * Allowed characters: horizontal tabs, spaces or visible ascii characters: https://www.rfc-editor.org/rfc/rfc7230#section-3.1.2
+ */
export function sanitizeStatusMessage(statusMessage = ""): string {
return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
}
+/**
+ * Make sure the status code is a valid HTTP status code.
+ */
export function sanitizeStatusCode(
statusCode?: string | number,
defaultStatusCode = 200,
diff --git a/src/utils/session.ts b/src/utils/session.ts
index e3b726ed..ddd4cc0c 100644
--- a/src/utils/session.ts
+++ b/src/utils/session.ts
@@ -41,6 +41,10 @@ const DEFAULT_COOKIE: SessionConfig["cookie"] = {
httpOnly: true,
};
+/**
+ * Create a session manager for the current request.
+ *
+ */
export async function useSession(
event: H3Event,
config: SessionConfig,
@@ -67,6 +71,9 @@ export async function useSession(
return sessionManager;
}
+/**
+ * Get the session for the current request.
+ */
export async function getSession(
event: H3Event,
config: SessionConfig,
@@ -136,6 +143,9 @@ type SessionUpdate =
| Partial>
| ((oldData: SessionData) => Partial> | undefined);
+/**
+ * Update the session data for the current request.
+ */
export async function updateSession(
event: H3Event,
config: SessionConfig,
@@ -171,6 +181,9 @@ export async function updateSession(
return session;
}
+/**
+ * Encrypt and sign the session data for the current request.
+ */
export async function sealSession(
event: H3Event,
config: SessionConfig,
@@ -191,6 +204,9 @@ export async function sealSession(
return sealed;
}
+/**
+ * Decrypt and verify the session data for the current request.
+ */
export async function unsealSession(
_event: H3Event,
config: SessionConfig,
@@ -215,6 +231,9 @@ export async function unsealSession(
return unsealed;
}
+/**
+ * Clear the session data for the current request.
+ */
export async function clearSession(
event: H3Event,
config: Partial,
diff --git a/src/utils/sse/event-stream.ts b/src/utils/sse/event-stream.ts
new file mode 100644
index 00000000..262a5083
--- /dev/null
+++ b/src/utils/sse/event-stream.ts
@@ -0,0 +1,172 @@
+import type { H3Event } from "../../event";
+import { sendStream, setResponseStatus } from "../response";
+import {
+ formatEventStreamMessage,
+ formatEventStreamMessages,
+ setEventStreamHeaders,
+} from "./utils";
+import { EventStreamMessage, EventStreamOptions } from "./types";
+
+/**
+ * A helper class for [server sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format)
+ */
+export class EventStream {
+ private readonly _h3Event: H3Event;
+ private readonly _transformStream = new TransformStream();
+ private readonly _writer: WritableStreamDefaultWriter;
+ private readonly _encoder: TextEncoder = new TextEncoder();
+
+ private _writerIsClosed = false;
+ private _paused = false;
+ private _unsentData: undefined | string;
+ private _disposed = false;
+ private _handled = false;
+
+ constructor(event: H3Event, opts: EventStreamOptions = {}) {
+ this._h3Event = event;
+ this._writer = this._transformStream.writable.getWriter();
+ this._writer.closed.then(() => {
+ this._writerIsClosed = true;
+ });
+ if (opts.autoclose !== false) {
+ this._h3Event.node.req.on("close", () => this.close());
+ }
+ }
+
+ /**
+ * Publish new event(s) for the client
+ */
+ async push(message: string): Promise;
+ async push(message: string[]): Promise;
+ async push(message: EventStreamMessage): Promise;
+ async push(message: EventStreamMessage[]): Promise;
+ async push(
+ message: EventStreamMessage | EventStreamMessage[] | string | string[],
+ ) {
+ if (typeof message === "string") {
+ await this._sendEvent({ data: message });
+ return;
+ }
+ if (Array.isArray(message)) {
+ if (message.length === 0) {
+ return;
+ }
+ if (typeof message[0] === "string") {
+ const msgs: EventStreamMessage[] = [];
+ for (const item of message as string[]) {
+ msgs.push({ data: item });
+ }
+ await this._sendEvents(msgs);
+ return;
+ }
+ await this._sendEvents(message as EventStreamMessage[]);
+ return;
+ }
+ await this._sendEvent(message);
+ }
+
+ private async _sendEvent(message: EventStreamMessage) {
+ if (this._writerIsClosed) {
+ return;
+ }
+ if (this._paused && !this._unsentData) {
+ this._unsentData = formatEventStreamMessage(message);
+ return;
+ }
+ if (this._paused) {
+ this._unsentData += formatEventStreamMessage(message);
+ return;
+ }
+ await this._writer
+ .write(this._encoder.encode(formatEventStreamMessage(message)))
+ .catch();
+ }
+
+ private async _sendEvents(messages: EventStreamMessage[]) {
+ if (this._writerIsClosed) {
+ return;
+ }
+ const payload = formatEventStreamMessages(messages);
+ if (this._paused && !this._unsentData) {
+ this._unsentData = payload;
+ return;
+ }
+ if (this._paused) {
+ this._unsentData += payload;
+ return;
+ }
+
+ await this._writer.write(this._encoder.encode(payload)).catch();
+ }
+
+ pause() {
+ this._paused = true;
+ }
+
+ get isPaused() {
+ return this._paused;
+ }
+
+ async resume() {
+ this._paused = false;
+ await this.flush();
+ }
+
+ async flush() {
+ if (this._writerIsClosed) {
+ return;
+ }
+ if (this._unsentData?.length) {
+ await this._writer.write(this._encoder.encode(this._unsentData));
+ this._unsentData = undefined;
+ }
+ }
+
+ /**
+ * Close the stream and the connection if the stream is being sent to the client
+ */
+ async close() {
+ if (this._disposed) {
+ return;
+ }
+ if (!this._writerIsClosed) {
+ try {
+ await this._writer.close();
+ } catch {}
+ }
+ // check if the stream has been given to the client before closing the connection
+ if (
+ this._h3Event._handled &&
+ this._handled &&
+ !this._h3Event.node.res.closed
+ ) {
+ this._h3Event.node.res.end();
+ }
+ this._disposed = true;
+ }
+
+ /**
+ * Triggers callback when the writable stream is closed.
+ * It is also triggered after calling the `close()` method.
+ * It also triggers when the request connection has been closed by either the client or the server.
+ */
+ onClosed(cb: () => any) {
+ this._writer.closed.then(cb);
+ this._h3Event.node?.req.on("close", cb);
+ }
+
+ async send() {
+ setEventStreamHeaders(this._h3Event);
+ setResponseStatus(this._h3Event, 200);
+ this._h3Event._handled = true;
+ this._handled = true;
+ await sendStream(this._h3Event, this._transformStream.readable);
+ }
+}
+
+export function isEventStream(input: unknown): input is EventStream {
+ if (typeof input !== "object" || input === null) {
+ return false;
+ }
+ return input instanceof EventStream;
+}
diff --git a/src/utils/sse/index.ts b/src/utils/sse/index.ts
new file mode 100644
index 00000000..9e418d1c
--- /dev/null
+++ b/src/utils/sse/index.ts
@@ -0,0 +1,38 @@
+import type { H3Event } from "../../event";
+import { EventStream } from "./event-stream";
+import { EventStreamOptions } from "./types";
+/**
+ * Initialize an EventStream instance for creating [server sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
+ *
+ * @experimental This function is experimental and might be unstable in some environments.
+ *
+ * @example
+ *
+ * ```ts
+ * import { createEventStream, sendEventStream } from "h3";
+ *
+ * eventHandler((event) => {
+ * const eventStream = createEventStream(event);
+ *
+ * // Send a message every second
+ * const interval = setInterval(async () => {
+ * await eventStream.push("Hello world");
+ * }, 1000);
+ *
+ * // cleanup the interval and close the stream when the connection is terminated
+ * eventStream.onClosed(async () => {
+ * console.log("closing SSE...");
+ * clearInterval(interval);
+ * await eventStream.close();
+ * });
+ *
+ * return eventStream.send();
+ * });
+ * ```
+ */
+export function createEventStream(
+ event: H3Event,
+ opts?: EventStreamOptions,
+): EventStream {
+ return new EventStream(event, opts);
+}
diff --git a/src/utils/sse/types.ts b/src/utils/sse/types.ts
new file mode 100644
index 00000000..6a3f1f15
--- /dev/null
+++ b/src/utils/sse/types.ts
@@ -0,0 +1,18 @@
+export interface EventStreamOptions {
+ /**
+ * Automatically close the writable stream when the request is closed
+ *
+ * Default is `true`
+ */
+ autoclose?: boolean;
+}
+
+/**
+ * See https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields
+ */
+export interface EventStreamMessage {
+ id?: string;
+ event?: string;
+ retry?: number;
+ data: string;
+}
diff --git a/src/utils/sse/utils.ts b/src/utils/sse/utils.ts
new file mode 100644
index 00000000..2a838eb7
--- /dev/null
+++ b/src/utils/sse/utils.ts
@@ -0,0 +1,54 @@
+import { HTTPHeaderName } from "../../types";
+import { H3Event } from "../../event";
+import { getHeader } from "../request";
+import { setResponseHeaders } from "../response";
+import { EventStreamMessage } from "./types";
+
+export function formatEventStreamMessage(message: EventStreamMessage): string {
+ let result = "";
+ if (message.id) {
+ result += `id: ${message.id}\n`;
+ }
+ if (message.event) {
+ result += `event: ${message.event}\n`;
+ }
+ if (typeof message.retry === "number" && Number.isInteger(message.retry)) {
+ result += `retry: ${message.retry}\n`;
+ }
+ result += `data: ${message.data}\n\n`;
+ return result;
+}
+
+export function formatEventStreamMessages(
+ messages: EventStreamMessage[],
+): string {
+ let result = "";
+ for (const msg of messages) {
+ result += formatEventStreamMessage(msg);
+ }
+ return result;
+}
+
+export function setEventStreamHeaders(event: H3Event) {
+ const headers: Partial<
+ Record
+ > = {
+ "Content-Type": "text/event-stream",
+ "Cache-Control":
+ "private, no-cache, no-store, no-transform, must-revalidate, max-age=0",
+ "X-Accel-Buffering": "no", // prevent nginx from buffering the response
+ };
+
+ if (!isHttp2Request(event)) {
+ headers.Connection = "keep-alive";
+ }
+
+ setResponseHeaders(event, headers);
+}
+
+export function isHttp2Request(event: H3Event) {
+ return (
+ getHeader(event, ":path") !== undefined &&
+ getHeader(event, ":method") !== undefined
+ );
+}
diff --git a/src/utils/static.ts b/src/utils/static.ts
index 949e5605..aec9c7b6 100644
--- a/src/utils/static.ts
+++ b/src/utils/static.ts
@@ -60,6 +60,9 @@ export interface ServeStaticOptions {
fallthrough?: boolean;
}
+/**
+ * Dynamically serve static assets based on the request path.
+ */
export async function serveStatic(
event: H3Event,
options: ServeStaticOptions,
@@ -115,6 +118,10 @@ export async function serveStatic(
return false;
}
+ if (meta.etag && !getResponseHeader(event, "etag")) {
+ setResponseHeader(event, "etag", meta.etag);
+ }
+
const ifNotMatch =
meta.etag && getRequestHeader(event, "if-none-match") === meta.etag;
if (ifNotMatch) {
@@ -140,10 +147,6 @@ export async function serveStatic(
setResponseHeader(event, "content-type", meta.type);
}
- if (meta.etag && !getResponseHeader(event, "etag")) {
- setResponseHeader(event, "etag", meta.etag);
- }
-
if (meta.encoding && !getResponseHeader(event, "content-encoding")) {
setResponseHeader(event, "content-encoding", meta.encoding);
}
diff --git a/src/utils/ws.ts b/src/utils/ws.ts
new file mode 100644
index 00000000..74b51958
--- /dev/null
+++ b/src/utils/ws.ts
@@ -0,0 +1,30 @@
+import type { Hooks as WSHooks } from "crossws";
+
+import { createError } from "../error";
+import { defineEventHandler } from "../event";
+
+/**
+ * Define WebSocket hooks.
+ *
+ * @see https://h3.unjs.io/guide/websocket
+ */
+export function defineWebSocket(hooks: Partial): Partial {
+ return hooks;
+}
+
+/**
+ * Define WebSocket event handler.
+ *
+ * @see https://h3.unjs.io/guide/websocket
+ */
+export function defineWebSocketHandler(hooks: Partial) {
+ return defineEventHandler({
+ handler() {
+ throw createError({
+ statusCode: 426,
+ statusMessage: "Upgrade Required",
+ });
+ },
+ websocket: hooks,
+ });
+}
diff --git a/test/iteratable.test.ts b/test/iteratable.test.ts
new file mode 100644
index 00000000..43bc4077
--- /dev/null
+++ b/test/iteratable.test.ts
@@ -0,0 +1,153 @@
+import { ReadableStream } from "node:stream/web";
+import supertest, { SuperTest, Test } from "supertest";
+import { describe, it, expect, beforeEach, vi } from "vitest";
+import {
+ createApp,
+ App,
+ toNodeListener,
+ eventHandler,
+ sendIterable,
+} from "../src";
+import { serializeIterableValue } from "../src/utils/internal/iteratable";
+
+describe("iteratable", () => {
+ let app: App;
+ let request: SuperTest;
+
+ beforeEach(() => {
+ app = createApp({ debug: false });
+ request = supertest(toNodeListener(app));
+ });
+
+ describe("serializeIterableValue", () => {
+ const exampleDate: Date = new Date(Date.UTC(2015, 6, 21, 3, 24, 54, 888));
+ it.each([
+ { value: "Hello, world!", output: "Hello, world!" },
+ { value: 123, output: "123" },
+ { value: 1n, output: "1" },
+ { value: true, output: "true" },
+ { value: false, output: "false" },
+ { value: undefined, output: undefined },
+ { value: null, output: "null" },
+ { value: exampleDate, output: JSON.stringify(exampleDate) },
+ { value: { field: 1 }, output: '{"field":1}' },
+ { value: [1, 2, 3], output: "[1,2,3]" },
+ { value: () => {}, output: undefined },
+ {
+ value: Buffer.from("Hello, world!"),
+ output: Buffer.from("Hello, world!"),
+ },
+ { value: Uint8Array.from([1, 2, 3]), output: Uint8Array.from([1, 2, 3]) },
+ ])("$value => $output", ({ value, output }) => {
+ const serialized = serializeIterableValue(value);
+ expect(serialized).toStrictEqual(output);
+ });
+ });
+
+ describe("sendIterable", () => {
+ it("sends empty body for an empty iterator", async () => {
+ app.use(eventHandler((event) => sendIterable(event, [])));
+ const result = await request.get("/");
+ expect(result.header["content-length"]).toBe("0");
+ expect(result.text).toBe("");
+ });
+
+ it("concatenates iterated values", async () => {
+ app.use(eventHandler((event) => sendIterable(event, ["a", "b", "c"])));
+ const result = await request.get("/");
+ expect(result.text).toBe("abc");
+ });
+
+ describe("iterable support", () => {
+ it.each([
+ { type: "Array", iterable: ["the-value"] },
+ { type: "Set", iterable: new Set(["the-value"]) },
+ {
+ type: "Map.keys()",
+ iterable: new Map([["the-value", "unused"]]).keys(),
+ },
+ {
+ type: "Map.values()",
+ iterable: new Map([["unused", "the-value"]]).values(),
+ },
+ {
+ type: "Iterator object",
+ iterable: { next: () => ({ value: "the-value", done: true }) },
+ },
+ {
+ type: "AsyncIterator object",
+ iterable: {
+ next: () => Promise.resolve({ value: "the-value", done: true }),
+ },
+ },
+ {
+ type: "Generator (yield)",
+ iterable: (function* () {
+ yield "the-value";
+ })(),
+ },
+ {
+ type: "Generator (return)",
+ iterable: (function* () {
+ return "the-value";
+ })(),
+ },
+ {
+ type: "Generator (yield*)",
+ iterable: (function* () {
+ // prettier-ignore
+ yield * ["the-value"];
+ })(),
+ },
+ {
+ type: "AsyncGenerator",
+ iterable: (async function* () {
+ await Promise.resolve();
+ yield "the-value";
+ })(),
+ },
+ {
+ type: "ReadableStream (push-mode)",
+ iterable: new ReadableStream({
+ start(controller) {
+ controller.enqueue("the-value");
+ controller.close();
+ },
+ }),
+ },
+ {
+ type: "ReadableStream (pull-mode)",
+ iterable: new ReadableStream({
+ pull(controller) {
+ controller.enqueue("the-value");
+ controller.close();
+ },
+ }),
+ },
+ ])("$type", async ({ iterable }) => {
+ app.use(eventHandler((event) => sendIterable(event, iterable)));
+ const response = await request.get("/");
+ expect(response.text).toBe("the-value");
+ });
+ });
+
+ describe("serializer argument", () => {
+ it("is called for every value", async () => {
+ const iterable = [1, "2", { field: 3 }, null];
+ const serializer = vi.fn(() => "x");
+
+ app.use(
+ eventHandler((event) =>
+ sendIterable(event, iterable, { serializer }),
+ ),
+ );
+ const response = await request.get("/");
+ expect(response.text).toBe("x".repeat(iterable.length));
+ expect(serializer).toBeCalledTimes(4);
+ for (const [i, obj] of iterable.entries()) {
+ expect.soft(serializer).toHaveBeenNthCalledWith(i + 1, obj);
+ }
+ });
+ });
+ });
+});
diff --git a/test/resolve.test.ts b/test/resolve.test.ts
new file mode 100644
index 00000000..50e4a4d8
--- /dev/null
+++ b/test/resolve.test.ts
@@ -0,0 +1,108 @@
+import { describe, it, expect } from "vitest";
+import {
+ createApp,
+ createRouter,
+ eventHandler,
+ lazyEventHandler,
+} from "../src";
+
+describe("Event handler resolver", () => {
+ const testHandlers = Array.from({ length: 10 }).map((_, i) =>
+ eventHandler(() => i),
+ );
+
+ const app = createApp();
+
+ const router = createRouter();
+ app.use(router);
+
+ // Middlware
+ app.use(testHandlers[0]);
+ app.use("/", testHandlers[1]);
+
+ // Path prefix
+ app.use("/test", testHandlers[2]);
+ app.use("/lazy", () => testHandlers[3], { lazy: true });
+
+ // Sub app
+ const app2 = createApp();
+ app.use("/nested", app2 as any);
+ app2.use("/path", testHandlers[4]);
+ // app2.use("/lazy", () => testHandlers[5], { lazy: true });
+
+ // Router
+ router.get("/router", testHandlers[6]);
+ router.get("/router/:id", testHandlers[7]);
+ router.get(
+ "/router/lazy",
+ lazyEventHandler(() => testHandlers[8]),
+ );
+
+ describe("middleware", () => {
+ it("does not resolves /", async () => {
+ expect(await app.resolve("/")).toBeUndefined();
+ });
+ });
+
+ describe("path prefix", () => {
+ it("resolves /test", async () => {
+ expect(await app.resolve("/test")).toMatchObject({
+ route: "/test",
+ handler: testHandlers[2],
+ });
+ });
+
+ it("resolves /test/foo", async () => {
+ expect((await app.resolve("/test/foo"))?.route).toEqual("/test");
+ });
+ });
+
+ it("resolves /lazy", async () => {
+ expect(await app.resolve("/lazy")).toMatchObject({
+ route: "/lazy",
+ handler: testHandlers[3],
+ });
+ });
+
+ describe("nested app", () => {
+ it("resolves /nested/path/foo", async () => {
+ expect(await app.resolve("/nested/path/foo")).toMatchObject({
+ route: "/nested/path",
+ handler: testHandlers[4],
+ });
+ });
+
+ it.skip("resolves /nested/lazy", async () => {
+ expect(await app.resolve("/nested/lazy")).toMatchObject({
+ route: "/nested/lazy",
+ handler: testHandlers[5],
+ });
+ });
+ });
+
+ describe("router", () => {
+ it("resolves /router", async () => {
+ expect(await app.resolve("/router")).toMatchObject({
+ route: "/router",
+ handler: testHandlers[6],
+ });
+ expect(await app.resolve("/router/")).toMatchObject(
+ (await app.resolve("/router")) as any,
+ );
+ });
+
+ it("resolves /router/:id", async () => {
+ expect(await app.resolve("/router/foo")).toMatchObject({
+ route: "/router/:id",
+ handler: testHandlers[7],
+ });
+ });
+
+ it("resolves /router/lazy", async () => {
+ expect(await app.resolve("/router/lazy")).toMatchObject({
+ route: "/router/lazy",
+ handler: testHandlers[8],
+ });
+ });
+ });
+});
diff --git a/test/sse.test.ts b/test/sse.test.ts
new file mode 100644
index 00000000..e18db2e6
--- /dev/null
+++ b/test/sse.test.ts
@@ -0,0 +1,125 @@
+import supertest, { SuperTest, Test } from "supertest";
+import { describe, it, beforeEach, expect } from "vitest";
+import {
+ App,
+ createApp,
+ createEventStream,
+ eventHandler,
+ getQuery,
+ toNodeListener,
+} from "../src";
+import {
+ formatEventStreamMessage,
+ formatEventStreamMessages,
+} from "../src/utils/sse/utils";
+
+describe("Server Sent Events (SSE)", () => {
+ let app: App;
+ let request: SuperTest;
+ beforeEach(() => {
+ app = createApp({ debug: true });
+ app.use(
+ "/sse",
+ eventHandler((event) => {
+ const includeMeta = getQuery(event).includeMeta !== undefined;
+ const eventStream = createEventStream(event);
+ const interval = setInterval(() => {
+ if (includeMeta) {
+ eventStream.push({
+ id: "1",
+ event: "custom-event",
+ data: "hello world",
+ });
+ return;
+ }
+ eventStream.push("hello world");
+ });
+ eventStream.onClosed(async () => {
+ await eventStream.close();
+ clearInterval(interval);
+ });
+ return eventStream.send();
+ }),
+ );
+ request = supertest(toNodeListener(app)) as any;
+ });
+ it("streams events", async () => {
+ let messageCount = 0;
+ request
+ .get("/sse")
+ .expect(200)
+ .expect("Content-Type", "text/event-stream")
+ .buffer()
+ .parse((res, callback) => {
+ res.on("data", (chunk: Buffer) => {
+ messageCount++;
+ const message = chunk.toString();
+ expect(message).toEqual("data: hello world\n\n");
+ });
+ res.on("end", () => {
+ callback(null, "");
+ });
+ })
+ .then()
+ .catch();
+ await new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(true);
+ }, 100);
+ });
+ expect(messageCount > 10).toBe(true);
+ });
+ it("streams events with metadata", async () => {
+ let messageCount = 0;
+ request
+ .get("/sse?includeMeta=true")
+ .expect(200)
+ .expect("Content-Type", "text/event-stream")
+ .buffer()
+ .parse((res, callback) => {
+ res.on("data", (chunk: Buffer) => {
+ messageCount++;
+ const message = chunk.toString();
+ expect(message).toEqual(
+ `id: 1\nevent: custom-event\ndata: hello world\n\n`,
+ );
+ });
+ res.on("end", () => {
+ callback(null, "");
+ });
+ })
+ .then()
+ .catch();
+ await new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(true);
+ }, 100);
+ });
+ expect(messageCount > 10).toBe(true);
+ });
+});
+
+it("properly formats sse messages", () => {
+ const result = formatEventStreamMessage({ data: "hello world" });
+ expect(result).toEqual(`data: hello world\n\n`);
+ const result2 = formatEventStreamMessage({
+ id: "1",
+ event: "custom-event",
+ retry: 10,
+ data: "hello world",
+ });
+ expect(result2).toEqual(
+ `id: 1\nevent: custom-event\nretry: 10\ndata: hello world\n\n`,
+ );
+});
+
+it("properly formats multiple sse messages", () => {
+ const result = formatEventStreamMessages([
+ {
+ data: "hello world",
+ },
+
+ { id: "1", data: "hello world 2" },
+ ]);
+ expect(result).toEqual(`data: hello world\n\nid: 1\ndata: hello world 2\n\n`);
+});
diff --git a/test/static.test.ts b/test/static.test.ts
index 7446e20e..e47f66f3 100644
--- a/test/static.test.ts
+++ b/test/static.test.ts
@@ -83,6 +83,7 @@ describe("Serve Static", () => {
it("Handles cache (if-none-match)", async () => {
const res = await request.get("/test.png").set("if-none-match", "w/123");
+ expect(res.headers.etag).toBe(expectedHeaders.etag);
expect(res.status).toEqual(304);
expect(res.text).toBe("");
});
diff --git a/test/status.test.ts b/test/status.test.ts
index c95d50a5..ca29feba 100644
--- a/test/status.test.ts
+++ b/test/status.test.ts
@@ -6,7 +6,6 @@ import {
PlainHandler,
eventHandler,
setResponseStatus,
- send,
} from "../src";
describe("setResponseStatus", () => {
@@ -127,7 +126,7 @@ describe("setResponseStatus", () => {
body: "",
});
- console.log(res.headers);
+ // console.log(res.headers);
expect(res).toMatchObject({
status: 304,
diff --git a/test/utils.test.ts b/test/utils.test.ts
index 5eb61402..e4511efa 100644
--- a/test/utils.test.ts
+++ b/test/utils.test.ts
@@ -1,5 +1,6 @@
+import { ReadableStream } from "node:stream/web";
import supertest, { SuperTest, Test } from "supertest";
-import { describe, it, expect, beforeEach } from "vitest";
+import { describe, it, expect, beforeEach, vi } from "vitest";
import {
createApp,
App,
@@ -13,7 +14,9 @@ import {
readFormData,
getRequestIP,
getRequestFingerprint,
+ sendIterable,
} from "../src";
+import { serializeIterableValue } from "../src/utils/internal/iteratable";
describe("", () => {
let app: App;
@@ -36,6 +39,138 @@ describe("", () => {
});
});
+ describe("serializeIterableValue", () => {
+ const exampleDate: Date = new Date(Date.UTC(2015, 6, 21, 3, 24, 54, 888));
+ it.each([
+ { value: "Hello, world!", output: "Hello, world!" },
+ { value: 123, output: "123" },
+ { value: 1n, output: "1" },
+ { value: true, output: "true" },
+ { value: false, output: "false" },
+ { value: undefined, output: undefined },
+ { value: null, output: "null" },
+ { value: exampleDate, output: JSON.stringify(exampleDate) },
+ { value: { field: 1 }, output: '{"field":1}' },
+ { value: [1, 2, 3], output: "[1,2,3]" },
+ { value: () => {}, output: undefined },
+ {
+ value: Buffer.from("Hello, world!"),
+ output: Buffer.from("Hello, world!"),
+ },
+ { value: Uint8Array.from([1, 2, 3]), output: Uint8Array.from([1, 2, 3]) },
+ ])("$value => $output", ({ value, output }) => {
+ const serialized = serializeIterableValue(value);
+ expect(serialized).toStrictEqual(output);
+ });
+ });
+
+ describe("sendIterable", () => {
+ it("sends empty body for an empty iterator", async () => {
+ app.use(eventHandler((event) => sendIterable(event, [])));
+ const result = await request.get("/");
+ expect(result.header["content-length"]).toBe("0");
+ expect(result.text).toBe("");
+ });
+
+ it("concatenates iterated values", async () => {
+ app.use(eventHandler((event) => sendIterable(event, ["a", "b", "c"])));
+ const result = await request.get("/");
+ expect(result.text).toBe("abc");
+ });
+
+ describe("iterable support", () => {
+ it.each([
+ { type: "Array", iterable: ["the-value"] },
+ { type: "Set", iterable: new Set(["the-value"]) },
+ {
+ type: "Map.keys()",
+ iterable: new Map([["the-value", "unused"]]).keys(),
+ },
+ {
+ type: "Map.values()",
+ iterable: new Map([["unused", "the-value"]]).values(),
+ },
+ {
+ type: "Iterator object",
+ iterable: { next: () => ({ value: "the-value", done: true }) },
+ },
+ {
+ type: "AsyncIterator object",
+ iterable: {
+ next: () => Promise.resolve({ value: "the-value", done: true }),
+ },
+ },
+ {
+ type: "Generator (yield)",
+ iterable: (function* () {
+ yield "the-value";
+ })(),
+ },
+ {
+ type: "Generator (return)",
+ iterable: (function* () {
+ return "the-value";
+ })(),
+ },
+ {
+ type: "Generator (yield*)",
+ iterable: (function* () {
+ // prettier-ignore
+ yield * ["the-value"];
+ })(),
+ },
+ {
+ type: "AsyncGenerator",
+ iterable: (async function* () {
+ await Promise.resolve();
+ yield "the-value";
+ })(),
+ },
+ {
+ type: "ReadableStream (push-mode)",
+ iterable: new ReadableStream({
+ start(controller) {
+ controller.enqueue("the-value");
+ controller.close();
+ },
+ }),
+ },
+ {
+ type: "ReadableStream (pull-mode)",
+ iterable: new ReadableStream({
+ pull(controller) {
+ controller.enqueue("the-value");
+ controller.close();
+ },
+ }),
+ },
+ ])("$type", async ({ iterable }) => {
+ app.use(eventHandler((event) => sendIterable(event, iterable)));
+ const response = await request.get("/");
+ expect(response.text).toBe("the-value");
+ });
+ });
+
+ describe("serializer argument", () => {
+ it("is called for every value", async () => {
+ const iterable = [1, "2", { field: 3 }, null];
+ const serializer = vi.fn(() => "x");
+
+ app.use(
+ eventHandler((event) =>
+ sendIterable(event, iterable, { serializer }),
+ ),
+ );
+ const response = await request.get("/");
+ expect(response.text).toBe("x".repeat(iterable.length));
+ expect(serializer).toBeCalledTimes(4);
+ for (const [i, obj] of iterable.entries()) {
+ expect.soft(serializer).toHaveBeenNthCalledWith(i + 1, obj);
+ }
+ });
+ });
+ });
+
describe("useBase", () => {
it("can prefix routes", async () => {
app.use(