diff --git a/example/dubbo-http2-node-example/README.md b/example/dubbo-http2-node-example/README.md new file mode 100644 index 00000000..38dcb24b --- /dev/null +++ b/example/dubbo-http2-node-example/README.md @@ -0,0 +1,204 @@ +# 使用 Node.js 开发后端服务 + +基于 Dubbo 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。Dubbo Node.js SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。 + +本示例演示了基于 Triple 协议的 RPC 通信模式,示例使用 Protocol Buffer 定义 RPC 服务,并演示了代码生成、服务发布和服务访问等过程。 + +## 前置条件 + +因为使用 Protocol Buffer 的原因,我们首先需要安装相关的代码生成工具,这包括 `@bufbuild/protoc-gen-es`、`@bufbuild/protobuf`、`@apachedubbo/protoc-gen-apache-dubbo-es`、`@apachedubbo/dubbo`。 + +```Shell +npm install @bufbuild/protoc-gen-es @bufbuild/protobuf @apachedubbo/protoc-gen-apache-dubbo-es @apachedubbo/dubbo +``` + +## 定义服务 + +现在,使用 Protocol Buffer (IDL) 来定义一个 Dubbo 服务。 + +创建目录,并生成文件 + +```Shell +mkdir -p proto && touch proto/example.proto +``` + +写入内容 + +```Protobuf +syntax = "proto3"; + +package apache.dubbo.demo.example.v1; + +message SayRequest { + string sentence = 1; +} + +message SayResponse { + string sentence = 1; +} + +service ExampleService { + rpc Say(SayRequest) returns (SayResponse) {} +} +``` + +这个文件声明了一个叫做 `ExampleService` 的服务,为这个服务定义了 `Say` 方法以及它的请求参数 `SayRequest` 和返回值 `SayResponse`。 + +## 生成代码 + +创建 gen 目录,做为生成文件放置的目标目录 + +``` +mkdir -p gen +``` + +运行以下命令,在 gen 目录下生成代码文件 + +```Shell +PATH=$PATH:$(pwd)/node_modules/.bin \ + protoc -I proto \ + --es_out gen \ + --es_opt target=ts \ + --apache-dubbo-es_out gen \ + --apache-dubbo-es_opt target=ts \ + example.proto +``` + +运行命令后,应该可以在目标目录中看到以下生成的文件: + +```Plain Text +├── gen +│ ├── example_dubbo.ts +│ └── example_pb.ts +├── proto +│ └── example.proto +``` + +## 实现服务 + +接下来我们就需要添加业务逻辑了,实现 ExampleService ,并将其注册到 DubboRouter 中。 + +创建 dubbo.ts 文件 + +```typescript +import type { DubboRouter } from "@apachedubbo/dubbo"; +import { ExampleService } from "./gen/example_dubbo"; + +export default (router: DubboRouter) => + // registers apache.dubbo.demo.example.v1 + router.service(ExampleService, { + // implements rpc Say + async say(req) { + return { + sentence: `You said: ${req.sentence}`, + }; + }, + }, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); +``` + +## 启动 Server + +Dubbo 服务可以嵌入到普通的 Node.js 服务器、Next.js、Express 或 Fastify 中。 +在这里我们将使用 Fastify,所以让我们安装 Fastify 以及我们为 Fastify 准备的插件。 + +```Shell +npm install fastify @apachedubbo/dubbo-fastify +``` + +创建 server.ts 文件,新建一个 Server,把上一步中实现的 `ExampleService` 注册给它。 +接下来就可以直接初始化和启动 Server 了,它将在指定的端口接收请求。 + +```typescript +import { fastify } from "fastify"; +import { fastifyDubboPlugin } from "@apachedubbo/dubbo-fastify"; +import routes from "./dubbo"; +import { readFileSync } from "fs"; + +async function main() { + const server = fastify({ + http2: true, + https: { + key: readFileSync("localhost+1-key.pem", "utf8"), + cert: readFileSync("localhost+1.pem", "utf8"), + } + }); + await server.register(fastifyDubboPlugin, { + routes, + }); + await server.listen({ host: "localhost", port: 8443 }); + console.log("server is listening at", server.addresses()); +} +void main(); +``` + +最后,运行代码启动服务 + +```Shell +npx tsx server.ts +``` + +## 访问服务 + +我们将使用 `mkcert` 来生成证书。如果你还没有安装它,请运行以下命令: + +``` +brew install mkcert +mkcert -install +mkcert localhost 127.0.0.1 ::1 +export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" +``` + +如果你没有使用 macOS 或 `brew`,请参阅 [mkcert 文档](https://github.com/FiloSottile/mkcert#installation) 获取安装说明。你可以将最后一行复制到你的 `~/.zprofile` 或 `~/.profile` 中,这样每次打开终端时,Node.js 的环境变量都会自动设置。 + +如果你已经在使用 `mkcert`,只需运行 `mkcert localhost 127.0.0.1 ::1` 来为我们的示例服务器生成证书。 + +```Shell +npx buf curl --protocol grpc --schema . -d '{"sentence": "Hello Word!"}' \ +https://localhost:8443/apache.dubbo.demo.example.v1.ExampleService/Say +``` + +也可以使用标准的 Dubbo client 请求服务,我们首先需要从生成代码即 dubbo-node 包中获取服务代理,为它指定 server 地址并初始化,之后就可以发起起 RPC 调用了。 + +创建 client.ts 文件。 + +```typescript +import { createPromiseClient } from "@apachedubbo/dubbo"; +import { ExampleService } from "./gen/example_dubbo"; +import { stdin, stdout, env } from "process"; +import * as readline from "node:readline/promises"; +import { createDubboTransport } from "@apachedubbo/dubbo-node"; + +const rl = readline.createInterface(stdin, stdout); + +let rejectUnauthorized = true; + +if (process.env.NODE_EXTRA_CA_CERTS == undefined) { + console.log(env.NODE_EXTRA_CA_CERTS); + rl.write("It appears that you haven't configured Node.js with your certificate authority for local development. This is okay; we'll bypass TLS errors in this example client. \n"); + rejectUnauthorized = false; +} + + +const transport = createDubboTransport({ + baseUrl: "https://localhost:8443", + httpVersion: "2", + nodeOptions: { rejectUnauthorized }, +}); + +async function main() { + const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }); + const res = await client.say({ sentence: "Hello World" }); + console.log(res); +} +void main(); +``` + +运行客户端 + +```Shell +npx tsx client.ts +``` + +## 其他 + +参考[开发运行在浏览器上的 web 应用](../dubbo-web-example/README.md),了解如何开发能访问 Dubbo 后端服务的浏览器页面。 diff --git a/example/dubbo-http2-node-example/client.ts b/example/dubbo-http2-node-example/client.ts new file mode 100644 index 00000000..dddd1b5e --- /dev/null +++ b/example/dubbo-http2-node-example/client.ts @@ -0,0 +1,29 @@ +import { createPromiseClient } from "@apachedubbo/dubbo"; +import { ExampleService } from "./gen/example_dubbo"; +import { stdin, stdout, env } from "process"; +import * as readline from "node:readline/promises"; +import { createDubboTransport } from "@apachedubbo/dubbo-node"; + +const rl = readline.createInterface(stdin, stdout); + +let rejectUnauthorized = true; + +if (process.env.NODE_EXTRA_CA_CERTS == undefined) { + console.log(env.NODE_EXTRA_CA_CERTS); + rl.write("It appears that you haven't configured Node.js with your certificate authority for local development. This is okay; we'll bypass TLS errors in this example client. \n"); + rejectUnauthorized = false; +} + + +const transport = createDubboTransport({ + baseUrl: "https://localhost:8443", + httpVersion: "2", + nodeOptions: { rejectUnauthorized }, +}); + +async function main() { + const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }); + const res = await client.say({ sentence: "Hello World" }); + console.log(res); +} +void main(); \ No newline at end of file diff --git a/example/dubbo-http2-node-example/dubbo.ts b/example/dubbo-http2-node-example/dubbo.ts new file mode 100644 index 00000000..8374a785 --- /dev/null +++ b/example/dubbo-http2-node-example/dubbo.ts @@ -0,0 +1,13 @@ +import type { DubboRouter } from "@apachedubbo/dubbo"; +import { ExampleService } from "./gen/example_dubbo"; + +export default (router: DubboRouter) => + // registers apache.dubbo.demo.example.v1 + router.service(ExampleService, { + // implements rpc Say + async say(req) { + return { + sentence: `You said: ${req.sentence}`, + }; + }, + }, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); diff --git a/example/dubbo-http2-node-example/gen/example_dubbo.ts b/example/dubbo-http2-node-example/gen/example_dubbo.ts new file mode 100644 index 00000000..cfcb2856 --- /dev/null +++ b/example/dubbo-http2-node-example/gen/example_dubbo.ts @@ -0,0 +1,26 @@ +// @generated by @apachedubbo/protoc-gen-apache-dubbo-es v3.0.0-alpha with parameter "target=ts" +// @generated from file example.proto (package apache.dubbo.demo.example.v1, syntax proto3) +/* eslint-disable */ +// @ts-nocheck + +import { SayRequest, SayResponse } from "./example_pb.js"; +import { MethodKind } from "@bufbuild/protobuf"; + +/** + * @generated from service apache.dubbo.demo.example.v1.ExampleService + */ +export const ExampleService = { + typeName: "apache.dubbo.demo.example.v1.ExampleService", + methods: { + /** + * @generated from rpc apache.dubbo.demo.example.v1.ExampleService.Say + */ + say: { + name: "Say", + I: SayRequest, + O: SayResponse, + kind: MethodKind.Unary, + }, + } +} as const; + diff --git a/example/dubbo-http2-node-example/gen/example_pb.ts b/example/dubbo-http2-node-example/gen/example_pb.ts new file mode 100644 index 00000000..99c878b2 --- /dev/null +++ b/example/dubbo-http2-node-example/gen/example_pb.ts @@ -0,0 +1,82 @@ +// @generated by protoc-gen-es v1.3.0 with parameter "target=ts" +// @generated from file example.proto (package apache.dubbo.demo.example.v1, syntax proto3) +/* eslint-disable */ +// @ts-nocheck + +import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; +import { Message, proto3 } from "@bufbuild/protobuf"; + +/** + * @generated from message apache.dubbo.demo.example.v1.SayRequest + */ +export class SayRequest extends Message { + /** + * @generated from field: string sentence = 1; + */ + sentence = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "apache.dubbo.demo.example.v1.SayRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "sentence", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): SayRequest { + return new SayRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): SayRequest { + return new SayRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): SayRequest { + return new SayRequest().fromJsonString(jsonString, options); + } + + static equals(a: SayRequest | PlainMessage | undefined, b: SayRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(SayRequest, a, b); + } +} + +/** + * @generated from message apache.dubbo.demo.example.v1.SayResponse + */ +export class SayResponse extends Message { + /** + * @generated from field: string sentence = 1; + */ + sentence = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "apache.dubbo.demo.example.v1.SayResponse"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "sentence", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): SayResponse { + return new SayResponse().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): SayResponse { + return new SayResponse().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): SayResponse { + return new SayResponse().fromJsonString(jsonString, options); + } + + static equals(a: SayResponse | PlainMessage | undefined, b: SayResponse | PlainMessage | undefined): boolean { + return proto3.util.equals(SayResponse, a, b); + } +} + diff --git a/example/dubbo-http2-node-example/localhost+1-key.pem b/example/dubbo-http2-node-example/localhost+1-key.pem new file mode 100644 index 00000000..9ac6d78e --- /dev/null +++ b/example/dubbo-http2-node-example/localhost+1-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCkM4avGmv88fB8 +Yh7Xk4RNbj5KdNAhInF7lSa0gmt9ZTXLdBQ6Ep80Qn0Afmxu8N5MplmQqcx5M1vJ +JtTBtbKWGurT0GeLna1Fp0ASIbeRuxAJMWwjU2k+P2hqUGUOIStV5H/azQ5GeTpo +wObHsbFBqBkvNh+lt1pr2t471+sihhdPe8qvWIddCkmiBbMFXvb70oIf34B+WnfV +oOeSiujtLoxKhmoijox5mntaegDdVNCQEPifTNg/jLHwx14lt388Y/ri9fZXsYQy +VVaLcpINNfxp7GE0U5FdmvZYiIgcKfCuqhtlaGYOpMGe907v2wH+e6IJ1aOrjy2c +gaVCH0ozAgMBAAECggEANJ/+7me9bFfuBy87S0QQBvDqLdq6SaRMUps+yGN0J8Ak +OYx+Xw5Qz+LvRRU/k17HIDHASsjgq4d2R0WWsm6VSd5enHwSc4CZY9Vyh10fBCm7 +vfaE/d1hwX147XnOqXSf+us8vtcxWAzKV4BbdmzQroY9bBAgnG/jHuYKi4tr5Kgp +hsj8FfrRm/FrWMsU9QWYlDYsuRuN9i3qUzPYvSO8HvbNfssA+f01bONvXgXUbz4/ +1IlCV/najUcfDfK9QhauftZhNpXku4BbWlDqPP8rNE5SBG7iK8HI1jqf4GKM5UCl +aTh2aIqxUEfLdhzBbRHkLy+EE4qjZDHqzm/vbxvLYQKBgQDDfRojlTFtAfVtkDwl +xbPnkOvu6sp0fcui5ix/u70lYz+7p3kBKA9t6xm22NdSaE6qkxjNMj5gNBLyhTN5 +oJqroobT3wlN6xAvr8d/Nzynh4/XcUfwlM7yqet9cDVMf8nLGE340Zmn5jPYVaTX +b38kkaynaXmAureZQtHtb6EE/QKBgQDXByZiITw3xMn7+bkA1wOTUfRcUhYt9izV +NtnP0P8WC0lkSgYmE+s2B6SMhUb/IS+AfOIMsmFdxxqgmHT+QFLJ4XiGwPMBCiL6 +MAM7DbJ6AeadpjDQ1B9m+jyu1wmA14re0xU0XB5hyMZgtQOXN5Ram89H0DOvUFUh +MTywFQzK7wKBgQCSo1zgJCGXK0j2jqMPkmWI5mSUKvsCtvnxj8cBacpQKUq9cLqL +64jnYts/FRkvb57SxNRt16qCb41m7hPWwGpFJP0OINfR4umZW7nB66VL5Zw4d3kH +NhimXl+PEIRqhdDQz8JtSoyALWXmeRfVooU04TEpwyypK2ZdSIpAGOQn4QKBgQDG +G5RFfJFaYDgnqp/EIlTs+ejE1ewRVGlh1zM9wDQEP0nS2FBp7JgcI1Z7EJ+klxKI +soYhZIdIOxRROaUwSlr8HHtKy6IXJxuqnWmckrYIqo+qV19KRuTXn10hSIU861jK +indS0jw7oxsCJkO0okRQZpTGeQ/lSYHlHtPm9r3eiQKBgGys6eZ7AJ3/c3RmvYM0 +R+QFug9r3/l76Q+gusfRSGkvuL3fH+gpD5glSQu5cukJefAUCTecbLJ7SBEgSb7E +9TLgWGTi9MGDJSiPadvNdnOSXcJifPRDbVTzzoseZUy8reIgchMKQgRpeBrPJt3M +nsC2oUnADd7/6pzrGjPyxl0D +-----END PRIVATE KEY----- diff --git a/example/dubbo-http2-node-example/localhost+1.pem b/example/dubbo-http2-node-example/localhost+1.pem new file mode 100644 index 00000000..aa5cbe1b --- /dev/null +++ b/example/dubbo-http2-node-example/localhost+1.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEUDCCArigAwIBAgIRAKuTG+GjDnE/HARizF2WJ18wDQYJKoZIhvcNAQELBQAw +gYcxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTEuMCwGA1UECwwlU0Mt +MjAyNDAyMjYyMzA5XEFkbWluQFNDLTIwMjQwMjI2MjMwOTE1MDMGA1UEAwwsbWtj +ZXJ0IFNDLTIwMjQwMjI2MjMwOVxBZG1pbkBTQy0yMDI0MDIyNjIzMDkwHhcNMjQw +ODI0MDc0ODM3WhcNMjYxMTI0MDc0ODM3WjBZMScwJQYDVQQKEx5ta2NlcnQgZGV2 +ZWxvcG1lbnQgY2VydGlmaWNhdGUxLjAsBgNVBAsMJVNDLTIwMjQwMjI2MjMwOVxB +ZG1pbkBTQy0yMDI0MDIyNjIzMDkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCkM4avGmv88fB8Yh7Xk4RNbj5KdNAhInF7lSa0gmt9ZTXLdBQ6Ep80Qn0A +fmxu8N5MplmQqcx5M1vJJtTBtbKWGurT0GeLna1Fp0ASIbeRuxAJMWwjU2k+P2hq +UGUOIStV5H/azQ5GeTpowObHsbFBqBkvNh+lt1pr2t471+sihhdPe8qvWIddCkmi +BbMFXvb70oIf34B+WnfVoOeSiujtLoxKhmoijox5mntaegDdVNCQEPifTNg/jLHw +x14lt388Y/ri9fZXsYQyVVaLcpINNfxp7GE0U5FdmvZYiIgcKfCuqhtlaGYOpMGe +907v2wH+e6IJ1aOrjy2cgaVCH0ozAgMBAAGjZDBiMA4GA1UdDwEB/wQEAwIFoDAT +BgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBTic1/yG3hd+OqMl94SCVGa +YVILdzAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcNAQELBQAD +ggGBAB1fmrDJ9BTqsgUtvzJPcmdrdNrUNWfQPflAT712n3DLwN4ZAH6N3UDYknkb +Xp72TX+z0hZlrwOThPgTFwiMPNx686RXPdvNFGqNRouGiINJa85qsjyW81ToARea +RO36mIVnWOClkTuDQqfcHCUK72h9q4KKpop7RC8nQnJ9ZHpgTNkYEoVpeLXa2/DF +CiGjGYCiEC0E+vH8ZW6SZHvjf3JeBh0dHgDdXuSrxnw/nZApBxdTM5utNbx/vY/P +HOhMHluJsBuiyqPIDvrpp8bksQuSPTZha9yx8T5bSx7R/auNoEYBuJfPJ7dRViYV +BNKkM0cI82QGd7FgZWrmOlaFLztcCrtl62vwxcOioJ3se7UFovcHqJCwK/4EY6d2 +lGsK0XDSzr4/Xj2Ta+gDVudhOw+LE6h54i2LDIWnuhR+XRSobjNRim+T9w4GOdsB +fKPGZsP5dXOXXjAT+tPdmNo3VT1c0o+QkpMilBBI9vR0xUr+PZR4VmL1ldIxUdru +SKUHxQ== +-----END CERTIFICATE----- diff --git a/example/dubbo-http2-node-example/package-lock.json b/example/dubbo-http2-node-example/package-lock.json new file mode 100644 index 00000000..a6d8066f --- /dev/null +++ b/example/dubbo-http2-node-example/package-lock.json @@ -0,0 +1,1498 @@ +{ + "name": "dubbo-node-example", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "dubbo-node-example", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "@apachedubbo/dubbo-fastify": "3.0.0-alpha", + "@apachedubbo/protoc-gen-apache-dubbo-es": "3.0.0-alpha", + "@bufbuild/protobuf": "^1.2.1", + "@bufbuild/protoc-gen-es": "^1.2.1", + "@fastify/cors": "^8.3.0", + "@types/express": "^4.17.18", + "fastify": "^4.19.2" + }, + "devDependencies": { + "@types/node": "^22.5.0" + } + }, + "node_modules/@apachedubbo/dubbo": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/dubbo/-/dubbo-3.0.0-alpha.tgz", + "integrity": "sha512-ZdLHlfrXy4PUkTNSUctaKAaA7fcv8B0DjH5waFVTAgRmup1WT0ABK9HAmCLb4FIBYLsQ3QiPKZ7sW0l6SUe5tQ==", + "peerDependencies": { + "@bufbuild/protobuf": "^1.2.1" + } + }, + "node_modules/@apachedubbo/dubbo-fastify": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/dubbo-fastify/-/dubbo-fastify-3.0.0-alpha.tgz", + "integrity": "sha512-xbcEQQjTx4aHuBVJzK7pHOXD9DzFBI/tiF8o28o9Gvhr1HjwhOpmSZ1hFR1J7+WLh34mT5/SdNeoxH7dGtBsgg==", + "dependencies": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "@apachedubbo/dubbo-node": "3.0.0-alpha", + "fastify": "^4.17.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@bufbuild/protobuf": "^1.2.1" + } + }, + "node_modules/@apachedubbo/dubbo-node": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/dubbo-node/-/dubbo-node-3.0.0-alpha.tgz", + "integrity": "sha512-OiBJIbun8JVdyHNrbpq8irb3xdZsqfMPh9ZcO5xyTQfTicc355vA079AOZznR005bvGSU9Tk8cWQe7FtQfMN1A==", + "dependencies": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "headers-polyfill": "^3.1.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@bufbuild/protobuf": "^1.2.1" + } + }, + "node_modules/@apachedubbo/protoc-gen-apache-dubbo-es": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/protoc-gen-apache-dubbo-es/-/protoc-gen-apache-dubbo-es-3.0.0-alpha.tgz", + "integrity": "sha512-U6iOYl0HWVe9eXA3T+OsPx161xuDtXanKr9DNB0a+PFzUeC7Xdeyuq3xZkfYB14697xK7fZXHBxwOcCA4boyTw==", + "dependencies": { + "@bufbuild/protobuf": "^1.2.1", + "@bufbuild/protoplugin": "^1.2.1" + }, + "bin": { + "protoc-gen-apache-dubbo-es": "bin/protoc-gen-apache-dubbo-es" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "@bufbuild/protoc-gen-es": "^1.2.1" + }, + "peerDependenciesMeta": { + "@apachedubbo/dubbo": { + "optional": true + }, + "@bufbuild/protoc-gen-es": { + "optional": true + } + } + }, + "node_modules/@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, + "node_modules/@bufbuild/protoc-gen-es": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protoc-gen-es/-/protoc-gen-es-1.10.0.tgz", + "integrity": "sha512-zBYBsVT/ul4uZb6F+kD7/k4sWNHVVbEPfJwKi0FDr+9VJo8MKIofI6pkr5ksBLr4fi/74r+e/75Xi/0clL5dXg==", + "dependencies": { + "@bufbuild/protobuf": "^1.10.0", + "@bufbuild/protoplugin": "1.10.0" + }, + "bin": { + "protoc-gen-es": "bin/protoc-gen-es" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@bufbuild/protobuf": "1.10.0" + }, + "peerDependenciesMeta": { + "@bufbuild/protobuf": { + "optional": true + } + } + }, + "node_modules/@bufbuild/protoplugin": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protoplugin/-/protoplugin-1.10.0.tgz", + "integrity": "sha512-u6NE4vL0lw1+EK4/PiE/SQB7fKO4LRJNTEScIXVOi2x88K/c8WKc/k0KyEaA0asVBMpwekJQZGnRyj04ZtN5Gg==", + "dependencies": { + "@bufbuild/protobuf": "1.10.0", + "@typescript/vfs": "^1.4.0", + "typescript": "4.5.2" + } + }, + "node_modules/@fastify/ajv-compiler": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", + "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", + "dependencies": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fast-uri": "^2.0.0" + } + }, + "node_modules/@fastify/cors": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.5.0.tgz", + "integrity": "sha512-/oZ1QSb02XjP0IK1U0IXktEsw/dUBTxJOW7IpIeO8c/tNalw/KjoNSJv1Sf6eqoBPO+TDGkifq6ynFK3v68HFQ==", + "dependencies": { + "fastify-plugin": "^4.0.0", + "mnemonist": "0.39.6" + } + }, + "node_modules/@fastify/error": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", + "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", + "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", + "dependencies": { + "fast-json-stringify": "^5.7.0" + } + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", + "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/node": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@typescript/vfs": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.0.tgz", + "integrity": "sha512-hvJUjNVeBMp77qPINuUvYXj4FyWeeMMKZkxEATEU3hqBAQ7qdTBCUFT7Sp0Zu0faeEtFf+ldXxMEDr/bk73ISg==", + "dependencies": { + "debug": "^4.1.1" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "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": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv/node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", + "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", + "dependencies": { + "@fastify/error": "^3.3.0", + "fastq": "^1.17.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-content-type-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", + "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==" + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stringify": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", + "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", + "dependencies": { + "@fastify/merge-json-schemas": "^0.1.0", + "ajv": "^8.10.0", + "ajv-formats": "^3.0.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-json-stringify/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-uri": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==" + }, + "node_modules/fastify": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.28.1.tgz", + "integrity": "sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "dependencies": { + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", + "proxy-addr": "^2.0.7", + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" + } + }, + "node_modules/fastify-plugin": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", + "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/find-my-way": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.0.tgz", + "integrity": "sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/headers-polyfill": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.3.0.tgz", + "integrity": "sha512-5e57etwBpNcDc0b6KCVWEh/Ro063OxPvzVimUdM0/tsYM/T7Hfy3kknIGj78SFTOhNd8AZY41U8mOHoO4LzmIQ==" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/json-schema-ref-resolver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", + "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/light-my-request": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.13.0.tgz", + "integrity": "sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==", + "dependencies": { + "cookie": "^0.6.0", + "process-warning": "^3.0.0", + "set-cookie-parser": "^2.4.1" + } + }, + "node_modules/mnemonist": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.6.tgz", + "integrity": "sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==", + "dependencies": { + "obliterator": "^2.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/pino": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.3.2.tgz", + "integrity": "sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.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": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==" + }, + "node_modules/pino/node_modules/process-warning": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.0.tgz", + "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==" + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ret": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", + "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/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" + } + ] + }, + "node_modules/safe-regex2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", + "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", + "dependencies": { + "ret": "~0.4.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==" + }, + "node_modules/sonic-boom": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", + "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/typescript": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + } + }, + "dependencies": { + "@apachedubbo/dubbo": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/dubbo/-/dubbo-3.0.0-alpha.tgz", + "integrity": "sha512-ZdLHlfrXy4PUkTNSUctaKAaA7fcv8B0DjH5waFVTAgRmup1WT0ABK9HAmCLb4FIBYLsQ3QiPKZ7sW0l6SUe5tQ==", + "requires": {} + }, + "@apachedubbo/dubbo-fastify": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/dubbo-fastify/-/dubbo-fastify-3.0.0-alpha.tgz", + "integrity": "sha512-xbcEQQjTx4aHuBVJzK7pHOXD9DzFBI/tiF8o28o9Gvhr1HjwhOpmSZ1hFR1J7+WLh34mT5/SdNeoxH7dGtBsgg==", + "requires": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "@apachedubbo/dubbo-node": "3.0.0-alpha", + "fastify": "^4.17.0" + } + }, + "@apachedubbo/dubbo-node": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/dubbo-node/-/dubbo-node-3.0.0-alpha.tgz", + "integrity": "sha512-OiBJIbun8JVdyHNrbpq8irb3xdZsqfMPh9ZcO5xyTQfTicc355vA079AOZznR005bvGSU9Tk8cWQe7FtQfMN1A==", + "requires": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "headers-polyfill": "^3.1.2" + } + }, + "@apachedubbo/protoc-gen-apache-dubbo-es": { + "version": "3.0.0-alpha", + "resolved": "https://registry.npmjs.org/@apachedubbo/protoc-gen-apache-dubbo-es/-/protoc-gen-apache-dubbo-es-3.0.0-alpha.tgz", + "integrity": "sha512-U6iOYl0HWVe9eXA3T+OsPx161xuDtXanKr9DNB0a+PFzUeC7Xdeyuq3xZkfYB14697xK7fZXHBxwOcCA4boyTw==", + "requires": { + "@bufbuild/protobuf": "^1.2.1", + "@bufbuild/protoplugin": "^1.2.1" + } + }, + "@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, + "@bufbuild/protoc-gen-es": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protoc-gen-es/-/protoc-gen-es-1.10.0.tgz", + "integrity": "sha512-zBYBsVT/ul4uZb6F+kD7/k4sWNHVVbEPfJwKi0FDr+9VJo8MKIofI6pkr5ksBLr4fi/74r+e/75Xi/0clL5dXg==", + "requires": { + "@bufbuild/protobuf": "^1.10.0", + "@bufbuild/protoplugin": "1.10.0" + } + }, + "@bufbuild/protoplugin": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protoplugin/-/protoplugin-1.10.0.tgz", + "integrity": "sha512-u6NE4vL0lw1+EK4/PiE/SQB7fKO4LRJNTEScIXVOi2x88K/c8WKc/k0KyEaA0asVBMpwekJQZGnRyj04ZtN5Gg==", + "requires": { + "@bufbuild/protobuf": "1.10.0", + "@typescript/vfs": "^1.4.0", + "typescript": "4.5.2" + } + }, + "@fastify/ajv-compiler": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", + "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", + "requires": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fast-uri": "^2.0.0" + } + }, + "@fastify/cors": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.5.0.tgz", + "integrity": "sha512-/oZ1QSb02XjP0IK1U0IXktEsw/dUBTxJOW7IpIeO8c/tNalw/KjoNSJv1Sf6eqoBPO+TDGkifq6ynFK3v68HFQ==", + "requires": { + "fastify-plugin": "^4.0.0", + "mnemonist": "0.39.6" + } + }, + "@fastify/error": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", + "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==" + }, + "@fastify/fast-json-stringify-compiler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", + "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", + "requires": { + "fast-json-stringify": "^5.7.0" + } + }, + "@fastify/merge-json-schemas": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", + "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "@types/node": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "requires": { + "undici-types": "~6.19.2" + } + }, + "@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "requires": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "@typescript/vfs": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.0.tgz", + "integrity": "sha512-hvJUjNVeBMp77qPINuUvYXj4FyWeeMMKZkxEATEU3hqBAQ7qdTBCUFT7Sp0Zu0faeEtFf+ldXxMEDr/bk73ISg==", + "requires": { + "debug": "^4.1.1" + } + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" + }, + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "dependencies": { + "fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + } + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + } + }, + "atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" + }, + "avvio": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", + "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", + "requires": { + "@fastify/error": "^3.3.0", + "fastq": "^1.17.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" + }, + "debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "requires": { + "ms": "2.1.2" + } + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "fast-content-type-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", + "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==" + }, + "fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stringify": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", + "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", + "requires": { + "@fastify/merge-json-schemas": "^0.1.0", + "ajv": "^8.10.0", + "ajv-formats": "^3.0.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" + }, + "dependencies": { + "ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "requires": { + "ajv": "^8.0.0" + } + } + } + }, + "fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "requires": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==" + }, + "fast-uri": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==" + }, + "fastify": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.28.1.tgz", + "integrity": "sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==", + "requires": { + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", + "proxy-addr": "^2.0.7", + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" + } + }, + "fastify-plugin": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", + "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==" + }, + "fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "requires": { + "reusify": "^1.0.4" + } + }, + "find-my-way": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.0.tgz", + "integrity": "sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==", + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "headers-polyfill": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.3.0.tgz", + "integrity": "sha512-5e57etwBpNcDc0b6KCVWEh/Ro063OxPvzVimUdM0/tsYM/T7Hfy3kknIGj78SFTOhNd8AZY41U8mOHoO4LzmIQ==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "json-schema-ref-resolver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", + "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "light-my-request": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.13.0.tgz", + "integrity": "sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==", + "requires": { + "cookie": "^0.6.0", + "process-warning": "^3.0.0", + "set-cookie-parser": "^2.4.1" + } + }, + "mnemonist": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.6.tgz", + "integrity": "sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==", + "requires": { + "obliterator": "^2.0.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, + "on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==" + }, + "pino": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.3.2.tgz", + "integrity": "sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw==", + "requires": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.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" + }, + "dependencies": { + "process-warning": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.0.tgz", + "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==" + } + } + }, + "pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "requires": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + } + }, + "real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "ret": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", + "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", + "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", + "requires": { + "ret": "~0.4.0" + } + }, + "safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" + }, + "secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, + "set-cookie-parser": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==" + }, + "sonic-boom": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", + "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", + "requires": { + "atomic-sleep": "^1.0.0" + } + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "requires": { + "real-require": "^0.2.0" + } + }, + "toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==" + }, + "typescript": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==" + }, + "undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + } + } +} diff --git a/example/dubbo-http2-node-example/package.json b/example/dubbo-http2-node-example/package.json new file mode 100644 index 00000000..bcc4b934 --- /dev/null +++ b/example/dubbo-http2-node-example/package.json @@ -0,0 +1,27 @@ +{ + "name": "dubbo-node-example", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "engines": { + "node": ">=17" + }, + "dependencies": { + "@apachedubbo/dubbo": "3.0.0-alpha", + "@apachedubbo/dubbo-fastify": "3.0.0-alpha", + "@apachedubbo/protoc-gen-apache-dubbo-es": "3.0.0-alpha", + "@bufbuild/protobuf": "^1.2.1", + "@bufbuild/protoc-gen-es": "^1.2.1", + "@fastify/cors": "^8.3.0", + "@types/express": "^4.17.18", + "fastify": "^4.19.2" + }, + "devDependencies": { + "@types/node": "^22.5.0" + } +} diff --git a/example/dubbo-http2-node-example/proto/example.proto b/example/dubbo-http2-node-example/proto/example.proto new file mode 100644 index 00000000..4f74e0d4 --- /dev/null +++ b/example/dubbo-http2-node-example/proto/example.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package apache.dubbo.demo.example.v1; + +message SayRequest { + string sentence = 1; +} + +message SayResponse { + string sentence = 1; +} + +service ExampleService { + rpc Say(SayRequest) returns (SayResponse) {} +} \ No newline at end of file diff --git a/example/dubbo-http2-node-example/server.ts b/example/dubbo-http2-node-example/server.ts new file mode 100644 index 00000000..0bd33066 --- /dev/null +++ b/example/dubbo-http2-node-example/server.ts @@ -0,0 +1,20 @@ +import { fastify } from "fastify"; +import { fastifyDubboPlugin } from "@apachedubbo/dubbo-fastify"; +import routes from "./dubbo"; +import { readFileSync } from "fs"; + +async function main() { + const server = fastify({ + http2: true, + https: { + key: readFileSync("localhost+1-key.pem", "utf8"), + cert: readFileSync("localhost+1.pem", "utf8"), + } + }); + await server.register(fastifyDubboPlugin, { + routes, + }); + await server.listen({ host: "localhost", port: 8443 }); + console.log("server is listening at", server.addresses()); +} +void main(); \ No newline at end of file diff --git a/example/dubbo-node-example/package-lock.json b/example/dubbo-node-example/package-lock.json index 2dad4f4d..ee567f05 100644 --- a/example/dubbo-node-example/package-lock.json +++ b/example/dubbo-node-example/package-lock.json @@ -756,4 +756,4 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } -} \ No newline at end of file +} diff --git a/packages/dubbo/src/promise-client.spec.ts b/packages/dubbo/src/promise-client.spec.ts index 41b622d2..be900d12 100644 --- a/packages/dubbo/src/promise-client.spec.ts +++ b/packages/dubbo/src/promise-client.spec.ts @@ -21,6 +21,7 @@ import { import { createAsyncIterable } from "./protocol/async-iterable.js"; import { createRouterTransport } from "./router-transport.js"; import type { HandlerContext } from "./implementation"; +import type { TripleClientServiceOptions } from './protocol-triple/client-service-options.js'; const TestService = { typeName: "handwritten.TestService", @@ -52,6 +53,8 @@ describe("createClientStreamingFn()", function () { const output = new StringValue({ value: "yield 1" }); + // Define serviceOptions + const transport = createRouterTransport(({ service }) => { service(TestService, { clientStream: ( @@ -65,7 +68,7 @@ describe("createClientStreamingFn()", function () { const fn = createClientStreamingFn( transport, TestService, - TestService.methods.clientStream + TestService.methods.clientStream, ); const res = await fn( // eslint-disable-next-line @typescript-eslint/require-await @@ -78,6 +81,189 @@ describe("createClientStreamingFn()", function () { }); }); +describe("createClientStreamingFn()", function () { + it("works as expected on the happy path", async () => { + const input = new Int32Value({ value: 1 }); + + const output = new StringValue({ value: "yield 1" }); + + // Define serviceOptions + const serviceOptions: TripleClientServiceOptions = { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + clientStream: ( + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + _input: AsyncIterable, + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + _context: HandlerContext + ) => Promise.resolve(output), + }); + }); + const fn = createClientStreamingFn( + transport, + TestService, + TestService.methods.clientStream, + serviceOptions + ); + const res = await fn( + // eslint-disable-next-line @typescript-eslint/require-await + (async function* () { + yield input; + })() + ); + expect(res).toBeInstanceOf(StringValue); + expect(res.value).toEqual(output.value); + }); +}); + +describe("createClientStreamingFn()", function () { + it("works as expected when serviceVersion is missing", async () => { + const input = new Int32Value({ value: 1 }); + const output = new StringValue({ value: "yield 1" }); + + // Define serviceOptions without serviceVersion + const serviceOptions: TripleClientServiceOptions = { serviceGroup: 'dubbo' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + clientStream: ( + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + _input: AsyncIterable, + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + _context: HandlerContext + ) => Promise.resolve(output), + }); + }); + + const fn = createClientStreamingFn( + transport, + TestService, + TestService.methods.clientStream, + serviceOptions + ); + + const res = await fn( + // eslint-disable-next-line @typescript-eslint/require-await + (async function* () { + yield input; + })() + ); + + expect(res).toBeInstanceOf(StringValue); + expect(res.value).toEqual(output.value); + }); +}); + + +describe("createClientStreamingFn()", function () { + it("works as expected when serviceGroup is missing", async () => { + const input = new Int32Value({ value: 1 }); + const output = new StringValue({ value: "yield 1" }); + + // Define serviceOptions without serviceGroup + const serviceOptions: TripleClientServiceOptions = { serviceVersion: '1.0.0' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + clientStream: ( + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + _input: AsyncIterable, + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + _context: HandlerContext + ) => Promise.resolve(output), + }); + }); + + const fn = createClientStreamingFn( + transport, + TestService, + TestService.methods.clientStream, + serviceOptions + ); + + const res = await fn( + // eslint-disable-next-line @typescript-eslint/require-await + (async function* () { + yield input; + })() + ); + + expect(res).toBeInstanceOf(StringValue); + expect(res.value).toEqual(output.value); + }); +}); + + + +describe("createServerStreamingFn()", function () { + it("works as expected when serviceVersion is missing", async () => { + const output = [ + new StringValue({ value: "input1" }), + new StringValue({ value: "input2" }), + new StringValue({ value: "input3" }), + ]; + + // Define serviceOptions + const serviceOptions: TripleClientServiceOptions = { serviceGroup: 'dubbo' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + serverStream: (_input: Int32Value, _context: HandlerContext) => + createAsyncIterable(output), + }); + }); + + const fn = createServerStreamingFn( + transport, + TestService, + TestService.methods.serverStream, + serviceOptions + ); + const receivedMessages: StringValue[] = []; + const input = new Int32Value({ value: 123 }); + for await (const res of fn(input)) { + receivedMessages.push(res); + } + expect(receivedMessages).toEqual(output); + }); +}); + +describe("createServerStreamingFn()", function () { + it("works as expected when serviceGroup is missing", async () => { + const output = [ + new StringValue({ value: "input1" }), + new StringValue({ value: "input2" }), + new StringValue({ value: "input3" }), + ]; + + // Define serviceOptions + const serviceOptions: TripleClientServiceOptions = { serviceVersion: '1.0.0' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- arguments not used for mock + serverStream: (_input: Int32Value, _context: HandlerContext) => + createAsyncIterable(output), + }); + }); + + const fn = createServerStreamingFn( + transport, + TestService, + TestService.methods.serverStream, + serviceOptions + ); + const receivedMessages: StringValue[] = []; + const input = new Int32Value({ value: 123 }); + for await (const res of fn(input)) { + receivedMessages.push(res); + } + expect(receivedMessages).toEqual(output); + }); +}); + describe("createServerStreamingFn()", function () { it("works as expected on the happy path", async () => { const output = [ @@ -85,6 +271,9 @@ describe("createServerStreamingFn()", function () { new StringValue({ value: "input2" }), new StringValue({ value: "input3" }), ]; + + // Define serviceOptions + const serviceOptions: TripleClientServiceOptions = { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }; const transport = createRouterTransport(({ service }) => { service(TestService, { @@ -97,7 +286,8 @@ describe("createServerStreamingFn()", function () { const fn = createServerStreamingFn( transport, TestService, - TestService.methods.serverStream + TestService.methods.serverStream, + serviceOptions ); const receivedMessages: StringValue[] = []; const input = new Int32Value({ value: 123 }); @@ -116,6 +306,9 @@ describe("createBiDiStreamingFn()", () => { values.map((value) => new Int32Value({ value })) ); + // Define serviceOptions + const serviceOptions: TripleClientServiceOptions = { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }; + let bidiIndex = 0; const transport = createRouterTransport(({ service }) => { service(TestService, { @@ -131,7 +324,8 @@ describe("createBiDiStreamingFn()", () => { const fn = createBiDiStreamingFn( transport, TestService, - TestService.methods.bidiStream + TestService.methods.bidiStream, + serviceOptions ); let index = 0; @@ -143,3 +337,77 @@ describe("createBiDiStreamingFn()", () => { expect(bidiIndex).toBe(3); }); }); + +describe("createBiDiStreamingFn()", () => { + it("works as expected when serviceVersion is missing", async () => { + const values = [123, 456, 789]; + + const input = createAsyncIterable( + values.map((value) => new Int32Value({ value })) + ); + + // Define serviceOptions without serviceVersion + const serviceOptions: TripleClientServiceOptions = { serviceGroup: 'dubbo' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + bidiStream: async function* (input: AsyncIterable) { + for await (const thing of input) { + yield new StringValue({ value: thing.value.toString() }); + } + }, + }); + }); + + const fn = createBiDiStreamingFn( + transport, + TestService, + TestService.methods.bidiStream, + serviceOptions + ); + + let index = 0; + for await (const res of fn(input)) { + expect(res).toEqual(new StringValue({ value: values[index].toString() })); + index += 1; + } + expect(index).toBe(3); + }); +}); + +describe("createBiDiStreamingFn()", () => { + it("works as expected when serviceGroup is missing", async () => { + const values = [123, 456, 789]; + + const input = createAsyncIterable( + values.map((value) => new Int32Value({ value })) + ); + + // Define serviceOptions without serviceGroup + const serviceOptions: TripleClientServiceOptions = { serviceVersion: '1.0.0' }; + + const transport = createRouterTransport(({ service }) => { + service(TestService, { + bidiStream: async function* (input: AsyncIterable) { + for await (const thing of input) { + yield new StringValue({ value: thing.value.toString() }); + } + }, + }); + }); + + const fn = createBiDiStreamingFn( + transport, + TestService, + TestService.methods.bidiStream, + serviceOptions + ); + + let index = 0; + for await (const res of fn(input)) { + expect(res).toEqual(new StringValue({ value: values[index].toString() })); + index += 1; + } + expect(index).toBe(3); + }); +}); diff --git a/packages/dubbo/src/promise-client.ts b/packages/dubbo/src/promise-client.ts index 5bc64948..4ae7cdb9 100644 --- a/packages/dubbo/src/promise-client.ts +++ b/packages/dubbo/src/promise-client.ts @@ -59,11 +59,11 @@ export function createPromiseClient( case MethodKind.Unary: return createUnaryFn(transport, service, method, serviceOptions); case MethodKind.ServerStreaming: - return createServerStreamingFn(transport, service, method); + return createServerStreamingFn(transport, service, method, serviceOptions); case MethodKind.ClientStreaming: - return createClientStreamingFn(transport, service, method); + return createClientStreamingFn(transport, service, method, serviceOptions); case MethodKind.BiDiStreaming: - return createBiDiStreamingFn(transport, service, method); + return createBiDiStreamingFn(transport, service, method, serviceOptions); default: return null; } @@ -115,7 +115,8 @@ export function createServerStreamingFn< >( transport: Transport, service: ServiceType, - method: MethodInfo + method: MethodInfo, + serviceOptions?: TripleClientServiceOptions ): ServerStreamingFn { return async function* (input, options): AsyncIterable { const inputMessage = @@ -126,7 +127,8 @@ export function createServerStreamingFn< options?.signal, options?.timeoutMs, options?.headers, - createAsyncIterable([inputMessage]) + createAsyncIterable([inputMessage]), + serviceOptions ); options?.onHeader?.(response.header); yield* response.message; @@ -149,7 +151,8 @@ export function createClientStreamingFn< >( transport: Transport, service: ServiceType, - method: MethodInfo + method: MethodInfo, + serviceOptions?: TripleClientServiceOptions ): ClientStreamingFn { return async function ( request: AsyncIterable>, @@ -166,7 +169,8 @@ export function createClientStreamingFn< options?.signal, options?.timeoutMs, options?.headers, - input() + input(), + serviceOptions ); options?.onHeader?.(response.header); let singleMessage: O | undefined; @@ -199,7 +203,8 @@ export function createBiDiStreamingFn< >( transport: Transport, service: ServiceType, - method: MethodInfo + method: MethodInfo, + serviceOptions?: TripleClientServiceOptions ): BiDiStreamingFn { return async function* ( request: AsyncIterable>, @@ -216,7 +221,8 @@ export function createBiDiStreamingFn< options?.signal, options?.timeoutMs, options?.headers, - input() + input(), + serviceOptions ); options?.onHeader?.(response.header); yield* response.message; diff --git a/packages/dubbo/src/protocol-triple/transport.ts b/packages/dubbo/src/protocol-triple/transport.ts index d308e43c..c529aa84 100644 --- a/packages/dubbo/src/protocol-triple/transport.ts +++ b/packages/dubbo/src/protocol-triple/transport.ts @@ -266,7 +266,8 @@ export function createTransport(opt: CommonTransportOptions): Transport { signal: AbortSignal | undefined, timeoutMs: number | undefined, header: HeadersInit | undefined, - input: AsyncIterable + input: AsyncIterable, + serviceOptions?: TripleClientServiceOptions ): Promise> { const serialization = createMethodSerializationLookup( method, @@ -297,7 +298,8 @@ export function createTransport(opt: CommonTransportOptions): Transport { timeoutMs, header, opt.acceptCompression, - opt.sendCompression + opt.sendCompression, + serviceOptions ), message: pipe(input, transformNormalizeMessage(method.I), { propagateDownStreamError: true, diff --git a/packages/dubbo/src/transport.ts b/packages/dubbo/src/transport.ts index 4f48e07b..d988be10 100644 --- a/packages/dubbo/src/transport.ts +++ b/packages/dubbo/src/transport.ts @@ -52,6 +52,7 @@ export interface Transport { signal: AbortSignal | undefined, timeoutMs: number | undefined, header: HeadersInit | undefined, - input: AsyncIterable + input: AsyncIterable, + serviceOptions?: TripleClientServiceOptions ): Promise>; }