diff --git a/packages/server/package.json b/packages/server/package.json index 9f2797f6..ac3f8bd5 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -18,12 +18,16 @@ }, "dependencies": { "@interledger/http-signature-utils": "^2.0.0", + "@interledger/open-payments": "6.1.0", + "@koa/router": "^12.0.1", "koa": "^2.14.2", "koa-bodyparser": "^4.4.1" }, "devDependencies": { + "@interledger/wm-openapi": "workspace:^", "@types/koa": "^2.14.0", "@types/koa-bodyparser": "^4.3.12", + "@types/koa__router": "^12.0.4", "tsx": "^4.7.0" } } diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts new file mode 100644 index 00000000..16b1136a --- /dev/null +++ b/packages/server/src/app.ts @@ -0,0 +1,53 @@ +import { type AuthenticatedClient } from '@interledger/open-payments'; +import Koa from 'koa'; +import bodyParser from 'koa-bodyparser'; +import { Server } from 'node:http'; + +import { type Config } from './config'; +import { type Context, Router } from './context'; +import { registerPublicRoutes } from './routes/public'; + +export class Application { + #config: Config; + #koa: Koa; + #router: Router; + #server?: Server; + #client: AuthenticatedClient; + + constructor(config: Config, client: AuthenticatedClient) { + this.#config = config; + this.#client = client; + this.#koa = new Koa(); + this.#router = new Router(); + + this.#decorateContext(); + this.#koa.use(bodyParser()); + + registerPublicRoutes(this.#router); + + this.#koa.use(this.#router.routes()); + this.#koa.use(this.#router.allowedMethods()); + } + + #decorateContext(): void { + this.#koa.context.client = this.#client; + } + + async start(): Promise { + await new Promise(res => { + this.#server = this.#koa.listen(this.#config.PORT, res); + }); + } + + async stop(): Promise { + await new Promise((resolve, reject) => { + this.#server?.close(err => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } +} diff --git a/packages/server/src/bootstrap.ts b/packages/server/src/bootstrap.ts new file mode 100644 index 00000000..f8824b62 --- /dev/null +++ b/packages/server/src/bootstrap.ts @@ -0,0 +1,21 @@ +import { createAuthenticatedClient } from '@interledger/open-payments'; + +import { Application } from './app'; +import { config } from './config'; + +async function test() { + console.log('creating op client'); + return await createAuthenticatedClient({ + walletAddressUrl: config.WALLET_ADDRESS, + privateKey: Buffer.from(config.PRIVATE_KEY, 'base64'), + keyId: config.KEY_ID, + }); +} + +export async function bootstrap() { + const client = await test(); + + const app = new Application(config, client); + await app.start(); + console.log(`WM Server listening on port ${config.PORT}`); +} diff --git a/packages/server/src/config.ts b/packages/server/src/config.ts new file mode 100644 index 00000000..908e8ce6 --- /dev/null +++ b/packages/server/src/config.ts @@ -0,0 +1,16 @@ +function getEnvVariable(name: string, defaultValue?: any): string { + if (!process.env[name]) { + return defaultValue; + } + + return process.env[name]!; +} + +export type Config = typeof config; + +export const config = { + PORT: parseInt(getEnvVariable('PORT', 3000), 10), + WALLET_ADDRESS: getEnvVariable('WALLET_ADDRESS'), + PRIVATE_KEY: getEnvVariable('PRIVATE_KEY'), + KEY_ID: getEnvVariable('KEY_ID'), +} as const; diff --git a/packages/server/src/context.ts b/packages/server/src/context.ts new file mode 100644 index 00000000..aa914475 --- /dev/null +++ b/packages/server/src/context.ts @@ -0,0 +1,24 @@ +import { type AuthenticatedClient } from '@interledger/open-payments'; +import { operations as Operations } from '@interledger/wm-openapi'; +import KoaRouter from '@koa/router'; +import Koa from 'koa'; +import { type ParsedUrlQuery } from 'node:querystring'; + +export interface ContextExtension + extends Koa.ParameterizedContext { + client: AuthenticatedClient; +} + +interface Request + extends Omit { + body: TBody; + query: ParsedUrlQuery & TQuery; +} + +export interface ConnectWalletContext extends ContextExtension { + request: Request; +} + +export type Context = Koa.ParameterizedContext; + +export class Router extends KoaRouter {} diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 7761e50e..2fb9dfe3 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1,81 +1,3 @@ -import { - createHeaders, - Headers, - loadBase64Key, - RequestLike, -} from '@interledger/http-signature-utils'; -import Koa from 'koa'; -import bodyParser from 'koa-bodyparser'; +import { bootstrap } from './bootstrap'; -interface Context - extends Koa.ParameterizedContext {} - -interface GenerateSignatureRequestBody extends RequestLike {} - -function validateBody(body: any): body is GenerateSignatureRequestBody { - return !!body.headers && !!body.method && !!body.url; -} - -async function validatePath(ctx: Context, next: Koa.Next): Promise { - if (ctx.path !== '/') { - ctx.status = 403; - } else { - await next(); - } -} - -async function validateMethod(ctx: Context, next: Koa.Next): Promise { - if (ctx.method !== 'POST') { - ctx.status = 405; - } else { - await next(); - } -} - -async function createHeadersHandler(ctx: Context): Promise { - const { body } = ctx.request; - - if (!validateBody(body)) { - ctx.throw('Invalid request body', 400); - } - - let privateKey: ReturnType; - - try { - privateKey = loadBase64Key(BASE64_PRIVATE_KEY); - } catch { - ctx.throw('Not a valid private key', 400); - } - - if (privateKey === undefined) { - ctx.throw('Not an Ed25519 private key', 400); - } - - const headers = await createHeaders({ - request: body, - privateKey, - keyId: KEY_ID, - }); - - delete headers['Content-Length']; - delete headers['Content-Type']; - - ctx.body = headers; -} - -const PORT = 3000; -const BASE64_PRIVATE_KEY = - 'LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndCQ0lFSUUvVlJTRVUzYS9CTUE2cmhUQnZmKzcxMG10YWlmbkF6SzFsWGpDK0QrSTkKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQ=='; -const KEY_ID = 'f0ac2190-54d5-47c8-b061-221e7068d823'; - -const app = new Koa(); - -app.use(bodyParser()); -app.use(validatePath); -app.use(validateMethod); -app.use(createHeadersHandler); - -app.listen(3000, () => { - // eslint-disable-next-line no-console - console.log(`Local signatures server started on port ${PORT}`); -}); +bootstrap(); diff --git a/packages/server/src/routes/public.ts b/packages/server/src/routes/public.ts new file mode 100644 index 00000000..2ed4cd4c --- /dev/null +++ b/packages/server/src/routes/public.ts @@ -0,0 +1,13 @@ +import type { DefaultState } from 'koa'; + +import type { ConnectWalletContext, Router } from '../context'; + +export function registerPublicRoutes(router: Router) { + router.get('/', async ctx => { + const wallet = await ctx.client.walletAddress.get({ + url: 'https://ilp.rafiki.money/radu', + }); + + ctx.body = wallet; + }); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db3d6a9b..ddac0a25 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -237,6 +237,12 @@ importers: '@interledger/http-signature-utils': specifier: ^2.0.0 version: 2.0.0 + '@interledger/open-payments': + specifier: 6.1.0 + version: 6.1.0 + '@koa/router': + specifier: ^12.0.1 + version: 12.0.1 koa: specifier: ^2.14.2 version: 2.14.2 @@ -244,12 +250,18 @@ importers: specifier: ^4.4.1 version: 4.4.1 devDependencies: + '@interledger/wm-openapi': + specifier: workspace:^ + version: link:../openapi '@types/koa': specifier: ^2.14.0 version: 2.14.0 '@types/koa-bodyparser': specifier: ^4.3.12 version: 4.3.12 + '@types/koa__router': + specifier: ^12.0.4 + version: 12.0.4 tsx: specifier: ^4.7.0 version: 4.7.0 @@ -278,6 +290,17 @@ packages: '@jridgewell/trace-mapping': 0.3.20 dev: true + /@apidevtools/json-schema-ref-parser@10.1.0: + resolution: {integrity: sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==} + engines: {node: '>= 16'} + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + '@types/lodash.clonedeep': 4.5.9 + js-yaml: 4.1.0 + lodash.clonedeep: 4.5.0 + dev: false + /@babel/code-frame@7.23.5: resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} @@ -902,6 +925,37 @@ packages: uuid: 9.0.1 dev: false + /@interledger/open-payments@6.1.0: + resolution: {integrity: sha512-M7snUtsKdPGgKx4FyUfKFC2PeWTr2qIh+8AYpBXIj90GOMOU/u7ArEBxmrVzHD7PjKyE4fKatpuwTPlyvt7pCg==} + dependencies: + '@interledger/http-signature-utils': 2.0.0 + '@interledger/openapi': 1.2.1 + axios: 1.6.2 + base64url: 3.0.1 + http-message-signatures: 0.1.2 + pino: 8.17.2 + uuid: 9.0.1 + transitivePeerDependencies: + - debug + - supports-color + dev: false + + /@interledger/openapi@1.2.1: + resolution: {integrity: sha512-CVEMjLH94svT5ikaojplgZ3YlZAe7ml6G6bt0ZCbqkbwHszUwY1E6RexZZejiGju5QvwS/6Jl/Op5ymv/ECaLg==} + dependencies: + '@apidevtools/json-schema-ref-parser': 10.1.0 + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) + koa: 2.14.2 + openapi-default-setter: 12.1.3 + openapi-request-coercer: 12.1.3 + openapi-request-validator: 12.1.3 + openapi-response-validator: 12.1.3 + openapi-types: 12.1.3 + transitivePeerDependencies: + - supports-color + dev: false + /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -1170,6 +1224,23 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /@jsdevtools/ono@7.1.3: + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + dev: false + + /@koa/router@12.0.1: + resolution: {integrity: sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==} + engines: {node: '>= 12'} + dependencies: + debug: 4.3.4 + http-errors: 2.0.0 + koa-compose: 4.1.0 + methods: 1.1.2 + path-to-regexp: 6.2.1 + transitivePeerDependencies: + - supports-color + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1526,6 +1597,22 @@ packages: '@types/node': 20.10.4 dev: true + /@types/koa__router@12.0.4: + resolution: {integrity: sha512-Y7YBbSmfXZpa/m5UGGzb7XadJIRBRnwNY9cdAojZGp65Cpe5MAP3mOZE7e3bImt8dfKS4UFcR16SLH8L/z7PBw==} + dependencies: + '@types/koa': 2.14.0 + dev: true + + /@types/lodash.clonedeep@4.5.9: + resolution: {integrity: sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q==} + dependencies: + '@types/lodash': 4.14.202 + dev: false + + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} + dev: false + /@types/mime@1.3.5: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: true @@ -2039,6 +2126,13 @@ packages: deprecated: Use your platform's native atob() and btoa() methods instead dev: true + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -2190,7 +2284,6 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true /aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -2317,6 +2410,11 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + /autoprefixer@10.4.16(postcss@8.4.32): resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} @@ -2442,6 +2540,15 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /base64url@3.0.1: + resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} + engines: {node: '>=6.0.0'} + dev: false + /bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: @@ -2498,6 +2605,13 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -3808,6 +3922,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -3872,6 +3991,11 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true + /fast-redact@3.3.0: + resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} + engines: {node: '>=6'} + dev: false + /fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -4375,6 +4499,10 @@ packages: postcss: 8.4.32 dev: false + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + /ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} @@ -5260,7 +5388,6 @@ packages: hasBin: true dependencies: argparse: 2.0.1 - dev: true /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} @@ -5500,6 +5627,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false + /lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} dev: true @@ -5576,6 +5707,11 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: false + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -5775,6 +5911,11 @@ packages: es-abstract: 1.22.3 dev: true + /on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + dev: false + /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -5798,6 +5939,47 @@ packages: resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} dev: false + /openapi-default-setter@12.1.3: + resolution: {integrity: sha512-wHKwvEuOWwke5WcQn8pyCTXT5WQ+rm9FpJmDeEVECEBWjEyB/MVLYfXi+UQeSHTTu2Tg4VDHHmzbjOqN6hYeLQ==} + dependencies: + openapi-types: 12.1.3 + dev: false + + /openapi-jsonschema-parameters@12.1.3: + resolution: {integrity: sha512-aHypKxWHwu2lVqfCIOCZeJA/2NTDiP63aPwuoIC+5ksLK5/IQZ3oKTz7GiaIegz5zFvpMDxDvLR2DMQQSkOAug==} + dependencies: + openapi-types: 12.1.3 + dev: false + + /openapi-request-coercer@12.1.3: + resolution: {integrity: sha512-CT2ZDhBmAZpHhAzHhEN+/J5oMK3Ds99ayLLdXh2Aw1DCcn72EM8VuIGVwG5fSjvkMsgtn7FgltFosHqeM6PRFQ==} + dependencies: + openapi-types: 12.1.3 + ts-log: 2.2.5 + dev: false + + /openapi-request-validator@12.1.3: + resolution: {integrity: sha512-HW1sG00A9Hp2oS5g8CBvtaKvRAc4h5E4ksmuC5EJgmQ+eAUacL7g+WaYCrC7IfoQaZrjxDfeivNZUye/4D8pwA==} + dependencies: + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) + content-type: 1.0.5 + openapi-jsonschema-parameters: 12.1.3 + openapi-types: 12.1.3 + ts-log: 2.2.5 + dev: false + + /openapi-response-validator@12.1.3: + resolution: {integrity: sha512-beZNb6r1SXAg1835S30h9XwjE596BYzXQFAEZlYAoO2imfxAu5S7TvNFws5k/MMKMCOFTzBXSjapqEvAzlblrQ==} + dependencies: + ajv: 8.12.0 + openapi-types: 12.1.3 + dev: false + + /openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + dev: false + /openapi-typescript@6.7.4: resolution: {integrity: sha512-EZyeW9Wy7UDCKv0iYmKrq2pVZtquXiD/YHiUClAKqiMi42nodx/EQH11K6fLqjt1IZlJmVokrAsExsBMM2RROQ==} hasBin: true @@ -5927,6 +6109,10 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -5963,6 +6149,34 @@ packages: engines: {node: '>=0.10.0'} dev: false + /pino-abstract-transport@1.1.0: + resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} + dependencies: + readable-stream: 4.5.2 + split2: 4.2.0 + dev: false + + /pino-std-serializers@6.2.2: + resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} + dev: false + + /pino@8.17.2: + resolution: {integrity: sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.3.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.1.0 + pino-std-serializers: 6.2.2 + process-warning: 3.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 3.8.0 + thread-stream: 2.4.1 + dev: false + /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -6187,6 +6401,15 @@ packages: react-is: 18.2.0 dev: true + /process-warning@3.0.0: + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + dev: false + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: false + /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -6234,6 +6457,10 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: false + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -6305,12 +6532,28 @@ packages: pify: 2.3.0 dev: true + /readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: false + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 + /real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + dev: false + /rechoir@0.8.0: resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} engines: {node: '>= 10.13.0'} @@ -6500,6 +6743,11 @@ packages: is-regex: 1.1.4 dev: true + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -6665,6 +6913,12 @@ packages: engines: {node: '>=12'} dev: false + /sonic-boom@3.8.0: + resolution: {integrity: sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==} + dependencies: + atomic-sleep: 1.0.0 + dev: false + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -6694,6 +6948,11 @@ packages: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} dev: true + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: false + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true @@ -6794,6 +7053,12 @@ packages: es-abstract: 1.22.3 dev: true + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -6987,6 +7252,12 @@ packages: any-promise: 1.3.0 dev: true + /thread-stream@2.4.1: + resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==} + dependencies: + real-require: 0.2.0 + dev: false + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -7111,6 +7382,10 @@ packages: webpack: 5.89.0(webpack-cli@5.1.4) dev: true + /ts-log@2.2.5: + resolution: {integrity: sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==} + dev: false + /ts-node@10.9.2(@types/node@18.19.9)(typescript@5.3.3): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true