diff --git a/.env b/.env index 9106155..e30475a 100644 --- a/.env +++ b/.env @@ -9,4 +9,11 @@ LOG_FILE=./logs/app.log # 插件配置 PLUGIN_NAME=myapp -API_PREFIX=/api/v1 \ No newline at end of file +API_PREFIX=/api/v1 + +# 数据库 +DB_HOST=172.16.1.10 +DB_USER=nie +DB_PASSWORD=Hxl1314521 +DB_NAME=yuheng +DB_PORT=3306 diff --git a/.prettier.config.cjs b/.prettier.config.cjs new file mode 100644 index 0000000..b91f626 --- /dev/null +++ b/.prettier.config.cjs @@ -0,0 +1,30 @@ +// 转换为 CommonJS 格式(重要!) +module.exports = { + printWidth: 100, // 最大行宽 + semi: true, // 强制分号 + singleQuote: true, // 使用单引号 + trailingComma: 'all', // 自动尾逗号 + tabWidth: 4, // 缩进空格数 + + // 新增常用配置 + arrowParens: 'avoid', // 箭头函数单参数省略括号 + bracketSpacing: true, // 对象花括号空格 { key: value } + endOfLine: 'auto', // 自动识别换行符 + jsxBracketSameLine: false, // JSX 闭合标签换行(React 项目适用) + + // 文件类型覆盖规则 + overrides: [ + { + files: '*.md', + options: { + proseWrap: 'always' // Markdown 自动换行 + } + }, + { + files: '*.json', + options: { + tabWidth: 4 // JSON 使用 2 空格缩进 + } + } + ] +}; // 移除结尾分号保持风格统一 \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..2f7901d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,11 @@ +# 忽略环境文件 +.env +*.env + +# 忽略模块类型冲突文件 +*.cjs +*.mjs + +# 忽略的目录 +node_modules/* +doc/* \ No newline at end of file diff --git a/README.md b/README.md index 297be58..3c1a8ef 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ 基于 Fastify 的 Node.js 角色访问控制(RBAC)系统,提供灵活的权限管理能力。 ## 主要特性 + - 🛡️ 基于 JWT 的身份认证 - 🔑 角色-权限层级管理 - 🚦 请求权限验证中间件 @@ -12,12 +13,14 @@ ## 快速开始 ### 前置要求 + - Node.js v18+ - 数据库(PostgreSQL/MySQL) - Redis(用于会话管理) ### 安装步骤 -```bash + +````bash # 克隆仓库 git clone https://github.com/your-repo.git cd rbac-system @@ -55,4 +58,4 @@ npm run dev ├── config/ # 配置文件 │ ├── default.js # 通用配置 ├── package.json # 依赖管理 -``` \ No newline at end of file +```` diff --git a/config/index.js b/config/index.js index 020612a..56c7ae8 100644 --- a/config/index.js +++ b/config/index.js @@ -1,10 +1,9 @@ -import { config } from 'dotenv' -import path from 'path' +import { config } from 'dotenv'; +import path from 'path'; // 加载环境变量 -config({ path: path.resolve(process.cwd(), '.env') }) -console.log("[NODE_ENV]:", process.env.NODE_ENV); - +config({ path: path.resolve(process.cwd(), '.env') }); +console.log('[NODE_ENV]:', process.env.NODE_ENV); // 基础配置 const baseConfig = { @@ -12,7 +11,7 @@ const baseConfig = { server: { port: process.env.PORT || 9000, host: process.env.HOST || 'localhost', - backlog: process.env.BACKLOG || 511 + backlog: process.env.BACKLOG || 511, }, logger: { level: process.env.LOG_LEVEL || 'trace', @@ -21,9 +20,17 @@ const baseConfig = { }, pluginOptions: { name: process.env.PLUGIN_NAME || 'default', - prefix: process.env.API_PREFIX || '/api' - } -} + prefix: process.env.API_PREFIX || '/api', + }, + db: { + host: process.env.DB_HOST || '127.0.0.1', + port: process.env.DB_PORT || 3306, + user: process.env.DB_USER || 'root', + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME || 'yuheng', + ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: true } : null, + }, +}; // 环境特定配置 const envConfig = { @@ -33,27 +40,24 @@ const envConfig = { }, logger: { level: 'warn', - } + }, }, development: { logger: { level: 'trace', console: true, - } - } -} + }, + }, +}; // 使用深度合并代替展开操作符 function deepMerge(target, source) { for (const key of Object.keys(source)) { if (source[key] instanceof Object && key in target) { - Object.assign(source[key], deepMerge(target[key], source[key])) + Object.assign(source[key], deepMerge(target[key], source[key])); } } - return Object.assign({}, target, source) + return Object.assign({}, target, source); } -export default deepMerge( - baseConfig, - envConfig[process.env.NODE_ENV] || envConfig.development -) \ No newline at end of file +export default deepMerge(baseConfig, envConfig[process.env.NODE_ENV] || envConfig.development); diff --git a/doc/fastify-docs/README.md b/doc/fastify-docs/README.md index 4c5ca5e..7cbc35b 100644 --- a/doc/fastify-docs/README.md +++ b/doc/fastify-docs/README.md @@ -1,33 +1,34 @@ # Fastify 文档中文翻译 ### 文档目录 -* [入门](docs/Getting-Started.md) -* [服务器方法](docs/Server.md) -* [路由](docs/Routes.md) -* [日志](docs/Logging.md) -* [中间件](docs/Middleware.md) -* [钩子方法](docs/Hooks.md) -* [装饰器](docs/Decorators.md) -* [验证和序列化](docs/Validation-and-Serialization.md) -* [生命周期](docs/Lifecycle.md) -* [回复](docs/Reply.md) -* [请求](docs/Request.md) -* [错误](docs/Errors.md) -* [Content-Type 解析](docs/ContentTypeParser.md) -* [插件](docs/Plugins.md) -* [测试](docs/Testing.md) -* [基准测试](docs/Benchmarking.md) -* [如何写一个好的插件](docs/Write-Plugin.md) -* [插件指南](docs/Plugins-Guide.md) -* [HTTP2](docs/HTTP2.md) -* [长期支持计划](docs/LTS.md) -* [TypeScript 与类型支持](docs/TypeScript.md) -* [Serverless](docs/Serverless.md) -* [推荐方案](docs/Recommendations.md) + +- [入门](docs/Getting-Started.md) +- [服务器方法](docs/Server.md) +- [路由](docs/Routes.md) +- [日志](docs/Logging.md) +- [中间件](docs/Middleware.md) +- [钩子方法](docs/Hooks.md) +- [装饰器](docs/Decorators.md) +- [验证和序列化](docs/Validation-and-Serialization.md) +- [生命周期](docs/Lifecycle.md) +- [回复](docs/Reply.md) +- [请求](docs/Request.md) +- [错误](docs/Errors.md) +- [Content-Type 解析](docs/ContentTypeParser.md) +- [插件](docs/Plugins.md) +- [测试](docs/Testing.md) +- [基准测试](docs/Benchmarking.md) +- [如何写一个好的插件](docs/Write-Plugin.md) +- [插件指南](docs/Plugins-Guide.md) +- [HTTP2](docs/HTTP2.md) +- [长期支持计划](docs/LTS.md) +- [TypeScript 与类型支持](docs/TypeScript.md) +- [Serverless](docs/Serverless.md) +- [推荐方案](docs/Recommendations.md) ### 其他版本 -* [v2.x](https://github.com/fastify/docs-chinese/tree/2.x) +- [v2.x](https://github.com/fastify/docs-chinese/tree/2.x) ### 翻译指南 @@ -35,7 +36,8 @@ 为了提供一致的翻译体验,请在开始翻译前参阅[翻译指南](docs/Contributing.md)。感谢! ### 贡献者 -* [@fralonra](https://github.com/fralonra) -* [@poppinlp](https://github.com/poppinlp) -* [@vincent178](https://github.com/vincent178) -* [@xtx1130](https://github.com/xtx1130) + +- [@fralonra](https://github.com/fralonra) +- [@poppinlp](https://github.com/poppinlp) +- [@vincent178](https://github.com/vincent178) +- [@xtx1130](https://github.com/xtx1130) diff --git a/doc/fastify-docs/docs/Benchmarking.md b/doc/fastify-docs/docs/Benchmarking.md index a97c762..0ccb39e 100644 --- a/doc/fastify-docs/docs/Benchmarking.md +++ b/doc/fastify-docs/docs/Benchmarking.md @@ -1,9 +1,11 @@
Fastify server
实例。这个工厂函数的参数是一个配置对象,用于自定义最终生成的实例。本文描述了这一对象中可用的属性。
@@ -37,13 +38,15 @@ Fastify 模块导出了一个工厂函数,可以用于创建新的 Fa
- [initialConfig](./Server.md#initialConfig)
+
### `http2`
设置为 `true`,则会使用 Node.js 原生的 [HTTP/2](https://nodejs.org/dist/latest-v14.x/docs/api/http2.html) 模块来绑定 socket。
-+ 默认值:`false`
+- 默认值:`false`
+
### `https`
用于配置服务器的 TLS socket 的对象。其选项与 Node.js 原生的 [`createServer` 方法](https://nodejs.org/dist/latest-v14.x/docs/api/https.html#https_https_createserver_options_requestlistener)一致。
@@ -53,60 +56,67 @@ Fastify 模块导出了一个工厂函数,可以用于创建新的 Fa
http2
选项设置时,`https` 选项也会被应用。
-+ 默认值:`null`
+- 默认值:`null`
+
### `connectionTimeout`
定义服务器超时,单位为毫秒。作用请见 [`server.timeout` 属性](https://nodejs.org/api/http.html#http_server_timeout)的文档。当指定了 `serverFactory` 时,该选项被忽略。
-+ 默认值:`0` (无超时)
+- 默认值:`0` (无超时)
+
### `keepAliveTimeout`
定义服务器 keep-alive 超时,单位为毫秒。作用请见 [`server.keepAliveTimeout` 属性](https://nodejs.org/api/http.html#http_server_timeout)的文档。仅当使用 HTTP/1 时有效。当指定了 `serverFactory` 时,该选项被忽略。
-+ 默认值:`5000` (5 秒)
+- 默认值:`5000` (5 秒)
+
### `ignoreTrailingSlash`
Fastify 使用 [find-my-way](https://github.com/delvedor/find-my-way) 处理路由。该选项为 `true` 时,尾斜杠将被省略。
这一选项应用于 server 实例上注册的*所有*路由。
-+ 默认值:`false`
+- 默认值:`false`
```js
-const fastify = require('fastify')({
- ignoreTrailingSlash: true
-})
+const fastify = require("fastify")({
+ ignoreTrailingSlash: true,
+});
// 同时注册 "/foo" 与 "/foo/"
-fastify.get('/foo/', function (req, reply) {
- reply.send('foo')
-})
+fastify.get("/foo/", function (req, reply) {
+ reply.send("foo");
+});
// 同时注册 "/bar" 与 "/bar/"
-fastify.get('/bar', function (req, reply) {
- reply.send('bar')
-})
+fastify.get("/bar", function (req, reply) {
+ reply.send("bar");
+});
```
+
### `maxParamLength`
+
你可以为通过 `maxParamLength` 选项为带参路由 (无论是标准的、正则匹配的,还是复数的) 设置最大参数长度。选项的默认值为 100 字符。
当使用正则匹配的路由时,这非常有用,可以帮你抵御 [DoS 攻击](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)。
-*当达到长度限制时,将触发 not found 路由。*
+_当达到长度限制时,将触发 not found 路由。_
+
### `bodyLimit`
定义服务器可接受的最大 payload,以字节为单位。
-+ 默认值:`1048576` (1MiB)
+- 默认值:`1048576` (1MiB)
+
### `onProtoPoisoning`
由 [secure-json-parse](https://github.com/fastify/secure-json-parse) 提供的功能,指定解析带有 `__proto__` 键的 JSON 对象时框架的行为。
@@ -114,9 +124,10 @@ fastify.get('/bar', function (req, reply) {
允许的值为 `'error'`、`'remove'` 与 `'ignore'`。
-+ 默认值:`'error'`
+- 默认值:`'error'`
+
### `onConstructorPoisoning`
由 [secure-json-parse](https://github.com/fastify/secure-json-parse) 提供的功能,指定解析带有 `constructor` 的 JSON 对象时框架的行为。
@@ -124,33 +135,35 @@ fastify.get('/bar', function (req, reply) {
允许的值为 `'error'`、`'remove'` 与 `'ignore'`。
-+ 默认值:`'error'`
+- 默认值:`'error'`
+
### `logger`
Fastify 依托 [Pino](https://getpino.io/) 内建了一个日志工具。该属性用于配置日志实例。
属性可用的值为:
-+ 默认: `false`。禁用日志。所有记录日志的方法将会指向一个空日志工具 [abstract-logging](https://npm.im/abstract-logging) 的实例。
+- 默认: `false`。禁用日志。所有记录日志的方法将会指向一个空日志工具 [abstract-logging](https://npm.im/abstract-logging) 的实例。
-+ `pinoInstance`: 一个已被实例化的 Pino 实例。内建的日志工具将指向这个实例。
+- `pinoInstance`: 一个已被实例化的 Pino 实例。内建的日志工具将指向这个实例。
-+ `object`: 标准的 Pino [选项对象](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor)。
-它会被直接传递进 Pino 的构造函数。如果下列属性未在该对象中定义,它们将被相应地添加:
- * `level`: 最低的日志级别。若未被设置,则默认为 `'info'`。
- * `serializers`: 序列化函数的哈希。默认情况下,序列化函数应用在 `req` (来访的请求对象)、`res` (发送的响应对象) 以及 `err` (标准的 `Error` 对象) 之上。当一个日志方法接收到含有上述任意属性的对象时,对应的序列化器将会作用于该属性。举例如下:
- ```js
+- `object`: 标准的 Pino [选项对象](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor)。
+ 它会被直接传递进 Pino 的构造函数。如果下列属性未在该对象中定义,它们将被相应地添加:
+ _ `level`: 最低的日志级别。若未被设置,则默认为 `'info'`。
+ _ `serializers`: 序列化函数的哈希。默认情况下,序列化函数应用在 `req` (来访的请求对象)、`res` (发送的响应对象) 以及 `err` (标准的 `Error` 对象) 之上。当一个日志方法接收到含有上述任意属性的对象时,对应的序列化器将会作用于该属性。举例如下:
+ `js
fastify.get('/foo', function (req, res) {
req.log.info({req}) // 日志输出经过序列化的请求对象
res.send('foo')
})
- ```
- 用户提供的序列化函数将会覆盖对应属性默认的序列化函数。
-+ `loggerInstance`:自定义日志工具实例。日志工具必须实现 Pino 的接口,即拥有如下方法:`info`, `error`, `debug`, `fatal`, `warn`, `trace`, `child`。例如:
+ `
+ 用户提供的序列化函数将会覆盖对应属性默认的序列化函数。
+- `loggerInstance`:自定义日志工具实例。日志工具必须实现 Pino 的接口,即拥有如下方法:`info`, `error`, `debug`, `fatal`, `warn`, `trace`, `child`。例如:
+
```js
-const pino = require('pino')();
+const pino = require("pino")();
const customLogger = {
info: function (o, ...n) {},
@@ -159,93 +172,105 @@ const customLogger = {
fatal: function (o, ...n) {},
trace: function (o, ...n) {},
debug: function (o, ...n) {},
- child: function() {
+ child: function () {
const child = Object.create(this);
child.pino = pino.child(...arguments);
return child;
},
};
-const fastify = require('fastify')({logger: customLogger});
+const fastify = require("fastify")({ logger: customLogger });
```
+
### `disableRequestLogging`
+
默认情况下当开启日志时,Fastify 会在收到请求与发送该请求的响应时记录 `info` 级别的日志。你可以设置该选项为 `true` 来禁用该功能。这时,通过自定义 `onRequest` 和 `onResponse` 钩子,你能更灵活地记录一个请求的开始与结束。
-+ 默认值:`false`
+- 默认值:`false`
```js
// 例子:通过钩子再造被禁用的请求日志功能。
-fastify.addHook('onRequest', (req, reply, done) => {
- req.log.info({ url: req.raw.url, id: req.id }, 'received request')
- done()
-})
+fastify.addHook("onRequest", (req, reply, done) => {
+ req.log.info({ url: req.raw.url, id: req.id }, "received request");
+ done();
+});
-fastify.addHook('onResponse', (req, reply, done) => {
- req.log.info({ url: req.raw.originalUrl, statusCode: reply.raw.statusCode }, 'request completed')
- done()
-})
+fastify.addHook("onResponse", (req, reply, done) => {
+ req.log.info(
+ { url: req.raw.originalUrl, statusCode: reply.raw.statusCode },
+ "request completed",
+ );
+ done();
+});
```
请注意,该选项同时也会禁止默认的 `onResponse` 钩子在响应的回调函数出错时记录错误日志。
+
### `serverFactory`
+
通过 `serverFactory` 选项,你可以向 Fastify 传递一个自定义的 HTTP server。
`serverFactory` 函数的参数为 `handler` 函数及一个选项对象。`handler` 函数的参数为 `request` 和 `response` 对象,选项对象则与你传递给 Fastify 的一致。
```js
const serverFactory = (handler, opts) => {
const server = http.createServer((req, res) => {
- handler(req, res)
- })
+ handler(req, res);
+ });
- return server
-}
+ return server;
+};
-const fastify = Fastify({ serverFactory })
+const fastify = Fastify({ serverFactory });
-fastify.get('/', (req, reply) => {
- reply.send({ hello: 'world' })
-})
+fastify.get("/", (req, reply) => {
+ reply.send({ hello: "world" });
+});
-fastify.listen(3000)
+fastify.listen(3000);
```
+
Fastify 内在地使用 Node 原生 HTTP server 的 API。因此,如果你使用一个自定义的 server,你必须保证暴露了相同的 API。不这么做的话,你可以在 `serverFactory` 函数内部 `return` 语句之前,向 server 实例添加新的属性。
+
### `jsonShorthand`
-+ 默认值:`true`
+- 默认值:`true`
当未发现 JSON Schema 规范中合法的根属性时,Fastify 会默认地自动推断该根属性。如果你想实现自定义的 schema 校验编译器,例如使用 JTD (JSON Type Definition) 代替 JSON schema,你应当设置该选项为 `false` 来确保 schema 不被修改且不会被当成 JSON Schema 处理。
```js
-const AjvJTD = require('ajv/dist/jtd'/* 只在 AJV v7 以上版本生效 */)
+const AjvJTD = require("ajv/dist/jtd" /* 只在 AJV v7 以上版本生效 */);
const ajv = new AjvJTD({
// 当遇到非法 JTD schema 对象时抛出错误。
- allErrors: process.env.NODE_ENV === 'development'
-})
-const fastify = Fastify({ jsonShorthand: false })
+ allErrors: process.env.NODE_ENV === "development",
+});
+const fastify = Fastify({ jsonShorthand: false });
fastify.setValidatorCompiler(({ schema }) => {
- return ajv.compile(schema)
-})
-fastify.post('/', {
+ return ajv.compile(schema);
+});
+fastify.post("/", {
schema: {
body: {
properties: {
- foo: { type: 'uint8' }
- }
- }
+ foo: { type: "uint8" },
+ },
+ },
},
- handler (req, reply) { reply.send({ ok: 1 }) }
-})
+ handler(req, reply) {
+ reply.send({ ok: 1 });
+ },
+});
```
**注:目前 Fastify 并不会在发现非法 schema 时抛错。因此,假如你在已有项目中关闭了该选项,请确保现存所有的 schema 不会因此变得非法,因为它们会被当作笼统的一类进行处理。**
+
### `caseSensitive`
默认值为 `true`,此时路由对大小写敏感。这就意味着 `/foo` 与 `/Foo` 是两个不同的路由。当该选项为 `false` 时,路由大小写不敏感,`/foo`、`/Foo` 以及 `/FOO` 都是一样的。
@@ -253,10 +278,10 @@ fastify.post('/', {
将 `caseSensitive` 设置为 `false`,会导致所有路径变为小写,除了路由参数与通配符。
```js
-fastify.get('/user/:username', (request, reply) => {
+fastify.get("/user/:username", (request, reply) => {
// 原 URL: /USER/NodeJS
- console.log(request.params.username) // -> 'NodeJS'
-})
+ console.log(request.params.username); // -> 'NodeJS'
+});
```
要注意的是,将该选项设为 `false` 与 [RFC3986](https://tools.ietf.org/html/rfc3986#section-6.2.2.1) 相悖。
@@ -264,109 +289,121 @@ fastify.get('/user/:username', (request, reply) => {
此外,该选项不影响 query string 的解析。要让 query string 忽略大小写,请看 [`querystringParser`](./Server.md#querystringParser)。
+
### `requestIdHeader`
用来获知请求 ID 的 header 名。请看[请求 ID](Logging.md#logging-request-id) 一节。
-+ 默认值:`'request-id'`
+- 默认值:`'request-id'`
+
### `requestIdLogLabel`
定义日志中请求 ID 的标签。
-+ 默认值:`'reqId'`
+- 默认值:`'reqId'`
+
### `genReqId`
+
用于生成请求 ID 的函数。参数为来访的请求对象。
-+ 默认值:`'request-id' header 的值 (当存在时) 或单调递增的整数`
-在分布式系统中,你可能会特别想覆盖如下默认的 ID 生成行为。要生成 `UUID`,请看[hyperid](https://github.com/mcollina/hyperid)。
- ```js
-let i = 0
-const fastify = require('fastify')({
- genReqId: function (req) { return i++ }
-})
+- 默认值:`'request-id' header 的值 (当存在时) 或单调递增的整数`
+ 在分布式系统中,你可能会特别想覆盖如下默认的 ID 生成行为。要生成 `UUID`,请看[hyperid](https://github.com/mcollina/hyperid)。
+
+```js
+let i = 0;
+const fastify = require("fastify")({
+ genReqId: function (req) {
+ return i++;
+ },
+});
```
**注意:当设置了 [requestIdHeader](#requestidheader)
中定义的 header (默认为 'request-id') 时,genReqId _不会_ 被调用。**
+
### `trustProxy`
通过开启 `trustProxy` 选项,Fastify 会认为使用了代理服务,且 `X-Forwarded-*` header 是可信的,否则该值被认为是极具欺骗性的。
```js
-const fastify = Fastify({ trustProxy: true })
+const fastify = Fastify({ trustProxy: true });
```
-+ 默认值:`false`
-+ `true/false`: 信任所有代理 (`true`) 或不信任任意的代理 (`false`)。
-+ `string`: 只信任给定的 IP/CIDR (例如 `'127.0.0.1'`)。可以是一组用英文逗号分隔的地址 (例如 `'127.0.0.1,192.168.1.1/24'`)。
-+ `Array`: 只信任给定的 IP/CIDR 列表 (例如 `['127.0.0.1']`)。
-+ `number`: 信任来自前置代理服务器的第n跳 (hop) 地址作为客户端。
-+ `Function`: 自定义的信任函数,第一个参数为 `address`
- ```js
- function myTrustFn(address, hop) {
- return address === '1.2.3.4' || hop === 1
- }
- ```
+- 默认值:`false`
+- `true/false`: 信任所有代理 (`true`) 或不信任任意的代理 (`false`)。
+- `string`: 只信任给定的 IP/CIDR (例如 `'127.0.0.1'`)。可以是一组用英文逗号分隔的地址 (例如 `'127.0.0.1,192.168.1.1/24'`)。
+- `Array`: 只信任给定的 IP/CIDR 列表 (例如 `['127.0.0.1']`)。
+- `number`: 信任来自前置代理服务器的第n跳 (hop) 地址作为客户端。
+- `Function`: 自定义的信任函数,第一个参数为 `address`
+ ```js
+ function myTrustFn(address, hop) {
+ return address === "1.2.3.4" || hop === 1;
+ }
+ ```
更多示例详见 [`proxy-addr`](https://www.npmjs.com/package/proxy-addr)。
你还可以通过 [`request`](Request.md) 对象获取 `ip`、`ips`、`hostname` 与 `protocol` 的值。
```js
-fastify.get('/', (request, reply) => {
- console.log(request.ip)
- console.log(request.ips)
- console.log(request.hostname)
- console.log(request.protocol)
-})
+fastify.get("/", (request, reply) => {
+ console.log(request.ip);
+ console.log(request.ips);
+ console.log(request.hostname);
+ console.log(request.protocol);
+});
```
**注:如果请求存在多个 x-forwarded-host
或 x-forwarded-proto
header,只会根据最后一个产生 request.hostname
和 request.protocol
**
+
### `pluginTimeout`
单个插件允许加载的最长时间,以毫秒计。如果某个插件加载超时,则 [`ready`](Server.md#ready) 会抛出一个含有 `'ERR_AVVIO_PLUGIN_TIMEOUT'` 代码的 `Error` 对象。
-+ 默认值:`10000`
+- 默认值:`10000`
+
+
+
+### `querystringParser`
-
- ### `querystringParser`
-
Fastify 默认使用 Node.js 核心的 `querystring` 模块作为 query string 解析器。
你可以通过 `querystringParser` 选项来使用自定义的解析器,例如 [`qs`](https://www.npmjs.com/package/qs)。
```js
-const qs = require('qs')
-const fastify = require('fastify')({
- querystringParser: str => qs.parse(str)
-})
+const qs = require("qs");
+const fastify = require("fastify")({
+ querystringParser: (str) => qs.parse(str),
+});
```
你也可以改变默认解析器的行为,例如忽略 query string 的大小写:
```js
-const querystring = require('querystring')
-const fastify = require('fastify')({
- querystringParser: str => querystring.parse(str.toLowerCase())
-})
+const querystring = require("querystring");
+const fastify = require("fastify")({
+ querystringParser: (str) => querystring.parse(str.toLowerCase()),
+});
```
若你只想忽略键的大小写,我们推荐你使用自定义解析器。
+
### `exposeHeadRoutes`
自动为每个 `GET` 路由添加对应的 `HEAD` 路由。如果你不想禁用该选项,又希望自定义 `HEAD` 处理函数,请在 `GET` 路由前定义该处理函数。
-+ 默认值:`false`
+- 默认值:`false`
+
### `constraints`
Fastify 内建的路由约束由 `find-my-way` 支持,允许使用 `version` 或 `host` 来约束路由。通过为 `find-my-way` 提供 `constraints` 对象,你可以添加新的约束策略,或覆盖原有策略。更多内容可见于 [find-my-way](https://github.com/delvedor/find-my-way) 的文档。
@@ -374,40 +411,50 @@ Fastify 内建的路由约束由 `find-my-way` 支持,允许使用 `version`
```js
const customVersionStrategy = {
storage: function () {
- let versions = {}
+ let versions = {};
return {
- get: (version) => { return versions[version] || null },
- set: (version, store) => { versions[version] = store },
- del: (version) => { delete versions[version] },
- empty: () => { versions = {} }
- }
+ get: (version) => {
+ return versions[version] || null;
+ },
+ set: (version, store) => {
+ versions[version] = store;
+ },
+ del: (version) => {
+ delete versions[version];
+ },
+ empty: () => {
+ versions = {};
+ },
+ };
},
deriveVersion: (req, ctx) => {
- return req.headers['accept']
- }
-}
+ return req.headers["accept"];
+ },
+};
-const fastify = require('fastify')({
+const fastify = require("fastify")({
constraints: {
- version: customVersionStrategy
- }
-})
+ version: customVersionStrategy,
+ },
+});
```
+
### `return503OnClosing`
调用 `close` 方法后返回 503 状态码。
如果为 `false`,服务器会正常处理请求。
-+ 默认值:`true`
+- 默认值:`true`
+
### `ajv`
配置 Fastify 使用的 Ajv 6 实例。这使得你无需提供一个自定义的实例。
-+ 默认值:
+- 默认值:
```js
{
@@ -423,35 +470,37 @@ const fastify = require('fastify')({
```
```js
-const fastify = require('fastify')({
+const fastify = require("fastify")({
ajv: {
customOptions: {
- nullable: false // 参见 [ajv 的配置选项](https://ajv.js.org/#options)
+ nullable: false, // 参见 [ajv 的配置选项](https://ajv.js.org/#options)
},
plugins: [
- require('ajv-merge-patch'),
- [require('ajv-keywords'), 'instanceof']
+ require("ajv-merge-patch"),
+ [require("ajv-keywords"), "instanceof"],
// 用法: [plugin, pluginOptions] - 插件与选项
// 用法: plugin - 仅插件
- ]
- }
-})
+ ],
+ },
+});
```
+
### `serializerOpts`
自定义用于序列化响应 payload 的 [`fast-json-stringify`](https://github.com/fastify/fast-json-stringify#options) 实例的配置:
```js
-const fastify = require('fastify')({
+const fastify = require("fastify")({
serializerOpts: {
- rounding: 'ceil'
- }
-})
+ rounding: "ceil",
+ },
+});
```
+
### `http2SessionTimeout`
为每个 HTTP/2 会话设置默认[超时时间](https://nodejs.org/api/http2.html#http2_http2session_settimeout_msecs_callback)。超时后,会话将关闭。默认值:`5000` 毫秒。
@@ -459,74 +508,82 @@ const fastify = require('fastify')({
要注意的是,使用 HTTP/2 时需要提供一个优雅的“close”体验。一个低的默认值有助于减轻拒绝服务型攻击 (Denial-of-Service Attacks) 的影响。但当你的服务器使用负载均衡策略,或能自动扩容时,则可以延长超时时间。Node 的默认值为 `0`,即无超时。
+
### `frameworkErrors`
-+ 默认值:`null`
+- 默认值:`null`
对于最常见的场景,Fastify 已经提供了默认的错误处理方法。这个选项允许你重写这些处理方法。
-*注:目前只实现了 `FST_ERR_BAD_URL` 这个错误。*
+_注:目前只实现了 `FST_ERR_BAD_URL` 这个错误。_
```js
-const fastify = require('fastify')({
+const fastify = require("fastify")({
frameworkErrors: function (error, req, res) {
if (error instanceof FST_ERR_BAD_URL) {
- res.code(400)
- return res.send("Provided url is not valid")
+ res.code(400);
+ return res.send("Provided url is not valid");
} else {
- res.send(err)
+ res.send(err);
}
- }
-})
+ },
+});
```
+
### `clientErrorHandler`
设置 [clientErrorHandler](https://nodejs.org/api/http.html#http_event_clienterror) 来监听客户端连接造成的 `error` 事件,并响应 `400` 状态码。
设置了该选项,会覆盖默认的 `clientErrorHandler`。
-+ 默认值:
+- 默认值:
+
```js
-function defaultClientErrorHandler (err, socket) {
- if (err.code === 'ECONNRESET') {
- return
+function defaultClientErrorHandler(err, socket) {
+ if (err.code === "ECONNRESET") {
+ return;
}
const body = JSON.stringify({
- error: http.STATUS_CODES['400'],
- message: 'Client Error',
- statusCode: 400
- })
- this.log.trace({ err }, 'client error')
+ error: http.STATUS_CODES["400"],
+ message: "Client Error",
+ statusCode: 400,
+ });
+ this.log.trace({ err }, "client error");
if (socket.writable) {
- socket.end(`HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`)
+ socket.end(
+ `HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`,
+ );
}
}
```
-*注:`clientErrorHandler` 使用底层的 socket,故处理函数需要返回格式正确的 HTTP 响应信息,包括状态行、HTTP header 以及 body。在写入之前,为了避免 socket 已被销毁,你还应该检查 socket 是否依然可写。*
+_注:`clientErrorHandler` 使用底层的 socket,故处理函数需要返回格式正确的 HTTP 响应信息,包括状态行、HTTP header 以及 body。在写入之前,为了避免 socket 已被销毁,你还应该检查 socket 是否依然可写。_
```js
-const fastify = require('fastify')({
+const fastify = require("fastify")({
clientErrorHandler: function (err, socket) {
const body = JSON.stringify({
error: {
- message: 'Client error',
- code: '400'
- }
- })
+ message: "Client error",
+ code: "400",
+ },
+ });
// `this` 为 fastify 实例
- this.log.trace({ err }, 'client error')
+ this.log.trace({ err }, "client error");
// 处理函数应当发送正确的 HTTP 响应信息。
- socket.end(`HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`)
- }
-})
+ socket.end(
+ `HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`,
+ );
+ },
+});
```
+
### `rewriteUrl`
设置一个异步函数,返回一个字符串,用于重写 URL。
@@ -534,8 +591,9 @@ const fastify = require('fastify')({
> 重写 URL 会修改 `req` 对象的 `url` 属性
```js
-function rewriteUrl (req) { // req 是 Node.js 的 HTTP 请求对象
- return req.url === '/hi' ? '/hello' : req.url;
+function rewriteUrl(req) {
+ // req 是 Node.js 的 HTTP 请求对象
+ return req.url === "/hi" ? "/hello" : req.url;
}
```
@@ -546,305 +604,378 @@ function rewriteUrl (req) { // req 是 Node.js 的 HTTP 请求对象
### 服务器方法
+
#### 服务器
+
`fastify.server`:由 [**`Fastify 的工厂函数`**](Server.md) 生成的 Node 原生 [server](https://nodejs.org/api/http.html#http_class_http_server) 对象。
+
#### after
+
当前插件及在其中注册的所有插件加载完毕后调用。总在 `fastify.ready` 之前执行。
```js
fastify
.register((instance, opts, done) => {
- console.log('当前插件')
- done()
+ console.log("当前插件");
+ done();
})
- .after(err => {
- console.log('当前插件之后')
+ .after((err) => {
+ console.log("当前插件之后");
})
.register((instance, opts, done) => {
- console.log('下一个插件')
- done()
- })
- .ready(err => {
- console.log('万事俱备')
+ console.log("下一个插件");
+ done();
})
+ .ready((err) => {
+ console.log("万事俱备");
+ });
```
当 `after()` 没有回调参数时,它返回一个 `Promise`:
```js
fastify.register(async (instance, opts) => {
- console.log('Current plugin')
-})
+ console.log("Current plugin");
+});
-await fastify.after()
-console.log('After current plugin')
+await fastify.after();
+console.log("After current plugin");
fastify.register(async (instance, opts) => {
- console.log('Next plugin')
-})
+ console.log("Next plugin");
+});
-await fastify.ready()
+await fastify.ready();
-console.log('Everything has been loaded')
+console.log("Everything has been loaded");
```
+
#### ready
+
当所有插件的加载都完成时调用。如有错误发生,它会传递一个 `error` 参数。
+
```js
-fastify.ready(err => {
- if (err) throw err
-})
+fastify.ready((err) => {
+ if (err) throw err;
+});
```
+
调用时不加参数,它会返回一个 `Promise` 对象:
```js
-fastify.ready().then(() => {
- console.log('successfully booted!')
-}, (err) => {
- console.log('an error happened', err)
-})
+fastify.ready().then(
+ () => {
+ console.log("successfully booted!");
+ },
+ (err) => {
+ console.log("an error happened", err);
+ },
+);
```
+
#### listen
+
所有的插件加载完毕、`ready` 事件触发后,在指定的端口启动服务器。它的回调函数与 Node 原生方法的回调相同。默认情况下,服务器监听 `localhost` 所决定的地址 (`127.0.0.1` 或 `::1`,取决于操作系统)。将地址设置为 `0.0.0.0` 可监听所有的 IPV4 地址。设置为 `::` 则可监听所有的 IPV6 地址,在某些系统中,这么做亦可同时监听所有 IPV4 地址。监听所有的接口要格外谨慎,因为这种方式存在着固有的[安全风险](https://web.archive.org/web/20170831174611/https://snyk.io/blog/mongodb-hack-and-secure-defaults/)。
```js
fastify.listen(3000, (err, address) => {
if (err) {
- fastify.log.error(err)
- process.exit(1)
+ fastify.log.error(err);
+ process.exit(1);
}
-})
+});
```
指定监听的地址:
```js
-fastify.listen(3000, '127.0.0.1', (err, address) => {
+fastify.listen(3000, "127.0.0.1", (err, address) => {
if (err) {
- fastify.log.error(err)
- process.exit(1)
+ fastify.log.error(err);
+ process.exit(1);
}
-})
+});
```
指定积压队列 (backlog queue size) 的大小:
```js
-fastify.listen(3000, '127.0.0.1', 511, (err, address) => {
+fastify.listen(3000, "127.0.0.1", 511, (err, address) => {
if (err) {
- fastify.log.error(err)
- process.exit(1)
+ fastify.log.error(err);
+ process.exit(1);
}
-})
+});
```
没有提供回调函数时,它会返回一个 Promise 对象:
```js
-fastify.listen(3000)
+fastify
+ .listen(3000)
.then((address) => console.log(`server listening on ${address}`))
- .catch(err => {
- console.log('Error starting server:', err)
- process.exit(1)
- })
+ .catch((err) => {
+ console.log("Error starting server:", err);
+ process.exit(1);
+ });
```
你还可以在使用 Promise 的同时指定地址:
```js
-fastify.listen(3000, '127.0.0.1')
+fastify
+ .listen(3000, "127.0.0.1")
.then((address) => console.log(`server listening on ${address}`))
- .catch(err => {
- console.log('Error starting server:', err)
- process.exit(1)
- })
+ .catch((err) => {
+ console.log("Error starting server:", err);
+ process.exit(1);
+ });
```
当部署在 Docker 或其它容器上时,明智的做法是监听 `0.0.0.0`。因为默认情况下,这些容器并未将映射的端口暴露在 `127.0.0.1`:
```js
-fastify.listen(3000, '0.0.0.0', (err, address) => {
+fastify.listen(3000, "0.0.0.0", (err, address) => {
if (err) {
- fastify.log.error(err)
- process.exit(1)
+ fastify.log.error(err);
+ process.exit(1);
}
-})
+});
```
假如未设置 `port` (或设为 0),则会自动选择一个随机可用的端口 (之后可通过 `fastify.server.address().port` 获知)。
+
#### getDefaultRoute
+
获取服务器 `defaultRoute` 属性的方法:
```js
-const defaultRoute = fastify.getDefaultRoute()
+const defaultRoute = fastify.getDefaultRoute();
```
+
#### setDefaultRoute
+
设置服务器 `defaultRoute` 属性的方法:
```js
const defaultRoute = function (req, res) {
- res.end('hello world')
-}
+ res.end("hello world");
+};
-fastify.setDefaultRoute(defaultRoute)
+fastify.setDefaultRoute(defaultRoute);
```
+
#### routing
+
访问内部路由库的 `lookup` 方法,该方法将请求匹配到合适的处理函数:
```js
-fastify.routing(req, res)
+fastify.routing(req, res);
```
+
#### route
+
将路由添加到服务器的方法,支持简写。请看[这里](Routes.md)。
+
#### close
+
`fastify.close(callback)`:调用这个函数来关闭服务器实例,并触发 [`'onClose'`](Hooks.md#on-close) 钩子。
服务器会向所有新的请求发送 `503` 错误,并销毁它们。
要改变这一行为,请见 [`return503OnClosing`](Server.md#factory-return-503-on-closing)。
如果无参调用,它会返回一个 Promise:
- ```js
-fastify.close().then(() => {
- console.log('successfully closed!')
-}, (err) => {
- console.log('an error happened', err)
-})
+```js
+fastify.close().then(
+ () => {
+ console.log("successfully closed!");
+ },
+ (err) => {
+ console.log("an error happened", err);
+ },
+);
```
-#### decorate*
+
+#### decorate\*
+
向 Fastify 实例、响应或请求添加装饰器函数。参阅[这里](Decorators.md)了解更多。
+
#### register
+
Fastify 允许用户通过插件扩展功能。插件可以是一组路由、装饰器或其他。请看[这里](Plugins.md)。
+
#### addHook
+
向 Fastify 添加特定的生命周期钩子函数,请看[这里](Hooks.md)。
+
#### prefix
+
添加在路由前的完整路径。
示例:
```js
-fastify.register(function (instance, opts, done) {
- instance.get('/foo', function (request, reply) {
- // 输出:"prefix: /v1"
- request.log.info('prefix: %s', instance.prefix)
- reply.send({prefix: instance.prefix})
- })
+fastify.register(
+ function (instance, opts, done) {
+ instance.get("/foo", function (request, reply) {
+ // 输出:"prefix: /v1"
+ request.log.info("prefix: %s", instance.prefix);
+ reply.send({ prefix: instance.prefix });
+ });
- instance.register(function (instance, opts, done) {
- instance.get('/bar', function (request, reply) {
- // 输出:"prefix: /v1/v2"
- request.log.info('prefix: %s', instance.prefix)
- reply.send({prefix: instance.prefix})
- })
+ instance.register(
+ function (instance, opts, done) {
+ instance.get("/bar", function (request, reply) {
+ // 输出:"prefix: /v1/v2"
+ request.log.info("prefix: %s", instance.prefix);
+ reply.send({ prefix: instance.prefix });
+ });
- done()
- }, { prefix: '/v2' })
+ done();
+ },
+ { prefix: "/v2" },
+ );
- done()
-}, { prefix: '/v1' })
+ done();
+ },
+ { prefix: "/v1" },
+);
```
+
#### pluginName
+
当前插件的名称。有三种定义插件名称的方式(按顺序)。
1. 如果插件使用 [fastify-plugin](https://github.com/fastify/fastify-plugin),那么名称为元数据 (metadata) 中的 `name`。
2. 如果插件通过 `module.exports` 导出,使用文件名。
3. 如果插件通过常规的 [函数定义](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Defining_functions),则使用函数名。
-*回退方案*:插件函数的头两行将作为插件名,并使用 `--` 替代换行符。这有助于在处理涉及许多插件的问题时,找到根源。
+_回退方案_:插件函数的头两行将作为插件名,并使用 `--` 替代换行符。这有助于在处理涉及许多插件的问题时,找到根源。
重点:如果你要处理一些通过 [fastify-plugin](https://github.com/fastify/fastify-plugin) 包装的嵌套的异名插件,由于没有生成新的定义域,因此不会去覆盖上下文数据,而是将各插件名加入一个数组。在这种情况下,会按涉及到的插件的启动顺序,以 `plugin-A -> plugin-B` 的格式来展示插件名称。
+
#### log
+
日志的实例,详见[这里](Logging.md)。
+
#### version
+
Fastify 实例的版本。可在插件中使用。详见[插件](Plugins.md#handle-the-scope)一文。
+
#### inject
+
伪造 HTTP 注入 (作为测试之用) 。请看[更多内容](Testing.md#inject)。
+
#### addSchema
+
`fastify.addSchema(schemaObj)`,向 Fastify 实例添加 JSON schema。你可以通过 `$ref` 关键字在应用的任意位置使用它。
更多内容,请看[验证和序列化](Validation-and-Serialization.md)。
+
#### getSchemas
+
`fastify.getSchemas()`,返回一个对象,包含所有通过 `addSchema` 添加的 schema,对象的键是 JSON schema 的 `$id`。
+
#### getSchema
+
`fastify.getSchema(id)`,返回通过 `addSchema` 添加的拥有匹配 `id` 的 schema,未找到则返回 `undefined`。
+
#### setReplySerializer
+
作用于未设置 [Reply.serializer(func)](Reply.md#serializerfunc) 的所有路由的默认序列化方法。这个处理函数是完全封装的,因此,不同的插件允许有不同的错误处理函数。
注:仅当状态码为 `2xx` 时才被调用。关于错误处理,请看 [`setErrorHandler`](Server.md#seterrorhandler)。
- ```js
-fastify.setReplySerializer(function (payload, statusCode){
+```js
+fastify.setReplySerializer(function (payload, statusCode) {
// 使用同步函数序列化 payload
- return `my serialized ${statusCode} content: ${payload}`
-})
+ return `my serialized ${statusCode} content: ${payload}`;
+});
```
+
#### setValidatorCompiler
+
为所有的路由设置 schema 校验编译器 (validator compiler)。详见 [#schema-validator](Validation-and-Serialization.md#schema-validator)。
+
#### setSchemaErrorFormatter
+
为所有的路由设置 schema 错误格式化器 (schema error formatter)。详见 [#error-handling](Validation-and-Serialization.md#schemaerrorformatter)。
+
#### setSerializerCompiler
+
为所有的路由设置 schema 序列化编译器 (serializer compiler)。详见 [#schema-serializer](Validation-and-Serialization.md#schema-serializer)。
**注:** [`setReplySerializer`](#set-reply-serializer) 有更高的优先级!
+
#### validatorCompiler
+
该属性用于获取 schema 校验器。未设置校验器时,在服务器启动前,该值是 `null`,之后是一个签名为 `function ({ schema, method, url, httpPart })` 的函数。该函数将 `schema` 参数编译为一个校验数据的函数,并返回生成的函数。
`schema` 参数能访问到所有通过 [`.addSchema`](#add-schema) 添加的共用 schema。
+
#### serializerCompiler
+
该属性用于获取 schema 序列化器。未设置序列化器时,在服务器启动前,该值是 `null`,之后是一个签名为 `function ({ schema, method, url, httpPart })` 的函数。该函数将 `schema` 参数编译为一个校验数据的函数,并返回生成的函数。
`schema` 参数能访问到所有通过 [`.addSchema`](#add-schema) 添加的共用 schema。
+
#### schemaErrorFormatter
+
该属性设置一个函数用于格式化 `validationCompiler` 在校验 schema 时发生的错误。详见 [#error-handling](Validation-and-Serialization.md#schemaerrorformatter)。
+
#### schemaController
+
该属性用于管理:
+
- `bucket`:应用的 schema 的存放位置
- `compilersFactory`:必须编译 JSON schema 的模块
@@ -861,27 +992,27 @@ const fastify = Fastify({
* @param {object} parentSchemas 会由 `bucket` 对象的 `getSchemas()` 方法返回。
*/
- bucket: function factory (parentSchemas) {
+ bucket: function factory(parentSchemas) {
return {
- addSchema (inputSchema) {
+ addSchema(inputSchema) {
// 该函数保存用户添加的 schema。
// 调用 `fastify.addSchema()` 时被执行。
},
- getSchema (schema$id) {
+ getSchema(schema$id) {
// 该函数返回通过 `schema$id` 检索得到的原始 schema。
// 调用 `fastify.getSchema()` 时被执行。
- return aSchema
+ return aSchema;
},
- getSchemas () {
+ getSchemas() {
// 返回路由 schema 中通过 $ref 引用的所有 schema。
// 返回对象以 schema 的 `$id` 为键,以原始内容为值。
const allTheSchemaStored = {
- 'schema$id1': schema1,
- 'schema$id2': schema2
- }
- return allTheSchemaStored
- }
- }
+ schema$id1: schema1,
+ schema$id2: schema2,
+ };
+ return allTheSchemaStored;
+ },
+ };
},
/**
@@ -895,13 +1026,13 @@ const fastify = Fastify({
* @param {object} externalSchemas 这些 schema 将被 `bucket.getSchemas()` 返回。需要处理外部引用 $ref。
* @param {object} ajvServerOption 服务器的 `ajv` 选项。
*/
- buildValidator: function factory (externalSchemas, ajvServerOption) {
+ buildValidator: function factory(externalSchemas, ajvServerOption) {
// 该 factory 函数必须返回一个 schema 校验编译器。
// 详见 [#schema-validator](Validation-and-Serialization.md#schema-validator)。
- const yourAjvInstance = new Ajv(ajvServerOption.customOptions)
- return function validatorCompiler ({ schema, method, url, httpPart }) {
- return yourAjvInstance.compile(schema)
- }
+ const yourAjvInstance = new Ajv(ajvServerOption.customOptions);
+ return function validatorCompiler({ schema, method, url, httpPart }) {
+ return yourAjvInstance.compile(schema);
+ };
},
/**
@@ -911,15 +1042,23 @@ const fastify = Fastify({
* @param {object} externalSchemas 这些 schema 将被 `bucket.getSchemas()` 返回。需要处理外部引用 $ref。
* @param {object} serializerOptsServerOption 服务器的 `serializerOpts` 选项。
*/
- buildSerializer: function factory (externalSchemas, serializerOptsServerOption) {
+ buildSerializer: function factory(
+ externalSchemas,
+ serializerOptsServerOption,
+ ) {
// 该 factory 函数必须返回一个 schema 序列化编译器。
// 详见 [#schema-serializer](Validation-and-Serialization.md#schema-serializer)。
- return function serializerCompiler ({ schema, method, url, httpStatus }) {
- return data => JSON.stringify(data)
- }
- }
- }
- }
+ return function serializerCompiler({
+ schema,
+ method,
+ url,
+ httpStatus,
+ }) {
+ return (data) => JSON.stringify(data);
+ };
+ },
+ },
+ },
});
```
@@ -930,30 +1069,31 @@ Ajv 8 是 Ajv 6 的后继版本,拥有许多改进与新特性。Ajv 8 新特
下列代码可以将 Ajv 8 作为默认的 schema 验证器使用:
```js
-const AjvCompiler = require('@fastify/ajv-compiler') // 必须是 v2.x.x 版本
+const AjvCompiler = require("@fastify/ajv-compiler"); // 必须是 v2.x.x 版本
// 请注意,默认情况下 Ajv 8 不支持 schema 的关键词 `format`,
// 因此需要手动添加
-const ajvFormats = require('ajv-formats')
+const ajvFormats = require("ajv-formats");
const app = fastify({
ajv: {
customOptions: {
- validateFormats: true
+ validateFormats: true,
},
- plugins: [ajvFormats]
+ plugins: [ajvFormats],
},
schemaController: {
compilersFactory: {
- buildValidator: AjvCompiler()
- }
- }
-})
+ buildValidator: AjvCompiler(),
+ },
+ },
+});
// 大功告成!现在你可以在 schema 中使用 Ajv 8 的选项与关键词了!
```
+
#### setNotFoundHandler
`fastify.setNotFoundHandler(handler(request, reply))`:为 404 状态 (not found) 设置处理函数 (handler)。向 `fastify.register()` 传递不同的 [`prefix` 选项](Plugins.md#route-prefixing-option),就可以为不同的插件设置不同的处理函数。这些处理函数被视为常规的路由处理函数,因此它们的请求会经历一个完整的 [Fastify 生命周期](Lifecycle.md#lifecycle)。
@@ -963,71 +1103,79 @@ const app = fastify({
_注:通过此方法注册的 `preValidation` 钩子会在遇到未知路由时触发,但手动调用 [`reply.callNotFound`](Reply.md#call-not-found) 方法时则**不会**_。此时只有 preHandler 会执行。
```js
-fastify.setNotFoundHandler({
- preValidation: (req, reply, done) => {
- // 你的代码
- done()
- } ,
- preHandler: (req, reply, done) => {
- // 你的代码
- done()
- }
-}, function (request, reply) {
+fastify.setNotFoundHandler(
+ {
+ preValidation: (req, reply, done) => {
+ // 你的代码
+ done();
+ },
+ preHandler: (req, reply, done) => {
+ // 你的代码
+ done();
+ },
+ },
+ function (request, reply) {
// 设置了 preValidation 与 preHandler 钩子的默认 not found 处理函数
-})
+ },
+);
-fastify.register(function (instance, options, done) {
- instance.setNotFoundHandler(function (request, reply) {
- // '/v1' 开头的 URL 的 not found 处理函数,
- // 未设置 preValidation 与 preHandler 钩子
- })
- done()
-}, { prefix: '/v1' })
+fastify.register(
+ function (instance, options, done) {
+ instance.setNotFoundHandler(function (request, reply) {
+ // '/v1' 开头的 URL 的 not found 处理函数,
+ // 未设置 preValidation 与 preHandler 钩子
+ });
+ done();
+ },
+ { prefix: "/v1" },
+);
```
Fastify 启动时,会在插件注册之前就调用 `setNotFoundHandler` 方法添加默认的 404 处理函数。假如你想拓展默认 404 处理函数的行为,例如与插件一同使用,你可以在插件上下文内,不传参数地调用 `fastify.setNotFoundHandler()`。
+
#### setErrorHandler
-`fastify.setErrorHandler(handler(error, request, reply))`:设置任意时刻的错误处理函数。错误处理函数绑定在 Fastify 实例之上,是完全封装 (fully encapsulated) 的,因此不同插件的处理函数可以不同。支持 *async-await* 语法。
-*注:假如错误的 `statusCode` 小于 400,在处理错误前 Fastify 将会自动将其设为 500。*
+`fastify.setErrorHandler(handler(error, request, reply))`:设置任意时刻的错误处理函数。错误处理函数绑定在 Fastify 实例之上,是完全封装 (fully encapsulated) 的,因此不同插件的处理函数可以不同。支持 _async-await_ 语法。
+_注:假如错误的 `statusCode` 小于 400,在处理错误前 Fastify 将会自动将其设为 500。_
```js
fastify.setErrorHandler(function (error, request, reply) {
// 记录错误
- this.log.error(error)
+ this.log.error(error);
// 发送错误响应
- reply.status(409).send({ ok: false })
-})
+ reply.status(409).send({ ok: false });
+});
```
当没有设置错误处理函数时,Fastify 会调用一个默认函数。你能通过 `fastify.errorHandler` 访问该函数。它根据 `statusCode` 相应地记录日志。
```js
-var statusCode = error.statusCode
+var statusCode = error.statusCode;
if (statusCode >= 500) {
- log.error(error)
+ log.error(error);
} else if (statusCode >= 400) {
- log.info(error)
+ log.info(error);
} else {
- log.error(error)
+ log.error(error);
}
```
+
#### printRoutes
`fastify.printRoutes()`:打印路由的基数树 (radix tree),可作调试之用。可以用 `fastify.printRoutes({ commonPrefix: false })` 来打印扁平化后的路由
-*记得在 `ready` 函数的内部或之后调用它。*
+_记得在 `ready` 函数的内部或之后调用它。_
```js
-fastify.get('/test', () => {})
-fastify.get('/test/hello', () => {})
-fastify.get('/hello/world', () => {})
+fastify.get("/test", () => {});
+fastify.get("/test/hello", () => {});
+fastify.get("/hello/world", () => {});
fastify.ready(() => {
- console.log(fastify.printRoutes())
+ console.log(fastify.printRoutes());
// └── /
// ├── test (GET)
// │ └── /hello (GET)
@@ -1035,63 +1183,67 @@ fastify.ready(() => {
// ├── lo/world (GET)
// └── licopter (GET)
- console.log(fastify.printRoutes({ commonPrefix: false }))
+ console.log(fastify.printRoutes({ commonPrefix: false }));
// └── / (-)
// ├── test (GET)
// │ └── /hello (GET)
// ├── hello/world (GET)
// └── helicopter (GET)
-})
+});
```
`fastify.printRoutes({ includeMeta: (true | []) })` 会打印出路由的 `route.store` 对象上的属性。`includeMeta` 的值可以是属性名的数组 (例如:`['onRequest', Symbol('key')]`),也可以只是一个 `true`,表示显示所有属性。简写 `fastify.printRoutes({ includeHooks: true })` 将包含所有的[钩子](Hooks.md)。
```js
- console.log(fastify.printRoutes({ includeHooks: true, includeMeta: ['metaProperty'] }))
- // └── /
- // ├── test (GET)
- // │ • (onRequest) ["anonymous()","namedFunction()"]
- // │ • (metaProperty) "value"
- // │ └── /hello (GET)
- // └── hel
- // ├── lo/world (GET)
- // │ • (onTimeout) ["anonymous()"]
- // └── licopter (GET)
-
- console.log(fastify.printRoutes({ includeHooks: true }))
- // └── /
- // ├── test (GET)
- // │ • (onRequest) ["anonymous()","namedFunction()"]
- // │ └── /hello (GET)
- // └── hel
- // ├── lo/world (GET)
- // │ • (onTimeout) ["anonymous()"]
- // └── licopter (GET)
+console.log(
+ fastify.printRoutes({ includeHooks: true, includeMeta: ["metaProperty"] }),
+);
+// └── /
+// ├── test (GET)
+// │ • (onRequest) ["anonymous()","namedFunction()"]
+// │ • (metaProperty) "value"
+// │ └── /hello (GET)
+// └── hel
+// ├── lo/world (GET)
+// │ • (onTimeout) ["anonymous()"]
+// └── licopter (GET)
+
+console.log(fastify.printRoutes({ includeHooks: true }));
+// └── /
+// ├── test (GET)
+// │ • (onRequest) ["anonymous()","namedFunction()"]
+// │ └── /hello (GET)
+// └── hel
+// ├── lo/world (GET)
+// │ • (onTimeout) ["anonymous()"]
+// └── licopter (GET)
```
+
#### printPlugins
`fastify.printPlugins()`:打印 avvio 内部的插件树,可用于调试插件注册顺序相关的问题。
-*请在 `ready` 事件的回调中或事件触发之后调用该方法。*
+_请在 `ready` 事件的回调中或事件触发之后调用该方法。_
```js
-fastify.register(async function foo (instance) {
- instance.register(async function bar () {})
-})
-fastify.register(async function baz () {})
+fastify.register(async function foo(instance) {
+ instance.register(async function bar() {});
+});
+fastify.register(async function baz() {});
fastify.ready(() => {
- console.error(fastify.printPlugins())
+ console.error(fastify.printPlugins());
// 输出:
// └── root
// ├── foo
// │ └── bar
// └── baz
-})
+});
```
+
#### addContentTypeParser
`fastify.addContentTypeParser(content-type, options, parser)` 用于给指定 content type 自定义解析器,当你使用自定义的 content types 时会很有帮助。例如 `text/json, application/vnd.oasis.opendocument.text`。`content-type` 是一个字符串、字符串数组或正则表达式。
@@ -1099,47 +1251,64 @@ fastify.ready(() => {
```js
// 传递给 getDefaultJsonParser 的两个参数用于配置原型污染以及构造函数污染,允许的值为 'ignore'、'remove' 和 'error'。设置为 ignore 会跳过校验,和直接调用 JSON.parse() 效果相同。详见 `secure-json-parse` 的文档。
-fastify.addContentTypeParser('text/json', { asString: true }, fastify.getDefaultJsonParser('ignore', 'ignore'))
+fastify.addContentTypeParser(
+ "text/json",
+ { asString: true },
+ fastify.getDefaultJsonParser("ignore", "ignore"),
+);
```
+
#### getDefaultJsonParser
`fastify.getDefaultJsonParser(onProtoPoisoning, onConstructorPoisoning)` 接受两个参数。第一个参数是原型污染的配置,第二个则是构造函数污染的配置。详见 `secure-json-parse` 的文档。
+
#### defaultTextParser
`fastify.defaultTextParser()` 可用于将 content 解析为纯文本。
```js
-fastify.addContentTypeParser('text/json', { asString: true }, fastify.defaultTextParser())
+fastify.addContentTypeParser(
+ "text/json",
+ { asString: true },
+ fastify.defaultTextParser(),
+);
```
+
#### errorHandler
`fastify.errorHandler` 使用 Fastify 默认的错误处理函数来处理错误。
```js
-fastify.get('/', {
- errorHandler: (error, request, reply) => {
- if (error.code === 'SOMETHING_SPECIFIC') {
- reply.send({ custom: 'response' })
- return
- }
+fastify.get(
+ "/",
+ {
+ errorHandler: (error, request, reply) => {
+ if (error.code === "SOMETHING_SPECIFIC") {
+ reply.send({ custom: "response" });
+ return;
+ }
- fastify.errorHandler(error, request, response)
- }
-}, handler)
+ fastify.errorHandler(error, request, response);
+ },
+ },
+ handler,
+);
```
+
#### initialConfig
`fastify.initialConfig`:暴露一个记录了 Fastify 初始选项的只读对象。
当前暴露的属性有:
+
- connectionTimeout
- keepAliveTimeout
- bodyLimit
@@ -1157,23 +1326,23 @@ fastify.get('/', {
- http2SessionTimeout
```js
-const { readFileSync } = require('fs')
-const Fastify = require('fastify')
+const { readFileSync } = require("fs");
+const Fastify = require("fastify");
const fastify = Fastify({
https: {
allowHTTP1: true,
- key: readFileSync('./fastify.key'),
- cert: readFileSync('./fastify.cert')
+ key: readFileSync("./fastify.key"),
+ cert: readFileSync("./fastify.cert"),
},
- logger: { level: 'trace'},
+ logger: { level: "trace" },
ignoreTrailingSlash: true,
maxParamLength: 200,
caseSensitive: true,
- trustProxy: '127.0.0.1,192.168.1.1/24',
-})
+ trustProxy: "127.0.0.1,192.168.1.1/24",
+});
-console.log(fastify.initialConfig)
+console.log(fastify.initialConfig);
/*
输出:
{
@@ -1185,8 +1354,8 @@ console.log(fastify.initialConfig)
*/
fastify.register(async (instance, opts) => {
- instance.get('/', async (request, reply) => {
- return instance.initialConfig
+ instance.get("/", async (request, reply) => {
+ return instance.initialConfig;
/*
返回:
{
@@ -1196,22 +1365,22 @@ fastify.register(async (instance, opts) => {
maxParamLength: 200
}
*/
- })
+ });
- instance.get('/error', async (request, reply) => {
+ instance.get("/error", async (request, reply) => {
// 会抛出错误
// 因为 initialConfig 是只读的,不可修改
- instance.initialConfig.https.allowHTTP1 = false
+ instance.initialConfig.https.allowHTTP1 = false;
- return instance.initialConfig
- })
-})
+ return instance.initialConfig;
+ });
+});
// 开始监听
fastify.listen(3000, (err) => {
if (err) {
- fastify.log.error(err)
- process.exit(1)
+ fastify.log.error(err);
+ process.exit(1);
}
-})
+});
```
diff --git a/doc/fastify-docs/docs/Serverless.md b/doc/fastify-docs/docs/Serverless.md
index 094d152..f71e917 100644
--- a/doc/fastify-docs/docs/Serverless.md
+++ b/doc/fastify-docs/docs/Serverless.md
@@ -21,16 +21,16 @@ Fastify 无法直接运行在无服务器平台上,需要做一点修改。本
以下是使用 Fastify 在 AWS Lambda 和 Amazon API Gateway 架构上构建无服务器 web 应用/服务的示例。
-*注:使用 [aws-lambda-fastify](https://github.com/fastify/aws-lambda-fastify) 仅是一种可行方案。*
+_注:使用 [aws-lambda-fastify](https://github.com/fastify/aws-lambda-fastify) 仅是一种可行方案。_
### app.js
```js
-const fastify = require('fastify');
+const fastify = require("fastify");
function init() {
const app = fastify();
- app.get('/', (request, reply) => reply.send({ hello: 'world' }));
+ app.get("/", (request, reply) => reply.send({ hello: "world" }));
return app;
}
@@ -38,7 +38,7 @@ if (require.main === module) {
// 直接调用,即执行 "node app"
init().listen(3000, (err) => {
if (err) console.error(err);
- console.log('server listening on 3000');
+ console.log("server listening on 3000");
});
} else {
// 作为模块引入 => 用于 aws lambda
@@ -52,16 +52,16 @@ if (require.main === module) {
在 [`lambda.js`](https://www.fastify.io/docs/latest/Serverless/#lambda-js) 里,我们会用到它。
当像往常一样运行 Fastify 应用,
-比如执行 `node app.js` 时 *(可以用 `require.main === module` 来判断)*,
+比如执行 `node app.js` 时 _(可以用 `require.main === module` 来判断)_,
你可以监听某个端口,如此便能本地运行应用了。
### lambda.js
```js
-const awsLambdaFastify = require('aws-lambda-fastify')
-const init = require('./app');
+const awsLambdaFastify = require("aws-lambda-fastify");
+const init = require("./app");
-const proxy = awsLambdaFastify(init())
+const proxy = awsLambdaFastify(init());
// 或
// const proxy = awsLambdaFastify(init(), { binaryMimeTypes: ['application/octet-stream'] })
@@ -82,7 +82,6 @@ exports.handler = proxy;
你可以在[这里](https://github.com/claudiajs/example-projects/tree/master/fastify-app-lambda)找到使用 [claudia.js](https://claudiajs.com/tutorials/serverless-express.html) 的可部署的例子。
-
### 注意事项
- 你没法操作 [stream](https://www.fastify.io/docs/latest/Reply/#streams),因为 API Gateway 还不支持它。
@@ -92,7 +91,7 @@ exports.handler = proxy;
与 AWS Lambda 和 Google Cloud Functions 不同,Google Cloud Run 是一个无服务器**容器**环境。它的首要目的是提供一个能运行任意容器的底层抽象 (infrastucture-abstracted) 的环境。因此,你能将 Fastify 部署在 Google Cloud Run 上,而且相比正常的写法,只需要改动极少的代码。
-*参照以下步骤部署 Google Cloud Run。如果你对 gcloud 还不熟悉,请看其[入门文档](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)*。
+_参照以下步骤部署 Google Cloud Run。如果你对 gcloud 还不熟悉,请看其[入门文档](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)_。
### 调整 Fastify 服务器
@@ -100,35 +99,35 @@ exports.handler = proxy;
```js
function build() {
- const fastify = Fastify({ trustProxy: true })
- return fastify
+ const fastify = Fastify({ trustProxy: true });
+ return fastify;
}
async function start() {
// Google Cloud Run 会设置这一环境变量,
// 因此,你可以使用它判断程序是否运行在 Cloud Run 之中
- const IS_GOOGLE_CLOUD_RUN = process.env.K_SERVICE !== undefined
+ const IS_GOOGLE_CLOUD_RUN = process.env.K_SERVICE !== undefined;
// 监听 Cloud Run 提供的端口
- const port = process.env.PORT || 3000
+ const port = process.env.PORT || 3000;
// 监听 Cloud Run 中所有的 IPV4 地址
- const address = IS_GOOGLE_CLOUD_RUN ? "0.0.0.0" : undefined
+ const address = IS_GOOGLE_CLOUD_RUN ? "0.0.0.0" : undefined;
try {
- const server = build()
- const address = await server.listen(port, address)
- console.log(`Listening on ${address}`)
+ const server = build();
+ const address = await server.listen(port, address);
+ console.log(`Listening on ${address}`);
} catch (err) {
- console.error(err)
- process.exit(1)
+ console.error(err);
+ process.exit(1);
}
}
-module.exports = build
+module.exports = build;
if (require.main === module) {
- start()
+ start();
}
```
@@ -197,7 +196,7 @@ gcloud beta run deploy --image gcr.io/PROJECT-ID/APP-NAME --platform managed
### functions/server.js
```js
-export { handler } from '../lambda.js'; // 记得将路径修改为你的应用中对应的 `lambda.js` 的路径
+export { handler } from "../lambda.js"; // 记得将路径修改为你的应用中对应的 `lambda.js` 的路径
```
### netlify.toml
@@ -218,12 +217,12 @@ export { handler } from '../lambda.js'; // 记得将路径修改为你的应用
**别忘记添加这个文件,否则会有不少问题**
```js
-const nodeExternals = require('webpack-node-externals');
-const dotenv = require('dotenv-safe');
-const webpack = require('webpack');
+const nodeExternals = require("webpack-node-externals");
+const dotenv = require("dotenv-safe");
+const webpack = require("webpack");
-const env = process.env.NODE_ENV || 'production';
-const dev = env === 'development';
+const env = process.env.NODE_ENV || "production";
+const dev = env === "development";
if (dev) {
dotenv.config({ allowEmptyValues: true });
@@ -231,32 +230,32 @@ if (dev) {
module.exports = {
mode: env,
- devtool: dev ? 'eval-source-map' : 'none',
+ devtool: dev ? "eval-source-map" : "none",
externals: [nodeExternals()],
devServer: {
proxy: {
- '/.netlify': {
- target: 'http://localhost:9000',
- pathRewrite: { '^/.netlify/functions': '' }
- }
- }
+ "/.netlify": {
+ target: "http://localhost:9000",
+ pathRewrite: { "^/.netlify/functions": "" },
+ },
+ },
},
module: {
- rules: []
+ rules: [],
},
plugins: [
new webpack.DefinePlugin({
- 'process.env.APP_ROOT_PATH': JSON.stringify('/'),
- 'process.env.NETLIFY_ENV': true,
- 'process.env.CONTEXT': env
- })
- ]
+ "process.env.APP_ROOT_PATH": JSON.stringify("/"),
+ "process.env.NETLIFY_ENV": true,
+ "process.env.CONTEXT": env,
+ }),
+ ],
};
```
### Scripts
-在 `package.json` 的 *scripts* 里加上这一命令
+在 `package.json` 的 _scripts_ 里加上这一命令
```json
"scripts": {
@@ -305,6 +304,6 @@ app.register(import("../src/app"));
export default async (req, res) => {
await app.ready();
- app.server.emit('request', req, res);
-}
-```
\ No newline at end of file
+ app.server.emit("request", req, res);
+};
+```
diff --git a/doc/fastify-docs/docs/Testing.md b/doc/fastify-docs/docs/Testing.md
index a2fc20a..e7997a6 100644
--- a/doc/fastify-docs/docs/Testing.md
+++ b/doc/fastify-docs/docs/Testing.md
@@ -15,40 +15,40 @@
**app.js**:
```js
-'use strict'
+"use strict";
-const fastify = require('fastify')
+const fastify = require("fastify");
-function build(opts={}) {
- const app = fastify(opts)
- app.get('/', async function (request, reply) {
- return { hello: 'world' }
- })
+function build(opts = {}) {
+ const app = fastify(opts);
+ app.get("/", async function (request, reply) {
+ return { hello: "world" };
+ });
- return app
+ return app;
}
-module.exports = build
+module.exports = build;
```
**server.js**:
```js
-'use strict'
+"use strict";
-const server = require('./app')({
+const server = require("./app")({
logger: {
- level: 'info',
- prettyPrint: true
- }
-})
+ level: "info",
+ prettyPrint: true,
+ },
+});
server.listen(3000, (err, address) => {
if (err) {
- console.log(err)
- process.exit(1)
+ console.log(err);
+ process.exit(1);
}
-})
+});
```
### 使用 fastify.inject() 的好处
@@ -60,22 +60,22 @@ server.listen(3000, (err, address) => {
**app.test.js**:
```js
-'use strict'
+"use strict";
-const build = require('./app')
+const build = require("./app");
const test = async () => {
- const app = build()
+ const app = build();
const response = await app.inject({
- method: 'GET',
- url: '/'
- })
+ method: "GET",
+ url: "/",
+ });
- console.log('status code: ', response.statusCode)
- console.log('body: ', response.body)
-}
-test()
+ console.log("status code: ", response.statusCode);
+ console.log("body: ", response.body);
+};
+test();
```
我们的代码运行在异步函数里,因此可以使用 async/await。
@@ -100,36 +100,40 @@ body: {"hello":"world"}
**app.test.js**:
```js
-'use strict'
+"use strict";
-const { test } = require('tap')
-const build = require('./app')
+const { test } = require("tap");
+const build = require("./app");
-test('requests the "/" route', async t => {
- const app = build()
+test('requests the "/" route', async (t) => {
+ const app = build();
const response = await app.inject({
- method: 'GET',
- url: '/'
- })
- t.equal(response.statusCode, 200, 'returns a status code of 200')
-})
+ method: "GET",
+ url: "/",
+ });
+ t.equal(response.statusCode, 200, "returns a status code of 200");
+});
```
执行 `npm test`,查看结果!
`inject` 方法能完成的不只有简单的 GET 请求:
+
```js
-fastify.inject({
- method: String,
- url: String,
- query: Object,
- payload: Object,
- headers: Object,
- cookies: Object
-}, (error, response) => {
- // 你的测试
-})
+fastify.inject(
+ {
+ method: String,
+ url: String,
+ query: Object,
+ payload: Object,
+ headers: Object,
+ cookies: Object,
+ },
+ (error, response) => {
+ // 你的测试
+ },
+);
```
忽略回调函数,可以链式调用 `.inject` 提供的方法:
@@ -137,12 +141,13 @@ fastify.inject({
```js
fastify
.inject()
- .get('/')
- .headers({ foo: 'bar' })
- .query({ foo: 'bar' })
- .end((err, res) => { // 调用 .end 触发请求
- console.log(res.payload)
- })
+ .get("/")
+ .headers({ foo: "bar" })
+ .query({ foo: "bar" })
+ .end((err, res) => {
+ // 调用 .end 触发请求
+ console.log(res.payload);
+ });
```
或是用 promise 的版本
@@ -155,20 +160,26 @@ fastify
query: Object,
payload: Object,
headers: Object,
- cookies: Object
+ cookies: Object,
})
- .then(response => {
+ .then((response) => {
// 你的测试
})
- .catch(err => {
+ .catch((err) => {
// 处理错误
- })
+ });
```
Async await 也是支持的!
+
```js
try {
- const res = await fastify.inject({ method: String, url: String, payload: Object, headers: Object })
+ const res = await fastify.inject({
+ method: String,
+ url: String,
+ payload: Object,
+ headers: Object,
+ });
// 你的测试
} catch (err) {
// 处理错误
@@ -178,49 +189,58 @@ try {
#### 另一个例子:
**app.js**
+
```js
-const Fastify = require('fastify')
+const Fastify = require("fastify");
-function buildFastify () {
- const fastify = Fastify()
+function buildFastify() {
+ const fastify = Fastify();
- fastify.get('/', function (request, reply) {
- reply.send({ hello: 'world' })
- })
-
- return fastify
+ fastify.get("/", function (request, reply) {
+ reply.send({ hello: "world" });
+ });
+
+ return fastify;
}
-module.exports = buildFastify
+module.exports = buildFastify;
```
**test.js**
+
```js
-const tap = require('tap')
-const buildFastify = require('./app')
+const tap = require("tap");
+const buildFastify = require("./app");
-tap.test('GET `/` route', t => {
- t.plan(4)
+tap.test("GET `/` route", (t) => {
+ t.plan(4);
- const fastify = buildFastify()
+ const fastify = buildFastify();
// 在测试的最后,我们强烈建议你调用 `.close()`
// 方法来确保所有与外部服务的连接被关闭。
- t.teardown(() => fastify.close())
+ t.teardown(() => fastify.close());
- fastify.inject({
- method: 'GET',
- url: '/'
- }, (err, response) => {
- t.error(err)
- t.equal(response.statusCode, 200)
- t.equal(response.headers['content-type'], 'application/json; charset=utf-8')
- t.same(response.json(), { hello: 'world' })
- })
-})
+ fastify.inject(
+ {
+ method: "GET",
+ url: "/",
+ },
+ (err, response) => {
+ t.error(err);
+ t.equal(response.statusCode, 200);
+ t.equal(
+ response.headers["content-type"],
+ "application/json; charset=utf-8",
+ );
+ t.same(response.json(), { hello: "world" });
+ },
+ );
+});
```
### 测试正在运行的服务器
+
你还可以在 fastify.listen() 启动服务器之后,或是 fastify.ready() 初始化路由与插件之后,进行 Fastify 的测试。
#### 举例:
@@ -228,67 +248,81 @@ tap.test('GET `/` route', t => {
使用之前例子的 **app.js**。
**test-listen.js** (用 [`Request`](https://www.npmjs.com/package/request) 测试)
+
```js
-const tap = require('tap')
-const request = require('request')
-const buildFastify = require('./app')
+const tap = require("tap");
+const request = require("request");
+const buildFastify = require("./app");
-tap.test('GET `/` route', t => {
- t.plan(5)
+tap.test("GET `/` route", (t) => {
+ t.plan(5);
- const fastify = buildFastify()
+ const fastify = buildFastify();
- t.teardown(() => fastify.close())
+ t.teardown(() => fastify.close());
fastify.listen(0, (err) => {
- t.error(err)
-
- request({
- method: 'GET',
- url: 'http://localhost:' + fastify.server.address().port
- }, (err, response, body) => {
- t.error(err)
- t.equal(response.statusCode, 200)
- t.equal(response.headers['content-type'], 'application/json; charset=utf-8')
- t.same(JSON.parse(body), { hello: 'world' })
- })
- })
-})
+ t.error(err);
+
+ request(
+ {
+ method: "GET",
+ url: "http://localhost:" + fastify.server.address().port,
+ },
+ (err, response, body) => {
+ t.error(err);
+ t.equal(response.statusCode, 200);
+ t.equal(
+ response.headers["content-type"],
+ "application/json; charset=utf-8",
+ );
+ t.same(JSON.parse(body), { hello: "world" });
+ },
+ );
+ });
+});
```
**test-ready.js** (用 [`SuperTest`](https://www.npmjs.com/package/supertest) 测试)
+
```js
-const tap = require('tap')
-const supertest = require('supertest')
-const buildFastify = require('./app')
+const tap = require("tap");
+const supertest = require("supertest");
+const buildFastify = require("./app");
-tap.test('GET `/` route', async (t) => {
- const fastify = buildFastify()
+tap.test("GET `/` route", async (t) => {
+ const fastify = buildFastify();
- t.teardown(() => fastify.close())
+ t.teardown(() => fastify.close());
- await fastify.ready()
+ await fastify.ready();
const response = await supertest(fastify.server)
- .get('/')
+ .get("/")
.expect(200)
- .expect('Content-Type', 'application/json; charset=utf-8')
- t.same(response.body, { hello: 'world' })
-})
+ .expect("Content-Type", "application/json; charset=utf-8");
+ t.same(response.body, { hello: "world" });
+});
```
### 如何检测 tap 的测试
+
1. 设置 `{only: true}` 选项,将需要检测的测试与其他测试分离
+
```javascript
test('should ...', {only: true}, t => ...)
```
+
2. 通过 `npx` 运行 `tap`
+
```bash
> npx tap -O -T --node-arg=--inspect-brk test/
```
+
- `-O` 表示开启 `only` 选项,只运行设置了 `{only: true}` 的测试
- `-T` 表示不设置超时
- `--node-arg=--inspect-brk` 会启动 node 调试工具
+
3. 在 VS Code 中创建并运行一个 `Node.js: Attach` 调试配置,不需要额外修改。
-现在你便可以在编辑器中检测你的测试文件 (以及 `Fastify` 的其他部分) 了。
\ No newline at end of file
+现在你便可以在编辑器中检测你的测试文件 (以及 `Fastify` 的其他部分) 了。
diff --git a/doc/fastify-docs/docs/TypeScript.md b/doc/fastify-docs/docs/TypeScript.md
index 274eb2f..06c3ebb 100644
--- a/doc/fastify-docs/docs/TypeScript.md
+++ b/doc/fastify-docs/docs/TypeScript.md
@@ -21,44 +21,50 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
这个例子展示了如何使用 Fastify 和 TypeScript 构建一个最简单的 http 服务器。
1. 创建一个 npm 项目,安装 Fastify、typescript 和 node.js 的类型文件:
- ```bash
- npm init -y
- npm i fastify
- npm i -D typescript @types/node
- ```
+
+```bash
+npm init -y
+npm i fastify
+npm i -D typescript @types/node
+```
+
2. 在 `package.json` 的 `"scripts"` 里添加以下内容:
- ```json
- {
- "scripts": {
- "build": "tsc -p tsconfig.json",
- "start": "node index.js"
- }
+
+```json
+{
+ "scripts": {
+ "build": "tsc -p tsconfig.json",
+ "start": "node index.js"
}
- ```
+}
+```
+
3. 初始化 TypeScript 配置文件:
- ```bash
- npx tsc --init
- ```
- 或使用一个[推荐的配置文件](https://github.com/tsconfig/bases#node-10-tsconfigjson)。
-4. 创建 `index.ts` ,在此编写服务器的代码。
-5. 将下列代码添加到该文件中:
- ```typescript
- import fastify from 'fastify'
- const server = fastify()
+```bash
+npx tsc --init
+```
- server.get('/ping', async (request, reply) => {
- return 'pong\n'
- })
+或使用一个[推荐的配置文件](https://github.com/tsconfig/bases#node-10-tsconfigjson)。4. 创建 `index.ts` ,在此编写服务器的代码。5. 将下列代码添加到该文件中:
+
+```typescript
+import fastify from "fastify";
+
+const server = fastify();
+
+server.get("/ping", async (request, reply) => {
+ return "pong\n";
+});
+
+server.listen(8080, (err, address) => {
+ if (err) {
+ console.error(err);
+ process.exit(1);
+ }
+ console.log(`Server listening at ${address}`);
+});
+```
- server.listen(8080, (err, address) => {
- if (err) {
- console.error(err)
- process.exit(1)
- }
- console.log(`Server listening at ${address}`)
- })
- ```
6. 执行 `npm run build`。这么做会将 `index.ts` 编译为能被 Node.js 运行的 `index.js`。如果遇到了错误,请在 [fastify/help](https://github.com/fastify/help/) 发布 issue。
7. 执行 `npm run start` 来启动 Fastify 服务器。
8. 你将看到控制台输出: `Server listening at http://127.0.0.1:8080`。
@@ -74,6 +80,7 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
1. 照着上面例子的 1-4 步来初始化项目。
2. 在 `index.ts` 中定义两个接口 (interface),`IQuerystring` 和 `IHeaders`:
+
```typescript
interface IQuerystring {
username: string;
@@ -81,21 +88,23 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
}
interface IHeaders {
- 'h-Custom': string;
+ "h-Custom": string;
}
```
+
3. 使用这两个接口,定义一个新的 API 路由,并将它们用作泛型。路由方法的简写形式 (如 `.get`) 接受一个泛型对象 `RouteGenericInterface`,它包含了五个具名属性:`Body`、`Querystring`、`Params`、`Headers` 以及 `Reply`。`Body`、`Querystring`、`Params` 和 `Headers` 四个接口会随着路由方法向下传递,到达路由处理函数中的 `request` 实例,`Reply` 接口则会到达 `reply` 实例。
+
```typescript
server.get<{
- Querystring: IQuerystring,
- Headers: IHeaders
- }>('/auth', async (request, reply) => {
- const { username, password } = request.query
- const customerHeader = request.headers['h-Custom']
+ Querystring: IQuerystring;
+ Headers: IHeaders;
+ }>("/auth", async (request, reply) => {
+ const { username, password } = request.query;
+ const customerHeader = request.headers["h-Custom"];
// 处理请求数据
- return `logged in!`
- })
+ return `logged in!`;
+ });
```
4. 执行 `npm run build` 和 `npm run start` 来构建并运行项目。
@@ -107,23 +116,27 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
6. 此外,泛型接口还可以用在路由层钩子方法中。在上面的路由内加上一个 `preValidation` 钩子:
```typescript
server.get<{
- Querystring: IQuerystring,
- Headers: IHeaders
- }>('/auth', {
- preValidation: (request, reply, done) => {
- const { username, password } = request.query
- done(username !== 'admin' ? new Error('Must be admin') : undefined)
- }
- // 或使用 async
- // preValidation: async (request, reply) => {
- // const { username, password } = request.query
- // return username !== "admin" ? new Error("Must be admin") : undefined;
- // }
- }, async (request, reply) => {
- const customerHeader = request.headers['h-Custom']
- // 处理请求数据
- return `logged in!`
- })
+ Querystring: IQuerystring;
+ Headers: IHeaders;
+ }>(
+ "/auth",
+ {
+ preValidation: (request, reply, done) => {
+ const { username, password } = request.query;
+ done(username !== "admin" ? new Error("Must be admin") : undefined);
+ },
+ // 或使用 async
+ // preValidation: async (request, reply) => {
+ // const { username, password } = request.query
+ // return username !== "admin" ? new Error("Must be admin") : undefined;
+ // }
+ },
+ async (request, reply) => {
+ const customerHeader = request.headers["h-Custom"];
+ // 处理请求数据
+ return `logged in!`;
+ },
+ );
```
7. 构建运行之后,使用任何值不为 `admin` 的 `username` 查询字符串访问服务。你将收到一个 500 错误:`{"statusCode":500,"error":"Internal Server Error","message":"Must be admin"}`
@@ -145,50 +158,50 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
1. 安装 `typebox`。
- ```bash
- npm i @sinclair/typebox
- ```
+ ```bash
+ npm i @sinclair/typebox
+ ```
2. 使用 `Type` 定义 schema,并通过 `Static` 创建相应的类型。
- ```typescript
- import { Static, Type } from '@sinclair/typebox'
+ ```typescript
+ import { Static, Type } from "@sinclair/typebox";
- const User = Type.Object({
- name: Type.String(),
- mail: Type.Optional(Type.String({ format: "email" })),
- });
- type UserType = Static;
- ```
+ const User = Type.Object({
+ name: Type.String(),
+ mail: Type.Optional(Type.String({ format: "email" })),
+ });
+ type UserType = Static;
+ ```
3. 在路由中使用定义好的类型与 schema。
- ```typescript
- const app = fastify();
+ ```typescript
+ const app = fastify();
- app.post<{ Body: UserType; Reply: UserType }>(
- "/",
- {
- schema: {
- body: User,
- response: {
- 200: User,
- },
- },
- },
- (req, rep) => {
- const { body: user } = req;
- /* user 的类型如下:
+ app.post<{ Body: UserType; Reply: UserType }>(
+ "/",
+ {
+ schema: {
+ body: User,
+ response: {
+ 200: User,
+ },
+ },
+ },
+ (req, rep) => {
+ const { body: user } = req;
+ /* user 的类型如下:
* const user: StaticProperties<{
* name: TString;
* mail: TOptional;
* }>
*/
- //...
- rep.status(200).send(user);
- }
- );
- ```
+ //...
+ rep.status(200).send(user);
+ },
+ );
+ ```
#### Schemas in JSON Files
@@ -239,70 +252,76 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
```
`json2ts` 是囊括在 `json-schema-to-typescript` 中的命令行工具。`schemas` 是输入路径,`types` 则是输出路径。
+
5. 执行 `npm run compile-schemas`,在 `types` 文件夹下生成两个新文件。
6. 更新 `index.ts`:
```typescript
- import fastify from 'fastify'
+ import fastify from "fastify";
// 导入 json schema
- import QuerystringSchema from './schemas/querystring.json'
- import HeadersSchema from './schemas/headers.json'
+ import QuerystringSchema from "./schemas/querystring.json";
+ import HeadersSchema from "./schemas/headers.json";
// 导入生成的接口
- import { QuerystringSchema as QuerystringSchemaInterface } from './types/querystring'
- import { HeadersSchema as HeadersSchemaInterface } from './types/headers'
+ import { QuerystringSchema as QuerystringSchemaInterface } from "./types/querystring";
+ import { HeadersSchema as HeadersSchemaInterface } from "./types/headers";
- const server = fastify()
+ const server = fastify();
server.get<{
- Querystring: QuerystringSchemaInterface,
- Headers: HeadersSchemaInterface
- }>('/auth', {
- schema: {
- querystring: QuerystringSchema,
- headers: HeadersSchema
+ Querystring: QuerystringSchemaInterface;
+ Headers: HeadersSchemaInterface;
+ }>(
+ "/auth",
+ {
+ schema: {
+ querystring: QuerystringSchema,
+ headers: HeadersSchema,
+ },
+ preValidation: (request, reply, done) => {
+ const { username, password } = request.query;
+ done(username !== "admin" ? new Error("Must be admin") : undefined);
+ },
},
- preValidation: (request, reply, done) => {
- const { username, password } = request.query
- done(username !== 'admin' ? new Error('Must be admin') : undefined)
- }
- }, async (request, reply) => {
- const customerHeader = request.headers['h-Custom']
- // 处理请求数据
- return `logged in!`
- })
+ async (request, reply) => {
+ const customerHeader = request.headers["h-Custom"];
+ // 处理请求数据
+ return `logged in!`;
+ },
+ );
server.route<{
- Querystring: QuerystringSchemaInterface,
- Headers: HeadersSchemaInterface
+ Querystring: QuerystringSchemaInterface;
+ Headers: HeadersSchemaInterface;
}>({
- method: 'GET',
- url: '/auth2',
+ method: "GET",
+ url: "/auth2",
schema: {
querystring: QuerystringSchema,
- headers: HeadersSchema
+ headers: HeadersSchema,
},
preHandler: (request, reply, done) => {
- const { username, password } = request.query
- const customerHeader = request.headers['h-Custom']
- done()
+ const { username, password } = request.query;
+ const customerHeader = request.headers["h-Custom"];
+ done();
},
handler: (request, reply) => {
- const { username, password } = request.query
- const customerHeader = request.headers['h-Custom']
- reply.status(200).send({username});
- }
- })
+ const { username, password } = request.query;
+ const customerHeader = request.headers["h-Custom"];
+ reply.status(200).send({ username });
+ },
+ });
server.listen(8080, (err, address) => {
if (err) {
- console.error(err)
- process.exit(0)
+ console.error(err);
+ process.exit(0);
}
- console.log(`Server listening at ${address}`)
- })
+ console.log(`Server listening at ${address}`);
+ });
```
+
要特别关注文件顶部的导入。虽然看上去有些多余,但你必须同时导入 schema 与生成的接口。
真棒!现在你就能同时运用 JSON Schema 与 TypeScript 的定义了。
@@ -317,17 +336,17 @@ Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并
npm install -D json-schema-to-ts
```
-你可以像定义正常的对象一样定义 schema。但得注意要用 *const* 来定义,原因见该模块的文档。
+你可以像定义正常的对象一样定义 schema。但得注意要用 _const_ 来定义,原因见该模块的文档。
```typescript
const todo = {
- type: 'object',
+ type: "object",
properties: {
- name: { type: 'string' },
- description: { type: 'string' },
- done: { type: 'boolean' },
+ name: { type: "string" },
+ description: { type: "string" },
+ done: { type: "boolean" },
},
- required: ['name'],
+ required: ["name"],
} as const;
```
@@ -336,19 +355,18 @@ const todo = {
```typescript
import { FromSchema } from "json-schema-to-ts";
fastify.post<{ Body: FromSchema }>(
- '/todo',
+ "/todo",
{
schema: {
body: todo,
response: {
201: {
- type: 'string',
+ type: "string",
},
},
- }
+ },
},
async (request, reply): Promise => {
-
/*
request.body 的类型如下:
{
@@ -359,9 +377,9 @@ fastify.post<{ Body: FromSchema }>(
}
*/
- request.body.name // 不会抛出类型错误
- request.body.notthere // 会抛出类型错误
-
+ request.body.name; // 不会抛出类型错误
+ request.body.notthere; // 会抛出类型错误
+
reply.status(201).send();
},
);
@@ -402,44 +420,53 @@ fastify.post<{ Body: FromSchema }>(
```
4. 新建 `index.ts` 文件,在这里编写插件代码。
5. 在 `index.ts` 中写入以下代码。
+
```typescript
- import { FastifyPluginCallback, FastifyPluginAsync } from 'fastify'
- import fp from 'fastify-plugin'
+ import { FastifyPluginCallback, FastifyPluginAsync } from "fastify";
+ import fp from "fastify-plugin";
// 利用声明合并,将插件的属性加入合适的 fastify 接口。
- declare module 'fastify' {
+ declare module "fastify" {
interface FastifyRequest {
- myPluginProp: string
+ myPluginProp: string;
}
interface FastifyReply {
- myPluginProp: number
+ myPluginProp: number;
}
}
// 定义选项
export interface MyPluginOptions {
- myPluginOption: string
+ myPluginOption: string;
}
// 使用回调函数定义插件
- const myPluginCallback: FastifyPluginCallback = (fastify, options, done) => {
- fastify.decorateRequest('myPluginProp', 'super_secret_value')
- fastify.decorateReply('myPluginProp', options.myPluginOption)
+ const myPluginCallback: FastifyPluginCallback = (
+ fastify,
+ options,
+ done,
+ ) => {
+ fastify.decorateRequest("myPluginProp", "super_secret_value");
+ fastify.decorateReply("myPluginProp", options.myPluginOption);
- done()
- }
+ done();
+ };
// 使用 promise 定义插件
- const myPluginAsync: FastifyPluginAsync = async (fastify, options) => {
- fastify.decorateRequest('myPluginProp', 'super_secret_value')
- fastify.decorateReply('myPluginProp', options.myPluginOption)
- }
+ const myPluginAsync: FastifyPluginAsync = async (
+ fastify,
+ options,
+ ) => {
+ fastify.decorateRequest("myPluginProp", "super_secret_value");
+ fastify.decorateReply("myPluginProp", options.myPluginOption);
+ };
// 使用 fastify-plugin 导出插件
- export default fp(myPluginCallback, '3.x')
+ export default fp(myPluginCallback, "3.x");
// 或者
// export default fp(myPluginAsync, '3.x')
```
+
6. 运行 `npm run build` 编译,生成 JavaScript 源文件以及类型定义文件。
7. 如此一来,插件便完工了。你可以[发布到 npm] 或直接本地使用。
> 并非将插件发布到 npm _才能_ 使用。你可以将其放在 Fastify 项目内,并像引用任意代码一样引用它!请确保声明文件在项目编译的范围内,以便能被 TypeScript 处理器使用。
@@ -462,28 +489,30 @@ fastify.post<{ Body: FromSchema }>(
}
```
4. 在 `index.js` 中加入以下代码:
+
```javascript
// 极力推荐使用 fastify-plugin 包装插件
- const fp = require('fastify-plugin')
-
- function myPlugin (instance, options, done) {
+ const fp = require("fastify-plugin");
+ function myPlugin(instance, options, done) {
// 用自定义函数 myPluginFunc 装饰 fastify 实例
- instance.decorate('myPluginFunc', (input) => {
- return input.toUpperCase()
- })
+ instance.decorate("myPluginFunc", (input) => {
+ return input.toUpperCase();
+ });
- done()
+ done();
}
-
+
module.exports = fp(myPlugin, {
- fastify: '3.x',
- name: 'my-plugin' // 被 fastify-plugin 用来获取属性名
- })
+ fastify: "3.x",
+ name: "my-plugin", // 被 fastify-plugin 用来获取属性名
+ });
```
+
5. 在 `index.d.ts` 中加入以下代码:
+
```typescript
- import { FastifyPlugin } from 'fastify'
+ import { FastifyPlugin } from "fastify";
interface PluginOptions {
//...
@@ -491,24 +520,24 @@ fastify.post<{ Body: FromSchema }>(
// 你可以导出任意内容
// 在此,我们导出之前添加的装饰器
export interface myPluginFunc {
- (input: string): string
+ (input: string): string;
}
// 利用声明合并将自定义属性加入 Fastify 的类型系统
- declare module 'fastify' {
+ declare module "fastify" {
interface FastifyInstance {
- myPluginFunc: myPluginFunc
+ myPluginFunc: myPluginFunc;
}
}
// fastify-plugin 会自动添加具名导出,因此请确保加上该类型。
// 如果缺少 `module.exports.myPlugin`,变量名会通过 `options.name` 属性获取。
- export const myPlugin: FastifyPlugin
+ export const myPlugin: FastifyPlugin;
// fastify-plugin 会自动在导出的插件上添加 `.default` 属性。详见下文。
- export default myPlugin
+ export default myPlugin;
```
-__注意__:v2.3.0 及以上版本的 [fastify-plugin](https://github.com/fastify/fastify-plugin) 会自动给导出的插件添加 `default` 属性以及具名导出。为了更好的开发体验,请确保在类型文件中加上了 `export default` 与 `export const myPlugin`。完整的例子可以查看 [fastify-swagger](https://github.com/fastify/fastify-swagger/blob/main/index.d.ts)。
+**注意**:v2.3.0 及以上版本的 [fastify-plugin](https://github.com/fastify/fastify-plugin) 会自动给导出的插件添加 `default` 属性以及具名导出。为了更好的开发体验,请确保在类型文件中加上了 `export default` 与 `export const myPlugin`。完整的例子可以查看 [fastify-swagger](https://github.com/fastify/fastify-swagger/blob/main/index.d.ts)。
这样一来,该插件便能被任意 TypeScript 项目使用了!
@@ -521,6 +550,7 @@ Fastify 的插件系统允许开发者装饰 Fastify 以及 request/reply 的实
Fastify 插件使用声明合并来修改已有的 Fastify 类型接口 (详见上一个例子)。声明合并没有那么 _聪明_,只要插件的类型定义在 TypeScript 解释器的范围内,那么**不管**插件本身是否被使用,这些定义都会被包括。这是 TypeScript 的限制,目前无法规避。
尽管如此,还是有一些建议能帮助改善这种状况:
+
- 确保 [ESLint](https://eslint.org/docs/rules/no-unused-vars) 开启了 `no-unused-vars`,并且所有导入的插件都得到了加载。
- 通过诸如 [depcheck](https://www.npmjs.com/package/depcheck) 或 [npm-check](https://www.npmjs.com/package/npm-check) 的工具来验证所有插件都在项目中得到了使用。
@@ -533,8 +563,8 @@ Fastify 插件使用声明合并来修改已有的 Fastify 类型接口 (详见
```js
/** @type {import('fastify').FastifyPluginAsync<{ optionA: boolean, optionB: string }>} */
module.exports = async function (fastify, { optionA, optionB }) {
- fastify.get('/look', () => 'at me');
-}
+ fastify.get("/look", () => "at me");
+};
```
## API 类型系统文档
@@ -544,6 +574,7 @@ module.exports = async function (fastify, { optionA, optionB }) {
所有 `http`、`https` 以及 `http2` 的类型来自 `@types/node`。
[泛型](#generics)的文档包括了其默认值以及约束值。更多关于 TypeScript 泛型的信息请阅读以下文章。
+
- [泛型参数默认值](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#generic-parameter-defaults)
- [泛型约束](https://www.typescriptlang.org/docs/handbook/generics.html#generic-constraints)
@@ -552,53 +583,79 @@ module.exports = async function (fastify, { optionA, optionB }) {
Fastify 的 API 都首先来自于 `fastify()` 方法。在 JavaScript 中,通过 `const fastify = require('fastify')` 来导入。在 TypeScript 中,建议的做法是使用 `import/from` 语法,这样类型能得到处理。有如下几种导入的方法。
1. `import fastify from 'fastify'`
+
- 类型得到了处理,但无法通过点标记 (dot notation) 访问
- 例子:
- ```typescript
- import fastify from 'fastify'
- const f = fastify()
- f.listen(8080, () => { console.log('running') })
+ ```typescript
+ import fastify from "fastify";
+
+ const f = fastify();
+ f.listen(8080, () => {
+ console.log("running");
+ });
```
+
- 通过解构赋值访问类型
- ```typescript
- import fastify, { FastifyInstance } from 'fastify'
- const f: FastifyInstance = fastify()
- f.listen(8080, () => { console.log('running') })
+ ```typescript
+ import fastify, { FastifyInstance } from "fastify";
+
+ const f: FastifyInstance = fastify();
+ f.listen(8080, () => {
+ console.log("running");
+ });
```
+
- 主 API 方法也可以使用解构赋值
- ```typescript
- import { fastify, FastifyInstance } from 'fastify'
- const f: FastifyInstance = fastify()
- f.listen(8080, () => { console.log('running') })
+ ```typescript
+ import { fastify, FastifyInstance } from "fastify";
+
+ const f: FastifyInstance = fastify();
+ f.listen(8080, () => {
+ console.log("running");
+ });
```
+
2. `import * as Fastify from 'fastify'`
+
- 类型得到了处理,并可通过点标记访问
- 主 API 方法要用稍微不同的语法调用 (见例子)
- 例子:
- ```typescript
- import * as Fastify from 'fastify'
- const f: Fastify.FastifyInstance = Fastify.fastify()
- f.listen(8080, () => { console.log('running') })
+ ```typescript
+ import * as Fastify from "fastify";
+
+ const f: Fastify.FastifyInstance = Fastify.fastify();
+ f.listen(8080, () => {
+ console.log("running");
+ });
```
+
3. `const fastify = require('fastify')`
+
- 语法有效,也能正确地导入。然而并**不**支持类型
- 例子:
- ```typescript
- const fastify = require('fastify')
- const f = fastify()
- f.listen(8080, () => { console.log('running') })
+ ```typescript
+ const fastify = require("fastify");
+
+ const f = fastify();
+ f.listen(8080, () => {
+ console.log("running");
+ });
```
- - 支持解构,且能处理类型
- ```typescript
- const { fastify } = require('fastify')
- const f = fastify()
- f.listen(8080, () => { console.log('running') })
+ - 支持解构,且能处理类型
+
+ ```typescript
+ const { fastify } = require("fastify");
+
+ const f = fastify();
+ f.listen(8080, () => {
+ console.log("running");
+ });
```
#### 泛型
@@ -608,6 +665,7 @@ Fastify 的 API 都首先来自于 `fastify()` 方法。在 JavaScript 中,通
多数定义依赖于 `@node/types` 中的 `http`、`https` 与 `http2` 模块。
##### RawServer
+
底层 Node.js server 的类型。
默认值:`http.Server`
@@ -617,6 +675,7 @@ Fastify 的 API 都首先来自于 `fastify()` 方法。在 JavaScript 中,通
必要的泛型参数 (Enforces generic parameters):[`RawRequest`][RawRequestGeneric]、[`RawReply`][RawReplyGeneric]
##### RawRequest
+
底层 Node.js request 的类型。
默认值:[`RawRequestDefaultExpression`][RawRequestDefaultExpression]
@@ -626,22 +685,25 @@ Fastify 的 API 都首先来自于 `fastify()` 方法。在 JavaScript 中,通
被 [`RawServer`][RawServerGeneric] 约束。
##### RawReply
+
底层 Node.js response 的类型。
默认值:[`RawReplyDefaultExpression`][RawReplyDefaultExpression]
约束值:`http.ServerResponse`、`http2.Http2ServerResponse`
-被 [`RawServer`][RawServerGeneric] 约束。
+被 [`RawServer`][RawServerGeneric] 约束。
##### Logger
+
Fastify 日志工具。
默认值:[`FastifyLoggerOptions`][FastifyLoggerOptions]
-被 [`RawServer`][RawServerGeneric] 约束。
+被 [`RawServer`][RawServerGeneric] 约束。
##### RawBody
+
为 content-type-parser 方法提供的泛型参数。
约束值:`string | Buffer`
@@ -651,6 +713,7 @@ Fastify 日志工具。
#### Fastify
##### fastify<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [Logger][LoggerGeneric]>(opts?: [FastifyServerOptions][FastifyServerOptions]): [FastifyInstance][FastifyInstance]
+
[源码](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L19)
Fastify 首要的 API 方法。默认情况下创建一个 HTTP 服务器。通过可辨识联合 (discriminant unions) 及重载的方法 (overload methods),类型系统能自动地根据传递给该方法的选项 (详见下文例子),推断出服务器的类型 (http、https 或 http2)。同时,可拓展的泛型类型系统允许用户拓展底层的 Node.js Server、Request 和 Reply 对象。此外,自定义日志类型则可以运用 `Logger` 泛型。详见下文的例子和泛型分类说明。
@@ -658,43 +721,47 @@ Fastify 首要的 API 方法。默认情况下创建一个 HTTP 服务器。通
###### 例子 1:标准的 HTTP 服务器
无需指明 `Server` 的具体类型,因为默认值就是 HTTP 服务器。
-```typescript
-import fastify from 'fastify'
-const server = fastify()
+```typescript
+import fastify from "fastify";
+
+const server = fastify();
```
+
回顾“从例子中学习”的[起步](#getting-started)一节的示例来获取更详细的内容。
###### 例子 2:HTTPS 服务器
1. 从 `@types/node` 与 `fastify` 导入模块。
```typescript
- import fs from 'fs'
- import path from 'path'
- import fastify from 'fastify'
+ import fs from "fs";
+ import path from "path";
+ import fastify from "fastify";
```
2. 按照官方 [Node.js https 服务器指南](https://nodejs.org/en/knowledge/HTTP/servers/how-to-create-a-HTTPS-server/)的步骤,创建 `key.pem` 与 `cert.pem` 文件。
3. 实例化一个 Fastify https 服务器,并添加一个路由:
+
```typescript
const server = fastify({
https: {
- key: fs.readFileSync(path.join(__dirname, 'key.pem')),
- cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))
- }
- })
+ key: fs.readFileSync(path.join(__dirname, "key.pem")),
+ cert: fs.readFileSync(path.join(__dirname, "cert.pem")),
+ },
+ });
- server.get('/', async function (request, reply) {
- return { hello: 'world' }
- })
+ server.get("/", async function (request, reply) {
+ return { hello: "world" };
+ });
server.listen(8080, (err, address) => {
if (err) {
- console.error(err)
- process.exit(0)
+ console.error(err);
+ process.exit(0);
}
- console.log(`Server listening at ${address}`)
- })
+ console.log(`Server listening at ${address}`);
+ });
```
+
4. 构建并运行!执行 `curl -k https://localhost:8080` 来测试服务。
###### 例子 3:HTTP2 服务器
@@ -702,11 +769,11 @@ const server = fastify()
HTTP2 服务器有两种类型,非安全与安全。两种类型都需要在 `options` 对象中设置 `http2` 属性的值为 `true`。设置 `https` 属性会创建一个安全的 http2 服务器;忽略该属性则创建非安全的服务器。
```typescript
-const insecureServer = fastify({ http2: true })
+const insecureServer = fastify({ http2: true });
const secureServer = fastify({
http2: true,
- https: {} // 使用 https 服务的 `key.pem` 和 `cert.pem` 文件
-})
+ https: {}, // 使用 https 服务的 `key.pem` 和 `cert.pem` 文件
+});
```
更多细节详见 Fastify 的 [HTTP2](HTTP2.md) 文档。
@@ -714,20 +781,21 @@ const secureServer = fastify({
###### 例子 4:拓展 HTTP 服务器
你不仅可以指定服务器的类型,还可以指定请求与响应的类型,即指定特殊的属性、方法等!在服务器实例化之时指定类型,则之后的实例都可应用自定义的类型。
+
```typescript
-import fastify from 'fastify'
-import http from 'http'
+import fastify from "fastify";
+import http from "http";
interface customRequest extends http.IncomingMessage {
- mySpecialProp: string
+ mySpecialProp: string;
}
-const server = fastify()
+const server = fastify();
-server.get('/', async (request, reply) => {
- const someValue = request.raw.mySpecialProp // 由于 `customRequest` 接口的存在,TypeScript 能知道这是一个字符串
- return someValue.toUpperCase()
-})
+server.get("/", async (request, reply) => {
+ const someValue = request.raw.mySpecialProp; // 由于 `customRequest` 接口的存在,TypeScript 能知道这是一个字符串
+ return someValue.toUpperCase();
+});
```
###### 例子 5:指定日志类型
@@ -737,31 +805,33 @@ Fastify 使用 [Pino](https://getpino.io/#/) 作为日志工具。其中一些
要使用 Pino 的外部实例,请将 `@types/pino` 添加到 devDependencies 中,并把实例传给 `logger` 字段:
```typescript
-import fastify from 'fastify'
-import pino from 'pino'
+import fastify from "fastify";
+import pino from "pino";
const server = fastify({
logger: pino({
- level: 'info',
- redact: ['x-userinfo'],
- messageKey: 'message'
- })
-})
+ level: "info",
+ redact: ["x-userinfo"],
+ messageKey: "message",
+ }),
+});
-server.get('/', async (request, reply) => {
- server.log.info('log message')
- return 'another message'
-})
+server.get("/", async (request, reply) => {
+ server.log.info("log message");
+ return "another message";
+});
```
---
##### fastify.HTTPMethods
+
[源码](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L8)
`'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS'` 的联合类型 (Union type)
##### fastify.RawServerBase
+
[源码](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L13)
依赖于 `@types/node` 的模块 `http`、`https`、`http2`
@@ -769,6 +839,7 @@ server.get('/', async (request, reply) => {
`http.Server | https.Server | http2.Http2Server | http2.Http2SecureServer` 的联合类型
##### fastify.RawServerDefault
+
[源码](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L18)
依赖于 `@types/node` 的模块 `http`
@@ -800,6 +871,7 @@ Fastify 服务器实例化时,调用 [`fastify()`][Fastify] 方法使用到的
#### Request
##### fastify.FastifyRequest<[RequestGeneric][FastifyRequestGenericInterface], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>
+
[源码](https://github.com/fastify/fastify/blob/main/types/request.d.ts#L15)
该接口包含了 Fastify 请求对象的属性。这些属性无视请求类型 (http 或 http2),也无关路由层级。因此在 GET 请求中访问 `request.body` 并不会抛错 (假如 GET 有 body 😉)。
@@ -809,60 +881,67 @@ Fastify 服务器实例化时,调用 [`fastify()`][Fastify] 方法使用到的
在 [`FastifyRequest`][FastifyRequest] 里有基本的范例。更详细的例子请见“从例子中学习”的[插件](#plugins)一节。
###### 例子
+
```typescript
-import fastify from 'fastify'
+import fastify from "fastify";
-const server = fastify()
+const server = fastify();
-server.decorateRequest('someProp', 'hello!')
+server.decorateRequest("someProp", "hello!");
-server.get('/', async (request, reply) => {
- const { someProp } = request // 需要通过声明合并将该属性添加到 request 接口上
- return someProp
-})
+server.get("/", async (request, reply) => {
+ const { someProp } = request; // 需要通过声明合并将该属性添加到 request 接口上
+ return someProp;
+});
// 以下声明必须在 typescript 解释器的作用域内
-declare module 'fastify' {
- interface FastifyRequest { // 引用的是接口而非类型
- someProp: string
+declare module "fastify" {
+ interface FastifyRequest {
+ // 引用的是接口而非类型
+ someProp: string;
}
}
// 你也可以如此定义 request 的类型
type CustomRequest = FastifyRequest<{
Body: { test: boolean };
-}>
+}>;
-server.get('/typedRequest', async (request: CustomRequest, reply: FastifyReply) => {
- return request.body.test
-})
+server.get(
+ "/typedRequest",
+ async (request: CustomRequest, reply: FastifyReply) => {
+ return request.body.test;
+ },
+);
```
##### fastify.RequestGenericInterface
+
[源码](https://github.com/fastify/fastify/blob/main/types/request.d.ts#L4)
Fastify 的请求对象有四个动态属性:`body`、`params`、`query` 以及 `headers`,它们对应的类型可以通过该接口设定。这是具名属性接口,允许开发者忽略他们不想指定的类型。所有忽略的属性默认为 `unknown`。四个属性名为:`Body`、`Querystring`、`Params` 和 `Headers`。
```typescript
-import fastify, { RequestGenericInterface } from 'fastify'
+import fastify, { RequestGenericInterface } from "fastify";
-const server = fastify()
+const server = fastify();
interface requestGeneric extends RequestGenericInterface {
Querystring: {
- name: string
- }
+ name: string;
+ };
}
-server.get('/', async (request, reply) => {
- const { name } = request.query // 此时 query 属性上有了 name
- return name.toUpperCase()
-})
+server.get("/", async (request, reply) => {
+ const { name } = request.query; // 此时 query 属性上有了 name
+ return name.toUpperCase();
+});
```
在“从例子中学习”的 [JSON Schema](#jsonschema) 一节中,你能找到更具体的范例。
##### fastify.RawRequestDefaultExpression\<[RawServer][RawServerGeneric]\>
+
[源码](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L23)
依赖于 `@types/node` 的模块 `http`、`https`、`http2`
@@ -872,12 +951,12 @@ server.get('/', async (request, reply) => {
如果 `RawServer` 的类型为 `http.Server` 或 `https.Server`,那么该表达式返回 `http.IncomingMessage`,否则返回 `http2.Http2ServerRequest`。
```typescript
-import http from 'http'
-import http2 from 'http2'
-import { RawRequestDefaultExpression } from 'fastify'
+import http from "http";
+import http2 from "http2";
+import { RawRequestDefaultExpression } from "fastify";
-RawRequestDefaultExpression // -> http.IncomingMessage
-RawRequestDefaultExpression // -> http2.Http2ServerRequest
+RawRequestDefaultExpression; // -> http.IncomingMessage
+RawRequestDefaultExpression; // -> http2.Http2ServerRequest
```
---
@@ -885,6 +964,7 @@ RawRequestDefaultExpression // -> http2.Http2ServerRequest
#### Reply
##### fastify.FastifyReply<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>
+
[源码](https://github.com/fastify/fastify/blob/main/types/reply.d.ts#L32)
该接口包含了 Fastify 添加到 Node.js 标准的 reply 对象上的属性。这些属性和 reply 对象的类型 (http 或 http2) 无关。
@@ -894,27 +974,30 @@ RawRequestDefaultExpression // -> http2.Http2ServerRequest
在 [`FastifyReply`][FastifyReply] 里有基本的范例。更详细的例子请见“从例子中学习”的[插件](#plugins)一节。
###### 例子
+
```typescript
-import fastify from 'fastify'
+import fastify from "fastify";
-const server = fastify()
+const server = fastify();
-server.decorateReply('someProp', 'world')
+server.decorateReply("someProp", "world");
-server.get('/', async (request, reply) => {
- const { someProp } = reply //需要通过声明合并将该属性添加到 reply 接口上
- return someProp
-})
+server.get("/", async (request, reply) => {
+ const { someProp } = reply; //需要通过声明合并将该属性添加到 reply 接口上
+ return someProp;
+});
// 以下声明必须在 typescript 解释器的作用域内
-declare module 'fastify' {
- interface FastifyReply { // 引用的是接口而非类型
- someProp: string
+declare module "fastify" {
+ interface FastifyReply {
+ // 引用的是接口而非类型
+ someProp: string;
}
}
```
##### fastify.RawReplyDefaultExpression<[RawServer][RawServerGeneric]>
+
[源码](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L27)
依赖于 `@types/node` 的模块 `http`、`https`、`http2`
@@ -924,12 +1007,12 @@ declare module 'fastify' {
如果 `RawServer` 的类型为 `http.Server` 或 `https.Server`,那么该表达式返回 `http.ServerResponse`,否则返回 `http2.Http2ServerResponse`。
```typescript
-import http from 'http'
-import http2 from 'http2'
-import { RawReplyDefaultExpression } from 'fastify'
+import http from "http";
+import http2 from "http2";
+import { RawReplyDefaultExpression } from "fastify";
-RawReplyDefaultExpression // -> http.ServerResponse
-RawReplyDefaultExpression // -> http2.Http2ServerResponse
+RawReplyDefaultExpression; // -> http.ServerResponse
+RawReplyDefaultExpression; // -> http2.Http2ServerResponse
```
---
@@ -941,16 +1024,19 @@ RawReplyDefaultExpression // -> http2.Http2ServerResponse
创建插件时,我们推荐使用 `fastify-plugin`。在“从例子中学习”的[插件](#plugins)一节中有使用 TypeScript 创建插件的指南。
##### fastify.FastifyPluginCallback<[Options][FastifyPluginOptions]>
+
[源码](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L9)
[`fastify.register()`][FastifyRegister] 使用的接口方法定义。
##### fastify.FastifyPluginAsync<[Options][FastifyPluginOptions]>
+
[源码](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L20)
[`fastify.register()`][FastifyRegister] 使用的接口方法定义。
##### fastify.FastifyPlugin<[Options][FastifyPluginOptions]>
+
[源码](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L29)
[`fastify.register()`][FastifyRegister] 使用的接口方法定义。
@@ -958,6 +1044,7 @@ RawReplyDefaultExpression // -> http2.Http2ServerResponse
通用的 `FastifyPlugin` 已不推荐使用,取而代之的是上述 `FastifyPluginCallback` 以及 `FastifyPluginAsync`。这是因为 `FastifyPlugin` 无法正确推断出异步函数的类型。
##### fastify.FastifyPluginOptions
+
[源码](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L31)
一个用于约束 [`fastify.register()`][FastifyRegister] 的 `options` 参数为对象类型的宽松类型对象 (loosely typed object)。在创建插件时,将插件的选项定义为此接口 (`interface MyPluginOptions extends FastifyPluginOptions`),传递给 register 方法。
@@ -967,10 +1054,15 @@ RawReplyDefaultExpression // -> http2.Http2ServerResponse
#### Register
##### fastify.FastifyRegister(plugin: [FastifyPluginCallback][FastifyPluginCallback], opts: [FastifyRegisterOptions][FastifyRegisterOptions])
+
[源码](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L9)
+
##### fastify.FastifyRegister(plugin: [FastifyPluginAsync][FastifyPluginAsync], opts: [FastifyRegisterOptions][FastifyRegisterOptions])
+
[源码](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L9)
+
##### fastify.FastifyRegister(plugin: [FastifyPlugin][FastifyPlugin], opts: [FastifyRegisterOptions][FastifyRegisterOptions])
+
[源码](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L9)
指定 [`fastify.register()`](Server.md#register) 类型的类型接口,返回一个拥有默认值为 [FastifyPluginOptions][FastifyPluginOptions] 的 `Options` 泛型的函数签名。当调用此函数时,根据 FastifyPlugin 参数能推断出该泛型,因此不必特别指定。options 参数是插件选项以及 `prefix: string` 和 `logLevel` ([LogLevel][LogLevel]) 两个属性的交叉类型。
@@ -978,20 +1070,21 @@ RawReplyDefaultExpression // -> http2.Http2ServerResponse
以下例子展示了 options 的推断:
```typescript
-const server = fastify()
+const server = fastify();
const plugin: FastifyPlugin<{
option1: string;
option2: boolean;
-}> = function (instance, opts, done) { }
+}> = function (instance, opts, done) {};
-fastify().register(plugin, {}) // 错误 - options 对象缺失了必要的属性
-fastify().register(plugin, { option1: '', option2: true }) // OK - options 对象包括了必要的属性
+fastify().register(plugin, {}); // 错误 - options 对象缺失了必要的属性
+fastify().register(plugin, { option1: "", option2: true }); // OK - options 对象包括了必要的属性
```
在“从例子中学习”的[插件](#plugins)一节中有使用 TypeScript 创建插件的详细示例。
##### fastify.FastifyRegisterOptions
+
[源码](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L16)
该类型是 `Options` 泛型以及包括 `prefix: string` 和 `logLevel` ([LogLevel][LogLevel]) 两个可选属性的未导出接口 `RegisterOptions` 的交叉类型。也可以被指定为返回前述交叉类型的函数。
@@ -1051,6 +1144,7 @@ Fastify 的其中一条核心原则便是强大的路由。本节中多数的类
[源码](https://github.com/fastify/fastify/blob/main/types/route.d.ts#L78)
拓展了 RouteShorthandOptions 的接口,并添加以下三个必填属性:
+
1. `method` 单个或一组 [HTTP 方法][HTTPMethods]。
2. `url` 路由路径字符串。
3. `handler` 路由控制函数,详见 [RouteHandlerMethod][]。
@@ -1153,7 +1247,7 @@ FastifyError 是自定义的错误对象,包括了状态码及校验结果。
`preValidation` 是第三个钩子,前一个为 `preParsing`,下一个为 `preHandler`。
-注意:在 `preValidation` 钩子中,request.body 永远为 null,因为此时 body 尚未解析 (解析发生在 `preHandler` 钩子之前)。
+注意:在 `preValidation` 钩子中,request.body 永远为 null,因为此时 body 尚未解析 (解析发生在 `preHandler` 钩子之前)。
##### fastify.preHandlerHookHandler<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\ | void
@@ -1167,7 +1261,7 @@ FastifyError 是自定义的错误对象,包括了状态码及校验结果。
`preSerialization` 是第五个钩子,前一个为 `preHandler`,下一个为 `onSend`。
-注:当 payload 为 string、Buffer、stream 或 null 时,该钩子不会执行。
+注:当 payload 为 string、Buffer、stream 或 null 时,该钩子不会执行。
##### fastify.onSendHookHandler(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], payload: OnSendPayload, done: (err: [FastifyError][FastifyError] | null, res?: unknown) => void): Promise\ | void
@@ -1247,4 +1341,4 @@ FastifyError 是自定义的错误对象,包括了状态码及校验结果。
[FastifyRegisterOptions]: #fastifyfastifytregisteroptions
[LogLevel]: #fastifyloglevel
[FastifyError]: #fastifyfastifyerror
-[RouteOptions]: #fastifyrouteoptionsrawserver-rawrequest-rawreply-requestgeneric-contextconfig
\ No newline at end of file
+[RouteOptions]: #fastifyrouteoptionsrawserver-rawrequest-rawreply-requestgeneric-contextconfig
diff --git a/doc/fastify-docs/docs/Validation-and-Serialization.md b/doc/fastify-docs/docs/Validation-and-Serialization.md
index eb88dd3..025eb28 100644
--- a/doc/fastify-docs/docs/Validation-and-Serialization.md
+++ b/doc/fastify-docs/docs/Validation-and-Serialization.md
@@ -1,79 +1,85 @@
Fastify
## 验证和序列化
+
Fastify 使用基于 schema 的途径,从本质上将 schema 编译成了高性能的函数,来实现路由的验证与输出的序列化。我们推荐使用 [JSON Schema](https://json-schema.org/),虽然这并非必要。
-> ## ⚠ 安全须知
+> ## ⚠ 安全须知
+>
> 应当将 schema 的定义写入代码。
> 因为不管是验证还是序列化,都会使用 `new Function()` 来动态生成代码并执行。
> 所以,用户提供的 schema 是不安全的。
> 更多内容,请看 [Ajv](https://npm.im/ajv) 与 [fast-json-stringify](https://npm.im/fast-json-stringify)。
### 核心观念
+
验证与序列化的任务分别由两个可定制的工具完成:
+
- [Ajv 6](https://www.npmjs.com/package/ajv/v/6.12.6) 用于验证请求。
- [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) 用于序列化响应的 body。
这些工具相互独立,但共享通过 `.addSchema(schema)` 方法添加到 Fastify 实例上的 JSON schema。
+
#### 添加共用 schema (shared schema)
+
得益于 `addSchema` API,你能向 Fastify 实例添加多个 schema,并在程序的不同部分复用它们。
像往常一样,该 API 是封装好的。
共用 schema 可以通过 JSON Schema 的 [**`$ref`**](https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8) 关键字复用。
以下是引用方法的 _总结_:
-+ `myField: { $ref: '#foo'}` 将在当前 schema 内搜索 `$id: '#foo'` 字段。
-+ `myField: { $ref: '#/definitions/foo'}` 将在当前 schema 内搜索 `definitions.foo` 字段。
-+ `myField: { $ref: 'http://url.com/sh.json#'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema。
-+ `myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema,并使用其 `definitions.foo` 字段。
-+ `myField: { $ref: 'http://url.com/sh.json#foo'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema,并使用其内部带 `$id: '#foo'` 的对象。
-
+- `myField: { $ref: '#foo'}` 将在当前 schema 内搜索 `$id: '#foo'` 字段。
+- `myField: { $ref: '#/definitions/foo'}` 将在当前 schema 内搜索 `definitions.foo` 字段。
+- `myField: { $ref: 'http://url.com/sh.json#'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema。
+- `myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema,并使用其 `definitions.foo` 字段。
+- `myField: { $ref: 'http://url.com/sh.json#foo'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema,并使用其内部带 `$id: '#foo'` 的对象。
**简单用法:**
```js
fastify.addSchema({
- $id: 'http://example.com/',
- type: 'object',
+ $id: "http://example.com/",
+ type: "object",
properties: {
- hello: { type: 'string' }
- }
-})
+ hello: { type: "string" },
+ },
+});
-fastify.post('/', {
- handler () {},
+fastify.post("/", {
+ handler() {},
schema: {
body: {
- type: 'array',
- items: { $ref: 'http://example.com#/properties/hello' }
- }
- }
-})
+ type: "array",
+ items: { $ref: "http://example.com#/properties/hello" },
+ },
+ },
+});
```
**`$ref` 作为根引用 (root reference):**
```js
fastify.addSchema({
- $id: 'commonSchema',
- type: 'object',
+ $id: "commonSchema",
+ type: "object",
properties: {
- hello: { type: 'string' }
- }
-})
+ hello: { type: "string" },
+ },
+});
-fastify.post('/', {
- handler () {},
+fastify.post("/", {
+ handler() {},
schema: {
- body: { $ref: 'commonSchema#' },
- headers: { $ref: 'commonSchema#' }
- }
-})
+ body: { $ref: "commonSchema#" },
+ headers: { $ref: "commonSchema#" },
+ },
+});
```
+
#### 获取共用 schema
当自定义验证器或序列化器的时候,Fastify 不再能控制它们,此时 `.addSchema` 方法失去了作用。
@@ -81,43 +87,51 @@ fastify.post('/', {
```js
fastify.addSchema({
- $id: 'schemaId',
- type: 'object',
+ $id: "schemaId",
+ type: "object",
properties: {
- hello: { type: 'string' }
- }
-})
+ hello: { type: "string" },
+ },
+});
-const mySchemas = fastify.getSchemas()
-const mySchema = fastify.getSchema('schemaId')
+const mySchemas = fastify.getSchemas();
+const mySchema = fastify.getSchema("schemaId");
```
`getSchemas` 方法也是封装好的,返回的是指定作用域中可用的共用 schema:
```js
-fastify.addSchema({ $id: 'one', my: 'hello' })
+fastify.addSchema({ $id: "one", my: "hello" });
// 只返回 schema `one`
-fastify.get('/', (request, reply) => { reply.send(fastify.getSchemas()) })
+fastify.get("/", (request, reply) => {
+ reply.send(fastify.getSchemas());
+});
fastify.register((instance, opts, done) => {
- instance.addSchema({ $id: 'two', my: 'ciao' })
+ instance.addSchema({ $id: "two", my: "ciao" });
// 会返回 schema `one` 与 `two`
- instance.get('/sub', (request, reply) => { reply.send(instance.getSchemas()) })
+ instance.get("/sub", (request, reply) => {
+ reply.send(instance.getSchemas());
+ });
instance.register((subinstance, opts, done) => {
- subinstance.addSchema({ $id: 'three', my: 'hola' })
+ subinstance.addSchema({ $id: "three", my: "hola" });
// 会返回 schema `one`、`two` 和 `three`
- subinstance.get('/deep', (request, reply) => { reply.send(subinstance.getSchemas()) })
- done()
- })
- done()
-})
+ subinstance.get("/deep", (request, reply) => {
+ reply.send(subinstance.getSchemas());
+ });
+ done();
+ });
+ done();
+});
```
### 验证
+
路由的验证是依赖 [Ajv 6](https://www.npmjs.com/package/ajv/v/6.12.6) 实现的。这是一个高性能的 JSON schema 校验工具。验证输入十分简单,只需将字段加入路由的 schema 中即可!
支持的验证类型如下:
+
- `body`:当请求方法为 POST、PUT 或 PATCH 时,验证 body。
- `querystring` 或 `query`:验证 querystring。
- `params`:验证路由参数。
@@ -128,71 +142,72 @@ fastify.register((instance, opts, done) => {
> ℹ 想要使用最新版 Ajv (Ajv 8) 的话,请查阅 [`schemaController`](Server.md#schema-controller) 一节,里边描述了比自定义校验器更简单的方法。
示例:
+
```js
const bodyJsonSchema = {
- type: 'object',
- required: ['requiredKey'],
+ type: "object",
+ required: ["requiredKey"],
properties: {
- someKey: { type: 'string' },
- someOtherKey: { type: 'number' },
+ someKey: { type: "string" },
+ someOtherKey: { type: "number" },
requiredKey: {
- type: 'array',
+ type: "array",
maxItems: 3,
- items: { type: 'integer' }
+ items: { type: "integer" },
},
- nullableKey: { type: ['number', 'null'] }, // 或 { type: 'number', nullable: true }
- multipleTypesKey: { type: ['boolean', 'number'] },
+ nullableKey: { type: ["number", "null"] }, // 或 { type: 'number', nullable: true }
+ multipleTypesKey: { type: ["boolean", "number"] },
multipleRestrictedTypesKey: {
oneOf: [
- { type: 'string', maxLength: 5 },
- { type: 'number', minimum: 10 }
- ]
+ { type: "string", maxLength: 5 },
+ { type: "number", minimum: 10 },
+ ],
},
enumKey: {
- type: 'string',
- enum: ['John', 'Foo']
+ type: "string",
+ enum: ["John", "Foo"],
},
notTypeKey: {
- not: { type: 'array' }
- }
- }
-}
+ not: { type: "array" },
+ },
+ },
+};
const queryStringJsonSchema = {
- type: 'object',
+ type: "object",
properties: {
- name: { type: 'string' },
- excitement: { type: 'integer' }
- }
-}
+ name: { type: "string" },
+ excitement: { type: "integer" },
+ },
+};
const paramsJsonSchema = {
- type: 'object',
+ type: "object",
properties: {
- par1: { type: 'string' },
- par2: { type: 'number' }
- }
-}
+ par1: { type: "string" },
+ par2: { type: "number" },
+ },
+};
const headersJsonSchema = {
- type: 'object',
+ type: "object",
properties: {
- 'x-foo': { type: 'string' }
+ "x-foo": { type: "string" },
},
- required: ['x-foo']
-}
+ required: ["x-foo"],
+};
const schema = {
body: bodyJsonSchema,
querystring: queryStringJsonSchema,
params: paramsJsonSchema,
- headers: headersJsonSchema
-}
+ headers: headersJsonSchema,
+};
-fastify.post('/the/url', { schema }, handler)
+fastify.post("/the/url", { schema }, handler);
```
-*请注意,为了通过校验,并在后续过程中使用正确类型的数据,Ajv 会尝试将数据[隐式转换](https://github.com/epoberezkin/ajv#coercing-data-types)为 schema 中 `type` 属性指明的类型。*
+_请注意,为了通过校验,并在后续过程中使用正确类型的数据,Ajv 会尝试将数据[隐式转换](https://github.com/epoberezkin/ajv#coercing-data-types)为 schema 中 `type` 属性指明的类型。_
Fastify 提供给 Ajv 的默认配置并不支持隐式转换 querystring 中的数组参数。但是,Fastify 允许你通过设置 Ajv 实例的 [`customOptions`](Server.md#ajv) 选项为 'array',来将参数转换为数组。举例如下:
@@ -200,24 +215,24 @@ Fastify 提供给 Ajv 的默认配置并不支持隐式转换 querystring 中的
const opts = {
schema: {
querystring: {
- type: 'object',
+ type: "object",
properties: {
ids: {
- type: 'array',
- default: []
+ type: "array",
+ default: [],
},
},
- }
- }
-}
+ },
+ },
+};
-fastify.get('/', opts, (request, reply) => {
- reply.send({ params: request.query })
-})
+fastify.get("/", opts, (request, reply) => {
+ reply.send({ params: request.query });
+});
fastify.listen(3000, (err) => {
- if (err) throw err
-})
+ if (err) throw err;
+});
```
默认情况下,该处的请求将返回 `400`:
@@ -234,13 +249,13 @@ curl -X GET "http://localhost:3000/?ids=1
const ajv = new Ajv({
removeAdditional: true,
useDefaults: true,
- coerceTypes: 'array', // 看这里
- allErrors: true
-})
+ coerceTypes: "array", // 看这里
+ allErrors: true,
+});
fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
- return ajv.compile(schema)
-})
+ return ajv.compile(schema);
+});
```
```sh
@@ -258,40 +273,41 @@ const schemaCompilers = {
body: new Ajv({
removeAdditional: false,
coerceTypes: false,
- allErrors: true
+ allErrors: true,
}),
params: new Ajv({
removeAdditional: false,
coerceTypes: true,
- allErrors: true
+ allErrors: true,
}),
querystring: new Ajv({
removeAdditional: false,
coerceTypes: true,
- allErrors: true
+ allErrors: true,
}),
headers: new Ajv({
removeAdditional: false,
coerceTypes: true,
- allErrors: true
- })
-}
+ allErrors: true,
+ }),
+};
-server.setValidatorCompiler(req => {
- if (!req.httpPart) {
- throw new Error('Missing httpPart')
- }
- const compiler = schemaCompilers[req.httpPart]
- if (!compiler) {
- throw new Error(`Missing compiler for ${req.httpPart}`)
- }
- return compiler.compile(req.schema)
-})
+server.setValidatorCompiler((req) => {
+ if (!req.httpPart) {
+ throw new Error("Missing httpPart");
+ }
+ const compiler = schemaCompilers[req.httpPart];
+ if (!compiler) {
+ throw new Error(`Missing compiler for ${req.httpPart}`);
+ }
+ return compiler.compile(req.schema);
+});
```
更多信息请看[这里](https://ajv.js.org/coercion.html)。
+
#### Ajv 插件
你可以给默认的 `ajv` 实例提供一组插件。这些插件必须**兼容 Ajv 6**。
@@ -299,62 +315,65 @@ server.setValidatorCompiler(req => {
> 插件格式参见 [`ajv 选项`](Server.md#ajv)
```js
-const fastify = require('fastify')({
+const fastify = require("fastify")({
ajv: {
- plugins: [
- require('ajv-merge-patch')
- ]
- }
-})
+ plugins: [require("ajv-merge-patch")],
+ },
+});
-fastify.post('/', {
- handler (req, reply) { reply.send({ ok: 1 }) },
+fastify.post("/", {
+ handler(req, reply) {
+ reply.send({ ok: 1 });
+ },
schema: {
body: {
$patch: {
source: {
- type: 'object',
+ type: "object",
properties: {
q: {
- type: 'string'
- }
- }
+ type: "string",
+ },
+ },
},
with: [
{
- op: 'add',
- path: '/properties/q',
- value: { type: 'number' }
- }
- ]
- }
- }
- }
-})
+ op: "add",
+ path: "/properties/q",
+ value: { type: "number" },
+ },
+ ],
+ },
+ },
+ },
+});
-fastify.post('/foo', {
- handler (req, reply) { reply.send({ ok: 1 }) },
+fastify.post("/foo", {
+ handler(req, reply) {
+ reply.send({ ok: 1 });
+ },
schema: {
body: {
$merge: {
source: {
- type: 'object',
+ type: "object",
properties: {
q: {
- type: 'string'
- }
- }
+ type: "string",
+ },
+ },
},
with: {
- required: ['q']
- }
- }
- }
- }
-})
+ required: ["q"],
+ },
+ },
+ },
+ },
+});
```
+
#### 验证生成器
`validatorCompiler` 返回一个用于验证 body、URL、路由参数、header 以及 querystring 的函数。默认返回一个实现了 [ajv](https://ajv.js.org/) 验证接口的函数。Fastify 内在地使用该函数以加速验证。
@@ -375,8 +394,8 @@ Fastify 使用的 [ajv 基本配置](https://github.com/epoberezkin/ajv#options-
假如你想改变或增加额外的选项,你需要创建一个自定义的实例,并覆盖已存在的实例:
```js
-const fastify = require('fastify')()
-const Ajv = require('ajv')
+const fastify = require("fastify")();
+const Ajv = require("ajv");
const ajv = new Ajv({
// fastify 使用的默认参数(如果需要)
removeAdditional: true,
@@ -385,64 +404,78 @@ const ajv = new Ajv({
nullable: true,
// 任意其他参数
// ...
-})
+});
fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
- return ajv.compile(schema)
-})
+ return ajv.compile(schema);
+});
```
_**注意:** 如果你使用自定义校验工具的实例(即使是 Ajv),你应当向该实例而非 Fastify 添加 schema,因为在这种情况下,Fastify 默认的校验工具不再使用,而 `addSchema` 方法也不清楚你在使用什么工具进行校验。_
+
##### 使用其他验证工具
-通过 `setValidatorCompiler` 函数,你可以轻松地将 `ajv` 替换为几乎任意的 Javascript 验证工具 (如 [joi](https://github.com/hapijs/joi/)、[yup](https://github.com/jquense/yup/) 等),或自定义它们。
+通过 `setValidatorCompiler` 函数,你可以轻松地将 `ajv` 替换为几乎任意的 Javascript 验证工具 (如 [joi](https://github.com/hapijs/joi/)、[yup](https://github.com/jquense/yup/) 等),或自定义它们。
```js
-const Joi = require('@hapi/joi')
+const Joi = require("@hapi/joi");
-fastify.post('/the/url', {
- schema: {
- body: Joi.object().keys({
- hello: Joi.string().required()
- }).required()
+fastify.post(
+ "/the/url",
+ {
+ schema: {
+ body: Joi.object()
+ .keys({
+ hello: Joi.string().required(),
+ })
+ .required(),
+ },
+ validatorCompiler: ({ schema, method, url, httpPart }) => {
+ return (data) => schema.validate(data);
+ },
},
- validatorCompiler: ({ schema, method, url, httpPart }) => {
- return data => schema.validate(data)
- }
-}, handler)
+ handler,
+);
```
```js
-const yup = require('yup')
+const yup = require("yup");
// 等同于前文 ajv 基本配置的 yup 的配置
const yupOptions = {
strict: false,
abortEarly: false, // 返回所有错误(译注:为 true 时出现首个错误后即返回)
stripUnknown: true, // 移除额外属性
- recursive: true
-}
-fastify.post('/the/url', {
- schema: {
- body: yup.object({
- age: yup.number().integer().required(),
- sub: yup.object().shape({
- name: yup.string().required()
- }).required()
- })
+ recursive: true,
+};
+fastify.post(
+ "/the/url",
+ {
+ schema: {
+ body: yup.object({
+ age: yup.number().integer().required(),
+ sub: yup
+ .object()
+ .shape({
+ name: yup.string().required(),
+ })
+ .required(),
+ }),
+ },
+ validatorCompiler: ({ schema, method, url, httpPart }) => {
+ return function (data) {
+ // 当设置 strict = false 时, yup 的 `validateSync` 函数在验证成功后会返回经过转换的值,而失败时则会抛错。
+ try {
+ const result = schema.validateSync(data, yupOptions);
+ return { value: result };
+ } catch (e) {
+ return { error: e };
+ }
+ };
+ },
},
- validatorCompiler: ({ schema, method, url, httpPart }) => {
- return function (data) {
- // 当设置 strict = false 时, yup 的 `validateSync` 函数在验证成功后会返回经过转换的值,而失败时则会抛错。
- try {
- const result = schema.validateSync(data, yupOptions)
- return { value: result }
- } catch (e) {
- return { error: e }
- }
- }
- }
-}, handler)
+ handler,
+);
```
##### 其他验证工具的验证信息
@@ -451,145 +484,155 @@ Fastify 的错误验证与其默认的验证引擎 `ajv` 紧密结合,错误
要规避以上问题,主要有两个途径:
-1. 确保自定义的 `schemaCompiler` 返回的错误结构与 `ajv` 的一致 (当然,由于各引擎的差异,这是件困难的活儿)。
+1. 确保自定义的 `schemaCompiler` 返回的错误结构与 `ajv` 的一致 (当然,由于各引擎的差异,这是件困难的活儿)。
2. 使用自定义的 `errorHandler` 拦截并格式化验证错误。
Fastify 给所有的验证错误添加了两个属性,来帮助你自定义 `errorHandler`:
-* validation:来自 `schemaCompiler` 函数的验证函数所返回的对象上的 `error` 属性的内容。
-* validationContext:验证错误的上下文 (body、params、query、headers)。
+- validation:来自 `schemaCompiler` 函数的验证函数所返回的对象上的 `error` 属性的内容。
+- validationContext:验证错误的上下文 (body、params、query、headers)。
以下是一个自定义 `errorHandler` 来处理验证错误的例子:
```js
const errorHandler = (error, request, reply) => {
- const statusCode = error.statusCode
- let response
+ const statusCode = error.statusCode;
+ let response;
- const { validation, validationContext } = error
+ const { validation, validationContext } = error;
// 检验是否发生了验证错误
if (validation) {
response = {
// validationContext 的值可能是 'body'、'params'、'headers' 或 'query'
message: `A validation error occured when validating the ${validationContext}...`,
- // 验证工具返回的结果
- errors: validation
- }
+ // 验证工具返回的结果
+ errors: validation,
+ };
} else {
response = {
- message: 'An error occurred...'
- }
+ message: "An error occurred...",
+ };
}
- // 其余代码。例如,记录错误日志。
+ // 其余代码。例如,记录错误日志。
// ...
- reply.status(statusCode).send(response)
-}
+ reply.status(statusCode).send(response);
+};
```
+
### 序列化
+
通常,你会通过 JSON 格式将数据发送至客户端。鉴于此,Fastify 提供了一个强大的工具——[fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) 来帮助你。当你在路由选项中提供了输出的 schema 时,它能派上用场。
我们推荐你编写一个输出的 schema,因为这能让应用的吞吐量提升 100-400% (根据 payload 的不同而有所变化),也能防止敏感信息的意外泄露。
示例:
+
```js
const schema = {
response: {
200: {
- type: 'object',
+ type: "object",
properties: {
- value: { type: 'string' },
- otherValue: { type: 'boolean' }
- }
- }
- }
-}
+ value: { type: "string" },
+ otherValue: { type: "boolean" },
+ },
+ },
+ },
+};
-fastify.post('/the/url', { schema }, handler)
+fastify.post("/the/url", { schema }, handler);
```
如你所见,响应的 schema 是建立在状态码的基础之上的。当你想对多个状态码使用同一个 schema 时,你可以使用类似 `'2xx'` 的表达方法,例如:
+
```js
const schema = {
response: {
- '2xx': {
- type: 'object',
+ "2xx": {
+ type: "object",
properties: {
- value: { type: 'string' },
- otherValue: { type: 'boolean' }
- }
+ value: { type: "string" },
+ otherValue: { type: "boolean" },
+ },
},
201: {
// 对比写法
- value: { type: 'string' }
- }
- }
-}
+ value: { type: "string" },
+ },
+ },
+};
-fastify.post('/the/url', { schema }, handler)
+fastify.post("/the/url", { schema }, handler);
```
+
#### 序列化函数生成器
`serializerCompiler` 返回一个根据输入参数返回字符串的函数。你应该提供一个函数,用于序列化所有定义了 `response` JSON Schema 的路由。
```js
fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
- return data => JSON.stringify(data)
-})
+ return (data) => JSON.stringify(data);
+});
-fastify.get('/user', {
- handler (req, reply) {
- reply.send({ id: 1, name: 'Foo', image: 'BIG IMAGE' })
+fastify.get("/user", {
+ handler(req, reply) {
+ reply.send({ id: 1, name: "Foo", image: "BIG IMAGE" });
},
schema: {
response: {
- '2xx': {
- id: { type: 'number' },
- name: { type: 'string' }
- }
- }
- }
-})
+ "2xx": {
+ id: { type: "number" },
+ name: { type: "string" },
+ },
+ },
+ },
+});
```
-*假如你需要在特定位置使用自定义的序列化工具,你可以使用 [`reply.serializer(...)`](Reply.md#serializerfunc)。*
+_假如你需要在特定位置使用自定义的序列化工具,你可以使用 [`reply.serializer(...)`](Reply.md#serializerfunc)。_
### 错误控制
+
当某个请求 schema 校验失败时,Fastify 会自动返回一个包含校验结果的 400 响应。举例来说,假如你的路由有一个如下的 schema:
- ```js
+
+```js
const schema = {
body: {
- type: 'object',
+ type: "object",
properties: {
- name: { type: 'string' }
+ name: { type: "string" },
},
- required: ['name']
- }
-}
+ required: ["name"],
+ },
+};
```
+
当校验失败时,路由会立即返回一个包含以下内容的响应:
- ```js
+
+```js
{
- "statusCode": 400,
- "error": "Bad Request",
- "message": "body should have required property 'name'"
+ "statusCode": 400,
+ "error": "Bad Request",
+ "message": "body should have required property 'name'"
}
```
如果你想在路由内部控制错误,可以设置 `attachValidation` 选项。当出现 _验证错误_ 时,请求的 `validationError` 属性将会包含一个 `Error` 对象,在这对象内部有原始的验证结果 `validation`,如下所示:
- ```js
-const fastify = Fastify()
- fastify.post('/', { schema, attachValidation: true }, function (req, reply) {
+
+```js
+const fastify = Fastify();
+fastify.post("/", { schema, attachValidation: true }, function (req, reply) {
if (req.validationError) {
// `req.validationError.validation` 包含了原始的验证错误信息
- reply.code(400).send(req.validationError)
+ reply.code(400).send(req.validationError);
}
-})
+});
```
#### `schemaErrorFormatter`
@@ -603,31 +646,33 @@ const fastify = Fastify()
const fastify = Fastify({
schemaErrorFormatter: (errors, dataVar) => {
// ... 自定义的格式化逻辑
- return new Error(myErrorMessage)
- }
-})
+ return new Error(myErrorMessage);
+ },
+});
// 或
fastify.setSchemaErrorFormatter(function (errors, dataVar) {
- this.log.error({ err: errors }, 'Validation failed')
+ this.log.error({ err: errors }, "Validation failed");
// ... 自定义的格式化逻辑
- return new Error(myErrorMessage)
-})
+ return new Error(myErrorMessage);
+});
```
你还可以使用 [setErrorHandler](https://www.fastify.io/docs/latest/Server/#seterrorhandler) 方法来自定义一个校验错误响应,如下:
- ```js
+
+```js
fastify.setErrorHandler(function (error, request, reply) {
if (error.validation) {
- // error.validationContext 是 [body, params, querystring, headers] 之中的值
- reply.status(422).send(new Error(`validation failed of the ${error.validationContext}`))
+ // error.validationContext 是 [body, params, querystring, headers] 之中的值
+ reply
+ .status(422)
+ .send(new Error(`validation failed of the ${error.validationContext}`));
}
-})
+});
```
假如你想轻松愉快地自定义错误响应,请查看 [`ajv-errors`](https://github.com/epoberezkin/ajv-errors)。具体的例子可以移步[这里](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js)。
-
下面的例子展示了如何通过自定义 AJV,为 schema 的**每个属性添加自定义错误信息**。
其中的注释描述了在不同场景下设置不同信息的方法。
@@ -635,89 +680,87 @@ fastify.setErrorHandler(function (error, request, reply) {
const fastify = Fastify({
ajv: {
customOptions: { jsonPointers: true },
- plugins: [
- require('ajv-errors')
- ]
- }
-})
+ plugins: [require("ajv-errors")],
+ },
+});
const schema = {
body: {
- type: 'object',
+ type: "object",
properties: {
name: {
- type: 'string',
+ type: "string",
errorMessage: {
- type: 'Bad name'
- }
+ type: "Bad name",
+ },
},
age: {
- type: 'number',
+ type: "number",
errorMessage: {
- type: 'Bad age', // 为除了必填外的所有限制
- min: 'Too young' // 自定义错误信息
- }
- }
+ type: "Bad age", // 为除了必填外的所有限制
+ min: "Too young", // 自定义错误信息
+ },
+ },
},
- required: ['name', 'age'],
+ required: ["name", "age"],
errorMessage: {
required: {
- name: 'Why no name!', // 为必填设置
- age: 'Why no age!' // 错误信息
- }
- }
- }
-}
+ name: "Why no name!", // 为必填设置
+ age: "Why no age!", // 错误信息
+ },
+ },
+ },
+};
-fastify.post('/', { schema, }, (request, reply) => {
+fastify.post("/", { schema }, (request, reply) => {
reply.send({
- hello: 'world'
- })
-})
+ hello: "world",
+ });
+});
```
想要本地化错误信息,请看 [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)
```js
-const localize = require('ajv-i18n')
+const localize = require("ajv-i18n");
-const fastify = Fastify()
+const fastify = Fastify();
const schema = {
body: {
- type: 'object',
+ type: "object",
properties: {
name: {
- type: 'string',
+ type: "string",
},
age: {
- type: 'number',
- }
+ type: "number",
+ },
},
- required: ['name', 'age'],
- }
-}
+ required: ["name", "age"],
+ },
+};
fastify.setErrorHandler(function (error, request, reply) {
if (error.validation) {
- localize.ru(error.validation)
- reply.status(400).send(error.validation)
- return
+ localize.ru(error.validation);
+ reply.status(400).send(error.validation);
+ return;
}
- reply.send(error)
-})
+ reply.send(error);
+});
```
### JSON Schema 支持
为了能更简单地重用 schema,JSON Schema 提供了一些功能,来结合 Fastify 的共用 schema。
-| 用例 | 验证器 | 序列化器 |
-|-----------------------------------|-----------|------------|
-| 引用 (`$ref`) `$id` | ✔ | ✔️ |
-| 引用 (`$ref`) `/definitions` | ✔️ | ✔️ |
-| 引用 (`$ref`) 共用 schema `$id` | ✔ | ✔️ |
-| 引用 (`$ref`) 共用 schema `/definitions` | ✔ | ✔️ |
+| 用例 | 验证器 | 序列化器 |
+| ---------------------------------------- | ------ | -------- |
+| 引用 (`$ref`) `$id` | ✔ | ✔️ |
+| 引用 (`$ref`) `/definitions` | ✔️ | ✔️ |
+| 引用 (`$ref`) 共用 schema `$id` | ✔ | ✔️ |
+| 引用 (`$ref`) 共用 schema `/definitions` | ✔ | ✔️ |
#### 示例
@@ -725,98 +768,103 @@ fastify.setErrorHandler(function (error, request, reply) {
```js
const refToId = {
- type: 'object',
+ type: "object",
definitions: {
foo: {
- $id: '#address',
- type: 'object',
+ $id: "#address",
+ type: "object",
properties: {
- city: { type: 'string' }
- }
- }
+ city: { type: "string" },
+ },
+ },
},
properties: {
- home: { $ref: '#address' },
- work: { $ref: '#address' }
- }
-}
+ home: { $ref: "#address" },
+ work: { $ref: "#address" },
+ },
+};
```
##### 同一个 JSON Schema 中对 `/definitions` 的引用 ($ref)
+
```js
const refToDefinitions = {
- type: 'object',
+ type: "object",
definitions: {
foo: {
- $id: '#address',
- type: 'object',
+ $id: "#address",
+ type: "object",
properties: {
- city: { type: 'string' }
- }
- }
+ city: { type: "string" },
+ },
+ },
},
properties: {
- home: { $ref: '#/definitions/foo' },
- work: { $ref: '#/definitions/foo' }
- }
-}
+ home: { $ref: "#/definitions/foo" },
+ work: { $ref: "#/definitions/foo" },
+ },
+};
```
##### 对外部共用 schema 的 `$id` 的引用 ($ref)
+
```js
fastify.addSchema({
- $id: 'http://foo/common.json',
- type: 'object',
+ $id: "http://foo/common.json",
+ type: "object",
definitions: {
foo: {
- $id: '#address',
- type: 'object',
+ $id: "#address",
+ type: "object",
properties: {
- city: { type: 'string' }
- }
- }
- }
-})
+ city: { type: "string" },
+ },
+ },
+ },
+});
const refToSharedSchemaId = {
- type: 'object',
+ type: "object",
properties: {
- home: { $ref: 'http://foo/common.json#address' },
- work: { $ref: 'http://foo/common.json#address' }
- }
-}
+ home: { $ref: "http://foo/common.json#address" },
+ work: { $ref: "http://foo/common.json#address" },
+ },
+};
```
##### 对外部共用 schema 的 `/definitions` 的引用 ($ref)
+
```js
fastify.addSchema({
- $id: 'http://foo/shared.json',
- type: 'object',
+ $id: "http://foo/shared.json",
+ type: "object",
definitions: {
foo: {
- type: 'object',
+ type: "object",
properties: {
- city: { type: 'string' }
- }
- }
- }
-})
+ city: { type: "string" },
+ },
+ },
+ },
+});
const refToSharedSchemaDefinitions = {
- type: 'object',
+ type: "object",
properties: {
- home: { $ref: 'http://foo/shared.json#/definitions/foo' },
- work: { $ref: 'http://foo/shared.json#/definitions/foo' }
- }
-}
+ home: { $ref: "http://foo/shared.json#/definitions/foo" },
+ work: { $ref: "http://foo/shared.json#/definitions/foo" },
+ },
+};
```
+
### 资源
+
- [JSON Schema](https://json-schema.org/)
- [理解 JSON Schema](https://spacetelescope.github.io/understanding-json-schema/)
- [fast-json-stringify 文档](https://github.com/fastify/fast-json-stringify)
- [Ajv 文档](https://github.com/epoberezkin/ajv/blob/master/README.md)
- [Ajv i18n](https://github.com/epoberezkin/ajv-i18n)
- [Ajv 自定义错误](https://github.com/epoberezkin/ajv-errors)
-- 使用核心方法自定义错误处理,并实现错误文件转储的[例子](https://github.com/fastify/example/tree/main/validation-messages)
\ No newline at end of file
+- 使用核心方法自定义错误处理,并实现错误文件转储的[例子](https://github.com/fastify/example/tree/main/validation-messages)
diff --git a/doc/fastify-docs/docs/Write-Plugin.md b/doc/fastify-docs/docs/Write-Plugin.md
index 08483a7..49d9135 100644
--- a/doc/fastify-docs/docs/Write-Plugin.md
+++ b/doc/fastify-docs/docs/Write-Plugin.md
@@ -1,12 +1,14 @@
Fastify
# 如何写一个好的插件
+
首先,要感谢你决定为 Fastify 编写插件。Fastify 本身是一个极简的框架,插件才是它强大功能的来源,所以,谢谢你。
Fastify 的核心原则是高性能、低成本、提供优秀的用户体验。当编写插件时,这些原则应当被遵循。因此,本文我们将会分析一个优质的插件所具有的特征。
-*需要一些灵感?你可以在 issue 中使用 ["plugin suggestion"](https://github.com/fastify/fastify/issues?q=is%3Aissue+is%3Aopen+label%3A%22plugin+suggestion%22) 标签!*
+_需要一些灵感?你可以在 issue 中使用 ["plugin suggestion"](https://github.com/fastify/fastify/issues?q=is%3Aissue+is%3Aopen+label%3A%22plugin+suggestion%22) 标签!_
## 代码
+
Fastify 运用了不同的技术来优化代码,其大部分都被写入了文档。我们强烈建议你阅读 [插件指南](Plugins-Guide.md) 一文,以了解所有可用于构建插件的 API 及其用法。
存有疑虑或寻求建议?我们非常高兴能帮助你!只需在我们的 [求助仓库](https://github.com/fastify/help) 提一个 issue 即可!
@@ -14,8 +16,10 @@ Fastify 运用了不同的技术来优化代码,其大部分都被写入了文
一旦你向我们的 [生态列表](https://github.com/fastify/fastify/blob/main/docs/Ecosystem.md) 提交了一个插件,我们将会检查你的代码,需要时也会帮忙改进它。
## 文档
+
文档相当重要。假如你的插件没有好的文档,我们将拒绝将其加入生态列表。缺乏良好的文档会提升用户使用插件的难度,并有可能导致弃用。
以下列出了一些优秀插件文档的示例:
+
- [`fastify-caching`](https://github.com/fastify/fastify-caching)
- [`fastify-compress`](https://github.com/fastify/fastify-compress)
- [`fastify-cookie`](https://github.com/fastify/fastify-cookie)
@@ -23,37 +27,44 @@ Fastify 运用了不同的技术来优化代码,其大部分都被写入了文
- [`under-pressure`](https://github.com/fastify/under-pressure)
## 许可证
+
你可以为你的插件使用自己偏好的许可,我们不会强求。
我们推荐 [MIT 许可证](https://choosealicense.com/licenses/mit/),因为我们认为它允许更多人自由地使用代码。其他可替代的许可证参见 [OSI list](https://opensource.org/licenses) 或 GitHub 的 [choosealicense.com](https://choosealicense.com/)。
## 示例
+
总在你的仓库里添加一个示例文件。这对于用户是相当有帮助的,也提供了一个快速的手段来测试你的插件。使用者们会为此感激的。
## 测试
+
彻底地测试一个插件,来验证其是否正常执行,是极为重要的。
缺乏测试会影响用户的信任感,也无法保证代码在不同版本的依赖下还能正常工作。
我们不强求使用某一测试工具。我们使用的是 [`tap`](https://www.node-tap.org/),因为它提供了开箱即用的并行测试以及代码覆盖率检测。
## 代码检查
+
这一项不是强制的,但我们强烈推荐你在插件中使用一个代码检查工具。这可以帮助你保持统一的代码风格,同时避免许多错误。
我们使用 [`standard`](https://standardjs.com/),因为它不需任何配置,并且容易与测试集成。
## 持续集成
+
这一项也不是强制的,但假如你开源发布你的代码,持续集成能保证其他人的参与不会破坏你的插件,并检查插件是否如预期般工作。[CircleCI](https://circleci.com/) 和 [GitHub Actions](https://github.com/features/actions) 都是对开源项目免费的持续集成系统,且易于安装配置。
此外,你还可以启用 [Dependabot](https://dependabot.com/) 或 [Snyk](https://snyk.io/) 等服务,它可以帮你将依赖保持在最新版本,并检查在 Fastify 的新版本上你的插件是否存在问题。
## 让我们开始吧!
+
棒极了,现在你已经了解了如何为 Fastify 写一个好插件!
当你完成了一个插件(或更多)之后,请让我们知道!我们会将其添加到 [生态](https://github.com/fastify/fastify#ecosystem) 一节中!
想看更多真实的例子?请参阅:
+
- [`point-of-view`](https://github.com/fastify/point-of-view)
-Fastify 的模板渲染 (*ejs, pug, handlebars, marko*) 插件。
+ Fastify 的模板渲染 (_ejs, pug, handlebars, marko_) 插件。
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb)
-Fastify 的 MongoDB 连接插件,通过它你可以在你服务器的每个部分共享同一个 MongoDB 连接池。
+ Fastify 的 MongoDB 连接插件,通过它你可以在你服务器的每个部分共享同一个 MongoDB 连接池。
- [`fastify-multipart`](https://github.com/fastify/fastify-multipart)
-为 Fastify 提供 mltipart 支持。
+ 为 Fastify 提供 mltipart 支持。
- [`fastify-helmet`](https://github.com/fastify/fastify-helmet)
-重要的请求头安全插件。
\ No newline at end of file
+ 重要的请求头安全插件。
diff --git a/drizzle.config.js b/drizzle.config.js
new file mode 100644
index 0000000..32729c1
--- /dev/null
+++ b/drizzle.config.js
@@ -0,0 +1,22 @@
+import dotenv from 'dotenv';
+
+dotenv.config({ path: '.env' });
+
+export default {
+ schema: './src/entities/schema.js',
+ out: './SQL',
+ dialect: 'mysql',
+ dbCredentials: {
+ host: process.env.DB_HOST,
+ port: Number(process.env.DB_PORT),
+ user: process.env.DB_USER,
+ password: process.env.DB_PASSWORD,
+ database: process.env.DB_NAME,
+ },
+ verbose: true,
+ strict: true,
+ introspect: {
+ // 启用驼峰命名
+ casing: 'camel',
+ },
+};
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 0000000..3158922
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,35 @@
+import configPrettier from 'eslint-config-prettier';
+import pluginImport from 'eslint-plugin-import';
+
+export default [
+ {
+ // 将 settings 提升到顶层
+ settings: {
+ 'import/resolver': {
+ 'custom-alias': {
+ extensions: ['.js'],
+ alias: {
+ '#config': './config',
+ '#src': './src',
+ '#start': './src/utils/start.js',
+ },
+ },
+ },
+ },
+ languageOptions: {
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ },
+ rules: {
+ 'no-console': 'warn',
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
+ semi: ['error', 'always'],
+ 'comma-dangle': ['error', 'always-multiline'],
+ },
+ },
+ configPrettier,
+ {
+ plugins: { import: pluginImport },
+ rules: pluginImport.configs.recommended.rules,
+ },
+];
diff --git a/migrations/0000_wandering_marvel_boy.sql b/migrations/0000_wandering_marvel_boy.sql
new file mode 100644
index 0000000..9bafbba
--- /dev/null
+++ b/migrations/0000_wandering_marvel_boy.sql
@@ -0,0 +1,7 @@
+CREATE TABLE `users` (
+ `id` int NOT NULL,
+ `name` varchar(255),
+ `email` varchar(255),
+ CONSTRAINT `users_id` PRIMARY KEY(`id`),
+ CONSTRAINT `users_email_unique` UNIQUE(`email`)
+);
diff --git a/migrations/meta/0000_snapshot.json b/migrations/meta/0000_snapshot.json
new file mode 100644
index 0000000..d2f208f
--- /dev/null
+++ b/migrations/meta/0000_snapshot.json
@@ -0,0 +1,59 @@
+{
+ "version": "5",
+ "dialect": "mysql",
+ "id": "08e581e2-3826-4de5-b172-057ee6a72da0",
+ "prevId": "00000000-0000-0000-0000-000000000000",
+ "tables": {
+ "users": {
+ "name": "users",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "email": {
+ "name": "email",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "users_id": {
+ "name": "users_id",
+ "columns": ["id"]
+ }
+ },
+ "uniqueConstraints": {
+ "users_email_unique": {
+ "name": "users_email_unique",
+ "columns": ["email"]
+ }
+ },
+ "checkConstraint": {}
+ }
+ },
+ "views": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "tables": {},
+ "indexes": {}
+ }
+}
diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json
new file mode 100644
index 0000000..34e808e
--- /dev/null
+++ b/migrations/meta/_journal.json
@@ -0,0 +1,13 @@
+{
+ "version": "7",
+ "dialect": "mysql",
+ "entries": [
+ {
+ "idx": 0,
+ "version": "5",
+ "when": 1742369871003,
+ "tag": "0000_wandering_marvel_boy",
+ "breakpoints": true
+ }
+ ]
+}
diff --git a/package-lock.json b/package-lock.json
index 09c34bb..7e2ae33 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,1330 +1,5369 @@
{
- "name": "yuheng",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "yuheng",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "dotenv": "^16.4.7",
- "fastify": "^5.2.1",
- "fastify-plugin": "^5.0.1",
- "pino": "^9.6.0",
- "pino-multi-stream": "^6.0.0",
- "pino-pretty": "^13.0.0"
- },
- "devDependencies": {
- "cross-env": "^7.0.3",
- "nodemon": "^3.1.9"
- },
- "engines": {
- "node": ">=22"
- }
- },
- "node_modules/@fastify/ajv-compiler": {
- "version": "4.0.2",
- "resolved": "https://registry.npmmirror.com/@fastify/ajv-compiler/-/ajv-compiler-4.0.2.tgz",
- "integrity": "sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "name": "yuheng",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "yuheng",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "drizzle-kit": "^0.30.5",
+ "drizzle-orm": "^0.40.1",
+ "fastify": "^5.2.1",
+ "fastify-plugin": "^5.0.1",
+ "mysql2": "^3.13.0",
+ "pino": "^9.6.0",
+ "pino-multi-stream": "^6.0.0",
+ "pino-pretty": "^13.0.0"
+ },
+ "devDependencies": {
+ "cross-env": "^7.0.3",
+ "eslint": "^9.21.0",
+ "eslint-config-prettier": "^10.0.2",
+ "eslint-import-resolver-custom-alias": "^1.3.2",
+ "eslint-plugin-import": "^2.31.0",
+ "nodemon": "^3.1.9",
+ "prettier": "^3.5.3"
+ },
+ "engines": {
+ "node": ">=22"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "ajv": "^8.12.0",
- "ajv-formats": "^3.0.1",
- "fast-uri": "^3.0.0"
- }
- },
- "node_modules/@fastify/error": {
- "version": "4.0.0",
- "resolved": "https://registry.npmmirror.com/@fastify/error/-/error-4.0.0.tgz",
- "integrity": "sha512-OO/SA8As24JtT1usTUTKgGH7uLvhfwZPwlptRi2Dp5P4KKmJI3gvsZ8MIHnNwDs4sLf/aai5LzTyl66xr7qMxA==",
- "license": "MIT"
- },
- "node_modules/@fastify/fast-json-stringify-compiler": {
- "version": "5.0.2",
- "resolved": "https://registry.npmmirror.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.0.2.tgz",
- "integrity": "sha512-YdR7gqlLg1xZAQa+SX4sMNzQHY5pC54fu9oC5aYSUqBhyn6fkLkrdtKlpVdCNPlwuUuXA1PjFTEmvMF6ZVXVGw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@drizzle-team/brocli": {
+ "version": "0.10.2",
+ "resolved": "https://registry.npmmirror.com/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
+ "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==",
+ "license": "Apache-2.0"
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "fast-json-stringify": "^6.0.0"
- }
- },
- "node_modules/@fastify/forwarded": {
- "version": "3.0.0",
- "resolved": "https://registry.npmmirror.com/@fastify/forwarded/-/forwarded-3.0.0.tgz",
- "integrity": "sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==",
- "license": "MIT"
- },
- "node_modules/@fastify/merge-json-schemas": {
- "version": "0.2.1",
- "resolved": "https://registry.npmmirror.com/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz",
- "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmmirror.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
+ "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
+ "deprecated": "Merged into tsx: https://tsx.is",
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.18.20",
+ "source-map-support": "^0.5.21"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "dequal": "^2.0.3"
- }
- },
- "node_modules/@fastify/proxy-addr": {
- "version": "5.0.0",
- "resolved": "https://registry.npmmirror.com/@fastify/proxy-addr/-/proxy-addr-5.0.0.tgz",
- "integrity": "sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==",
- "license": "MIT",
- "dependencies": {
- "@fastify/forwarded": "^3.0.0",
- "ipaddr.js": "^2.1.0"
- }
- },
- "node_modules/abstract-logging": {
- "version": "2.0.1",
- "resolved": "https://registry.npmmirror.com/abstract-logging/-/abstract-logging-2.0.1.tgz",
- "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==",
- "license": "MIT"
- },
- "node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ajv-formats": {
- "version": "3.0.1",
- "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz",
- "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
- "license": "MIT",
- "dependencies": {
- "ajv": "^8.0.0"
- },
- "peerDependencies": {
- "ajv": "^8.0.0"
- },
- "peerDependenciesMeta": {
- "ajv": {
- "optional": true
- }
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/atomic-sleep": {
- "version": "1.0.0",
- "resolved": "https://registry.npmmirror.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
- "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/avvio": {
- "version": "9.1.0",
- "resolved": "https://registry.npmmirror.com/avvio/-/avvio-9.1.0.tgz",
- "integrity": "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==",
- "license": "MIT",
- "dependencies": {
- "@fastify/error": "^4.0.0",
- "fastq": "^1.17.1"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/colorette": {
- "version": "2.0.20",
- "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz",
- "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
- "license": "MIT"
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cookie": {
- "version": "1.0.2",
- "resolved": "https://registry.npmmirror.com/cookie/-/cookie-1.0.2.tgz",
- "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/cross-env": {
- "version": "7.0.3",
- "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
- "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.1"
- },
- "bin": {
- "cross-env": "src/bin/cross-env.js",
- "cross-env-shell": "src/bin/cross-env-shell.js"
- },
- "engines": {
- "node": ">=10.14",
- "npm": ">=6",
- "yarn": ">=1"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/dateformat": {
- "version": "4.6.3",
- "resolved": "https://registry.npmmirror.com/dateformat/-/dateformat-4.6.3.tgz",
- "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/dotenv": {
- "version": "16.4.7",
- "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.4.7.tgz",
- "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
- }
- },
- "node_modules/duplexify": {
- "version": "4.1.3",
- "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-4.1.3.tgz",
- "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.4.1",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1",
- "stream-shift": "^1.0.2"
- }
- },
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "license": "MIT",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
- "node_modules/fast-copy": {
- "version": "3.0.2",
- "resolved": "https://registry.npmmirror.com/fast-copy/-/fast-copy-3.0.2.tgz",
- "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==",
- "license": "MIT"
- },
- "node_modules/fast-decode-uri-component": {
- "version": "1.0.1",
- "resolved": "https://registry.npmmirror.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
- "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==",
- "license": "MIT"
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "license": "MIT"
- },
- "node_modules/fast-json-stringify": {
- "version": "6.0.1",
- "resolved": "https://registry.npmmirror.com/fast-json-stringify/-/fast-json-stringify-6.0.1.tgz",
- "integrity": "sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@fastify/merge-json-schemas": "^0.2.0",
- "ajv": "^8.12.0",
- "ajv-formats": "^3.0.1",
- "fast-uri": "^3.0.0",
- "json-schema-ref-resolver": "^2.0.0",
- "rfdc": "^1.2.0"
- }
- },
- "node_modules/fast-querystring": {
- "version": "1.1.2",
- "resolved": "https://registry.npmmirror.com/fast-querystring/-/fast-querystring-1.1.2.tgz",
- "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==",
- "license": "MIT",
- "dependencies": {
- "fast-decode-uri-component": "^1.0.1"
- }
- },
- "node_modules/fast-redact": {
- "version": "3.5.0",
- "resolved": "https://registry.npmmirror.com/fast-redact/-/fast-redact-3.5.0.tgz",
- "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/fast-safe-stringify": {
- "version": "2.1.1",
- "resolved": "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
- "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
- "license": "MIT"
- },
- "node_modules/fast-uri": {
- "version": "3.0.6",
- "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.0.6.tgz",
- "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/fastify": {
- "version": "5.2.1",
- "resolved": "https://registry.npmmirror.com/fastify/-/fastify-5.2.1.tgz",
- "integrity": "sha512-rslrNBF67eg8/Gyn7P2URV8/6pz8kSAscFL4EThZJ8JBMaXacVdVE4hmUcnPNKERl5o/xTiBSLfdowBRhVF1WA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@fastify/ajv-compiler": "^4.0.0",
- "@fastify/error": "^4.0.0",
- "@fastify/fast-json-stringify-compiler": "^5.0.0",
- "@fastify/proxy-addr": "^5.0.0",
- "abstract-logging": "^2.0.1",
- "avvio": "^9.0.0",
- "fast-json-stringify": "^6.0.0",
- "find-my-way": "^9.0.0",
- "light-my-request": "^6.0.0",
- "pino": "^9.0.0",
- "process-warning": "^4.0.0",
- "rfdc": "^1.3.1",
- "secure-json-parse": "^3.0.1",
- "semver": "^7.6.0",
- "toad-cache": "^3.7.0"
- }
- },
- "node_modules/fastify-plugin": {
- "version": "5.0.1",
- "resolved": "https://registry.npmmirror.com/fastify-plugin/-/fastify-plugin-5.0.1.tgz",
- "integrity": "sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==",
- "license": "MIT"
- },
- "node_modules/fastq": {
- "version": "1.19.1",
- "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.19.1.tgz",
- "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-my-way": {
- "version": "9.2.0",
- "resolved": "https://registry.npmmirror.com/find-my-way/-/find-my-way-9.2.0.tgz",
- "integrity": "sha512-d3uCir8Hmg7W1Ywp8nKf2lJJYU9Nwinvo+1D39Dn09nz65UKXIxUh7j7K8zeWhxqe1WrkS7FJyON/Q/3lPoc6w==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-querystring": "^1.0.0",
- "safe-regex2": "^4.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/help-me": {
- "version": "5.0.0",
- "resolved": "https://registry.npmmirror.com/help-me/-/help-me-5.0.0.tgz",
- "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==",
- "license": "MIT"
- },
- "node_modules/ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmmirror.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ipaddr.js": {
- "version": "2.2.0",
- "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
- "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/joycon": {
- "version": "3.1.1",
- "resolved": "https://registry.npmmirror.com/joycon/-/joycon-3.1.1.tgz",
- "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/json-schema-ref-resolver": {
- "version": "2.0.1",
- "resolved": "https://registry.npmmirror.com/json-schema-ref-resolver/-/json-schema-ref-resolver-2.0.1.tgz",
- "integrity": "sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "dequal": "^2.0.3"
- }
- },
- "node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "license": "MIT"
- },
- "node_modules/light-my-request": {
- "version": "6.6.0",
- "resolved": "https://registry.npmmirror.com/light-my-request/-/light-my-request-6.6.0.tgz",
- "integrity": "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "BSD-3-Clause",
- "dependencies": {
- "cookie": "^1.0.1",
- "process-warning": "^4.0.0",
- "set-cookie-parser": "^2.6.0"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/nodemon": {
- "version": "3.1.9",
- "resolved": "https://registry.npmmirror.com/nodemon/-/nodemon-3.1.9.tgz",
- "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chokidar": "^3.5.2",
- "debug": "^4",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.1.2",
- "pstree.remy": "^1.1.8",
- "semver": "^7.5.3",
- "simple-update-notifier": "^2.0.0",
- "supports-color": "^5.5.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.5"
- },
- "bin": {
- "nodemon": "bin/nodemon.js"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/nodemon"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/on-exit-leak-free": {
- "version": "2.1.2",
- "resolved": "https://registry.npmmirror.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
- "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pino": {
- "version": "9.6.0",
- "resolved": "https://registry.npmmirror.com/pino/-/pino-9.6.0.tgz",
- "integrity": "sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==",
- "license": "MIT",
- "dependencies": {
- "atomic-sleep": "^1.0.0",
- "fast-redact": "^3.1.1",
- "on-exit-leak-free": "^2.1.0",
- "pino-abstract-transport": "^2.0.0",
- "pino-std-serializers": "^7.0.0",
- "process-warning": "^4.0.0",
- "quick-format-unescaped": "^4.0.3",
- "real-require": "^0.2.0",
- "safe-stable-stringify": "^2.3.1",
- "sonic-boom": "^4.0.1",
- "thread-stream": "^3.0.0"
- },
- "bin": {
- "pino": "bin.js"
- }
- },
- "node_modules/pino-abstract-transport": {
- "version": "2.0.0",
- "resolved": "https://registry.npmmirror.com/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz",
- "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==",
- "license": "MIT",
- "dependencies": {
- "split2": "^4.0.0"
- }
- },
- "node_modules/pino-multi-stream": {
- "version": "6.0.0",
- "resolved": "https://registry.npmmirror.com/pino-multi-stream/-/pino-multi-stream-6.0.0.tgz",
- "integrity": "sha512-oCuTtaDSUB5xK1S45r9oWE0Dj8RWdHVvaGTft5pO/rmzgIqQRkilf5Ooilz3uRm0IYj8sPRho3lVx48LCmXjvQ==",
- "deprecated": "No longer supported. Use the multi-stream support in the latest core Pino",
- "license": "MIT",
- "dependencies": {
- "pino": "^7.0.0"
- }
- },
- "node_modules/pino-multi-stream/node_modules/on-exit-leak-free": {
- "version": "0.2.0",
- "resolved": "https://registry.npmmirror.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz",
- "integrity": "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==",
- "license": "MIT"
- },
- "node_modules/pino-multi-stream/node_modules/pino": {
- "version": "7.11.0",
- "resolved": "https://registry.npmmirror.com/pino/-/pino-7.11.0.tgz",
- "integrity": "sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==",
- "license": "MIT",
- "dependencies": {
- "atomic-sleep": "^1.0.0",
- "fast-redact": "^3.0.0",
- "on-exit-leak-free": "^0.2.0",
- "pino-abstract-transport": "v0.5.0",
- "pino-std-serializers": "^4.0.0",
- "process-warning": "^1.0.0",
- "quick-format-unescaped": "^4.0.3",
- "real-require": "^0.1.0",
- "safe-stable-stringify": "^2.1.0",
- "sonic-boom": "^2.2.1",
- "thread-stream": "^0.15.1"
- },
- "bin": {
- "pino": "bin.js"
- }
- },
- "node_modules/pino-multi-stream/node_modules/pino-abstract-transport": {
- "version": "0.5.0",
- "resolved": "https://registry.npmmirror.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz",
- "integrity": "sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==",
- "license": "MIT",
- "dependencies": {
- "duplexify": "^4.1.2",
- "split2": "^4.0.0"
- }
- },
- "node_modules/pino-multi-stream/node_modules/pino-std-serializers": {
- "version": "4.0.0",
- "resolved": "https://registry.npmmirror.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz",
- "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==",
- "license": "MIT"
- },
- "node_modules/pino-multi-stream/node_modules/process-warning": {
- "version": "1.0.0",
- "resolved": "https://registry.npmmirror.com/process-warning/-/process-warning-1.0.0.tgz",
- "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==",
- "license": "MIT"
- },
- "node_modules/pino-multi-stream/node_modules/real-require": {
- "version": "0.1.0",
- "resolved": "https://registry.npmmirror.com/real-require/-/real-require-0.1.0.tgz",
- "integrity": "sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==",
- "license": "MIT",
- "engines": {
- "node": ">= 12.13.0"
- }
- },
- "node_modules/pino-multi-stream/node_modules/sonic-boom": {
- "version": "2.8.0",
- "resolved": "https://registry.npmmirror.com/sonic-boom/-/sonic-boom-2.8.0.tgz",
- "integrity": "sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==",
- "license": "MIT",
- "dependencies": {
- "atomic-sleep": "^1.0.0"
- }
- },
- "node_modules/pino-multi-stream/node_modules/thread-stream": {
- "version": "0.15.2",
- "resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-0.15.2.tgz",
- "integrity": "sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==",
- "license": "MIT",
- "dependencies": {
- "real-require": "^0.1.0"
- }
- },
- "node_modules/pino-pretty": {
- "version": "13.0.0",
- "resolved": "https://registry.npmmirror.com/pino-pretty/-/pino-pretty-13.0.0.tgz",
- "integrity": "sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==",
- "license": "MIT",
- "dependencies": {
- "colorette": "^2.0.7",
- "dateformat": "^4.6.3",
- "fast-copy": "^3.0.2",
- "fast-safe-stringify": "^2.1.1",
- "help-me": "^5.0.0",
- "joycon": "^3.1.1",
- "minimist": "^1.2.6",
- "on-exit-leak-free": "^2.1.0",
- "pino-abstract-transport": "^2.0.0",
- "pump": "^3.0.0",
- "secure-json-parse": "^2.4.0",
- "sonic-boom": "^4.0.1",
- "strip-json-comments": "^3.1.1"
- },
- "bin": {
- "pino-pretty": "bin.js"
- }
- },
- "node_modules/pino-pretty/node_modules/secure-json-parse": {
- "version": "2.7.0",
- "resolved": "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
- "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/pino-std-serializers": {
- "version": "7.0.0",
- "resolved": "https://registry.npmmirror.com/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz",
- "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==",
- "license": "MIT"
- },
- "node_modules/process-warning": {
- "version": "4.0.1",
- "resolved": "https://registry.npmmirror.com/process-warning/-/process-warning-4.0.1.tgz",
- "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT"
- },
- "node_modules/pstree.remy": {
- "version": "1.1.8",
- "resolved": "https://registry.npmmirror.com/pstree.remy/-/pstree.remy-1.1.8.tgz",
- "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/pump": {
- "version": "3.0.2",
- "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.2.tgz",
- "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/quick-format-unescaped": {
- "version": "4.0.4",
- "resolved": "https://registry.npmmirror.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
- "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
- "license": "MIT"
- },
- "node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/real-require": {
- "version": "0.2.0",
- "resolved": "https://registry.npmmirror.com/real-require/-/real-require-0.2.0.tgz",
- "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
- "license": "MIT",
- "engines": {
- "node": ">= 12.13.0"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/ret": {
- "version": "0.5.0",
- "resolved": "https://registry.npmmirror.com/ret/-/ret-0.5.0.tgz",
- "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rfdc": {
- "version": "1.4.1",
- "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
- "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
- "license": "MIT"
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safe-regex2": {
- "version": "4.0.1",
- "resolved": "https://registry.npmmirror.com/safe-regex2/-/safe-regex2-4.0.1.tgz",
- "integrity": "sha512-goqsB+bSlOmVX+CiFX2PFc1OV88j5jvBqIM+DgqrucHnUguAUNtiNOs+aTadq2NqsLQ+TQ3UEVG3gtSFcdlkCg==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "ret": "~0.5.0"
- }
- },
- "node_modules/safe-stable-stringify": {
- "version": "2.5.0",
- "resolved": "https://registry.npmmirror.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
- "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/secure-json-parse": {
- "version": "3.0.2",
- "resolved": "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-3.0.2.tgz",
- "integrity": "sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
+ "node_modules/@esbuild-kit/esm-loader": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz",
+ "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
+ "deprecated": "Merged into tsx: https://tsx.is",
+ "license": "MIT",
+ "dependencies": {
+ "@esbuild-kit/core-utils": "^3.3.2",
+ "get-tsconfig": "^4.7.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
+ "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+ "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+ "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmmirror.com/@eslint/config-array/-/config-array-0.19.2.tgz",
+ "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmmirror.com/@eslint/core/-/core-0.12.0.tgz",
+ "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
+ "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.21.0",
+ "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-9.21.0.tgz",
+ "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmmirror.com/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmmirror.com/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
+ "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.12.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@fastify/ajv-compiler": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/@fastify/ajv-compiler/-/ajv-compiler-4.0.2.tgz",
+ "integrity": "sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.12.0",
+ "ajv-formats": "^3.0.1",
+ "fast-uri": "^3.0.0"
+ }
+ },
+ "node_modules/@fastify/error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/@fastify/error/-/error-4.0.0.tgz",
+ "integrity": "sha512-OO/SA8As24JtT1usTUTKgGH7uLvhfwZPwlptRi2Dp5P4KKmJI3gvsZ8MIHnNwDs4sLf/aai5LzTyl66xr7qMxA==",
+ "license": "MIT"
+ },
+ "node_modules/@fastify/fast-json-stringify-compiler": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmmirror.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.0.2.tgz",
+ "integrity": "sha512-YdR7gqlLg1xZAQa+SX4sMNzQHY5pC54fu9oC5aYSUqBhyn6fkLkrdtKlpVdCNPlwuUuXA1PjFTEmvMF6ZVXVGw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "fast-json-stringify": "^6.0.0"
+ }
+ },
+ "node_modules/@fastify/forwarded": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/@fastify/forwarded/-/forwarded-3.0.0.tgz",
+ "integrity": "sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==",
+ "license": "MIT"
+ },
+ "node_modules/@fastify/merge-json-schemas": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmmirror.com/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz",
+ "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/@fastify/proxy-addr": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/@fastify/proxy-addr/-/proxy-addr-5.0.0.tgz",
+ "integrity": "sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fastify/forwarded": "^3.0.0",
+ "ipaddr.js": "^2.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmmirror.com/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmmirror.com/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/retry/-/retry-0.4.2.tgz",
+ "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@petamoriken/float16": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmmirror.com/@petamoriken/float16/-/float16-3.9.2.tgz",
+ "integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==",
+ "license": "MIT"
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/abstract-logging": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/abstract-logging/-/abstract-logging-2.0.1.tgz",
+ "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==",
+ "license": "MIT"
+ },
+ "node_modules/acorn": {
+ "version": "8.14.1",
+ "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
+ "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-shim-unscopables": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/atomic-sleep": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
+ "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/avvio": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmmirror.com/avvio/-/avvio-9.1.0.tgz",
+ "integrity": "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fastify/error": "^4.0.0",
+ "fastq": "^1.17.1"
+ }
+ },
+ "node_modules/aws-ssl-profiles": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
+ "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "license": "MIT"
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dateformat": {
+ "version": "4.6.3",
+ "resolved": "https://registry.npmmirror.com/dateformat/-/dateformat-4.6.3.tgz",
+ "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.4.7",
+ "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.4.7.tgz",
+ "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/drizzle-kit": {
+ "version": "0.30.5",
+ "resolved": "https://registry.npmmirror.com/drizzle-kit/-/drizzle-kit-0.30.5.tgz",
+ "integrity": "sha512-l6dMSE100u7sDaTbLczibrQZjA35jLsHNqIV+jmhNVO3O8jzM6kywMOmV9uOz9ZVSCMPQhAZEFjL/qDPVrqpUA==",
+ "license": "MIT",
+ "dependencies": {
+ "@drizzle-team/brocli": "^0.10.2",
+ "@esbuild-kit/esm-loader": "^2.5.5",
+ "esbuild": "^0.19.7",
+ "esbuild-register": "^3.5.0",
+ "gel": "^2.0.0"
+ },
+ "bin": {
+ "drizzle-kit": "bin.cjs"
+ }
+ },
+ "node_modules/drizzle-orm": {
+ "version": "0.40.1",
+ "resolved": "https://registry.npmmirror.com/drizzle-orm/-/drizzle-orm-0.40.1.tgz",
+ "integrity": "sha512-aPNhtiJiPfm3qxz1czrnIDkfvkSdKGXYeZkpG55NPTVI186LmK2fBLMi4dsHpPHlJrZeQ92D322YFPHADBALew==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@aws-sdk/client-rds-data": ">=3",
+ "@cloudflare/workers-types": ">=4",
+ "@electric-sql/pglite": ">=0.2.0",
+ "@libsql/client": ">=0.10.0",
+ "@libsql/client-wasm": ">=0.10.0",
+ "@neondatabase/serverless": ">=0.10.0",
+ "@op-engineering/op-sqlite": ">=2",
+ "@opentelemetry/api": "^1.4.1",
+ "@planetscale/database": ">=1",
+ "@prisma/client": "*",
+ "@tidbcloud/serverless": "*",
+ "@types/better-sqlite3": "*",
+ "@types/pg": "*",
+ "@types/sql.js": "*",
+ "@vercel/postgres": ">=0.8.0",
+ "@xata.io/client": "*",
+ "better-sqlite3": ">=7",
+ "bun-types": "*",
+ "expo-sqlite": ">=14.0.0",
+ "gel": ">=2",
+ "knex": "*",
+ "kysely": "*",
+ "mysql2": ">=2",
+ "pg": ">=8",
+ "postgres": ">=3",
+ "sql.js": ">=1",
+ "sqlite3": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/client-rds-data": {
+ "optional": true
+ },
+ "@cloudflare/workers-types": {
+ "optional": true
+ },
+ "@electric-sql/pglite": {
+ "optional": true
+ },
+ "@libsql/client": {
+ "optional": true
+ },
+ "@libsql/client-wasm": {
+ "optional": true
+ },
+ "@neondatabase/serverless": {
+ "optional": true
+ },
+ "@op-engineering/op-sqlite": {
+ "optional": true
+ },
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@planetscale/database": {
+ "optional": true
+ },
+ "@prisma/client": {
+ "optional": true
+ },
+ "@tidbcloud/serverless": {
+ "optional": true
+ },
+ "@types/better-sqlite3": {
+ "optional": true
+ },
+ "@types/pg": {
+ "optional": true
+ },
+ "@types/sql.js": {
+ "optional": true
+ },
+ "@vercel/postgres": {
+ "optional": true
+ },
+ "@xata.io/client": {
+ "optional": true
+ },
+ "better-sqlite3": {
+ "optional": true
+ },
+ "bun-types": {
+ "optional": true
+ },
+ "expo-sqlite": {
+ "optional": true
+ },
+ "gel": {
+ "optional": true
+ },
+ "knex": {
+ "optional": true
+ },
+ "kysely": {
+ "optional": true
+ },
+ "mysql2": {
+ "optional": true
+ },
+ "pg": {
+ "optional": true
+ },
+ "postgres": {
+ "optional": true
+ },
+ "prisma": {
+ "optional": true
+ },
+ "sql.js": {
+ "optional": true
+ },
+ "sqlite3": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/duplexify": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-4.1.3.tgz",
+ "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.4.1",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1",
+ "stream-shift": "^1.0.2"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/env-paths/-/env-paths-3.0.0.tgz",
+ "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.23.9",
+ "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.9.tgz",
+ "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.0",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-regex": "^1.2.1",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.0",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.18"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.19.12.tgz",
+ "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.19.12",
+ "@esbuild/android-arm": "0.19.12",
+ "@esbuild/android-arm64": "0.19.12",
+ "@esbuild/android-x64": "0.19.12",
+ "@esbuild/darwin-arm64": "0.19.12",
+ "@esbuild/darwin-x64": "0.19.12",
+ "@esbuild/freebsd-arm64": "0.19.12",
+ "@esbuild/freebsd-x64": "0.19.12",
+ "@esbuild/linux-arm": "0.19.12",
+ "@esbuild/linux-arm64": "0.19.12",
+ "@esbuild/linux-ia32": "0.19.12",
+ "@esbuild/linux-loong64": "0.19.12",
+ "@esbuild/linux-mips64el": "0.19.12",
+ "@esbuild/linux-ppc64": "0.19.12",
+ "@esbuild/linux-riscv64": "0.19.12",
+ "@esbuild/linux-s390x": "0.19.12",
+ "@esbuild/linux-x64": "0.19.12",
+ "@esbuild/netbsd-x64": "0.19.12",
+ "@esbuild/openbsd-x64": "0.19.12",
+ "@esbuild/sunos-x64": "0.19.12",
+ "@esbuild/win32-arm64": "0.19.12",
+ "@esbuild/win32-ia32": "0.19.12",
+ "@esbuild/win32-x64": "0.19.12"
+ }
+ },
+ "node_modules/esbuild-register": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/esbuild-register/-/esbuild-register-3.6.0.tgz",
+ "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.12 <1"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.21.0",
+ "resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.21.0.tgz",
+ "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.19.2",
+ "@eslint/core": "^0.12.0",
+ "@eslint/eslintrc": "^3.3.0",
+ "@eslint/js": "9.21.0",
+ "@eslint/plugin-kit": "^0.2.7",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.2.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmmirror.com/eslint-config-prettier/-/eslint-config-prettier-10.0.2.tgz",
+ "integrity": "sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "build/bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-custom-alias": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmmirror.com/eslint-import-resolver-custom-alias/-/eslint-import-resolver-custom-alias-1.3.2.tgz",
+ "integrity": "sha512-wBPcZA2k6/IXaT8FsLMyiyVSG6WVEuaYIAbeKLXeGwr523BmeB9lKAAoLJWSqp3txsnU4gpkgD2x1q6K8k0uDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-parent": "^6.0.2",
+ "resolve": "^1.22.2"
+ },
+ "peerDependencies": {
+ "eslint-plugin-import": ">=2.2.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-custom-alias/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.31.0",
+ "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlastindex": "^1.2.5",
+ "array.prototype.flat": "^1.3.2",
+ "array.prototype.flatmap": "^1.3.2",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.0",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.15.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.0",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
+ "tsconfig-paths": "^3.15.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-8.3.0.tgz",
+ "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/eslint/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/eslint/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/espree": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmmirror.com/espree/-/espree-10.3.0.tgz",
+ "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-copy": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/fast-copy/-/fast-copy-3.0.2.tgz",
+ "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==",
+ "license": "MIT"
+ },
+ "node_modules/fast-decode-uri-component": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
+ "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==",
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stringify": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/fast-json-stringify/-/fast-json-stringify-6.0.1.tgz",
+ "integrity": "sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@fastify/merge-json-schemas": "^0.2.0",
+ "ajv": "^8.12.0",
+ "ajv-formats": "^3.0.1",
+ "fast-uri": "^3.0.0",
+ "json-schema-ref-resolver": "^2.0.0",
+ "rfdc": "^1.2.0"
+ }
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-querystring": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/fast-querystring/-/fast-querystring-1.1.2.tgz",
+ "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-decode-uri-component": "^1.0.1"
+ }
+ },
+ "node_modules/fast-redact": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmmirror.com/fast-redact/-/fast-redact-3.5.0.tgz",
+ "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastify": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/fastify/-/fastify-5.2.1.tgz",
+ "integrity": "sha512-rslrNBF67eg8/Gyn7P2URV8/6pz8kSAscFL4EThZJ8JBMaXacVdVE4hmUcnPNKERl5o/xTiBSLfdowBRhVF1WA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@fastify/ajv-compiler": "^4.0.0",
+ "@fastify/error": "^4.0.0",
+ "@fastify/fast-json-stringify-compiler": "^5.0.0",
+ "@fastify/proxy-addr": "^5.0.0",
+ "abstract-logging": "^2.0.1",
+ "avvio": "^9.0.0",
+ "fast-json-stringify": "^6.0.0",
+ "find-my-way": "^9.0.0",
+ "light-my-request": "^6.0.0",
+ "pino": "^9.0.0",
+ "process-warning": "^4.0.0",
+ "rfdc": "^1.3.1",
+ "secure-json-parse": "^3.0.1",
+ "semver": "^7.6.0",
+ "toad-cache": "^3.7.0"
+ }
+ },
+ "node_modules/fastify-plugin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/fastify-plugin/-/fastify-plugin-5.0.1.tgz",
+ "integrity": "sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==",
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-my-way": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmmirror.com/find-my-way/-/find-my-way-9.2.0.tgz",
+ "integrity": "sha512-d3uCir8Hmg7W1Ywp8nKf2lJJYU9Nwinvo+1D39Dn09nz65UKXIxUh7j7K8zeWhxqe1WrkS7FJyON/Q/3lPoc6w==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-querystring": "^1.0.0",
+ "safe-regex2": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gel": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/gel/-/gel-2.0.1.tgz",
+ "integrity": "sha512-gfem3IGvqKqXwEq7XseBogyaRwGsQGuE7Cw/yQsjLGdgiyqX92G1xENPCE0ltunPGcsJIa6XBOTx/PK169mOqw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@petamoriken/float16": "^3.8.7",
+ "debug": "^4.3.4",
+ "env-paths": "^3.0.0",
+ "semver": "^7.6.2",
+ "shell-quote": "^1.8.1",
+ "which": "^4.0.0"
+ },
+ "bin": {
+ "gel": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ }
+ },
+ "node_modules/gel/node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/gel/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
+ "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmmirror.com/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/help-me": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/help-me/-/help-me-5.0.0.tgz",
+ "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==",
+ "license": "MIT"
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
+ "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
+ "license": "MIT"
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/joycon": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-ref-resolver": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/json-schema-ref-resolver/-/json-schema-ref-resolver-2.0.1.tgz",
+ "integrity": "sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/light-my-request": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmmirror.com/light-my-request/-/light-my-request-6.6.0.tgz",
+ "integrity": "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "process-warning": "^4.0.0",
+ "set-cookie-parser": "^2.6.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/long": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmmirror.com/long/-/long-5.3.1.tgz",
+ "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/lru.min": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/lru.min/-/lru.min-1.1.2.tgz",
+ "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==",
+ "license": "MIT",
+ "engines": {
+ "bun": ">=1.0.0",
+ "deno": ">=1.30.0",
+ "node": ">=8.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wellwelwel"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/mysql2": {
+ "version": "3.13.0",
+ "resolved": "https://registry.npmmirror.com/mysql2/-/mysql2-3.13.0.tgz",
+ "integrity": "sha512-M6DIQjTqKeqXH5HLbLMxwcK5XfXHw30u5ap6EZmu7QVmcF/gnh2wS/EOiQ4MTbXz/vQeoXrmycPlVRM00WSslg==",
+ "license": "MIT",
+ "dependencies": {
+ "aws-ssl-profiles": "^1.1.1",
+ "denque": "^2.1.0",
+ "generate-function": "^2.3.1",
+ "iconv-lite": "^0.6.3",
+ "long": "^5.2.1",
+ "lru.min": "^1.0.0",
+ "named-placeholders": "^1.1.3",
+ "seq-queue": "^0.0.5",
+ "sqlstring": "^2.3.2"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/named-placeholders": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/named-placeholders/-/named-placeholders-1.1.3.tgz",
+ "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==",
+ "license": "MIT",
+ "dependencies": {
+ "lru-cache": "^7.14.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nodemon": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmmirror.com/nodemon/-/nodemon-3.1.9.tgz",
+ "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^4",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.1.2",
+ "pstree.remy": "^1.1.8",
+ "semver": "^7.5.3",
+ "simple-update-notifier": "^2.0.0",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nodemon"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-exit-leak-free": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
+ "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pino": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmmirror.com/pino/-/pino-9.6.0.tgz",
+ "integrity": "sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0",
+ "fast-redact": "^3.1.1",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "^2.0.0",
+ "pino-std-serializers": "^7.0.0",
+ "process-warning": "^4.0.0",
+ "quick-format-unescaped": "^4.0.3",
+ "real-require": "^0.2.0",
+ "safe-stable-stringify": "^2.3.1",
+ "sonic-boom": "^4.0.1",
+ "thread-stream": "^3.0.0"
+ },
+ "bin": {
+ "pino": "bin.js"
+ }
+ },
+ "node_modules/pino-abstract-transport": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz",
+ "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==",
+ "license": "MIT",
+ "dependencies": {
+ "split2": "^4.0.0"
+ }
+ },
+ "node_modules/pino-multi-stream": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/pino-multi-stream/-/pino-multi-stream-6.0.0.tgz",
+ "integrity": "sha512-oCuTtaDSUB5xK1S45r9oWE0Dj8RWdHVvaGTft5pO/rmzgIqQRkilf5Ooilz3uRm0IYj8sPRho3lVx48LCmXjvQ==",
+ "deprecated": "No longer supported. Use the multi-stream support in the latest core Pino",
+ "license": "MIT",
+ "dependencies": {
+ "pino": "^7.0.0"
+ }
+ },
+ "node_modules/pino-multi-stream/node_modules/on-exit-leak-free": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz",
+ "integrity": "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==",
+ "license": "MIT"
+ },
+ "node_modules/pino-multi-stream/node_modules/pino": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmmirror.com/pino/-/pino-7.11.0.tgz",
+ "integrity": "sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0",
+ "fast-redact": "^3.0.0",
+ "on-exit-leak-free": "^0.2.0",
+ "pino-abstract-transport": "v0.5.0",
+ "pino-std-serializers": "^4.0.0",
+ "process-warning": "^1.0.0",
+ "quick-format-unescaped": "^4.0.3",
+ "real-require": "^0.1.0",
+ "safe-stable-stringify": "^2.1.0",
+ "sonic-boom": "^2.2.1",
+ "thread-stream": "^0.15.1"
+ },
+ "bin": {
+ "pino": "bin.js"
+ }
+ },
+ "node_modules/pino-multi-stream/node_modules/pino-abstract-transport": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmmirror.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz",
+ "integrity": "sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==",
+ "license": "MIT",
+ "dependencies": {
+ "duplexify": "^4.1.2",
+ "split2": "^4.0.0"
+ }
+ },
+ "node_modules/pino-multi-stream/node_modules/pino-std-serializers": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz",
+ "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==",
+ "license": "MIT"
+ },
+ "node_modules/pino-multi-stream/node_modules/process-warning": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/process-warning/-/process-warning-1.0.0.tgz",
+ "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==",
+ "license": "MIT"
+ },
+ "node_modules/pino-multi-stream/node_modules/real-require": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmmirror.com/real-require/-/real-require-0.1.0.tgz",
+ "integrity": "sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.13.0"
+ }
+ },
+ "node_modules/pino-multi-stream/node_modules/sonic-boom": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmmirror.com/sonic-boom/-/sonic-boom-2.8.0.tgz",
+ "integrity": "sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0"
+ }
+ },
+ "node_modules/pino-multi-stream/node_modules/thread-stream": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-0.15.2.tgz",
+ "integrity": "sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==",
+ "license": "MIT",
+ "dependencies": {
+ "real-require": "^0.1.0"
+ }
+ },
+ "node_modules/pino-pretty": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmmirror.com/pino-pretty/-/pino-pretty-13.0.0.tgz",
+ "integrity": "sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==",
+ "license": "MIT",
+ "dependencies": {
+ "colorette": "^2.0.7",
+ "dateformat": "^4.6.3",
+ "fast-copy": "^3.0.2",
+ "fast-safe-stringify": "^2.1.1",
+ "help-me": "^5.0.0",
+ "joycon": "^3.1.1",
+ "minimist": "^1.2.6",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "^2.0.0",
+ "pump": "^3.0.0",
+ "secure-json-parse": "^2.4.0",
+ "sonic-boom": "^4.0.1",
+ "strip-json-comments": "^3.1.1"
+ },
+ "bin": {
+ "pino-pretty": "bin.js"
+ }
+ },
+ "node_modules/pino-pretty/node_modules/secure-json-parse": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
+ "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/pino-std-serializers": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz",
+ "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==",
+ "license": "MIT"
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.5.3.tgz",
+ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/process-warning": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/process-warning/-/process-warning-4.0.1.tgz",
+ "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmmirror.com/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/quick-format-unescaped": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmmirror.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
+ "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
+ "license": "MIT"
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/real-require": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/real-require/-/real-require-0.2.0.tgz",
+ "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.13.0"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/ret": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmmirror.com/ret/-/ret-0.5.0.tgz",
+ "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "license": "MIT"
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex2": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/safe-regex2/-/safe-regex2-4.0.1.tgz",
+ "integrity": "sha512-goqsB+bSlOmVX+CiFX2PFc1OV88j5jvBqIM+DgqrucHnUguAUNtiNOs+aTadq2NqsLQ+TQ3UEVG3gtSFcdlkCg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "ret": "~0.5.0"
+ }
+ },
+ "node_modules/safe-stable-stringify": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+ "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/secure-json-parse": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-3.0.2.tgz",
+ "integrity": "sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/seq-queue": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmmirror.com/seq-queue/-/seq-queue-0.0.5.tgz",
+ "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmmirror.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.2.tgz",
+ "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/simple-update-notifier": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+ "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sonic-boom": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmmirror.com/sonic-boom/-/sonic-boom-4.2.0.tgz",
+ "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/sqlstring": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.3.tgz",
+ "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/stream-shift": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/stream-shift/-/stream-shift-1.0.3.tgz",
+ "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
+ "license": "MIT"
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/thread-stream": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.1.0.tgz",
+ "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==",
+ "license": "MIT",
+ "dependencies": {
+ "real-require": "^0.2.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toad-cache": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmmirror.com/toad-cache/-/toad-cache-3.7.0.tgz",
+ "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/touch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/touch/-/touch-3.1.1.tgz",
+ "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/set-cookie-parser": {
- "version": "2.7.1",
- "resolved": "https://registry.npmmirror.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
- "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
- "license": "MIT"
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/simple-update-notifier": {
- "version": "2.0.0",
- "resolved": "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
- "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/sonic-boom": {
- "version": "4.2.0",
- "resolved": "https://registry.npmmirror.com/sonic-boom/-/sonic-boom-4.2.0.tgz",
- "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==",
- "license": "MIT",
- "dependencies": {
- "atomic-sleep": "^1.0.0"
- }
- },
- "node_modules/split2": {
- "version": "4.2.0",
- "resolved": "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz",
- "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
- "license": "ISC",
- "engines": {
- "node": ">= 10.x"
- }
- },
- "node_modules/stream-shift": {
- "version": "1.0.3",
- "resolved": "https://registry.npmmirror.com/stream-shift/-/stream-shift-1.0.3.tgz",
- "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
- "license": "MIT"
- },
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/thread-stream": {
- "version": "3.1.0",
- "resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.1.0.tgz",
- "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==",
- "license": "MIT",
- "dependencies": {
- "real-require": "^0.2.0"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toad-cache": {
- "version": "3.7.0",
- "resolved": "https://registry.npmmirror.com/toad-cache/-/toad-cache-3.7.0.tgz",
- "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/touch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmmirror.com/touch/-/touch-3.1.1.tgz",
- "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "nodetouch": "bin/nodetouch.js"
- }
- },
- "node_modules/undefsafe": {
- "version": "2.0.5",
- "resolved": "https://registry.npmmirror.com/undefsafe/-/undefsafe-2.0.5.tgz",
- "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT"
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
}
- }
}
diff --git a/package.json b/package.json
index 343efed..4147b63 100644
--- a/package.json
+++ b/package.json
@@ -1,37 +1,52 @@
{
- "name": "yuheng",
- "version": "1.0.0",
- "description": "",
- "main": "src/application.js",
- "type": "module",
- "imports": {
- "#/*": "./*",
- "#common/*": "./src/common/*",
- "#config/*": "./config/*",
- "#start": "./src/utils/start.js",
- "#src/*": "./src/*"
- },
- "engines": {
- "node": ">=22"
- },
- "scripts": {
- "start": "cross-env NODE_ENV=production node src/application.js",
- "dev": "cross-env NODE_ENV=development nodemon src/application.js",
- "lint": "eslint --ext .js src"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "dependencies": {
- "dotenv": "^16.4.7",
- "fastify": "^5.2.1",
- "fastify-plugin": "^5.0.1",
- "pino": "^9.6.0",
- "pino-multi-stream": "^6.0.0",
- "pino-pretty": "^13.0.0"
- },
- "devDependencies": {
- "cross-env": "^7.0.3",
- "nodemon": "^3.1.9"
- }
+ "name": "yuheng",
+ "version": "1.0.0",
+ "description": "",
+ "main": "src/application.js",
+ "type": "module",
+ "imports": {
+ "#/*": "./*",
+ "#common/*": "./src/common/*",
+ "#config/*": "./config/*.js",
+ "#start": "./src/utils/start.js",
+ "#plugins/*": "./src/plugins/*.js",
+ "#src/*": "./src/*.js"
+ },
+ "engines": {
+ "node": ">=22"
+ },
+ "scripts": {
+ "start": "cross-env NODE_ENV=production node src/application.js",
+ "dev": "cross-env NODE_ENV=development nodemon src/application.js",
+ "lint": "eslint src --ext .js",
+ "format": "prettier --write . --config ./.prettier.config.cjs --ignore-path .prettierignore",
+ "lint:format": "prettier --check . --config ./.prettier.config.cjs --ignore-path .prettierignore",
+ "makeSQL": "drizzle-kit generate",
+ "makeEntity": "drizzle-kit introspect",
+ "syncDB": "drizzle-kit migrate",
+ "sqlV": "drizzle-kit studio"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "drizzle-kit": "^0.30.5",
+ "drizzle-orm": "^0.40.1",
+ "fastify": "^5.2.1",
+ "fastify-plugin": "^5.0.1",
+ "mysql2": "^3.13.0",
+ "pino": "^9.6.0",
+ "pino-multi-stream": "^6.0.0",
+ "pino-pretty": "^13.0.0"
+ },
+ "devDependencies": {
+ "cross-env": "^7.0.3",
+ "eslint": "^9.21.0",
+ "eslint-config-prettier": "^10.0.2",
+ "eslint-import-resolver-custom-alias": "^1.3.2",
+ "eslint-plugin-import": "^2.31.0",
+ "nodemon": "^3.1.9",
+ "prettier": "^3.5.3"
+ }
}
diff --git a/src/application.js b/src/application.js
index 4f9647a..6f51996 100644
--- a/src/application.js
+++ b/src/application.js
@@ -1,23 +1,19 @@
// ESM
-import "#start"
+import '#start';
import Fastify from 'fastify';
-import config from '#config/index.js'
-import plugin from '#src/plugins/index.js';
-import routes from '#src/routes/index.js';
-import logger from '#src/utils/logger.js';
+import config from '#config/index';
+import plugin from '#src/plugins/index';
+import routes from '#src/routes/index';
+import logger from '#src/utils/logger';
async function start() {
// 创建Fastify实例
- const fastify = new Fastify({
- logger
- })
+ const fastify = new Fastify({ logger });
// 加载插件
- await fastify.register(plugin);
+ await fastify.register(plugin, { config });
// 加载路由
- fastify.register(routes);
-
- await fastify.listen(config.server); // 使用配置中的服务器参数
+ await fastify.register(routes);
+ // 启动服务器
+ await fastify.listen(config.server); // 使用配置中的服务器参数
}
-
-
-start();
\ No newline at end of file
+start();
diff --git a/src/entities/schema.js b/src/entities/schema.js
new file mode 100644
index 0000000..7c3240e
--- /dev/null
+++ b/src/entities/schema.js
@@ -0,0 +1,17 @@
+/**
+ * @typedef {import('drizzle-orm/mysql-core').MySqlTable} MySqlTable
+ * @typedef {import('drizzle-orm/mysql-core').varchar} varchar
+ * @typedef {import('drizzle-orm/mysql-core').int} int
+ */
+
+import { mysqlTable, varchar, int } from 'drizzle-orm/mysql-core';
+
+/**
+ * 用户模型
+ * @type {MySqlTable}
+ */
+export const users = mysqlTable('users', {
+ id: int('id').primaryKey(),
+ name: varchar('name', { length: 255 }),
+ email: varchar('email', { length: 255 }).unique(),
+});
diff --git a/src/plugins/database/index.js b/src/plugins/database/index.js
new file mode 100644
index 0000000..367b67d
--- /dev/null
+++ b/src/plugins/database/index.js
@@ -0,0 +1,28 @@
+import { drizzle } from 'drizzle-orm/mysql2';
+import { sql } from 'drizzle-orm';
+import mysql from 'mysql2/promise';
+import fastifyPlugin from 'fastify-plugin';
+async function database(fastify, options) {
+ fastify.log.warn('Register Database Plugin!');
+ const config = fastify.config;
+ // 配置数据库
+ const pool = await mysql.createPool({
+ host: config.db.host,
+ port: config.db.port,
+ user: config.db.user,
+ password: config.db.password,
+ database: config.db.database,
+ ssl: config.db.ssl,
+ waitForConnections: true,
+ connectionLimit: 10,
+ queueLimit: 0,
+ });
+ // 暴露数据库
+ const db = drizzle(pool);
+ // 新增获取所有表名方法
+ const [result] = await db.execute(sql`SHOW TABLES`);
+ const tableList = result.map(row => Object.values(row)[0]);
+ db.tableList = tableList;
+ fastify.decorate('db', db);
+}
+export default fastifyPlugin(database);
diff --git a/src/plugins/index.js b/src/plugins/index.js
index 15fc3a2..163d9a5 100644
--- a/src/plugins/index.js
+++ b/src/plugins/index.js
@@ -1,13 +1,14 @@
-export default async function plugin(fastify, opts) {
+import fp from 'fastify-plugin';
+import database from '#plugins/database/index';
+
+async function plugin(fastify, opts) {
fastify.log.warn('Register Global Plugin!');
+ // 加载配置
fastify.decorate('config', opts.config);
- fastify.decorate('cfg', opts.config);
- await new Promise((resolve) => {
- setTimeout(() => {
- resolve();
- }, 1000);
- });
- fastify.log.warn(fastify.config);
- fastify.log.warn(fastify.cfg);
+ // 注册数据库
+ await fastify.register(database);
+ fastify.log.warn(fastify.db.tableList);
+ // 读取数据库基本信息
fastify.log.warn('Register Global Plugin complete!');
-}
\ No newline at end of file
+}
+export default fp(plugin);
diff --git a/src/routes/index.js b/src/routes/index.js
index 5f83f71..097c207 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -1,13 +1,7 @@
export default async function routes(fastify, options) {
- // 定义一个GET请求的路由,路径为根路径
- fastify.get('/', async (request, reply) => {
- return { hello: 'world' };
- });
-
- // 你可以在这里添加更多的路由
- // 例如:
- // fastify.get('/another-route', async (request, reply) => {
- // return { message: 'This is another route' };
- // });
+ // 定义一个GET请求的路由,路径为根路径
+ fastify.get('/', async (request, reply) => {
+ fastify.log.info(fastify.config);
+ return fastify.config;
+ });
}
-
diff --git a/src/services/user.service.js b/src/services/user.service.js
new file mode 100644
index 0000000..3d09096
--- /dev/null
+++ b/src/services/user.service.js
@@ -0,0 +1,35 @@
+import { eq } from 'drizzle-orm';
+import { users } from '#db/schema';
+
+/**
+ * 用户服务模块
+ * @param {object} fastify - Fastify实例
+ */
+export default async function userService(fastify) {
+ const { db } = fastify;
+
+ return {
+ /**
+ * 根据ID获取用户
+ * @param {number} userId - 用户ID
+ * @returns {Promise