From 8ac89016e7991c25f5c59438371925b0edb3a862 Mon Sep 17 00:00:00 2001 From: aboutphilippe Date: Thu, 21 Nov 2024 14:44:51 -0800 Subject: [PATCH] add encryption example --- examples/encryption/.env.example | 9 + examples/encryption/package.json | 41 + examples/encryption/pnpm-lock.yaml | 2514 +++++++++++++++++ examples/encryption/readme.md | 63 + examples/encryption/scheduleWorkflow.ts | 29 + examples/encryption/src/client.ts | 13 + examples/encryption/src/codec-server.ts | 94 + examples/encryption/src/crypto.ts | 36 + examples/encryption/src/data-converter.ts | 17 + examples/encryption/src/encryption-codec.ts | 81 + examples/encryption/src/functions/goodbye.ts | 11 + examples/encryption/src/functions/index.ts | 2 + .../functions/openai/chat/completionsBase.ts | 92 + .../openai/chat/completionsStream.ts | 193 ++ .../src/functions/openai/chat/index.ts | 2 + .../encryption/src/functions/openai/index.ts | 2 + .../openai/thread/createAssistant.ts | 34 + .../openai/thread/createMessageOnThread.ts | 28 + .../functions/openai/thread/createThread.ts | 19 + .../src/functions/openai/thread/index.ts | 4 + .../src/functions/openai/thread/runThread.ts | 31 + .../src/functions/openai/types/events.ts | 17 + .../src/functions/openai/types/index.ts | 1 + .../functions/openai/utils/aggregateStream.ts | 26 + .../src/functions/openai/utils/client.ts | 21 + .../src/functions/openai/utils/cost.ts | 24 + .../src/functions/openai/utils/index.ts | 4 + .../functions/openai/utils/mergeToolCalls.ts | 31 + examples/encryption/src/services.ts | 28 + examples/encryption/src/workflows/hello.ts | 48 + examples/encryption/src/workflows/index.ts | 1 + examples/encryption/tsconfig.json | 14 + 32 files changed, 3530 insertions(+) create mode 100644 examples/encryption/.env.example create mode 100644 examples/encryption/package.json create mode 100644 examples/encryption/pnpm-lock.yaml create mode 100644 examples/encryption/readme.md create mode 100644 examples/encryption/scheduleWorkflow.ts create mode 100644 examples/encryption/src/client.ts create mode 100644 examples/encryption/src/codec-server.ts create mode 100644 examples/encryption/src/crypto.ts create mode 100644 examples/encryption/src/data-converter.ts create mode 100644 examples/encryption/src/encryption-codec.ts create mode 100644 examples/encryption/src/functions/goodbye.ts create mode 100644 examples/encryption/src/functions/index.ts create mode 100644 examples/encryption/src/functions/openai/chat/completionsBase.ts create mode 100644 examples/encryption/src/functions/openai/chat/completionsStream.ts create mode 100644 examples/encryption/src/functions/openai/chat/index.ts create mode 100644 examples/encryption/src/functions/openai/index.ts create mode 100644 examples/encryption/src/functions/openai/thread/createAssistant.ts create mode 100644 examples/encryption/src/functions/openai/thread/createMessageOnThread.ts create mode 100644 examples/encryption/src/functions/openai/thread/createThread.ts create mode 100644 examples/encryption/src/functions/openai/thread/index.ts create mode 100644 examples/encryption/src/functions/openai/thread/runThread.ts create mode 100644 examples/encryption/src/functions/openai/types/events.ts create mode 100644 examples/encryption/src/functions/openai/types/index.ts create mode 100644 examples/encryption/src/functions/openai/utils/aggregateStream.ts create mode 100644 examples/encryption/src/functions/openai/utils/client.ts create mode 100644 examples/encryption/src/functions/openai/utils/cost.ts create mode 100644 examples/encryption/src/functions/openai/utils/index.ts create mode 100644 examples/encryption/src/functions/openai/utils/mergeToolCalls.ts create mode 100644 examples/encryption/src/services.ts create mode 100644 examples/encryption/src/workflows/hello.ts create mode 100644 examples/encryption/src/workflows/index.ts create mode 100644 examples/encryption/tsconfig.json diff --git a/examples/encryption/.env.example b/examples/encryption/.env.example new file mode 100644 index 0000000..adccfc3 --- /dev/null +++ b/examples/encryption/.env.example @@ -0,0 +1,9 @@ +OPENAI_API_KEY= + +# Restack + +RESTACK_ENGINE_ID= +RESTACK_ENGINE_ADDRESS= +RESTACK_ENGINE_API_KEY= + +RESTACK_CLOUD_TOKEN= \ No newline at end of file diff --git a/examples/encryption/package.json b/examples/encryption/package.json new file mode 100644 index 0000000..7a5c3f9 --- /dev/null +++ b/examples/encryption/package.json @@ -0,0 +1,41 @@ +{ + "name": "sdk-example-ts", + "version": "1.0.0", + "description": "Basic OpenAI example", + "main": "index.js", + "scripts": { + "start": "ts-node src/services.ts", + "start.watch": "nodemon src/services.ts", + "dev": "pnpm start.watch", + "codec": "ts-node src/codec-server.ts", + "build": "tsc --build", + "clean": "rm -rf node_modules", + "schedule": "ts-node ./scheduleWorkflow.ts", + "restack-up": "node restack_up.mjs" + }, + "nodemonConfig": { + "execMap": { + "ts": "ts-node" + }, + "ext": "ts", + "watch": [ + "src" + ] + }, + "dependencies": { + "@restackio/ai": "^0.0.84", + "@temporalio/workflow": "^1.11.2", + "dotenv": "^16.4.5", + "express": "^4.21.1", + "openai": "^4.71.1", + "yargs": "^17.7.2", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.23.3" + }, + "devDependencies": { + "@restackio/restack-sdk-cloud-ts": "^1.0.15", + "@types/node": "^20.16.9", + "nodemon": "^2.0.22", + "ts-node": "^10.9.2" + } +} diff --git a/examples/encryption/pnpm-lock.yaml b/examples/encryption/pnpm-lock.yaml new file mode 100644 index 0000000..f2d0485 --- /dev/null +++ b/examples/encryption/pnpm-lock.yaml @@ -0,0 +1,2514 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@restackio/ai': + specifier: ^0.0.82 + version: 0.0.82 + '@temporalio/workflow': + specifier: ^1.11.2 + version: 1.11.2 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + express: + specifier: ^4.21.1 + version: 4.21.1 + openai: + specifier: ^4.71.1 + version: 4.71.1(zod@3.23.8) + yargs: + specifier: ^17.7.2 + version: 17.7.2 + zod: + specifier: ^3.23.8 + version: 3.23.8 + zod-to-json-schema: + specifier: ^3.23.3 + version: 3.23.3(zod@3.23.8) + devDependencies: + '@restackio/restack-sdk-cloud-ts': + specifier: ^1.0.15 + version: 1.0.16 + '@types/node': + specifier: ^20.16.9 + version: 20.16.10 + nodemon: + specifier: ^2.0.22 + version: 2.0.22 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@swc/core@1.7.26)(@types/node@20.16.10)(typescript@5.5.4) + + integrations/openai: + dependencies: + '@restackio/ai': + specifier: ^0.0.40 + version: 0.0.40 + '@temporalio/worker': + specifier: ^1.10.3 + version: 1.11.1 + '@temporalio/workflow': + specifier: ^1.10.3 + version: 1.11.1 + openai: + specifier: ^4.56.0 + version: 4.56.0(zod@3.23.8) + ts-node: + specifier: ^10.0.0 + version: 10.9.2(@swc/core@1.7.2)(@types/node@14.18.63)(typescript@4.9.5) + typescript: + specifier: ^4.0.0 + version: 4.9.5 + zod: + specifier: ^3.23.8 + version: 3.23.8 + devDependencies: + '@types/node': + specifier: ^14.0.0 + version: 14.18.63 + +packages: + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@grpc/grpc-js@1.12.0': + resolution: {integrity: sha512-eWdP97A6xKtZXVP/ze9y8zYRB2t6ugQAuLXFuZXAsyqmyltaAjl4yPkmIfc0wuTFJMOUF1AdvIFQCL7fMtaX6g==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.13': + resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} + engines: {node: '>=6'} + hasBin: true + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.1.0': + resolution: {integrity: sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.5.0': + resolution: {integrity: sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@restackio/ai@0.0.82': + resolution: {integrity: sha512-PYdk0giSsejc3nfi16jHxIhlz56+ra7CpGvSfnt5uLCFvjqa+NeXhVaRcDjCGM95xPHKOwQcdqW2osjOry7nNA==} + engines: {node: '>=20'} + + '@restackio/restack-sdk-cloud-ts@1.0.16': + resolution: {integrity: sha512-oIanzD6ym6c+hZ6eMJozTaIxGmMn1hPZRwogzz4v2hdd40IpdbwuHc98bPrHjswS1rZa+vjPjLbKoSuLlZloOQ==} + engines: {node: '>=18'} + + '@swc/core-darwin-arm64@1.7.26': + resolution: {integrity: sha512-FF3CRYTg6a7ZVW4yT9mesxoVVZTrcSWtmZhxKCYJX9brH4CS/7PRPjAKNk6kzWgWuRoglP7hkjQcd6EpMcZEAw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.7.26': + resolution: {integrity: sha512-az3cibZdsay2HNKmc4bjf62QVukuiMRh5sfM5kHR/JMTrLyS6vSw7Ihs3UTkZjUxkLTT8ro54LI6sV6sUQUbLQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.7.26': + resolution: {integrity: sha512-VYPFVJDO5zT5U3RpCdHE5v1gz4mmR8BfHecUZTmD2v1JeFY6fv9KArJUpjrHEEsjK/ucXkQFmJ0jaiWXmpOV9Q==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.7.26': + resolution: {integrity: sha512-YKevOV7abpjcAzXrhsl+W48Z9mZvgoVs2eP5nY+uoMAdP2b3GxC0Df1Co0I90o2lkzO4jYBpTMcZlmUXLdXn+Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.7.26': + resolution: {integrity: sha512-3w8iZICMkQQON0uIcvz7+Q1MPOW6hJ4O5ETjA0LSP/tuKqx30hIniCGOgPDnv3UTMruLUnQbtBwVCZTBKR3Rkg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.7.26': + resolution: {integrity: sha512-c+pp9Zkk2lqb06bNGkR2Looxrs7FtGDMA4/aHjZcCqATgp348hOKH5WPvNLBl+yPrISuWjbKDVn3NgAvfvpH4w==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.7.26': + resolution: {integrity: sha512-PgtyfHBF6xG87dUSSdTJHwZ3/8vWZfNIXQV2GlwEpslrOkGqy+WaiiyE7Of7z9AvDILfBBBcJvJ/r8u980wAfQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.7.26': + resolution: {integrity: sha512-9TNXPIJqFynlAOrRD6tUQjMq7KApSklK3R/tXgIxc7Qx+lWu8hlDQ/kVPLpU7PWvMMwC/3hKBW+p5f+Tms1hmA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.7.26': + resolution: {integrity: sha512-9YngxNcG3177GYdsTum4V98Re+TlCeJEP4kEwEg9EagT5s3YejYdKwVAkAsJszzkXuyRDdnHUpYbTrPG6FiXrQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.7.26': + resolution: {integrity: sha512-VR+hzg9XqucgLjXxA13MtV5O3C0bK0ywtLIBw/+a+O+Oc6mxFWHtdUeXDbIi5AiPbn0fjgVJMqYnyjGyyX8u0w==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.7.26': + resolution: {integrity: sha512-f5uYFf+TmMQyYIoxkn/evWhNGuUzC730dFwAKGwBVHHVoPyak1/GvJUm6i1SKl+2Hrj9oN0i3WSoWWZ4pgI8lw==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.12': + resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + + '@temporalio/activity@1.11.2': + resolution: {integrity: sha512-Fqpgw5mxIP4VJO7+tRD82Tv2DXwTi7pFz1hBlqeZGyY0nWqA0SH7PGLvwUlhpNk01Vgo7vqZj9hGidITAHKFkw==} + + '@temporalio/client@1.11.2': + resolution: {integrity: sha512-jgN0rwdRyZp42rm6rbk23y6+bfoIC3tyiaPMZl3BZNS2C6x9vF+7cL7jz22CluEAHqA7sJXqCEzagh4hwkKVjA==} + + '@temporalio/common@1.11.2': + resolution: {integrity: sha512-2bUDFGhxWG7uLROkA0aP5oy6NPSmL+mPttObecMAXQqOs7Hb4s1o9uBQ98nojy25zauzvx5btIO/H+5UxUXfOQ==} + + '@temporalio/core-bridge@1.11.2': + resolution: {integrity: sha512-8oWdqmCoSDxH4W0GqfcrD2ffOqMU4gYEzMZ29TBTFekqxko8JAXKtS2pcXvFo9k5Y/Q81i/3sB867VaXWacjxw==} + + '@temporalio/proto@1.11.2': + resolution: {integrity: sha512-h7Iw5hmUf8dGaozpk3WyRuOB5ZzBaFensfocK2eGui15ocNvtAb/aLFsxVJ6xOtryOsHTkgRam5BBZi0NOj+cA==} + + '@temporalio/worker@1.11.2': + resolution: {integrity: sha512-XCFQAgvY9pMOkrgqR8bkHEEsUH2kr2yKmkKRPMVyVYblKCb2TH/MaodoYsCAgyoc3++m6UskSREbK+Fd1DvvIw==} + engines: {node: '>= 16.0.0'} + + '@temporalio/workflow@1.11.2': + resolution: {integrity: sha512-2E9hNKkeboOcdOddC/hd/bXL5kCfw2BgxskuPX8ipr6o8nQ7DaVFQapn+jEuw0pn7A5mLpPuNqF94vnZ4E37gQ==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node-fetch@2.6.11': + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + + '@types/node@18.19.54': + resolution: {integrity: sha512-+BRgt0G5gYjTvdLac9sIeE0iZcJxi4Jc4PV5EUzqi+88jmQLr+fRZdv2tCTV7IHKSGxM6SaLoOXQWWUiLUItMw==} + + '@types/node@20.16.10': + resolution: {integrity: sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==} + + '@webassemblyjs/ast@1.12.1': + resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + + '@webassemblyjs/floating-point-hex-parser@1.11.6': + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + + '@webassemblyjs/helper-api-error@1.11.6': + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + + '@webassemblyjs/helper-buffer@1.12.1': + resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + + '@webassemblyjs/helper-numbers@1.11.6': + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + + '@webassemblyjs/helper-wasm-bytecode@1.11.6': + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + + '@webassemblyjs/helper-wasm-section@1.12.1': + resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + + '@webassemblyjs/ieee754@1.11.6': + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + + '@webassemblyjs/leb128@1.11.6': + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + + '@webassemblyjs/utf8@1.11.6': + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + + '@webassemblyjs/wasm-edit@1.12.1': + resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + + '@webassemblyjs/wasm-gen@1.12.1': + resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + + '@webassemblyjs/wasm-opt@1.12.1': + resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + + '@webassemblyjs/wasm-parser@1.12.1': + resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + + '@webassemblyjs/wast-printer@1.12.1': + resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001667: + resolution: {integrity: sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==} + + cargo-cp-artifact@0.1.9: + resolution: {integrity: sha512-6F+UYzTaGB+awsTXg0uSJA1/b/B3DDJzpKVRu0UmyI7DmNeaAl2RFHuTGIN6fEgpadRxoXGb7gbC1xo4C3IdyA==} + hasBin: true + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.32: + resolution: {integrity: sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} + engines: {node: '>= 0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + formdata-node@4.4.1: + resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} + engines: {node: '>= 12.20'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-monkey@1.0.6: + resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + heap-js@2.5.0: + resolution: {integrity: sha512-kUGoI3p7u6B41z/dp33G6OaL7J4DRqRYwVmeIlwLClx7yaaAy7hoDExnuejTKtuDwfcatGmddHDEOjf6EyIxtQ==} + engines: {node: '>=10.0.0'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@4.12.0: + resolution: {integrity: sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==} + engines: {node: '>= 4.0.0'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + ms@3.0.0-canary.1: + resolution: {integrity: sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==} + engines: {node: '>=12.13'} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + nodemon@2.0.22: + resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} + engines: {node: '>=8.10.0'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + + openai@4.71.1: + resolution: {integrity: sha512-C6JNMaQ1eijM0lrjiRUL3MgThVP5RdwNAghpbJFdW0t11LzmyqON8Eh8MuUuEZ+CeD6bgYl2Fkn2BoptVxv9Ug==} + hasBin: true + peerDependencies: + zod: ^3.23.8 + peerDependenciesMeta: + zod: + optional: true + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + + proto3-json-serializer@2.0.2: + resolution: {integrity: sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==} + engines: {node: '>=14.0.0'} + + protobufjs@7.4.0: + resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@7.0.0: + resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + simple-git@3.27.0: + resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + + simple-update-notifier@1.1.0: + resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} + engines: {node: '>=8.10.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-loader@4.0.2: + resolution: {integrity: sha512-oYwAqCuL0OZhBoSgmdrLa7mv9MjommVMiQIWgcztf+eS4+8BfcUee6nenFnDhKOhzAVnk5gpZdfnz1iiBv+5sg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.72.1 + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + swc-loader@0.2.6: + resolution: {integrity: sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg==} + peerDependencies: + '@swc/core': ^1.2.147 + webpack: '>=2' + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.3.10: + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.34.1: + resolution: {integrity: sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==} + engines: {node: '>=10'} + hasBin: true + + thingies@1.21.0: + resolution: {integrity: sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + tiny-case@1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tree-dump@1.0.2: + resolution: {integrity: sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + unionfs@4.5.4: + resolution: {integrity: sha512-qI3RvJwwdFcWUdZz1dWgAyLSfGlY2fS2pstvwkZBUTnkxjcnIvzriBLtqJTKz9FtArAvJeiVCqHlxhOw8Syfyw==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + + web-streams-polyfill@4.0.0-beta.3: + resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} + engines: {node: '>= 14'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack@5.95.0: + resolution: {integrity: sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yup@1.4.0: + resolution: {integrity: sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==} + + zod-to-json-schema@3.23.3: + resolution: {integrity: sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==} + peerDependencies: + zod: ^3.23.3 + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + +snapshots: + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@grpc/grpc-js@1.12.0': + dependencies: + '@grpc/proto-loader': 0.7.13 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.7.13': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.2.3 + protobufjs: 7.4.0 + yargs: 17.7.2 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@js-sdsl/ordered-map@4.4.2': {} + + '@jsonjoy.com/base64@1.1.2(tslib@2.7.0)': + dependencies: + tslib: 2.7.0 + + '@jsonjoy.com/json-pack@1.1.0(tslib@2.7.0)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.7.0) + '@jsonjoy.com/util': 1.5.0(tslib@2.7.0) + hyperdyperid: 1.2.0 + thingies: 1.21.0(tslib@2.7.0) + tslib: 2.7.0 + + '@jsonjoy.com/util@1.5.0(tslib@2.7.0)': + dependencies: + tslib: 2.7.0 + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@restackio/ai@0.0.82': + dependencies: + '@temporalio/activity': 1.11.2 + '@temporalio/client': 1.11.2 + '@temporalio/worker': 1.11.2 + '@temporalio/workflow': 1.11.2 + transitivePeerDependencies: + - '@swc/helpers' + - esbuild + - uglify-js + - webpack-cli + + '@restackio/restack-sdk-cloud-ts@1.0.16': + dependencies: + chalk: 4.1.2 + dotenv: 16.4.5 + open: 10.1.0 + simple-git: 3.27.0 + yup: 1.4.0 + zod: 3.23.8 + transitivePeerDependencies: + - supports-color + + '@swc/core-darwin-arm64@1.7.26': + optional: true + + '@swc/core-darwin-x64@1.7.26': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.7.26': + optional: true + + '@swc/core-linux-arm64-gnu@1.7.26': + optional: true + + '@swc/core-linux-arm64-musl@1.7.26': + optional: true + + '@swc/core-linux-x64-gnu@1.7.26': + optional: true + + '@swc/core-linux-x64-musl@1.7.26': + optional: true + + '@swc/core-win32-arm64-msvc@1.7.26': + optional: true + + '@swc/core-win32-ia32-msvc@1.7.26': + optional: true + + '@swc/core-win32-x64-msvc@1.7.26': + optional: true + + '@swc/core@1.7.26': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.12 + optionalDependencies: + '@swc/core-darwin-arm64': 1.7.26 + '@swc/core-darwin-x64': 1.7.26 + '@swc/core-linux-arm-gnueabihf': 1.7.26 + '@swc/core-linux-arm64-gnu': 1.7.26 + '@swc/core-linux-arm64-musl': 1.7.26 + '@swc/core-linux-x64-gnu': 1.7.26 + '@swc/core-linux-x64-musl': 1.7.26 + '@swc/core-win32-arm64-msvc': 1.7.26 + '@swc/core-win32-ia32-msvc': 1.7.26 + '@swc/core-win32-x64-msvc': 1.7.26 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.12': + dependencies: + '@swc/counter': 0.1.3 + + '@temporalio/activity@1.11.2': + dependencies: + '@temporalio/common': 1.11.2 + abort-controller: 3.0.0 + + '@temporalio/client@1.11.2': + dependencies: + '@grpc/grpc-js': 1.12.0 + '@temporalio/common': 1.11.2 + '@temporalio/proto': 1.11.2 + abort-controller: 3.0.0 + long: 5.2.3 + uuid: 9.0.1 + + '@temporalio/common@1.11.2': + dependencies: + '@temporalio/proto': 1.11.2 + long: 5.2.3 + ms: 3.0.0-canary.1 + proto3-json-serializer: 2.0.2 + + '@temporalio/core-bridge@1.11.2': + dependencies: + '@temporalio/common': 1.11.2 + arg: 5.0.2 + cargo-cp-artifact: 0.1.9 + which: 4.0.0 + + '@temporalio/proto@1.11.2': + dependencies: + long: 5.2.3 + protobufjs: 7.4.0 + + '@temporalio/worker@1.11.2': + dependencies: + '@swc/core': 1.7.26 + '@temporalio/activity': 1.11.2 + '@temporalio/client': 1.11.2 + '@temporalio/common': 1.11.2 + '@temporalio/core-bridge': 1.11.2 + '@temporalio/proto': 1.11.2 + '@temporalio/workflow': 1.11.2 + abort-controller: 3.0.0 + heap-js: 2.5.0 + memfs: 4.12.0 + rxjs: 7.8.1 + source-map: 0.7.4 + source-map-loader: 4.0.2(webpack@5.95.0(@swc/core@1.7.26)) + supports-color: 8.1.1 + swc-loader: 0.2.6(@swc/core@1.7.26)(webpack@5.95.0(@swc/core@1.7.26)) + unionfs: 4.5.4 + webpack: 5.95.0(@swc/core@1.7.26) + transitivePeerDependencies: + - '@swc/helpers' + - esbuild + - uglify-js + - webpack-cli + + '@temporalio/workflow@1.11.2': + dependencies: + '@temporalio/common': 1.11.2 + '@temporalio/proto': 1.11.2 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/estree@1.0.6': {} + + '@types/json-schema@7.0.15': {} + + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 20.16.10 + form-data: 4.0.0 + + '@types/node@18.19.54': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.16.10': + dependencies: + undici-types: 6.19.8 + + '@webassemblyjs/ast@1.12.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + + '@webassemblyjs/floating-point-hex-parser@1.11.6': {} + + '@webassemblyjs/helper-api-error@1.11.6': {} + + '@webassemblyjs/helper-buffer@1.12.1': {} + + '@webassemblyjs/helper-numbers@1.11.6': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} + + '@webassemblyjs/helper-wasm-section@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.12.1 + + '@webassemblyjs/ieee754@1.11.6': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.11.6': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.11.6': {} + + '@webassemblyjs/wasm-edit@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-opt': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/wast-printer': 1.12.1 + + '@webassemblyjs/wasm-gen@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + + '@webassemblyjs/wasm-opt@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + + '@webassemblyjs/wasm-parser@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + + '@webassemblyjs/wast-printer@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-import-attributes@1.9.5(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + ajv-keywords@3.5.2(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + arg@5.0.2: {} + + array-flatten@1.1.1: {} + + asynckit@0.4.0: {} + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.0: + dependencies: + caniuse-lite: 1.0.30001667 + electron-to-chromium: 1.5.32 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + caniuse-lite@1.0.30001667: {} + + cargo-cp-artifact@0.1.9: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chrome-trace-event@1.0.4: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@2.20.3: {} + + concat-map@0.0.1: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + create-require@1.1.1: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7(supports-color@5.5.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + diff@4.0.2: {} + + dotenv@16.4.5: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.32: {} + + emoji-regex@8.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-module-lexer@1.5.4: {} + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + express@4.21.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + form-data-encoder@1.7.2: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + formdata-node@4.4.1: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fs-monkey@1.0.6: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + heap-js@2.5.0: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + hyperdyperid@1.2.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ignore-by-default@1.0.1: {} + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-number@7.0.0: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isexe@3.1.1: {} + + jest-worker@27.5.1: + dependencies: + '@types/node': 20.16.10 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + loader-runner@4.3.0: {} + + lodash.camelcase@4.3.0: {} + + long@5.2.3: {} + + make-error@1.3.6: {} + + media-typer@0.3.0: {} + + memfs@4.12.0: + dependencies: + '@jsonjoy.com/json-pack': 1.1.0(tslib@2.7.0) + '@jsonjoy.com/util': 1.5.0(tslib@2.7.0) + tree-dump: 1.0.2(tslib@2.7.0) + tslib: 2.7.0 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + methods@1.1.2: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + ms@2.0.0: {} + + ms@2.1.3: {} + + ms@3.0.0-canary.1: {} + + negotiator@0.6.3: {} + + neo-async@2.6.2: {} + + node-domexception@1.0.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-releases@2.0.18: {} + + nodemon@2.0.22: + dependencies: + chokidar: 3.6.0 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 5.7.2 + simple-update-notifier: 1.1.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + + normalize-path@3.0.0: {} + + object-inspect@1.13.3: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + openai@4.71.1(zod@3.23.8): + dependencies: + '@types/node': 18.19.54 + '@types/node-fetch': 2.6.11 + abort-controller: 3.0.0 + agentkeepalive: 4.5.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + optionalDependencies: + zod: 3.23.8 + transitivePeerDependencies: + - encoding + + parseurl@1.3.3: {} + + path-to-regexp@0.1.10: {} + + picocolors@1.1.0: {} + + picomatch@2.3.1: {} + + property-expr@2.0.6: {} + + proto3-json-serializer@2.0.2: + dependencies: + protobufjs: 7.4.0 + + protobufjs@7.4.0: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 20.16.10 + long: 5.2.3 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + pstree.remy@1.1.8: {} + + punycode@2.3.1: {} + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + require-directory@2.1.1: {} + + run-applescript@7.0.0: {} + + rxjs@7.8.1: + dependencies: + tslib: 2.7.0 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + + semver@5.7.2: {} + + semver@7.0.0: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.3 + + simple-git@3.27.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + simple-update-notifier@1.1.0: + dependencies: + semver: 7.0.0 + + source-map-js@1.2.1: {} + + source-map-loader@4.0.2(webpack@5.95.0(@swc/core@1.7.26)): + dependencies: + iconv-lite: 0.6.3 + source-map-js: 1.2.1 + webpack: 5.95.0(@swc/core@1.7.26) + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + statuses@2.0.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + swc-loader@0.2.6(@swc/core@1.7.26)(webpack@5.95.0(@swc/core@1.7.26)): + dependencies: + '@swc/core': 1.7.26 + '@swc/counter': 0.1.3 + webpack: 5.95.0(@swc/core@1.7.26) + + tapable@2.2.1: {} + + terser-webpack-plugin@5.3.10(@swc/core@1.7.26)(webpack@5.95.0(@swc/core@1.7.26)): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.2 + terser: 5.34.1 + webpack: 5.95.0(@swc/core@1.7.26) + optionalDependencies: + '@swc/core': 1.7.26 + + terser@5.34.1: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.12.1 + commander: 2.20.3 + source-map-support: 0.5.21 + + thingies@1.21.0(tslib@2.7.0): + dependencies: + tslib: 2.7.0 + + tiny-case@1.0.3: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + toposort@2.0.2: {} + + touch@3.1.1: {} + + tr46@0.0.3: {} + + tree-dump@1.0.2(tslib@2.7.0): + dependencies: + tslib: 2.7.0 + + ts-node@10.9.2(@swc/core@1.7.26)(@types/node@20.16.10)(typescript@5.5.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.16.10 + acorn: 8.12.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.7.26 + + tslib@2.7.0: {} + + type-fest@2.19.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typescript@5.5.4: {} + + undefsafe@2.0.5: {} + + undici-types@5.26.5: {} + + undici-types@6.19.8: {} + + unionfs@4.5.4: + dependencies: + fs-monkey: 1.0.6 + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.1(browserslist@4.24.0): + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + utils-merge@1.0.1: {} + + uuid@9.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + vary@1.1.2: {} + + watchpack@2.4.2: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + web-streams-polyfill@4.0.0-beta.3: {} + + webidl-conversions@3.0.1: {} + + webpack-sources@3.2.3: {} + + webpack@5.95.0(@swc/core@1.7.26): + dependencies: + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/wasm-edit': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + acorn: 8.12.1 + acorn-import-attributes: 1.9.5(acorn@8.12.1) + browserslist: 4.24.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.17.1 + es-module-lexer: 1.5.4 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.10(@swc/core@1.7.26)(webpack@5.95.0(@swc/core@1.7.26)) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@4.0.0: + dependencies: + isexe: 3.1.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yup@1.4.0: + dependencies: + property-expr: 2.0.6 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + + zod-to-json-schema@3.23.3(zod@3.23.8): + dependencies: + zod: 3.23.8 + + zod@3.23.8: {} diff --git a/examples/encryption/readme.md b/examples/encryption/readme.md new file mode 100644 index 0000000..94dadf3 --- /dev/null +++ b/examples/encryption/readme.md @@ -0,0 +1,63 @@ +# Requirements + +- Node 20 or higher + +brew install nvm +nvm use 20 + +- pnpm + +brew install pnpm + +# Install Restack Web UI + +To install the Restack Web UI, you can use Docker. +``` +docker run -d --pull always --name studio -p 5233:5233 -p 6233:6233 -p 7233:7233 ghcr.io/restackio/restack:main +``` + +# Start services + +Where all your code is defined, including workflow steps. + +add OPENAI_API_KEY in .env + +```bash +pnpm i + +pnpm dev +``` +Your code will be running and syncing with Restack engine to execute workflows or functions. + +# Schedule a workflow + +In another shell: + +pnpm schedule + +Will schedule to start example workflow immediately. + +# Architecture + +```mermaid +flowchart TD + C[fa:fa-bolt scheduleWorkflow client] -->|registers workflow with schedule| E{Restack Engine} + E --> |queries results| C + E -->|pulls queue with input| P1[fa:fa-ship restack pod] + E -->|orchestrates with rate limit| P2[fa:fa-ship openai pod] + P1 -->|runs| W[fa:fa-th-list example workflow] + P1 -->|runs| Go[fa:fa-code goodbye function] + P2 -->|runs| Gr[fa:fa-code greet function] + P1 -->|sends status + output | E + P2 -->|sends status output | E +``` + +## Deploy on Restack + +pnpm restack-up + +To deploy the application on Restack, you can use the provided `restack_up.mjs` script. This script utilizes the Restack Cloud SDK to define and deploy your application stack. It sets up the necessary environment variables and configures the application for deployment. + +To get started, ensure you have the required Restack Cloud credentials and environment variables set up. Then, run the script to initiate the deployment process. + +For more detailed information on deploying your repository to Restack, refer to the [Restack Cloud deployment documentation](https://docs.restack.io/restack-cloud/deployrepo). \ No newline at end of file diff --git a/examples/encryption/scheduleWorkflow.ts b/examples/encryption/scheduleWorkflow.ts new file mode 100644 index 0000000..085e08f --- /dev/null +++ b/examples/encryption/scheduleWorkflow.ts @@ -0,0 +1,29 @@ +import { client } from "./src/client"; + +export type InputSchedule = { + name: string; +}; + +async function scheduleWorkflow(input: InputSchedule) { + try { + const workflowId = `${Date.now()}-helloWorkflow`; + const runId = await client.scheduleWorkflow({ + workflowName: "helloWorkflow", + workflowId, + input, + }); + + const result = await client.getWorkflowResult({ workflowId, runId }); + + console.log("Workflow result:", result); + + process.exit(0); // Exit the process successfully + } catch (error) { + console.error("Error scheduling workflow:", error); + process.exit(1); // Exit the process with an error code + } +} + +scheduleWorkflow({ + name: "test", +}); diff --git a/examples/encryption/src/client.ts b/examples/encryption/src/client.ts new file mode 100644 index 0000000..b990acd --- /dev/null +++ b/examples/encryption/src/client.ts @@ -0,0 +1,13 @@ +import Restack from "@restackio/ai"; + +import "dotenv/config"; + +export const connectionOptions = { + engineId: process.env.RESTACK_ENGINE_ID!, + address: process.env.RESTACK_ENGINE_ADDRESS!, + apiKey: process.env.RESTACK_ENGINE_API_KEY!, +}; + +export const client = new Restack( + process.env.RESTACK_ENGINE_API_KEY ? connectionOptions : undefined +); diff --git a/examples/encryption/src/codec-server.ts b/examples/encryption/src/codec-server.ts new file mode 100644 index 0000000..5c12920 --- /dev/null +++ b/examples/encryption/src/codec-server.ts @@ -0,0 +1,94 @@ +import express from 'express'; +import cors from 'cors'; +import * as proto from '@temporalio/proto'; +import { EncryptionCodec } from './encryption-codec'; +import yargs from 'yargs/yargs'; + +type Payload = proto.temporal.api.common.v1.IPayload; + +interface JSONPayload { + metadata?: Record | null; + data?: string | null; +} + +interface Body { + payloads: JSONPayload[]; +} + +/** + * Helper function to convert a valid proto JSON to a payload object. + * + * This method will be part of the SDK when it supports proto JSON serialization. + */ +function fromJSON({ metadata, data }: JSONPayload): Payload { + return { + metadata: + metadata && + Object.fromEntries(Object.entries(metadata).map(([k, v]): [string, Uint8Array] => [k, Buffer.from(v, 'base64')])), + data: data ? Buffer.from(data, 'base64') : undefined, + }; +} + +/** + * Helper function to convert a payload object to a valid proto JSON. + * + * This method will be part of the SDK when it supports proto JSON serialization. + */ +function toJSON({ metadata, data }: proto.temporal.api.common.v1.IPayload): JSONPayload { + return { + metadata: + metadata && + Object.fromEntries( + Object.entries(metadata).map(([k, v]): [string, string] => [k, Buffer.from(v).toString('base64')]) + ), + data: data ? Buffer.from(data).toString('base64') : undefined, + }; +} + +async function main({ port = 8888 }: any) { + const codec = await EncryptionCodec.create('test-key-id'); + + const app = express(); + app.use(cors({ allowedHeaders: ['x-namespace', 'content-type'] })); + app.use(express.json()); + + app.post('/decode', async (req, res) => { + try { + const { payloads: raw } = req.body as Body; + const encoded = raw.map(fromJSON); + const decoded = await codec.decode(encoded); + const payloads = decoded.map(toJSON); + res.json({ payloads }).end(); + } catch (err) { + console.error('Error in /decode', err); + res.status(500).end('Internal server error'); + } + }); + + app.post('/encode', async (req, res) => { + try { + const { payloads: raw } = req.body as Body; + const decoded = raw.map(fromJSON); + const encoded = await codec.encode(decoded); + const payloads = encoded.map(toJSON); + res.json({ payloads }).end(); + } catch (err) { + console.error('Error in /encode', err); + res.status(500).end('Internal server error'); + } + }); + + await new Promise((resolve, reject) => { + app.listen(port, resolve); + app.on('error', reject); + }); + + console.log(`Codec server listening on port ${port}`); +} + +const argv = yargs(process.argv.slice(2)).argv; + +main(argv).catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/examples/encryption/src/crypto.ts b/examples/encryption/src/crypto.ts new file mode 100644 index 0000000..df9228f --- /dev/null +++ b/examples/encryption/src/crypto.ts @@ -0,0 +1,36 @@ +import { webcrypto as crypto } from 'node:crypto'; + +const CIPHER = 'AES-GCM'; +const IV_LENGTH_BYTES = 12; +const TAG_LENGTH_BYTES = 16; + +export async function encrypt(data: Uint8Array, key: crypto.CryptoKey): Promise { + const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH_BYTES)); + const encrypted = await crypto.subtle.encrypt( + { + name: CIPHER, + iv, + tagLength: TAG_LENGTH_BYTES * 8, + }, + key, + data + ); + + return Buffer.concat([iv, new Uint8Array(encrypted)]); +} + +export async function decrypt(encryptedData: Uint8Array, key: crypto.CryptoKey): Promise { + const iv = encryptedData.subarray(0, IV_LENGTH_BYTES); + const ciphertext = encryptedData.subarray(IV_LENGTH_BYTES); + const decrypted = await crypto.subtle.decrypt( + { + name: CIPHER, + iv, + tagLength: TAG_LENGTH_BYTES * 8, + }, + key, + ciphertext + ); + + return new Uint8Array(decrypted); +} diff --git a/examples/encryption/src/data-converter.ts b/examples/encryption/src/data-converter.ts new file mode 100644 index 0000000..ac3fa5c --- /dev/null +++ b/examples/encryption/src/data-converter.ts @@ -0,0 +1,17 @@ +import { DataConverter } from '@temporalio/common'; +import { EncryptionCodec } from './encryption-codec'; + +let dataConverterPromise: Promise; + +export async function getDataConverter(): Promise { + if (!dataConverterPromise) { + dataConverterPromise = createDataConverter(); + } + return await dataConverterPromise; +} + +async function createDataConverter(): Promise { + return { + payloadCodecs: [await EncryptionCodec.create('test-key-id')], + }; +} diff --git a/examples/encryption/src/encryption-codec.ts b/examples/encryption/src/encryption-codec.ts new file mode 100644 index 0000000..fc16299 --- /dev/null +++ b/examples/encryption/src/encryption-codec.ts @@ -0,0 +1,81 @@ +// @@@SNIPSTART typescript-encryption-codec +import { webcrypto as crypto } from 'node:crypto'; +import { METADATA_ENCODING_KEY, Payload, PayloadCodec, ValueError } from '@temporalio/common'; +import { temporal } from '@temporalio/proto'; +import { decode, encode } from '@temporalio/common/lib/encoding'; +import { decrypt, encrypt } from './crypto'; + +const ENCODING = 'binary/encrypted'; +const METADATA_ENCRYPTION_KEY_ID = 'encryption-key-id'; + +export class EncryptionCodec implements PayloadCodec { + constructor(protected readonly keys: Map, protected readonly defaultKeyId: string) {} + + static async create(keyId: string): Promise { + const keys = new Map(); + keys.set(keyId, await fetchKey(keyId)); + return new this(keys, keyId); + } + + async encode(payloads: Payload[]): Promise { + return Promise.all( + payloads.map(async (payload) => ({ + metadata: { + [METADATA_ENCODING_KEY]: encode(ENCODING), + [METADATA_ENCRYPTION_KEY_ID]: encode(this.defaultKeyId), + }, + // Encrypt entire payload, preserving metadata + data: await encrypt( + temporal.api.common.v1.Payload.encode(payload).finish(), + this.keys.get(this.defaultKeyId)! // eslint-disable-line @typescript-eslint/no-non-null-assertion + ), + })) + ); + } + + async decode(payloads: Payload[]): Promise { + return Promise.all( + payloads.map(async (payload) => { + if (!payload.metadata || decode(payload.metadata[METADATA_ENCODING_KEY]) !== ENCODING) { + return payload; + } + if (!payload.data) { + throw new ValueError('Payload data is missing'); + } + + const keyIdBytes = payload.metadata[METADATA_ENCRYPTION_KEY_ID]; + if (!keyIdBytes) { + throw new ValueError('Unable to decrypt Payload without encryption key id'); + } + + const keyId = decode(keyIdBytes); + let key = this.keys.get(keyId); + if (!key) { + key = await fetchKey(keyId); + this.keys.set(keyId, key); + } + const decryptedPayloadBytes = await decrypt(payload.data, key); + console.log('Decrypting payload.data:', payload.data); + return temporal.api.common.v1.Payload.decode(decryptedPayloadBytes); + }) + ); + } +} + +async function fetchKey(_keyId: string): Promise { + // In production, fetch key from a key management system (KMS). You may want to memoize requests if you'll be decoding + // Payloads that were encrypted using keys other than defaultKeyId. + const key = Buffer.from('test-key-test-key-test-key-test!'); + const cryptoKey = await crypto.subtle.importKey( + 'raw', + key, + { + name: 'AES-GCM', + }, + true, + ['encrypt', 'decrypt'] + ); + + return cryptoKey; +} +// @@@SNIPEND diff --git a/examples/encryption/src/functions/goodbye.ts b/examples/encryption/src/functions/goodbye.ts new file mode 100644 index 0000000..acf1d86 --- /dev/null +++ b/examples/encryption/src/functions/goodbye.ts @@ -0,0 +1,11 @@ +interface Input { + name: string; +} + +interface Output { + message: string; +} + +export async function goodbye(input: Input): Promise { + return { message: `Goodbye, ${input.name}!` }; +} diff --git a/examples/encryption/src/functions/index.ts b/examples/encryption/src/functions/index.ts new file mode 100644 index 0000000..b2c7ee2 --- /dev/null +++ b/examples/encryption/src/functions/index.ts @@ -0,0 +1,2 @@ +export * from "./goodbye"; +export * from "./openai"; \ No newline at end of file diff --git a/examples/encryption/src/functions/openai/chat/completionsBase.ts b/examples/encryption/src/functions/openai/chat/completionsBase.ts new file mode 100644 index 0000000..0889059 --- /dev/null +++ b/examples/encryption/src/functions/openai/chat/completionsBase.ts @@ -0,0 +1,92 @@ +import { FunctionFailure, log } from "@restackio/ai/function"; +import OpenAI from "openai/index"; +import { ChatCompletionCreateParamsNonStreaming } from "openai/resources/chat/completions"; +import { openaiClient } from "../utils/client"; +import { openaiCost, Price } from "../utils/cost"; +import { ChatCompletion, ChatModel } from "openai/resources/index"; + +export type UsageOutput = { tokens: number; cost: number }; + +export type OpenAIChatInput = { + userContent: string; + systemContent?: string; + model?: ChatModel; + jsonSchema?: { + name: string; + schema: Record; + }; + price?: Price; + apiKey?: string; + params?: ChatCompletionCreateParamsNonStreaming; + tools?: OpenAI.Chat.Completions.ChatCompletionTool[]; + toolChoice?: OpenAI.Chat.Completions.ChatCompletionToolChoiceOption; +}; + +export const openaiChatCompletionsBase = async ({ + userContent, + systemContent = "", + model = "gpt-4o-mini", + jsonSchema, + price, + apiKey, + params, + tools, + toolChoice, +}: OpenAIChatInput): Promise<{ result: ChatCompletion; cost?: number }> => { + try { + const openai = openaiClient({ apiKey }); + + const isO1Model = model.startsWith("o1-"); + + const o1ModelParams = { + temperature: 1, + top_p: 1, + frequency_penalty: 0, + presence_penalty: 0, + }; + + const chatParams: ChatCompletionCreateParamsNonStreaming = { + messages: [ + ...(systemContent ? [{ role: "system" as const, content: systemContent }] : []), + { role: "user" as const, content: userContent }, + ...(params?.messages ?? []), + ], + ...(jsonSchema && { + response_format: { + type: "json_schema", + json_schema: { + name: jsonSchema.name, + strict: true, + schema: jsonSchema.schema, + }, + }, + }), + model, + ...(tools && { tools }), + ...(toolChoice && { tool_choice: toolChoice }), + ...params, + ...(isO1Model && o1ModelParams), + }; + + log.debug("OpenAI chat completion params", { + chatParams, + }); + + const completion = await openai.chat.completions.create(chatParams); + + return { + result: completion, + cost: + price && + openaiCost({ + price, + tokensCount: { + input: completion.usage?.prompt_tokens ?? 0, + output: completion.usage?.completion_tokens ?? 0, + }, + }), + }; + } catch (error) { + throw FunctionFailure.nonRetryable(`Error OpenAI chat: ${error}`); + } +}; \ No newline at end of file diff --git a/examples/encryption/src/functions/openai/chat/completionsStream.ts b/examples/encryption/src/functions/openai/chat/completionsStream.ts new file mode 100644 index 0000000..bcd9097 --- /dev/null +++ b/examples/encryption/src/functions/openai/chat/completionsStream.ts @@ -0,0 +1,193 @@ +import OpenAI from "openai/index"; +import { ChatCompletionChunk } from "openai/resources/chat/completions"; + +import Restack from "@restackio/ai"; +import { currentWorkflow, log } from "@restackio/ai/function"; + +import { StreamEvent, ToolCallEvent } from "../types/events"; + +import { aggregateStreamChunks } from "../utils/aggregateStream"; +import { mergeToolCalls } from "../utils/mergeToolCalls"; +import { openaiClient } from "../utils/client"; +import { openaiCost, Price } from "../utils/cost"; +import { SendWorkflowEvent } from "@restackio/ai/event"; +import { ChatModel } from "openai/resources/index"; + +export async function openaiChatCompletionsStream({ + model = "gpt-4o-mini", + userName, + newMessage, + assistantName, + messages = [], + tools, + toolEvent, + streamAtCharacter, + streamEvent, + apiKey, + price, +}: { + model?: ChatModel; + userName?: string; + newMessage?: string; + assistantName?: string; + messages?: OpenAI.Chat.Completions.ChatCompletionMessageParam[]; + tools?: OpenAI.Chat.Completions.ChatCompletionTool[]; + toolEvent?: { + workflowEventName: string; + workflow?: SendWorkflowEvent["workflow"]; + }; + streamAtCharacter?: string; + streamEvent?: { + workflowEventName: string; + workflow?: SendWorkflowEvent["workflow"]; + }; + apiKey?: string; + price?: Price; +}) { + const restack = new Restack(); + const workflow = currentWorkflow().workflowExecution; + + log.debug("workflow", { workflow }); + + if (newMessage) { + messages.push({ + role: "user", + name: userName, + content: newMessage, + }); + } + + const openai = openaiClient({ apiKey }); + const chatStream = await openai.chat.completions.create({ + model: model, + messages, + tools, + stream: true, + stream_options: { + include_usage: true, + }, + }); + + const [stream, streamEnd] = chatStream.tee(); + const readableStream = streamEnd.toReadableStream() as unknown as ReadableStream; + const aggregatedStream = await aggregateStreamChunks(readableStream); + + let finishReason: ChatCompletionChunk.Choice["finish_reason"]; + let response: ChatCompletionChunk.Choice.Delta["content"] = ""; + let tokensCountInput = 0; + let tokensCountOutput = 0; + + for await (const chunk of stream) { + let content = chunk.choices[0]?.delta?.content || ""; + finishReason = chunk.choices[0]?.finish_reason; + tokensCountInput += chunk.usage?.prompt_tokens ?? 0; + tokensCountOutput += chunk.usage?.completion_tokens ?? 0; + + if (finishReason === "tool_calls") { + const { toolCalls } = mergeToolCalls(aggregatedStream); + await Promise.all( + toolCalls.map((toolCall) => { + if (toolEvent) { + const functionArguments = JSON.parse( + toolCall.function?.arguments ?? "" + ); + + const input: ToolCallEvent = { + ...toolCall, + function: { + name: toolCall.function?.name ?? "", + input: functionArguments, + }, + assistantName, + }; + + if (toolEvent) { + const workflowEvent = { + event: { + name: toolEvent.workflowEventName, + input, + }, + workflow: { + ...workflow, + ...toolEvent.workflow, + }, + }; + log.debug("toolEvent sendWorkflowEvent", { workflowEvent }); + + restack.sendWorkflowEvent(workflowEvent); + } + } + }) + ); + return { + result: { + messages, + toolCalls, + }, + cost: + price && + openaiCost({ + price, + tokensCount: { + input: tokensCountInput, + output: tokensCountOutput, + }, + }), + }; + } else { + response += content; + if ( + content.trim().slice(-1) === streamAtCharacter || + finishReason === "stop" + ) { + if (response.length) { + const input: StreamEvent = { + chunkId: chunk.id, + response, + assistantName, + isLast: finishReason === "stop", + }; + if (streamEvent) { + const workflowEvent = { + event: { + name: streamEvent.workflowEventName, + input, + }, + workflow: { + ...workflow, + ...streamEvent.workflow, + }, + }; + log.debug("streamEvent sendWorkflowEvent", { workflowEvent }); + restack.sendWorkflowEvent(workflowEvent); + } + } + } + + if (finishReason === "stop") { + const newMessage: OpenAI.Chat.Completions.ChatCompletionMessageParam = { + content: response, + role: "assistant", + name: assistantName, + }; + + messages.push(newMessage); + + return { + result: { + messages, + }, + cost: + price && + openaiCost({ + price, + tokensCount: { + input: tokensCountInput, + output: tokensCountOutput, + }, + }), + }; + } + } + } +} diff --git a/examples/encryption/src/functions/openai/chat/index.ts b/examples/encryption/src/functions/openai/chat/index.ts new file mode 100644 index 0000000..3cb4077 --- /dev/null +++ b/examples/encryption/src/functions/openai/chat/index.ts @@ -0,0 +1,2 @@ +export * from "./completionsBase"; +export * from "./completionsStream"; diff --git a/examples/encryption/src/functions/openai/index.ts b/examples/encryption/src/functions/openai/index.ts new file mode 100644 index 0000000..6a947d6 --- /dev/null +++ b/examples/encryption/src/functions/openai/index.ts @@ -0,0 +1,2 @@ +export * from "./chat"; +export * from "./thread"; diff --git a/examples/encryption/src/functions/openai/thread/createAssistant.ts b/examples/encryption/src/functions/openai/thread/createAssistant.ts new file mode 100644 index 0000000..f893399 --- /dev/null +++ b/examples/encryption/src/functions/openai/thread/createAssistant.ts @@ -0,0 +1,34 @@ +import { ChatModel } from "openai/resources/index"; +import { FunctionFailure } from "@restackio/ai/function"; +import { Assistant, AssistantTool } from "openai/resources/beta/index"; + +import { openaiClient } from "../utils/client"; + +export async function createAssistant({ + apiKey, + name, + instructions, + model = "gpt-4o-mini", + tools = [], +}: { + apiKey: string; + name: string; + instructions: string; + tools?: AssistantTool[]; + model: ChatModel; +}): Promise { + try { + const openai = openaiClient({ apiKey }); + + const assistant = await openai.beta.assistants.create({ + name, + instructions, + model, + tools, + }); + + return assistant; + } catch (error) { + throw FunctionFailure.nonRetryable(`Error creating assistant: ${error}`); + } +} diff --git a/examples/encryption/src/functions/openai/thread/createMessageOnThread.ts b/examples/encryption/src/functions/openai/thread/createMessageOnThread.ts new file mode 100644 index 0000000..63b4a24 --- /dev/null +++ b/examples/encryption/src/functions/openai/thread/createMessageOnThread.ts @@ -0,0 +1,28 @@ +import OpenAI from "openai/index"; +import { FunctionFailure } from "@restackio/ai/function"; + +import { openaiClient } from "../utils/client"; + +export async function createMessageOnThread({ + apiKey, + threadId, + content, + role, +}: { + apiKey: string; + threadId: string; + content: string; + role: OpenAI.Beta.Threads.MessageCreateParams["role"]; +}) { + try { + const openai = openaiClient({ apiKey }); + await openai.beta.threads.messages.create(threadId, { + role, + content, + }); + } catch (error) { + throw FunctionFailure.nonRetryable( + `Error creating message thread: ${error}` + ); + } +} diff --git a/examples/encryption/src/functions/openai/thread/createThread.ts b/examples/encryption/src/functions/openai/thread/createThread.ts new file mode 100644 index 0000000..5d29652 --- /dev/null +++ b/examples/encryption/src/functions/openai/thread/createThread.ts @@ -0,0 +1,19 @@ +import { FunctionFailure } from "@restackio/ai/function"; +import { Thread } from "openai/resources/beta/index"; + +import { openaiClient } from "../utils/client"; + +export async function createThread({ + apiKey, +}: { + apiKey: string; +}): Promise { + try { + const openai = openaiClient({ apiKey }); + const thread = await openai.beta.threads.create(); + + return thread; + } catch (error) { + throw FunctionFailure.nonRetryable(`Error creating thread: ${error}`); + } +} diff --git a/examples/encryption/src/functions/openai/thread/index.ts b/examples/encryption/src/functions/openai/thread/index.ts new file mode 100644 index 0000000..0ef24eb --- /dev/null +++ b/examples/encryption/src/functions/openai/thread/index.ts @@ -0,0 +1,4 @@ +export * from "./createAssistant"; +export * from "./createMessageOnThread"; +export * from "./createThread"; +export * from "./runThread"; diff --git a/examples/encryption/src/functions/openai/thread/runThread.ts b/examples/encryption/src/functions/openai/thread/runThread.ts new file mode 100644 index 0000000..57d17e6 --- /dev/null +++ b/examples/encryption/src/functions/openai/thread/runThread.ts @@ -0,0 +1,31 @@ +import { FunctionFailure } from "@restackio/ai/function"; +import { Stream } from "openai/streaming"; +import { AssistantStreamEvent } from "openai/resources/beta/index"; +import { Run } from "openai/resources/beta/threads/runs/index"; + +import { openaiClient } from "../utils/client"; + +export async function runThread({ + apiKey, + threadId, + assistantId, + stream = false, +}: { + apiKey: string; + threadId: string; + assistantId: string; + stream: boolean; +}): Promise | Run> { + try { + const openai = openaiClient({ apiKey }); + + const run = await openai.beta.threads.runs.create(threadId, { + assistant_id: assistantId, + ...(stream && { stream }), + }); + + return run; + } catch (error) { + throw FunctionFailure.nonRetryable(`Error running thread: ${error}`); + } +} \ No newline at end of file diff --git a/examples/encryption/src/functions/openai/types/events.ts b/examples/encryption/src/functions/openai/types/events.ts new file mode 100644 index 0000000..44b071b --- /dev/null +++ b/examples/encryption/src/functions/openai/types/events.ts @@ -0,0 +1,17 @@ +import OpenAI from "openai/index"; + +export type StreamEvent = { + chunkId?: string; + response: string; + assistantName?: string; + isLast: boolean; +}; + +export type ToolCallEvent = + OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta.ToolCall & { + function: { + name: string; + input: JSON; + }; + assistantName?: string; + }; diff --git a/examples/encryption/src/functions/openai/types/index.ts b/examples/encryption/src/functions/openai/types/index.ts new file mode 100644 index 0000000..1784004 --- /dev/null +++ b/examples/encryption/src/functions/openai/types/index.ts @@ -0,0 +1 @@ +export * from "./events"; diff --git a/examples/encryption/src/functions/openai/utils/aggregateStream.ts b/examples/encryption/src/functions/openai/utils/aggregateStream.ts new file mode 100644 index 0000000..18a7d74 --- /dev/null +++ b/examples/encryption/src/functions/openai/utils/aggregateStream.ts @@ -0,0 +1,26 @@ +export async function aggregateStreamChunks(stream: ReadableStream) { + const reader = stream.getReader(); + const chunks: Uint8Array[] = []; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + if (value) chunks.push(value); + } + + const aggregated = new Uint8Array( + chunks.reduce((acc, chunk) => acc + chunk.length, 0) + ); + let offset = 0; + for (const chunk of chunks) { + aggregated.set(chunk, offset); + offset += chunk.length; + } + + const textContent = new TextDecoder().decode(aggregated); + const jsonObjects = textContent + .split("\n") + .filter((line) => line.trim()) + .map((line) => JSON.parse(line)); + return jsonObjects; +} diff --git a/examples/encryption/src/functions/openai/utils/client.ts b/examples/encryption/src/functions/openai/utils/client.ts new file mode 100644 index 0000000..77fd385 --- /dev/null +++ b/examples/encryption/src/functions/openai/utils/client.ts @@ -0,0 +1,21 @@ +import OpenAI from "openai/index"; +import "dotenv/config"; + +let openaiInstance: OpenAI | null = null; + +export const openaiClient = ({ + apiKey = process.env.OPENAI_API_KEY, +}: { + apiKey?: string; +}): OpenAI => { + if (!apiKey) { + throw new Error("API key is required to create OpenAI client."); + } + + if (!openaiInstance) { + openaiInstance = new OpenAI({ + apiKey, + }); + } + return openaiInstance; +}; diff --git a/examples/encryption/src/functions/openai/utils/cost.ts b/examples/encryption/src/functions/openai/utils/cost.ts new file mode 100644 index 0000000..2724ab6 --- /dev/null +++ b/examples/encryption/src/functions/openai/utils/cost.ts @@ -0,0 +1,24 @@ +export type TokensCount = { + input: number; + output: number; +}; + +export type Price = { + input: number; + output: number; +}; +export const openaiCost = ({ + tokensCount, + price, +}: { + tokensCount: TokensCount; + price: Price; +}): number => { + let cost = 0; + const { input: inputTokens, output: outputTokens } = tokensCount; + const { input: inputPrice, output: outputPrice } = price; + + cost = inputTokens * inputPrice + outputTokens * outputPrice; + + return cost; +}; diff --git a/examples/encryption/src/functions/openai/utils/index.ts b/examples/encryption/src/functions/openai/utils/index.ts new file mode 100644 index 0000000..0707ebb --- /dev/null +++ b/examples/encryption/src/functions/openai/utils/index.ts @@ -0,0 +1,4 @@ +export * from "./aggregateStream"; +export * from "./client"; +export * from "./cost"; +export * from "./mergeToolCalls"; diff --git a/examples/encryption/src/functions/openai/utils/mergeToolCalls.ts b/examples/encryption/src/functions/openai/utils/mergeToolCalls.ts new file mode 100644 index 0000000..600170f --- /dev/null +++ b/examples/encryption/src/functions/openai/utils/mergeToolCalls.ts @@ -0,0 +1,31 @@ +import OpenAI from "openai/index"; +import { ChatCompletionChunk } from "openai/resources/chat/completions.mjs"; + +export function mergeToolCalls(aggregatedStream: ChatCompletionChunk[]) { + const toolCalls: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta.ToolCall[] = + []; + + aggregatedStream.forEach((chunk) => { + chunk.choices.forEach((choice) => { + if (choice.delta.tool_calls) { + choice.delta.tool_calls.forEach((toolCall) => { + const lastToolCall = toolCalls[toolCalls.length - 1]; + if (toolCall.id) { + toolCalls.push({ + ...toolCall, + function: { ...toolCall.function, arguments: "" }, + }); + } else if ( + lastToolCall && + lastToolCall.function && + toolCall.function?.arguments + ) { + lastToolCall.function.arguments += toolCall.function.arguments; + } + }); + } + }); + }); + + return { toolCalls }; +} diff --git a/examples/encryption/src/services.ts b/examples/encryption/src/services.ts new file mode 100644 index 0000000..e6fa15d --- /dev/null +++ b/examples/encryption/src/services.ts @@ -0,0 +1,28 @@ +import { goodbye, openaiChatCompletionsBase, openaiChatCompletionsStream } from "./functions"; +import { client } from "./client"; + +async function services() { + const workflowsPath = require.resolve("./workflows"); + try { + await Promise.all([ + // Start service with current workflows and functions + client.startService({ + workflowsPath, + functions: { goodbye }, + }), + // Start the openai service + client.startService({ + taskQueue: "openai", + functions: { openaiChatCompletionsBase, openaiChatCompletionsStream }, + }), + ]); + + console.log("Services running successfully."); + } catch (e) { + console.error("Failed to run services", e); + } +} + +services().catch((err) => { + console.error("Error running services:", err); +}); diff --git a/examples/encryption/src/workflows/hello.ts b/examples/encryption/src/workflows/hello.ts new file mode 100644 index 0000000..220009e --- /dev/null +++ b/examples/encryption/src/workflows/hello.ts @@ -0,0 +1,48 @@ +import { log, step } from "@restackio/ai/workflow"; +import * as functions from "../functions"; +import { z } from "zod"; +import zodToJsonSchema from "zod-to-json-schema"; + +interface Input { + name: string; +} + +export async function helloWorkflow({ name }: Input) { + const userContent = `Greet this person: ${name}. In 4 words or less.`; + + const MessageSchema = z.object({ + message: z.string().describe("The greeting message."), + }); + + const jsonSchema = { + name: "greet", + schema: zodToJsonSchema(MessageSchema), + }; + + // Step 1 create greeting message with openai + + const openaiOutput = await step({ + taskQueue: "openai", + }).openaiChatCompletionsBase({ + userContent, + jsonSchema, + }); + + const greetMessage = openaiOutput.result.choices[0].message.content ?? ""; + const greetCost = openaiOutput.cost; + + log.info("greeted", { greetMessage }); + + // Step 2 create goodbye message with simple function + + const { message: goodbyeMessage } = await step({}).goodbye({ + name, + }); + + log.info("goodbye", { goodbyeMessage }); + + return { + messages: [greetMessage, goodbyeMessage], + cost: greetCost, + }; +} diff --git a/examples/encryption/src/workflows/index.ts b/examples/encryption/src/workflows/index.ts new file mode 100644 index 0000000..a132395 --- /dev/null +++ b/examples/encryption/src/workflows/index.ts @@ -0,0 +1 @@ +export * from "./hello"; diff --git a/examples/encryption/tsconfig.json b/examples/encryption/tsconfig.json new file mode 100644 index 0000000..f4d02b9 --- /dev/null +++ b/examples/encryption/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "Node16", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "outDir": "./dist", + "rootDir": "./src", + "resolveJsonModule": true + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules"] +} \ No newline at end of file