├── .gitignore ├── README.md ├── jest.config.ts ├── package.json ├── pnpm-lock.yaml ├── src ├── application │ └── endpoints │ │ └── documentEndpoints.ts ├── domain │ ├── document.ts │ └── documentRepository.ts ├── index.ts ├── infrastructure │ └── semanticSearch │ │ ├── __tests__ │ │ ├── cloudflareAdapter.test.ts │ │ └── cloudflareDocumentRepository.test.ts │ │ ├── cloudflareAdapter.ts │ │ └── cloudflareDocumentRepository.ts ├── middleware │ ├── __tests__ │ │ └── auth.test.ts │ └── auth.ts ├── services │ ├── __tests__ │ │ └── documentService.test.ts │ └── documentService.ts └── types.ts ├── tsconfig.json ├── worker-configuration.d.ts └── wrangler.toml /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | 3 | logs 4 | _.log 5 | npm-debug.log_ 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | 13 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 14 | 15 | # Runtime data 16 | 17 | pids 18 | _.pid 19 | _.seed 20 | \*.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | 28 | coverage 29 | \*.lcov 30 | 31 | # nyc test coverage 32 | 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 36 | 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | 41 | bower_components 42 | 43 | # node-waf configuration 44 | 45 | .lock-wscript 46 | 47 | # Compiled binary addons (https://nodejs.org/api/addons.html) 48 | 49 | build/Release 50 | 51 | # Dependency directories 52 | 53 | node_modules/ 54 | jspm_packages/ 55 | 56 | # Snowpack dependency directory (https://snowpack.dev/) 57 | 58 | web_modules/ 59 | 60 | # TypeScript cache 61 | 62 | \*.tsbuildinfo 63 | 64 | # Optional npm cache directory 65 | 66 | .npm 67 | 68 | # Optional eslint cache 69 | 70 | .eslintcache 71 | 72 | # Optional stylelint cache 73 | 74 | .stylelintcache 75 | 76 | # Microbundle cache 77 | 78 | .rpt2_cache/ 79 | .rts2_cache_cjs/ 80 | .rts2_cache_es/ 81 | .rts2_cache_umd/ 82 | 83 | # Optional REPL history 84 | 85 | .node_repl_history 86 | 87 | # Output of 'npm pack' 88 | 89 | \*.tgz 90 | 91 | # Yarn Integrity file 92 | 93 | .yarn-integrity 94 | 95 | # dotenv environment variable files 96 | 97 | .env 98 | .env.development.local 99 | .env.test.local 100 | .env.production.local 101 | .env.local 102 | 103 | # parcel-bundler cache (https://parceljs.org/) 104 | 105 | .cache 106 | .parcel-cache 107 | 108 | # Next.js build output 109 | 110 | .next 111 | out 112 | 113 | # Nuxt.js build / generate output 114 | 115 | .nuxt 116 | dist 117 | 118 | # Gatsby files 119 | 120 | .cache/ 121 | 122 | # Comment in the public line in if your project uses Gatsby and not Next.js 123 | 124 | # https://nextjs.org/blog/next-9-1#public-directory-support 125 | 126 | # public 127 | 128 | # vuepress build output 129 | 130 | .vuepress/dist 131 | 132 | # vuepress v2.x temp and cache directory 133 | 134 | .temp 135 | .cache 136 | 137 | # Docusaurus cache and generated files 138 | 139 | .docusaurus 140 | 141 | # Serverless directories 142 | 143 | .serverless/ 144 | 145 | # FuseBox cache 146 | 147 | .fusebox/ 148 | 149 | # DynamoDB Local files 150 | 151 | .dynamodb/ 152 | 153 | # TernJS port file 154 | 155 | .tern-port 156 | 157 | # Stores VSCode versions used for testing VSCode extensions 158 | 159 | .vscode-test 160 | 161 | # yarn v2 162 | 163 | .yarn/cache 164 | .yarn/unplugged 165 | .yarn/build-state.yml 166 | .yarn/install-state.gz 167 | .pnp.\* 168 | 169 | # wrangler project 170 | 171 | .dev.vars 172 | 173 | .wrangler 174 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Semantic Search API 2 | 3 | ### Build a Zero-Cost Semantic Search Engine with Cloudflare Workers 4 | 5 | This project provides a production-ready semantic search engine built entirely on Cloudflare's free-tier infrastructure. 6 | 7 | The API follows OpenAPI specifications with full Swagger documentation available at `/swagger.json`, making it easy to integrate and use in your applications. 8 | 9 | ## Installation 10 | 11 | ### Option 1: One-Click Deploy 12 | [![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/SemanticSearch-ai/api.semanticsearch.ai.git) 13 | 14 | Before deployment, create a Vectorize index as described in step 4 below. 15 | 16 | ### Option 2: Manual Setup 17 | 1. Sign up for [Cloudflare Workers](https://workers.dev). The free tier is more than enough for most use cases. 18 | 2. Clone this project and install dependencies with `pnpm install` 19 | 3. Run `wrangler login` to login to your Cloudflare account in wrangler 20 | 4. Create a Vectorize index for semantic search: 21 | ```bash 22 | wrangler vectorize create semantic-search --dimensions=384 --metric=cosine 23 | ``` 24 | 5. Run `wrangler deploy` to publish the API to Cloudflare Workers 25 | 26 | Once deployed, set the API key by updating the `API_KEY` environment variable. 27 | 28 | ## Usage 29 | 30 | The API provides the following endpoints for managing and searching documents: 31 | 32 | ### Create/Update a document 33 | ```bash 34 | curl -X POST "https://your-worker.workers.dev/v1/documents" \ 35 | -H "Content-Type: application/json" \ 36 | -H "Authorization: Bearer YOUR_API_KEY" \ 37 | -d '{ 38 | "text": "This is a sample document for semantic search", 39 | "id": "document-id", 40 | "metadata": { 41 | "source": "example", 42 | "category": "documentation" 43 | } 44 | }' 45 | ``` 46 | 47 | Response: 48 | ```json 49 | { 50 | "id": "document-id" 51 | } 52 | ``` 53 | 54 | ### Retrieve a document 55 | ```bash 56 | curl -X GET "https://your-worker.workers.dev/v1/documents/{document-id}" \ 57 | -H "Authorization: Bearer YOUR_API_KEY" 58 | ``` 59 | 60 | Response: 61 | ```json 62 | { 63 | "id": "document-id", 64 | "text": "This is a sample document for semantic search", 65 | "metadata": { 66 | "source": "example", 67 | "category": "documentation" 68 | } 69 | } 70 | ``` 71 | 72 | ### Delete a document 73 | ```bash 74 | curl -X DELETE "https://your-worker.workers.dev/v1/documents/{document-id}" \ 75 | -H "Authorization: Bearer YOUR_API_KEY" 76 | ``` 77 | 78 | Response: 79 | ```json 80 | { 81 | "success": true 82 | } 83 | ``` 84 | 85 | ### Search documents 86 | ```bash 87 | curl -X POST "https://your-worker.workers.dev/v1/search" \ 88 | -H "Content-Type: application/json" \ 89 | -H "Authorization: Bearer YOUR_API_KEY" \ 90 | -d '{ 91 | "query": "sample document", 92 | "limit": 10 93 | }' 94 | ``` 95 | 96 | Response: 97 | ```json 98 | { 99 | "results": [ 100 | { 101 | "id": "document-id", 102 | "text": "This is a sample document for semantic search", 103 | "metadata": { 104 | "source": "example", 105 | "category": "documentation" 106 | }, 107 | "score": 0.95 108 | } 109 | ] 110 | } 111 | ``` 112 | 113 | All endpoints require authentication using a Bearer token in the Authorization header. Replace `YOUR_API_KEY` with your actual API key. 114 | 115 | ## Development 116 | 117 | 1. Run `wrangler dev` to start a local instance of the API. 118 | 2. Open `http://localhost:8787/` in your browser to see the Swagger interface where you can try the endpoints. 119 | 3. Changes made in the `src/` folder will automatically trigger the server to reload, you only need to refresh the Swagger interface. 120 | 121 | ## License 122 | 123 | This project is licensed under the Apache License 2.0. It is free for commercial use, but you need to include a link to https://semanticsearch.ai/ in your product. 124 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'jest' 2 | 3 | const config: Config = { 4 | preset: 'ts-jest/presets/default-esm', 5 | testEnvironment: 'node', 6 | testMatch: [ 7 | '**/src/**/__tests__/**/*.test.ts' 8 | ], 9 | moduleNameMapper: { 10 | '^@/(.*)$': '/src/$1', 11 | '^(\\.{1,2}/.*)\\.js$': '$1' 12 | }, 13 | transform: { 14 | '^.+\\.tsx?$': [ 15 | 'ts-jest', 16 | { 17 | useESM: true, 18 | }, 19 | ], 20 | }, 21 | transformIgnorePatterns: [ 22 | 'node_modules/(?!(nanoid)/)' 23 | ], 24 | extensionsToTreatAsEsm: ['.ts'], 25 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 26 | testPathIgnorePatterns: [ 27 | '/node_modules/', 28 | '/dist/' 29 | ], 30 | collectCoverage: true, 31 | collectCoverageFrom: [ 32 | 'src/**/*.ts', 33 | '!src/**/*.d.ts', 34 | '!src/**/__tests__/**' 35 | ], 36 | coverageDirectory: 'coverage', 37 | coverageReporters: ['text', 'lcov'], 38 | testTimeout: 10000 39 | } 40 | 41 | export default config 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-workers-openapi", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "deploy": "wrangler deploy", 8 | "dev": "wrangler dev", 9 | "start": "wrangler dev", 10 | "cf-typegen": "wrangler types", 11 | "test": "jest", 12 | "test:watch": "jest --watch", 13 | "test:service": "jest src/services/__tests__", 14 | "test:adapter": "jest src/infrastructure/*/__tests__" 15 | }, 16 | "dependencies": { 17 | "@hono/swagger-ui": "^0.5.0", 18 | "@hono/zod-openapi": "^0.18.3", 19 | "chanfana": "^2.0.2", 20 | "hono": "^4.4.7", 21 | "nanoid": "3.3.7", 22 | "zod": "^3.23.8" 23 | }, 24 | "devDependencies": { 25 | "@cloudflare/workers-types": "^4.20241205.0", 26 | "@types/jest": "^29.5.14", 27 | "@types/node": "20.8.3", 28 | "@types/service-worker-mock": "^2.0.1", 29 | "jest": "^29.7.0", 30 | "ts-jest": "^29.2.5", 31 | "ts-node": "^10.9.2", 32 | "wrangler": "^3.60.3" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@hono/swagger-ui': 12 | specifier: ^0.5.0 13 | version: 0.5.0(hono@4.6.14) 14 | '@hono/zod-openapi': 15 | specifier: ^0.18.3 16 | version: 0.18.3(hono@4.6.14)(zod@3.24.1) 17 | chanfana: 18 | specifier: ^2.0.2 19 | version: 2.5.1 20 | hono: 21 | specifier: ^4.4.7 22 | version: 4.6.14 23 | nanoid: 24 | specifier: 3.3.7 25 | version: 3.3.7 26 | zod: 27 | specifier: ^3.23.8 28 | version: 3.24.1 29 | devDependencies: 30 | '@cloudflare/workers-types': 31 | specifier: ^4.20241205.0 32 | version: 4.20241205.0 33 | '@types/jest': 34 | specifier: ^29.5.14 35 | version: 29.5.14 36 | '@types/node': 37 | specifier: 20.8.3 38 | version: 20.8.3 39 | '@types/service-worker-mock': 40 | specifier: ^2.0.1 41 | version: 2.0.4 42 | jest: 43 | specifier: ^29.7.0 44 | version: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 45 | ts-jest: 46 | specifier: ^29.2.5 47 | version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.17.19)(jest@29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)))(typescript@5.7.2) 48 | ts-node: 49 | specifier: ^10.9.2 50 | version: 10.9.2(@types/node@20.8.3)(typescript@5.7.2) 51 | wrangler: 52 | specifier: ^3.60.3 53 | version: 3.95.0(@cloudflare/workers-types@4.20241205.0) 54 | 55 | packages: 56 | 57 | '@ampproject/remapping@2.3.0': 58 | resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} 59 | engines: {node: '>=6.0.0'} 60 | 61 | '@asteasolutions/zod-to-openapi@7.3.0': 62 | resolution: {integrity: sha512-7tE/r1gXwMIvGnXVUdIqUhCU1RevEFC4Jk6Bussa0fk1ecbnnINkZzj1EOAJyE/M3AI25DnHT/zKQL1/FPFi8Q==} 63 | peerDependencies: 64 | zod: ^3.20.2 65 | 66 | '@babel/code-frame@7.26.2': 67 | resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} 68 | engines: {node: '>=6.9.0'} 69 | 70 | '@babel/compat-data@7.26.3': 71 | resolution: {integrity: sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==} 72 | engines: {node: '>=6.9.0'} 73 | 74 | '@babel/core@7.26.0': 75 | resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} 76 | engines: {node: '>=6.9.0'} 77 | 78 | '@babel/generator@7.26.3': 79 | resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} 80 | engines: {node: '>=6.9.0'} 81 | 82 | '@babel/helper-compilation-targets@7.25.9': 83 | resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} 84 | engines: {node: '>=6.9.0'} 85 | 86 | '@babel/helper-module-imports@7.25.9': 87 | resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} 88 | engines: {node: '>=6.9.0'} 89 | 90 | '@babel/helper-module-transforms@7.26.0': 91 | resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} 92 | engines: {node: '>=6.9.0'} 93 | peerDependencies: 94 | '@babel/core': ^7.0.0 95 | 96 | '@babel/helper-plugin-utils@7.25.9': 97 | resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} 98 | engines: {node: '>=6.9.0'} 99 | 100 | '@babel/helper-string-parser@7.25.9': 101 | resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} 102 | engines: {node: '>=6.9.0'} 103 | 104 | '@babel/helper-validator-identifier@7.25.9': 105 | resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} 106 | engines: {node: '>=6.9.0'} 107 | 108 | '@babel/helper-validator-option@7.25.9': 109 | resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} 110 | engines: {node: '>=6.9.0'} 111 | 112 | '@babel/helpers@7.26.0': 113 | resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} 114 | engines: {node: '>=6.9.0'} 115 | 116 | '@babel/parser@7.26.3': 117 | resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} 118 | engines: {node: '>=6.0.0'} 119 | hasBin: true 120 | 121 | '@babel/plugin-syntax-async-generators@7.8.4': 122 | resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} 123 | peerDependencies: 124 | '@babel/core': ^7.0.0-0 125 | 126 | '@babel/plugin-syntax-bigint@7.8.3': 127 | resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} 128 | peerDependencies: 129 | '@babel/core': ^7.0.0-0 130 | 131 | '@babel/plugin-syntax-class-properties@7.12.13': 132 | resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} 133 | peerDependencies: 134 | '@babel/core': ^7.0.0-0 135 | 136 | '@babel/plugin-syntax-class-static-block@7.14.5': 137 | resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} 138 | engines: {node: '>=6.9.0'} 139 | peerDependencies: 140 | '@babel/core': ^7.0.0-0 141 | 142 | '@babel/plugin-syntax-import-attributes@7.26.0': 143 | resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} 144 | engines: {node: '>=6.9.0'} 145 | peerDependencies: 146 | '@babel/core': ^7.0.0-0 147 | 148 | '@babel/plugin-syntax-import-meta@7.10.4': 149 | resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} 150 | peerDependencies: 151 | '@babel/core': ^7.0.0-0 152 | 153 | '@babel/plugin-syntax-json-strings@7.8.3': 154 | resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} 155 | peerDependencies: 156 | '@babel/core': ^7.0.0-0 157 | 158 | '@babel/plugin-syntax-jsx@7.25.9': 159 | resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} 160 | engines: {node: '>=6.9.0'} 161 | peerDependencies: 162 | '@babel/core': ^7.0.0-0 163 | 164 | '@babel/plugin-syntax-logical-assignment-operators@7.10.4': 165 | resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} 166 | peerDependencies: 167 | '@babel/core': ^7.0.0-0 168 | 169 | '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': 170 | resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} 171 | peerDependencies: 172 | '@babel/core': ^7.0.0-0 173 | 174 | '@babel/plugin-syntax-numeric-separator@7.10.4': 175 | resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} 176 | peerDependencies: 177 | '@babel/core': ^7.0.0-0 178 | 179 | '@babel/plugin-syntax-object-rest-spread@7.8.3': 180 | resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} 181 | peerDependencies: 182 | '@babel/core': ^7.0.0-0 183 | 184 | '@babel/plugin-syntax-optional-catch-binding@7.8.3': 185 | resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} 186 | peerDependencies: 187 | '@babel/core': ^7.0.0-0 188 | 189 | '@babel/plugin-syntax-optional-chaining@7.8.3': 190 | resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} 191 | peerDependencies: 192 | '@babel/core': ^7.0.0-0 193 | 194 | '@babel/plugin-syntax-private-property-in-object@7.14.5': 195 | resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} 196 | engines: {node: '>=6.9.0'} 197 | peerDependencies: 198 | '@babel/core': ^7.0.0-0 199 | 200 | '@babel/plugin-syntax-top-level-await@7.14.5': 201 | resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} 202 | engines: {node: '>=6.9.0'} 203 | peerDependencies: 204 | '@babel/core': ^7.0.0-0 205 | 206 | '@babel/plugin-syntax-typescript@7.25.9': 207 | resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} 208 | engines: {node: '>=6.9.0'} 209 | peerDependencies: 210 | '@babel/core': ^7.0.0-0 211 | 212 | '@babel/template@7.25.9': 213 | resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} 214 | engines: {node: '>=6.9.0'} 215 | 216 | '@babel/traverse@7.26.4': 217 | resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} 218 | engines: {node: '>=6.9.0'} 219 | 220 | '@babel/types@7.26.3': 221 | resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} 222 | engines: {node: '>=6.9.0'} 223 | 224 | '@bcoe/v8-coverage@0.2.3': 225 | resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} 226 | 227 | '@cloudflare/kv-asset-handler@0.3.4': 228 | resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} 229 | engines: {node: '>=16.13'} 230 | 231 | '@cloudflare/workerd-darwin-64@1.20241205.0': 232 | resolution: {integrity: sha512-TArEZkSZkHJyEwnlWWkSpCI99cF6lJ14OVeEoI9Um/+cD9CKZLM9vCmsLeKglKheJ0KcdCnkA+DbeD15t3VaWg==} 233 | engines: {node: '>=16'} 234 | cpu: [x64] 235 | os: [darwin] 236 | 237 | '@cloudflare/workerd-darwin-arm64@1.20241205.0': 238 | resolution: {integrity: sha512-u5eqKa9QRdA8MugfgCoD+ADDjY6EpKbv3hSYJETmmUh17l7WXjWBzv4pUvOKIX67C0UzMUy4jZYwC53MymhX3w==} 239 | engines: {node: '>=16'} 240 | cpu: [arm64] 241 | os: [darwin] 242 | 243 | '@cloudflare/workerd-linux-64@1.20241205.0': 244 | resolution: {integrity: sha512-OYA7S5zpumMamWEW+IhhBU6YojIEocyE5X/YFPiTOCrDE3dsfr9t6oqNE7hxGm1VAAu+Irtl+a/5LwmBOU681w==} 245 | engines: {node: '>=16'} 246 | cpu: [x64] 247 | os: [linux] 248 | 249 | '@cloudflare/workerd-linux-arm64@1.20241205.0': 250 | resolution: {integrity: sha512-qAzecONjFJGIAVJZKExQ5dlbic0f3d4A+GdKa+H6SoUJtPaWiE3K6WuePo4JOT7W3/Zfh25McmX+MmpMUUcM5Q==} 251 | engines: {node: '>=16'} 252 | cpu: [arm64] 253 | os: [linux] 254 | 255 | '@cloudflare/workerd-windows-64@1.20241205.0': 256 | resolution: {integrity: sha512-BEab+HiUgCdl6GXAT7EI2yaRtDPiRJlB94XLvRvXi1ZcmQqsrq6awGo6apctFo4WUL29V7c09LxmN4HQ3X2Tvg==} 257 | engines: {node: '>=16'} 258 | cpu: [x64] 259 | os: [win32] 260 | 261 | '@cloudflare/workers-shared@0.11.0': 262 | resolution: {integrity: sha512-A+lQ8xp7992qSeMmuQ0ssL6CPmm+ZmAv6Ddikan0n1jjpMAic+97l7xtVIsswSn9iLMFPYQ9uNN/8Fl0AgARIQ==} 263 | engines: {node: '>=16.7.0'} 264 | 265 | '@cloudflare/workers-types@4.20241205.0': 266 | resolution: {integrity: sha512-pj1VKRHT/ScQbHOIMFODZaNAlJHQHdBSZXNIdr9ebJzwBff9Qz8VdqhbhggV7f+aUEh8WSbrsPIo4a+WtgjUvw==} 267 | 268 | '@cspotcode/source-map-support@0.8.1': 269 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 270 | engines: {node: '>=12'} 271 | 272 | '@esbuild-plugins/node-globals-polyfill@0.2.3': 273 | resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} 274 | peerDependencies: 275 | esbuild: '*' 276 | 277 | '@esbuild-plugins/node-modules-polyfill@0.2.2': 278 | resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} 279 | peerDependencies: 280 | esbuild: '*' 281 | 282 | '@esbuild/android-arm64@0.17.19': 283 | resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} 284 | engines: {node: '>=12'} 285 | cpu: [arm64] 286 | os: [android] 287 | 288 | '@esbuild/android-arm@0.17.19': 289 | resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} 290 | engines: {node: '>=12'} 291 | cpu: [arm] 292 | os: [android] 293 | 294 | '@esbuild/android-x64@0.17.19': 295 | resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} 296 | engines: {node: '>=12'} 297 | cpu: [x64] 298 | os: [android] 299 | 300 | '@esbuild/darwin-arm64@0.17.19': 301 | resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} 302 | engines: {node: '>=12'} 303 | cpu: [arm64] 304 | os: [darwin] 305 | 306 | '@esbuild/darwin-x64@0.17.19': 307 | resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} 308 | engines: {node: '>=12'} 309 | cpu: [x64] 310 | os: [darwin] 311 | 312 | '@esbuild/freebsd-arm64@0.17.19': 313 | resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} 314 | engines: {node: '>=12'} 315 | cpu: [arm64] 316 | os: [freebsd] 317 | 318 | '@esbuild/freebsd-x64@0.17.19': 319 | resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} 320 | engines: {node: '>=12'} 321 | cpu: [x64] 322 | os: [freebsd] 323 | 324 | '@esbuild/linux-arm64@0.17.19': 325 | resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} 326 | engines: {node: '>=12'} 327 | cpu: [arm64] 328 | os: [linux] 329 | 330 | '@esbuild/linux-arm@0.17.19': 331 | resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} 332 | engines: {node: '>=12'} 333 | cpu: [arm] 334 | os: [linux] 335 | 336 | '@esbuild/linux-ia32@0.17.19': 337 | resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} 338 | engines: {node: '>=12'} 339 | cpu: [ia32] 340 | os: [linux] 341 | 342 | '@esbuild/linux-loong64@0.17.19': 343 | resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} 344 | engines: {node: '>=12'} 345 | cpu: [loong64] 346 | os: [linux] 347 | 348 | '@esbuild/linux-mips64el@0.17.19': 349 | resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} 350 | engines: {node: '>=12'} 351 | cpu: [mips64el] 352 | os: [linux] 353 | 354 | '@esbuild/linux-ppc64@0.17.19': 355 | resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} 356 | engines: {node: '>=12'} 357 | cpu: [ppc64] 358 | os: [linux] 359 | 360 | '@esbuild/linux-riscv64@0.17.19': 361 | resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} 362 | engines: {node: '>=12'} 363 | cpu: [riscv64] 364 | os: [linux] 365 | 366 | '@esbuild/linux-s390x@0.17.19': 367 | resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} 368 | engines: {node: '>=12'} 369 | cpu: [s390x] 370 | os: [linux] 371 | 372 | '@esbuild/linux-x64@0.17.19': 373 | resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} 374 | engines: {node: '>=12'} 375 | cpu: [x64] 376 | os: [linux] 377 | 378 | '@esbuild/netbsd-x64@0.17.19': 379 | resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} 380 | engines: {node: '>=12'} 381 | cpu: [x64] 382 | os: [netbsd] 383 | 384 | '@esbuild/openbsd-x64@0.17.19': 385 | resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} 386 | engines: {node: '>=12'} 387 | cpu: [x64] 388 | os: [openbsd] 389 | 390 | '@esbuild/sunos-x64@0.17.19': 391 | resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} 392 | engines: {node: '>=12'} 393 | cpu: [x64] 394 | os: [sunos] 395 | 396 | '@esbuild/win32-arm64@0.17.19': 397 | resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} 398 | engines: {node: '>=12'} 399 | cpu: [arm64] 400 | os: [win32] 401 | 402 | '@esbuild/win32-ia32@0.17.19': 403 | resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} 404 | engines: {node: '>=12'} 405 | cpu: [ia32] 406 | os: [win32] 407 | 408 | '@esbuild/win32-x64@0.17.19': 409 | resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} 410 | engines: {node: '>=12'} 411 | cpu: [x64] 412 | os: [win32] 413 | 414 | '@fastify/busboy@2.1.1': 415 | resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} 416 | engines: {node: '>=14'} 417 | 418 | '@hono/swagger-ui@0.5.0': 419 | resolution: {integrity: sha512-MWYYSv9kC8IwFBLZdwgZZMT9zUq2C/4/ekuyEYOkHEgUMqu+FG3eebtBZ4ofMh60xYRxRR2BgQGoNIILys/PFg==} 420 | peerDependencies: 421 | hono: '*' 422 | 423 | '@hono/zod-openapi@0.18.3': 424 | resolution: {integrity: sha512-bNlRDODnp7P9Fs13ZPajEOt13G0XwXKfKRHMEFCphQsFiD1Y+twzHaglpNAhNcflzR1DQwHY92ZS06b4LTPbIQ==} 425 | engines: {node: '>=16.0.0'} 426 | peerDependencies: 427 | hono: '>=4.3.6' 428 | zod: 3.* 429 | 430 | '@hono/zod-validator@0.4.2': 431 | resolution: {integrity: sha512-1rrlBg+EpDPhzOV4hT9pxr5+xDVmKuz6YJl+la7VCwK6ass5ldyKm5fD+umJdV2zhHD6jROoCCv8NbTwyfhT0g==} 432 | peerDependencies: 433 | hono: '>=3.9.0' 434 | zod: ^3.19.1 435 | 436 | '@istanbuljs/load-nyc-config@1.1.0': 437 | resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} 438 | engines: {node: '>=8'} 439 | 440 | '@istanbuljs/schema@0.1.3': 441 | resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} 442 | engines: {node: '>=8'} 443 | 444 | '@jest/console@29.7.0': 445 | resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} 446 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 447 | 448 | '@jest/core@29.7.0': 449 | resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} 450 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 451 | peerDependencies: 452 | node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 453 | peerDependenciesMeta: 454 | node-notifier: 455 | optional: true 456 | 457 | '@jest/environment@29.7.0': 458 | resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} 459 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 460 | 461 | '@jest/expect-utils@29.7.0': 462 | resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} 463 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 464 | 465 | '@jest/expect@29.7.0': 466 | resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} 467 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 468 | 469 | '@jest/fake-timers@29.7.0': 470 | resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} 471 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 472 | 473 | '@jest/globals@29.7.0': 474 | resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} 475 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 476 | 477 | '@jest/reporters@29.7.0': 478 | resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} 479 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 480 | peerDependencies: 481 | node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 482 | peerDependenciesMeta: 483 | node-notifier: 484 | optional: true 485 | 486 | '@jest/schemas@29.6.3': 487 | resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} 488 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 489 | 490 | '@jest/source-map@29.6.3': 491 | resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} 492 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 493 | 494 | '@jest/test-result@29.7.0': 495 | resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} 496 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 497 | 498 | '@jest/test-sequencer@29.7.0': 499 | resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} 500 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 501 | 502 | '@jest/transform@29.7.0': 503 | resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} 504 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 505 | 506 | '@jest/types@29.6.3': 507 | resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} 508 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 509 | 510 | '@jridgewell/gen-mapping@0.3.8': 511 | resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} 512 | engines: {node: '>=6.0.0'} 513 | 514 | '@jridgewell/resolve-uri@3.1.2': 515 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 516 | engines: {node: '>=6.0.0'} 517 | 518 | '@jridgewell/set-array@1.2.1': 519 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 520 | engines: {node: '>=6.0.0'} 521 | 522 | '@jridgewell/sourcemap-codec@1.5.0': 523 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 524 | 525 | '@jridgewell/trace-mapping@0.3.25': 526 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 527 | 528 | '@jridgewell/trace-mapping@0.3.9': 529 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 530 | 531 | '@sinclair/typebox@0.27.8': 532 | resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} 533 | 534 | '@sinonjs/commons@3.0.1': 535 | resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} 536 | 537 | '@sinonjs/fake-timers@10.3.0': 538 | resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} 539 | 540 | '@tsconfig/node10@1.0.11': 541 | resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} 542 | 543 | '@tsconfig/node12@1.0.11': 544 | resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} 545 | 546 | '@tsconfig/node14@1.0.3': 547 | resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} 548 | 549 | '@tsconfig/node16@1.0.4': 550 | resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} 551 | 552 | '@types/babel__core@7.20.5': 553 | resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} 554 | 555 | '@types/babel__generator@7.6.8': 556 | resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} 557 | 558 | '@types/babel__template@7.4.4': 559 | resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} 560 | 561 | '@types/babel__traverse@7.20.6': 562 | resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} 563 | 564 | '@types/graceful-fs@4.1.9': 565 | resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} 566 | 567 | '@types/istanbul-lib-coverage@2.0.6': 568 | resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} 569 | 570 | '@types/istanbul-lib-report@3.0.3': 571 | resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} 572 | 573 | '@types/istanbul-reports@3.0.4': 574 | resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} 575 | 576 | '@types/jest@29.5.14': 577 | resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} 578 | 579 | '@types/node-forge@1.3.11': 580 | resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} 581 | 582 | '@types/node@20.8.3': 583 | resolution: {integrity: sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==} 584 | 585 | '@types/service-worker-mock@2.0.4': 586 | resolution: {integrity: sha512-MEBT2eiqYfhxjqYm/oAf2AvKLbPTPwJJAYrMdheKnGyz1yG9XBRfxCzi93h27qpSvI7jOYfXqFLVMLBXFDqo4A==} 587 | 588 | '@types/stack-utils@2.0.3': 589 | resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} 590 | 591 | '@types/yargs-parser@21.0.3': 592 | resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} 593 | 594 | '@types/yargs@17.0.33': 595 | resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} 596 | 597 | acorn-walk@8.3.4: 598 | resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} 599 | engines: {node: '>=0.4.0'} 600 | 601 | acorn@8.14.0: 602 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 603 | engines: {node: '>=0.4.0'} 604 | hasBin: true 605 | 606 | ansi-escapes@4.3.2: 607 | resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} 608 | engines: {node: '>=8'} 609 | 610 | ansi-regex@5.0.1: 611 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 612 | engines: {node: '>=8'} 613 | 614 | ansi-styles@4.3.0: 615 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 616 | engines: {node: '>=8'} 617 | 618 | ansi-styles@5.2.0: 619 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} 620 | engines: {node: '>=10'} 621 | 622 | anymatch@3.1.3: 623 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 624 | engines: {node: '>= 8'} 625 | 626 | arg@4.1.3: 627 | resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} 628 | 629 | argparse@1.0.10: 630 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} 631 | 632 | argparse@2.0.1: 633 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 634 | 635 | as-table@1.0.55: 636 | resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} 637 | 638 | async@3.2.6: 639 | resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} 640 | 641 | babel-jest@29.7.0: 642 | resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} 643 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 644 | peerDependencies: 645 | '@babel/core': ^7.8.0 646 | 647 | babel-plugin-istanbul@6.1.1: 648 | resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} 649 | engines: {node: '>=8'} 650 | 651 | babel-plugin-jest-hoist@29.6.3: 652 | resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} 653 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 654 | 655 | babel-preset-current-node-syntax@1.1.0: 656 | resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} 657 | peerDependencies: 658 | '@babel/core': ^7.0.0 659 | 660 | babel-preset-jest@29.6.3: 661 | resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} 662 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 663 | peerDependencies: 664 | '@babel/core': ^7.0.0 665 | 666 | balanced-match@1.0.2: 667 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 668 | 669 | blake3-wasm@2.1.5: 670 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 671 | 672 | brace-expansion@1.1.11: 673 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 674 | 675 | brace-expansion@2.0.1: 676 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 677 | 678 | braces@3.0.3: 679 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 680 | engines: {node: '>=8'} 681 | 682 | browserslist@4.24.3: 683 | resolution: {integrity: sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==} 684 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 685 | hasBin: true 686 | 687 | bs-logger@0.2.6: 688 | resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} 689 | engines: {node: '>= 6'} 690 | 691 | bser@2.1.1: 692 | resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} 693 | 694 | buffer-from@1.1.2: 695 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 696 | 697 | callsites@3.1.0: 698 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 699 | engines: {node: '>=6'} 700 | 701 | camelcase@5.3.1: 702 | resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} 703 | engines: {node: '>=6'} 704 | 705 | camelcase@6.3.0: 706 | resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} 707 | engines: {node: '>=10'} 708 | 709 | caniuse-lite@1.0.30001689: 710 | resolution: {integrity: sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==} 711 | 712 | capnp-ts@0.7.0: 713 | resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} 714 | 715 | chalk@4.1.2: 716 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 717 | engines: {node: '>=10'} 718 | 719 | chanfana@2.5.1: 720 | resolution: {integrity: sha512-VpYnEY/5bHWp73emMMB4bKvjgOeeUnnaJSzvR7iDcGGMFMLOWzkO+hDBA7sUfU2xBorvmutMV7Oc2RpbwwTzzA==} 721 | 722 | char-regex@1.0.2: 723 | resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} 724 | engines: {node: '>=10'} 725 | 726 | chokidar@4.0.1: 727 | resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} 728 | engines: {node: '>= 14.16.0'} 729 | 730 | ci-info@3.9.0: 731 | resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} 732 | engines: {node: '>=8'} 733 | 734 | cjs-module-lexer@1.4.1: 735 | resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} 736 | 737 | cliui@8.0.1: 738 | resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} 739 | engines: {node: '>=12'} 740 | 741 | co@4.6.0: 742 | resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} 743 | engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} 744 | 745 | collect-v8-coverage@1.0.2: 746 | resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} 747 | 748 | color-convert@2.0.1: 749 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 750 | engines: {node: '>=7.0.0'} 751 | 752 | color-name@1.1.4: 753 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 754 | 755 | concat-map@0.0.1: 756 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 757 | 758 | convert-source-map@2.0.0: 759 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 760 | 761 | cookie@0.7.2: 762 | resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} 763 | engines: {node: '>= 0.6'} 764 | 765 | create-jest@29.7.0: 766 | resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} 767 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 768 | hasBin: true 769 | 770 | create-require@1.1.1: 771 | resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} 772 | 773 | cross-spawn@7.0.6: 774 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 775 | engines: {node: '>= 8'} 776 | 777 | data-uri-to-buffer@2.0.2: 778 | resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} 779 | 780 | date-fns@4.1.0: 781 | resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} 782 | 783 | debug@4.4.0: 784 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} 785 | engines: {node: '>=6.0'} 786 | peerDependencies: 787 | supports-color: '*' 788 | peerDependenciesMeta: 789 | supports-color: 790 | optional: true 791 | 792 | dedent@1.5.3: 793 | resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} 794 | peerDependencies: 795 | babel-plugin-macros: ^3.1.0 796 | peerDependenciesMeta: 797 | babel-plugin-macros: 798 | optional: true 799 | 800 | deepmerge@4.3.1: 801 | resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 802 | engines: {node: '>=0.10.0'} 803 | 804 | defu@6.1.4: 805 | resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 806 | 807 | detect-newline@3.1.0: 808 | resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} 809 | engines: {node: '>=8'} 810 | 811 | diff-sequences@29.6.3: 812 | resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} 813 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 814 | 815 | diff@4.0.2: 816 | resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} 817 | engines: {node: '>=0.3.1'} 818 | 819 | ejs@3.1.10: 820 | resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} 821 | engines: {node: '>=0.10.0'} 822 | hasBin: true 823 | 824 | electron-to-chromium@1.5.74: 825 | resolution: {integrity: sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==} 826 | 827 | emittery@0.13.1: 828 | resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} 829 | engines: {node: '>=12'} 830 | 831 | emoji-regex@8.0.0: 832 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 833 | 834 | error-ex@1.3.2: 835 | resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} 836 | 837 | esbuild@0.17.19: 838 | resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} 839 | engines: {node: '>=12'} 840 | hasBin: true 841 | 842 | escalade@3.2.0: 843 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 844 | engines: {node: '>=6'} 845 | 846 | escape-string-regexp@2.0.0: 847 | resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} 848 | engines: {node: '>=8'} 849 | 850 | escape-string-regexp@4.0.0: 851 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 852 | engines: {node: '>=10'} 853 | 854 | esprima@4.0.1: 855 | resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} 856 | engines: {node: '>=4'} 857 | hasBin: true 858 | 859 | estree-walker@0.6.1: 860 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} 861 | 862 | execa@5.1.1: 863 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} 864 | engines: {node: '>=10'} 865 | 866 | exit-hook@2.2.1: 867 | resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} 868 | engines: {node: '>=6'} 869 | 870 | exit@0.1.2: 871 | resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} 872 | engines: {node: '>= 0.8.0'} 873 | 874 | expect@29.7.0: 875 | resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} 876 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 877 | 878 | fast-json-stable-stringify@2.1.0: 879 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 880 | 881 | fb-watchman@2.0.2: 882 | resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} 883 | 884 | filelist@1.0.4: 885 | resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} 886 | 887 | fill-range@7.1.1: 888 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 889 | engines: {node: '>=8'} 890 | 891 | find-up@4.1.0: 892 | resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} 893 | engines: {node: '>=8'} 894 | 895 | fs.realpath@1.0.0: 896 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 897 | 898 | fsevents@2.3.3: 899 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 900 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 901 | os: [darwin] 902 | 903 | function-bind@1.1.2: 904 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 905 | 906 | gensync@1.0.0-beta.2: 907 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 908 | engines: {node: '>=6.9.0'} 909 | 910 | get-caller-file@2.0.5: 911 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 912 | engines: {node: 6.* || 8.* || >= 10.*} 913 | 914 | get-package-type@0.1.0: 915 | resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} 916 | engines: {node: '>=8.0.0'} 917 | 918 | get-source@2.0.12: 919 | resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} 920 | 921 | get-stream@6.0.1: 922 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 923 | engines: {node: '>=10'} 924 | 925 | glob-to-regexp@0.4.1: 926 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} 927 | 928 | glob@7.2.3: 929 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 930 | deprecated: Glob versions prior to v9 are no longer supported 931 | 932 | globals@11.12.0: 933 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 934 | engines: {node: '>=4'} 935 | 936 | graceful-fs@4.2.11: 937 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 938 | 939 | has-flag@4.0.0: 940 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 941 | engines: {node: '>=8'} 942 | 943 | hasown@2.0.2: 944 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 945 | engines: {node: '>= 0.4'} 946 | 947 | hono@4.6.14: 948 | resolution: {integrity: sha512-j4VkyUp2xazGJ8eCCLN1Vm/bxdvm/j5ZuU9AIjLu9vapn2M44p9L3Ktr9Vnb2RN2QtcR/wVjZVMlT5k7GJQgPw==} 949 | engines: {node: '>=16.9.0'} 950 | 951 | html-escaper@2.0.2: 952 | resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} 953 | 954 | human-signals@2.1.0: 955 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} 956 | engines: {node: '>=10.17.0'} 957 | 958 | import-local@3.2.0: 959 | resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} 960 | engines: {node: '>=8'} 961 | hasBin: true 962 | 963 | imurmurhash@0.1.4: 964 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 965 | engines: {node: '>=0.8.19'} 966 | 967 | inflight@1.0.6: 968 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 969 | deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 970 | 971 | inherits@2.0.4: 972 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 973 | 974 | is-arrayish@0.2.1: 975 | resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 976 | 977 | is-core-module@2.16.0: 978 | resolution: {integrity: sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==} 979 | engines: {node: '>= 0.4'} 980 | 981 | is-fullwidth-code-point@3.0.0: 982 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 983 | engines: {node: '>=8'} 984 | 985 | is-generator-fn@2.1.0: 986 | resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} 987 | engines: {node: '>=6'} 988 | 989 | is-number@7.0.0: 990 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 991 | engines: {node: '>=0.12.0'} 992 | 993 | is-stream@2.0.1: 994 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} 995 | engines: {node: '>=8'} 996 | 997 | isexe@2.0.0: 998 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 999 | 1000 | istanbul-lib-coverage@3.2.2: 1001 | resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} 1002 | engines: {node: '>=8'} 1003 | 1004 | istanbul-lib-instrument@5.2.1: 1005 | resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} 1006 | engines: {node: '>=8'} 1007 | 1008 | istanbul-lib-instrument@6.0.3: 1009 | resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} 1010 | engines: {node: '>=10'} 1011 | 1012 | istanbul-lib-report@3.0.1: 1013 | resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} 1014 | engines: {node: '>=10'} 1015 | 1016 | istanbul-lib-source-maps@4.0.1: 1017 | resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} 1018 | engines: {node: '>=10'} 1019 | 1020 | istanbul-reports@3.1.7: 1021 | resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} 1022 | engines: {node: '>=8'} 1023 | 1024 | itty-time@1.0.6: 1025 | resolution: {integrity: sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==} 1026 | 1027 | jake@10.9.2: 1028 | resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} 1029 | engines: {node: '>=10'} 1030 | hasBin: true 1031 | 1032 | jest-changed-files@29.7.0: 1033 | resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} 1034 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1035 | 1036 | jest-circus@29.7.0: 1037 | resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} 1038 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1039 | 1040 | jest-cli@29.7.0: 1041 | resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} 1042 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1043 | hasBin: true 1044 | peerDependencies: 1045 | node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 1046 | peerDependenciesMeta: 1047 | node-notifier: 1048 | optional: true 1049 | 1050 | jest-config@29.7.0: 1051 | resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} 1052 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1053 | peerDependencies: 1054 | '@types/node': '*' 1055 | ts-node: '>=9.0.0' 1056 | peerDependenciesMeta: 1057 | '@types/node': 1058 | optional: true 1059 | ts-node: 1060 | optional: true 1061 | 1062 | jest-diff@29.7.0: 1063 | resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} 1064 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1065 | 1066 | jest-docblock@29.7.0: 1067 | resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} 1068 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1069 | 1070 | jest-each@29.7.0: 1071 | resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} 1072 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1073 | 1074 | jest-environment-node@29.7.0: 1075 | resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} 1076 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1077 | 1078 | jest-get-type@29.6.3: 1079 | resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} 1080 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1081 | 1082 | jest-haste-map@29.7.0: 1083 | resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} 1084 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1085 | 1086 | jest-leak-detector@29.7.0: 1087 | resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} 1088 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1089 | 1090 | jest-matcher-utils@29.7.0: 1091 | resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} 1092 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1093 | 1094 | jest-message-util@29.7.0: 1095 | resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} 1096 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1097 | 1098 | jest-mock@29.7.0: 1099 | resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} 1100 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1101 | 1102 | jest-pnp-resolver@1.2.3: 1103 | resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} 1104 | engines: {node: '>=6'} 1105 | peerDependencies: 1106 | jest-resolve: '*' 1107 | peerDependenciesMeta: 1108 | jest-resolve: 1109 | optional: true 1110 | 1111 | jest-regex-util@29.6.3: 1112 | resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} 1113 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1114 | 1115 | jest-resolve-dependencies@29.7.0: 1116 | resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} 1117 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1118 | 1119 | jest-resolve@29.7.0: 1120 | resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} 1121 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1122 | 1123 | jest-runner@29.7.0: 1124 | resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} 1125 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1126 | 1127 | jest-runtime@29.7.0: 1128 | resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} 1129 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1130 | 1131 | jest-snapshot@29.7.0: 1132 | resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} 1133 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1134 | 1135 | jest-util@29.7.0: 1136 | resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} 1137 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1138 | 1139 | jest-validate@29.7.0: 1140 | resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} 1141 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1142 | 1143 | jest-watcher@29.7.0: 1144 | resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} 1145 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1146 | 1147 | jest-worker@29.7.0: 1148 | resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} 1149 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1150 | 1151 | jest@29.7.0: 1152 | resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} 1153 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1154 | hasBin: true 1155 | peerDependencies: 1156 | node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 1157 | peerDependenciesMeta: 1158 | node-notifier: 1159 | optional: true 1160 | 1161 | js-tokens@4.0.0: 1162 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1163 | 1164 | js-yaml@3.14.1: 1165 | resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} 1166 | hasBin: true 1167 | 1168 | js-yaml@4.1.0: 1169 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 1170 | hasBin: true 1171 | 1172 | jsesc@3.1.0: 1173 | resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} 1174 | engines: {node: '>=6'} 1175 | hasBin: true 1176 | 1177 | json-parse-even-better-errors@2.3.1: 1178 | resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} 1179 | 1180 | json5@2.2.3: 1181 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 1182 | engines: {node: '>=6'} 1183 | hasBin: true 1184 | 1185 | kleur@3.0.3: 1186 | resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} 1187 | engines: {node: '>=6'} 1188 | 1189 | leven@3.1.0: 1190 | resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} 1191 | engines: {node: '>=6'} 1192 | 1193 | lines-and-columns@1.2.4: 1194 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 1195 | 1196 | locate-path@5.0.0: 1197 | resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} 1198 | engines: {node: '>=8'} 1199 | 1200 | lodash.memoize@4.1.2: 1201 | resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} 1202 | 1203 | lru-cache@5.1.1: 1204 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} 1205 | 1206 | magic-string@0.25.9: 1207 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 1208 | 1209 | make-dir@4.0.0: 1210 | resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} 1211 | engines: {node: '>=10'} 1212 | 1213 | make-error@1.3.6: 1214 | resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} 1215 | 1216 | makeerror@1.0.12: 1217 | resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} 1218 | 1219 | merge-stream@2.0.0: 1220 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 1221 | 1222 | micromatch@4.0.8: 1223 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 1224 | engines: {node: '>=8.6'} 1225 | 1226 | mime@3.0.0: 1227 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 1228 | engines: {node: '>=10.0.0'} 1229 | hasBin: true 1230 | 1231 | mimic-fn@2.1.0: 1232 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 1233 | engines: {node: '>=6'} 1234 | 1235 | miniflare@3.20241205.0: 1236 | resolution: {integrity: sha512-Z0cTtIf6ZrcAJ3SrOI9EUM3s4dkGhNeU6Ubl8sroYhsPVD+rtz3m5+p6McHFWCkcMff1o60X5XEKVTmkz0gbpA==} 1237 | engines: {node: '>=16.13'} 1238 | hasBin: true 1239 | 1240 | minimatch@3.1.2: 1241 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1242 | 1243 | minimatch@5.1.6: 1244 | resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} 1245 | engines: {node: '>=10'} 1246 | 1247 | ms@2.1.3: 1248 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 1249 | 1250 | mustache@4.2.0: 1251 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} 1252 | hasBin: true 1253 | 1254 | nanoid@3.3.7: 1255 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 1256 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1257 | hasBin: true 1258 | 1259 | natural-compare@1.4.0: 1260 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1261 | 1262 | node-forge@1.3.1: 1263 | resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} 1264 | engines: {node: '>= 6.13.0'} 1265 | 1266 | node-int64@0.4.0: 1267 | resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} 1268 | 1269 | node-releases@2.0.19: 1270 | resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} 1271 | 1272 | normalize-path@3.0.0: 1273 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1274 | engines: {node: '>=0.10.0'} 1275 | 1276 | npm-run-path@4.0.1: 1277 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} 1278 | engines: {node: '>=8'} 1279 | 1280 | ohash@1.1.4: 1281 | resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} 1282 | 1283 | once@1.4.0: 1284 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 1285 | 1286 | onetime@5.1.2: 1287 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 1288 | engines: {node: '>=6'} 1289 | 1290 | openapi3-ts@4.4.0: 1291 | resolution: {integrity: sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==} 1292 | 1293 | p-limit@2.3.0: 1294 | resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} 1295 | engines: {node: '>=6'} 1296 | 1297 | p-limit@3.1.0: 1298 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1299 | engines: {node: '>=10'} 1300 | 1301 | p-locate@4.1.0: 1302 | resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} 1303 | engines: {node: '>=8'} 1304 | 1305 | p-try@2.2.0: 1306 | resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} 1307 | engines: {node: '>=6'} 1308 | 1309 | parse-json@5.2.0: 1310 | resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} 1311 | engines: {node: '>=8'} 1312 | 1313 | path-exists@4.0.0: 1314 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1315 | engines: {node: '>=8'} 1316 | 1317 | path-is-absolute@1.0.1: 1318 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 1319 | engines: {node: '>=0.10.0'} 1320 | 1321 | path-key@3.1.1: 1322 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1323 | engines: {node: '>=8'} 1324 | 1325 | path-parse@1.0.7: 1326 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 1327 | 1328 | path-to-regexp@6.3.0: 1329 | resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} 1330 | 1331 | pathe@1.1.2: 1332 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 1333 | 1334 | picocolors@1.1.1: 1335 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 1336 | 1337 | picomatch@2.3.1: 1338 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1339 | engines: {node: '>=8.6'} 1340 | 1341 | pirates@4.0.6: 1342 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} 1343 | engines: {node: '>= 6'} 1344 | 1345 | pkg-dir@4.2.0: 1346 | resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} 1347 | engines: {node: '>=8'} 1348 | 1349 | pretty-format@29.7.0: 1350 | resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} 1351 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1352 | 1353 | printable-characters@1.0.42: 1354 | resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} 1355 | 1356 | prompts@2.4.2: 1357 | resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} 1358 | engines: {node: '>= 6'} 1359 | 1360 | pure-rand@6.1.0: 1361 | resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} 1362 | 1363 | react-is@18.3.1: 1364 | resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} 1365 | 1366 | readdirp@4.0.2: 1367 | resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} 1368 | engines: {node: '>= 14.16.0'} 1369 | 1370 | require-directory@2.1.1: 1371 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 1372 | engines: {node: '>=0.10.0'} 1373 | 1374 | resolve-cwd@3.0.0: 1375 | resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} 1376 | engines: {node: '>=8'} 1377 | 1378 | resolve-from@5.0.0: 1379 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 1380 | engines: {node: '>=8'} 1381 | 1382 | resolve.exports@2.0.3: 1383 | resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} 1384 | engines: {node: '>=10'} 1385 | 1386 | resolve@1.22.9: 1387 | resolution: {integrity: sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==} 1388 | hasBin: true 1389 | 1390 | rollup-plugin-inject@3.0.2: 1391 | resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} 1392 | deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. 1393 | 1394 | rollup-plugin-node-polyfills@0.2.1: 1395 | resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} 1396 | 1397 | rollup-pluginutils@2.8.2: 1398 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} 1399 | 1400 | selfsigned@2.4.1: 1401 | resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} 1402 | engines: {node: '>=10'} 1403 | 1404 | semver@6.3.1: 1405 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 1406 | hasBin: true 1407 | 1408 | semver@7.6.3: 1409 | resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} 1410 | engines: {node: '>=10'} 1411 | hasBin: true 1412 | 1413 | shebang-command@2.0.0: 1414 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1415 | engines: {node: '>=8'} 1416 | 1417 | shebang-regex@3.0.0: 1418 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1419 | engines: {node: '>=8'} 1420 | 1421 | signal-exit@3.0.7: 1422 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 1423 | 1424 | sisteransi@1.0.5: 1425 | resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} 1426 | 1427 | slash@3.0.0: 1428 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1429 | engines: {node: '>=8'} 1430 | 1431 | source-map-support@0.5.13: 1432 | resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} 1433 | 1434 | source-map@0.6.1: 1435 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 1436 | engines: {node: '>=0.10.0'} 1437 | 1438 | sourcemap-codec@1.4.8: 1439 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 1440 | deprecated: Please use @jridgewell/sourcemap-codec instead 1441 | 1442 | sprintf-js@1.0.3: 1443 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 1444 | 1445 | stack-utils@2.0.6: 1446 | resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} 1447 | engines: {node: '>=10'} 1448 | 1449 | stacktracey@2.1.8: 1450 | resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} 1451 | 1452 | stoppable@1.1.0: 1453 | resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} 1454 | engines: {node: '>=4', npm: '>=6'} 1455 | 1456 | string-length@4.0.2: 1457 | resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} 1458 | engines: {node: '>=10'} 1459 | 1460 | string-width@4.2.3: 1461 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1462 | engines: {node: '>=8'} 1463 | 1464 | strip-ansi@6.0.1: 1465 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1466 | engines: {node: '>=8'} 1467 | 1468 | strip-bom@4.0.0: 1469 | resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} 1470 | engines: {node: '>=8'} 1471 | 1472 | strip-final-newline@2.0.0: 1473 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} 1474 | engines: {node: '>=6'} 1475 | 1476 | strip-json-comments@3.1.1: 1477 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 1478 | engines: {node: '>=8'} 1479 | 1480 | supports-color@7.2.0: 1481 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1482 | engines: {node: '>=8'} 1483 | 1484 | supports-color@8.1.1: 1485 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 1486 | engines: {node: '>=10'} 1487 | 1488 | supports-preserve-symlinks-flag@1.0.0: 1489 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1490 | engines: {node: '>= 0.4'} 1491 | 1492 | test-exclude@6.0.0: 1493 | resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} 1494 | engines: {node: '>=8'} 1495 | 1496 | tmpl@1.0.5: 1497 | resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} 1498 | 1499 | to-regex-range@5.0.1: 1500 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1501 | engines: {node: '>=8.0'} 1502 | 1503 | ts-jest@29.2.5: 1504 | resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} 1505 | engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} 1506 | hasBin: true 1507 | peerDependencies: 1508 | '@babel/core': '>=7.0.0-beta.0 <8' 1509 | '@jest/transform': ^29.0.0 1510 | '@jest/types': ^29.0.0 1511 | babel-jest: ^29.0.0 1512 | esbuild: '*' 1513 | jest: ^29.0.0 1514 | typescript: '>=4.3 <6' 1515 | peerDependenciesMeta: 1516 | '@babel/core': 1517 | optional: true 1518 | '@jest/transform': 1519 | optional: true 1520 | '@jest/types': 1521 | optional: true 1522 | babel-jest: 1523 | optional: true 1524 | esbuild: 1525 | optional: true 1526 | 1527 | ts-node@10.9.2: 1528 | resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} 1529 | hasBin: true 1530 | peerDependencies: 1531 | '@swc/core': '>=1.2.50' 1532 | '@swc/wasm': '>=1.2.50' 1533 | '@types/node': '*' 1534 | typescript: '>=2.7' 1535 | peerDependenciesMeta: 1536 | '@swc/core': 1537 | optional: true 1538 | '@swc/wasm': 1539 | optional: true 1540 | 1541 | tslib@2.8.1: 1542 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 1543 | 1544 | type-detect@4.0.8: 1545 | resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} 1546 | engines: {node: '>=4'} 1547 | 1548 | type-fest@0.21.3: 1549 | resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} 1550 | engines: {node: '>=10'} 1551 | 1552 | typescript@5.7.2: 1553 | resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} 1554 | engines: {node: '>=14.17'} 1555 | hasBin: true 1556 | 1557 | ufo@1.5.4: 1558 | resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} 1559 | 1560 | undici@5.28.4: 1561 | resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} 1562 | engines: {node: '>=14.0'} 1563 | 1564 | unenv-nightly@2.0.0-20241204-140205-a5d5190: 1565 | resolution: {integrity: sha512-jpmAytLeiiW01pl5bhVn9wYJ4vtiLdhGe10oXlJBuQEX8mxjxO8BlEXGHU4vr4yEikjFP1wsomTHt/CLU8kUwg==} 1566 | 1567 | update-browserslist-db@1.1.1: 1568 | resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} 1569 | hasBin: true 1570 | peerDependencies: 1571 | browserslist: '>= 4.21.0' 1572 | 1573 | v8-compile-cache-lib@3.0.1: 1574 | resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} 1575 | 1576 | v8-to-istanbul@9.3.0: 1577 | resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} 1578 | engines: {node: '>=10.12.0'} 1579 | 1580 | walker@1.0.8: 1581 | resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} 1582 | 1583 | which@2.0.2: 1584 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1585 | engines: {node: '>= 8'} 1586 | hasBin: true 1587 | 1588 | workerd@1.20241205.0: 1589 | resolution: {integrity: sha512-vso/2n0c5SdBDWiD+Sx5gM7unA6SiZXRVUHDqH1euoP/9mFVHZF8icoYsNLB87b/TX8zNgpae+I5N/xFpd9v0g==} 1590 | engines: {node: '>=16'} 1591 | hasBin: true 1592 | 1593 | wrangler@3.95.0: 1594 | resolution: {integrity: sha512-3w5852i3FNyDz421K2Qk4v5L8jjwegO5O8E1+VAQmjnm82HFNxpIRUBq0bmM7CTLvOPI/Jjcmj/eAWjQBL7QYg==} 1595 | engines: {node: '>=16.17.0'} 1596 | hasBin: true 1597 | peerDependencies: 1598 | '@cloudflare/workers-types': ^4.20241205.0 1599 | peerDependenciesMeta: 1600 | '@cloudflare/workers-types': 1601 | optional: true 1602 | 1603 | wrap-ansi@7.0.0: 1604 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1605 | engines: {node: '>=10'} 1606 | 1607 | wrappy@1.0.2: 1608 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1609 | 1610 | write-file-atomic@4.0.2: 1611 | resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} 1612 | engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} 1613 | 1614 | ws@8.18.0: 1615 | resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} 1616 | engines: {node: '>=10.0.0'} 1617 | peerDependencies: 1618 | bufferutil: ^4.0.1 1619 | utf-8-validate: '>=5.0.2' 1620 | peerDependenciesMeta: 1621 | bufferutil: 1622 | optional: true 1623 | utf-8-validate: 1624 | optional: true 1625 | 1626 | xxhash-wasm@1.1.0: 1627 | resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} 1628 | 1629 | y18n@5.0.8: 1630 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 1631 | engines: {node: '>=10'} 1632 | 1633 | yallist@3.1.1: 1634 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 1635 | 1636 | yaml@2.6.1: 1637 | resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} 1638 | engines: {node: '>= 14'} 1639 | hasBin: true 1640 | 1641 | yargs-parser@21.1.1: 1642 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 1643 | engines: {node: '>=12'} 1644 | 1645 | yargs@17.7.2: 1646 | resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} 1647 | engines: {node: '>=12'} 1648 | 1649 | yn@3.1.1: 1650 | resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} 1651 | engines: {node: '>=6'} 1652 | 1653 | yocto-queue@0.1.0: 1654 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1655 | engines: {node: '>=10'} 1656 | 1657 | youch@3.3.4: 1658 | resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} 1659 | 1660 | zod@3.24.1: 1661 | resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} 1662 | 1663 | snapshots: 1664 | 1665 | '@ampproject/remapping@2.3.0': 1666 | dependencies: 1667 | '@jridgewell/gen-mapping': 0.3.8 1668 | '@jridgewell/trace-mapping': 0.3.25 1669 | 1670 | '@asteasolutions/zod-to-openapi@7.3.0(zod@3.24.1)': 1671 | dependencies: 1672 | openapi3-ts: 4.4.0 1673 | zod: 3.24.1 1674 | 1675 | '@babel/code-frame@7.26.2': 1676 | dependencies: 1677 | '@babel/helper-validator-identifier': 7.25.9 1678 | js-tokens: 4.0.0 1679 | picocolors: 1.1.1 1680 | 1681 | '@babel/compat-data@7.26.3': {} 1682 | 1683 | '@babel/core@7.26.0': 1684 | dependencies: 1685 | '@ampproject/remapping': 2.3.0 1686 | '@babel/code-frame': 7.26.2 1687 | '@babel/generator': 7.26.3 1688 | '@babel/helper-compilation-targets': 7.25.9 1689 | '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) 1690 | '@babel/helpers': 7.26.0 1691 | '@babel/parser': 7.26.3 1692 | '@babel/template': 7.25.9 1693 | '@babel/traverse': 7.26.4 1694 | '@babel/types': 7.26.3 1695 | convert-source-map: 2.0.0 1696 | debug: 4.4.0 1697 | gensync: 1.0.0-beta.2 1698 | json5: 2.2.3 1699 | semver: 6.3.1 1700 | transitivePeerDependencies: 1701 | - supports-color 1702 | 1703 | '@babel/generator@7.26.3': 1704 | dependencies: 1705 | '@babel/parser': 7.26.3 1706 | '@babel/types': 7.26.3 1707 | '@jridgewell/gen-mapping': 0.3.8 1708 | '@jridgewell/trace-mapping': 0.3.25 1709 | jsesc: 3.1.0 1710 | 1711 | '@babel/helper-compilation-targets@7.25.9': 1712 | dependencies: 1713 | '@babel/compat-data': 7.26.3 1714 | '@babel/helper-validator-option': 7.25.9 1715 | browserslist: 4.24.3 1716 | lru-cache: 5.1.1 1717 | semver: 6.3.1 1718 | 1719 | '@babel/helper-module-imports@7.25.9': 1720 | dependencies: 1721 | '@babel/traverse': 7.26.4 1722 | '@babel/types': 7.26.3 1723 | transitivePeerDependencies: 1724 | - supports-color 1725 | 1726 | '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': 1727 | dependencies: 1728 | '@babel/core': 7.26.0 1729 | '@babel/helper-module-imports': 7.25.9 1730 | '@babel/helper-validator-identifier': 7.25.9 1731 | '@babel/traverse': 7.26.4 1732 | transitivePeerDependencies: 1733 | - supports-color 1734 | 1735 | '@babel/helper-plugin-utils@7.25.9': {} 1736 | 1737 | '@babel/helper-string-parser@7.25.9': {} 1738 | 1739 | '@babel/helper-validator-identifier@7.25.9': {} 1740 | 1741 | '@babel/helper-validator-option@7.25.9': {} 1742 | 1743 | '@babel/helpers@7.26.0': 1744 | dependencies: 1745 | '@babel/template': 7.25.9 1746 | '@babel/types': 7.26.3 1747 | 1748 | '@babel/parser@7.26.3': 1749 | dependencies: 1750 | '@babel/types': 7.26.3 1751 | 1752 | '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.0)': 1753 | dependencies: 1754 | '@babel/core': 7.26.0 1755 | '@babel/helper-plugin-utils': 7.25.9 1756 | 1757 | '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.0)': 1758 | dependencies: 1759 | '@babel/core': 7.26.0 1760 | '@babel/helper-plugin-utils': 7.25.9 1761 | 1762 | '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': 1763 | dependencies: 1764 | '@babel/core': 7.26.0 1765 | '@babel/helper-plugin-utils': 7.25.9 1766 | 1767 | '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.0)': 1768 | dependencies: 1769 | '@babel/core': 7.26.0 1770 | '@babel/helper-plugin-utils': 7.25.9 1771 | 1772 | '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.0)': 1773 | dependencies: 1774 | '@babel/core': 7.26.0 1775 | '@babel/helper-plugin-utils': 7.25.9 1776 | 1777 | '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.0)': 1778 | dependencies: 1779 | '@babel/core': 7.26.0 1780 | '@babel/helper-plugin-utils': 7.25.9 1781 | 1782 | '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.0)': 1783 | dependencies: 1784 | '@babel/core': 7.26.0 1785 | '@babel/helper-plugin-utils': 7.25.9 1786 | 1787 | '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': 1788 | dependencies: 1789 | '@babel/core': 7.26.0 1790 | '@babel/helper-plugin-utils': 7.25.9 1791 | 1792 | '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.0)': 1793 | dependencies: 1794 | '@babel/core': 7.26.0 1795 | '@babel/helper-plugin-utils': 7.25.9 1796 | 1797 | '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': 1798 | dependencies: 1799 | '@babel/core': 7.26.0 1800 | '@babel/helper-plugin-utils': 7.25.9 1801 | 1802 | '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.0)': 1803 | dependencies: 1804 | '@babel/core': 7.26.0 1805 | '@babel/helper-plugin-utils': 7.25.9 1806 | 1807 | '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': 1808 | dependencies: 1809 | '@babel/core': 7.26.0 1810 | '@babel/helper-plugin-utils': 7.25.9 1811 | 1812 | '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.0)': 1813 | dependencies: 1814 | '@babel/core': 7.26.0 1815 | '@babel/helper-plugin-utils': 7.25.9 1816 | 1817 | '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': 1818 | dependencies: 1819 | '@babel/core': 7.26.0 1820 | '@babel/helper-plugin-utils': 7.25.9 1821 | 1822 | '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.0)': 1823 | dependencies: 1824 | '@babel/core': 7.26.0 1825 | '@babel/helper-plugin-utils': 7.25.9 1826 | 1827 | '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.0)': 1828 | dependencies: 1829 | '@babel/core': 7.26.0 1830 | '@babel/helper-plugin-utils': 7.25.9 1831 | 1832 | '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': 1833 | dependencies: 1834 | '@babel/core': 7.26.0 1835 | '@babel/helper-plugin-utils': 7.25.9 1836 | 1837 | '@babel/template@7.25.9': 1838 | dependencies: 1839 | '@babel/code-frame': 7.26.2 1840 | '@babel/parser': 7.26.3 1841 | '@babel/types': 7.26.3 1842 | 1843 | '@babel/traverse@7.26.4': 1844 | dependencies: 1845 | '@babel/code-frame': 7.26.2 1846 | '@babel/generator': 7.26.3 1847 | '@babel/parser': 7.26.3 1848 | '@babel/template': 7.25.9 1849 | '@babel/types': 7.26.3 1850 | debug: 4.4.0 1851 | globals: 11.12.0 1852 | transitivePeerDependencies: 1853 | - supports-color 1854 | 1855 | '@babel/types@7.26.3': 1856 | dependencies: 1857 | '@babel/helper-string-parser': 7.25.9 1858 | '@babel/helper-validator-identifier': 7.25.9 1859 | 1860 | '@bcoe/v8-coverage@0.2.3': {} 1861 | 1862 | '@cloudflare/kv-asset-handler@0.3.4': 1863 | dependencies: 1864 | mime: 3.0.0 1865 | 1866 | '@cloudflare/workerd-darwin-64@1.20241205.0': 1867 | optional: true 1868 | 1869 | '@cloudflare/workerd-darwin-arm64@1.20241205.0': 1870 | optional: true 1871 | 1872 | '@cloudflare/workerd-linux-64@1.20241205.0': 1873 | optional: true 1874 | 1875 | '@cloudflare/workerd-linux-arm64@1.20241205.0': 1876 | optional: true 1877 | 1878 | '@cloudflare/workerd-windows-64@1.20241205.0': 1879 | optional: true 1880 | 1881 | '@cloudflare/workers-shared@0.11.0': 1882 | dependencies: 1883 | mime: 3.0.0 1884 | zod: 3.24.1 1885 | 1886 | '@cloudflare/workers-types@4.20241205.0': {} 1887 | 1888 | '@cspotcode/source-map-support@0.8.1': 1889 | dependencies: 1890 | '@jridgewell/trace-mapping': 0.3.9 1891 | 1892 | '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': 1893 | dependencies: 1894 | esbuild: 0.17.19 1895 | 1896 | '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': 1897 | dependencies: 1898 | esbuild: 0.17.19 1899 | escape-string-regexp: 4.0.0 1900 | rollup-plugin-node-polyfills: 0.2.1 1901 | 1902 | '@esbuild/android-arm64@0.17.19': 1903 | optional: true 1904 | 1905 | '@esbuild/android-arm@0.17.19': 1906 | optional: true 1907 | 1908 | '@esbuild/android-x64@0.17.19': 1909 | optional: true 1910 | 1911 | '@esbuild/darwin-arm64@0.17.19': 1912 | optional: true 1913 | 1914 | '@esbuild/darwin-x64@0.17.19': 1915 | optional: true 1916 | 1917 | '@esbuild/freebsd-arm64@0.17.19': 1918 | optional: true 1919 | 1920 | '@esbuild/freebsd-x64@0.17.19': 1921 | optional: true 1922 | 1923 | '@esbuild/linux-arm64@0.17.19': 1924 | optional: true 1925 | 1926 | '@esbuild/linux-arm@0.17.19': 1927 | optional: true 1928 | 1929 | '@esbuild/linux-ia32@0.17.19': 1930 | optional: true 1931 | 1932 | '@esbuild/linux-loong64@0.17.19': 1933 | optional: true 1934 | 1935 | '@esbuild/linux-mips64el@0.17.19': 1936 | optional: true 1937 | 1938 | '@esbuild/linux-ppc64@0.17.19': 1939 | optional: true 1940 | 1941 | '@esbuild/linux-riscv64@0.17.19': 1942 | optional: true 1943 | 1944 | '@esbuild/linux-s390x@0.17.19': 1945 | optional: true 1946 | 1947 | '@esbuild/linux-x64@0.17.19': 1948 | optional: true 1949 | 1950 | '@esbuild/netbsd-x64@0.17.19': 1951 | optional: true 1952 | 1953 | '@esbuild/openbsd-x64@0.17.19': 1954 | optional: true 1955 | 1956 | '@esbuild/sunos-x64@0.17.19': 1957 | optional: true 1958 | 1959 | '@esbuild/win32-arm64@0.17.19': 1960 | optional: true 1961 | 1962 | '@esbuild/win32-ia32@0.17.19': 1963 | optional: true 1964 | 1965 | '@esbuild/win32-x64@0.17.19': 1966 | optional: true 1967 | 1968 | '@fastify/busboy@2.1.1': {} 1969 | 1970 | '@hono/swagger-ui@0.5.0(hono@4.6.14)': 1971 | dependencies: 1972 | hono: 4.6.14 1973 | 1974 | '@hono/zod-openapi@0.18.3(hono@4.6.14)(zod@3.24.1)': 1975 | dependencies: 1976 | '@asteasolutions/zod-to-openapi': 7.3.0(zod@3.24.1) 1977 | '@hono/zod-validator': 0.4.2(hono@4.6.14)(zod@3.24.1) 1978 | hono: 4.6.14 1979 | zod: 3.24.1 1980 | 1981 | '@hono/zod-validator@0.4.2(hono@4.6.14)(zod@3.24.1)': 1982 | dependencies: 1983 | hono: 4.6.14 1984 | zod: 3.24.1 1985 | 1986 | '@istanbuljs/load-nyc-config@1.1.0': 1987 | dependencies: 1988 | camelcase: 5.3.1 1989 | find-up: 4.1.0 1990 | get-package-type: 0.1.0 1991 | js-yaml: 3.14.1 1992 | resolve-from: 5.0.0 1993 | 1994 | '@istanbuljs/schema@0.1.3': {} 1995 | 1996 | '@jest/console@29.7.0': 1997 | dependencies: 1998 | '@jest/types': 29.6.3 1999 | '@types/node': 20.8.3 2000 | chalk: 4.1.2 2001 | jest-message-util: 29.7.0 2002 | jest-util: 29.7.0 2003 | slash: 3.0.0 2004 | 2005 | '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2))': 2006 | dependencies: 2007 | '@jest/console': 29.7.0 2008 | '@jest/reporters': 29.7.0 2009 | '@jest/test-result': 29.7.0 2010 | '@jest/transform': 29.7.0 2011 | '@jest/types': 29.6.3 2012 | '@types/node': 20.8.3 2013 | ansi-escapes: 4.3.2 2014 | chalk: 4.1.2 2015 | ci-info: 3.9.0 2016 | exit: 0.1.2 2017 | graceful-fs: 4.2.11 2018 | jest-changed-files: 29.7.0 2019 | jest-config: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 2020 | jest-haste-map: 29.7.0 2021 | jest-message-util: 29.7.0 2022 | jest-regex-util: 29.6.3 2023 | jest-resolve: 29.7.0 2024 | jest-resolve-dependencies: 29.7.0 2025 | jest-runner: 29.7.0 2026 | jest-runtime: 29.7.0 2027 | jest-snapshot: 29.7.0 2028 | jest-util: 29.7.0 2029 | jest-validate: 29.7.0 2030 | jest-watcher: 29.7.0 2031 | micromatch: 4.0.8 2032 | pretty-format: 29.7.0 2033 | slash: 3.0.0 2034 | strip-ansi: 6.0.1 2035 | transitivePeerDependencies: 2036 | - babel-plugin-macros 2037 | - supports-color 2038 | - ts-node 2039 | 2040 | '@jest/environment@29.7.0': 2041 | dependencies: 2042 | '@jest/fake-timers': 29.7.0 2043 | '@jest/types': 29.6.3 2044 | '@types/node': 20.8.3 2045 | jest-mock: 29.7.0 2046 | 2047 | '@jest/expect-utils@29.7.0': 2048 | dependencies: 2049 | jest-get-type: 29.6.3 2050 | 2051 | '@jest/expect@29.7.0': 2052 | dependencies: 2053 | expect: 29.7.0 2054 | jest-snapshot: 29.7.0 2055 | transitivePeerDependencies: 2056 | - supports-color 2057 | 2058 | '@jest/fake-timers@29.7.0': 2059 | dependencies: 2060 | '@jest/types': 29.6.3 2061 | '@sinonjs/fake-timers': 10.3.0 2062 | '@types/node': 20.8.3 2063 | jest-message-util: 29.7.0 2064 | jest-mock: 29.7.0 2065 | jest-util: 29.7.0 2066 | 2067 | '@jest/globals@29.7.0': 2068 | dependencies: 2069 | '@jest/environment': 29.7.0 2070 | '@jest/expect': 29.7.0 2071 | '@jest/types': 29.6.3 2072 | jest-mock: 29.7.0 2073 | transitivePeerDependencies: 2074 | - supports-color 2075 | 2076 | '@jest/reporters@29.7.0': 2077 | dependencies: 2078 | '@bcoe/v8-coverage': 0.2.3 2079 | '@jest/console': 29.7.0 2080 | '@jest/test-result': 29.7.0 2081 | '@jest/transform': 29.7.0 2082 | '@jest/types': 29.6.3 2083 | '@jridgewell/trace-mapping': 0.3.25 2084 | '@types/node': 20.8.3 2085 | chalk: 4.1.2 2086 | collect-v8-coverage: 1.0.2 2087 | exit: 0.1.2 2088 | glob: 7.2.3 2089 | graceful-fs: 4.2.11 2090 | istanbul-lib-coverage: 3.2.2 2091 | istanbul-lib-instrument: 6.0.3 2092 | istanbul-lib-report: 3.0.1 2093 | istanbul-lib-source-maps: 4.0.1 2094 | istanbul-reports: 3.1.7 2095 | jest-message-util: 29.7.0 2096 | jest-util: 29.7.0 2097 | jest-worker: 29.7.0 2098 | slash: 3.0.0 2099 | string-length: 4.0.2 2100 | strip-ansi: 6.0.1 2101 | v8-to-istanbul: 9.3.0 2102 | transitivePeerDependencies: 2103 | - supports-color 2104 | 2105 | '@jest/schemas@29.6.3': 2106 | dependencies: 2107 | '@sinclair/typebox': 0.27.8 2108 | 2109 | '@jest/source-map@29.6.3': 2110 | dependencies: 2111 | '@jridgewell/trace-mapping': 0.3.25 2112 | callsites: 3.1.0 2113 | graceful-fs: 4.2.11 2114 | 2115 | '@jest/test-result@29.7.0': 2116 | dependencies: 2117 | '@jest/console': 29.7.0 2118 | '@jest/types': 29.6.3 2119 | '@types/istanbul-lib-coverage': 2.0.6 2120 | collect-v8-coverage: 1.0.2 2121 | 2122 | '@jest/test-sequencer@29.7.0': 2123 | dependencies: 2124 | '@jest/test-result': 29.7.0 2125 | graceful-fs: 4.2.11 2126 | jest-haste-map: 29.7.0 2127 | slash: 3.0.0 2128 | 2129 | '@jest/transform@29.7.0': 2130 | dependencies: 2131 | '@babel/core': 7.26.0 2132 | '@jest/types': 29.6.3 2133 | '@jridgewell/trace-mapping': 0.3.25 2134 | babel-plugin-istanbul: 6.1.1 2135 | chalk: 4.1.2 2136 | convert-source-map: 2.0.0 2137 | fast-json-stable-stringify: 2.1.0 2138 | graceful-fs: 4.2.11 2139 | jest-haste-map: 29.7.0 2140 | jest-regex-util: 29.6.3 2141 | jest-util: 29.7.0 2142 | micromatch: 4.0.8 2143 | pirates: 4.0.6 2144 | slash: 3.0.0 2145 | write-file-atomic: 4.0.2 2146 | transitivePeerDependencies: 2147 | - supports-color 2148 | 2149 | '@jest/types@29.6.3': 2150 | dependencies: 2151 | '@jest/schemas': 29.6.3 2152 | '@types/istanbul-lib-coverage': 2.0.6 2153 | '@types/istanbul-reports': 3.0.4 2154 | '@types/node': 20.8.3 2155 | '@types/yargs': 17.0.33 2156 | chalk: 4.1.2 2157 | 2158 | '@jridgewell/gen-mapping@0.3.8': 2159 | dependencies: 2160 | '@jridgewell/set-array': 1.2.1 2161 | '@jridgewell/sourcemap-codec': 1.5.0 2162 | '@jridgewell/trace-mapping': 0.3.25 2163 | 2164 | '@jridgewell/resolve-uri@3.1.2': {} 2165 | 2166 | '@jridgewell/set-array@1.2.1': {} 2167 | 2168 | '@jridgewell/sourcemap-codec@1.5.0': {} 2169 | 2170 | '@jridgewell/trace-mapping@0.3.25': 2171 | dependencies: 2172 | '@jridgewell/resolve-uri': 3.1.2 2173 | '@jridgewell/sourcemap-codec': 1.5.0 2174 | 2175 | '@jridgewell/trace-mapping@0.3.9': 2176 | dependencies: 2177 | '@jridgewell/resolve-uri': 3.1.2 2178 | '@jridgewell/sourcemap-codec': 1.5.0 2179 | 2180 | '@sinclair/typebox@0.27.8': {} 2181 | 2182 | '@sinonjs/commons@3.0.1': 2183 | dependencies: 2184 | type-detect: 4.0.8 2185 | 2186 | '@sinonjs/fake-timers@10.3.0': 2187 | dependencies: 2188 | '@sinonjs/commons': 3.0.1 2189 | 2190 | '@tsconfig/node10@1.0.11': {} 2191 | 2192 | '@tsconfig/node12@1.0.11': {} 2193 | 2194 | '@tsconfig/node14@1.0.3': {} 2195 | 2196 | '@tsconfig/node16@1.0.4': {} 2197 | 2198 | '@types/babel__core@7.20.5': 2199 | dependencies: 2200 | '@babel/parser': 7.26.3 2201 | '@babel/types': 7.26.3 2202 | '@types/babel__generator': 7.6.8 2203 | '@types/babel__template': 7.4.4 2204 | '@types/babel__traverse': 7.20.6 2205 | 2206 | '@types/babel__generator@7.6.8': 2207 | dependencies: 2208 | '@babel/types': 7.26.3 2209 | 2210 | '@types/babel__template@7.4.4': 2211 | dependencies: 2212 | '@babel/parser': 7.26.3 2213 | '@babel/types': 7.26.3 2214 | 2215 | '@types/babel__traverse@7.20.6': 2216 | dependencies: 2217 | '@babel/types': 7.26.3 2218 | 2219 | '@types/graceful-fs@4.1.9': 2220 | dependencies: 2221 | '@types/node': 20.8.3 2222 | 2223 | '@types/istanbul-lib-coverage@2.0.6': {} 2224 | 2225 | '@types/istanbul-lib-report@3.0.3': 2226 | dependencies: 2227 | '@types/istanbul-lib-coverage': 2.0.6 2228 | 2229 | '@types/istanbul-reports@3.0.4': 2230 | dependencies: 2231 | '@types/istanbul-lib-report': 3.0.3 2232 | 2233 | '@types/jest@29.5.14': 2234 | dependencies: 2235 | expect: 29.7.0 2236 | pretty-format: 29.7.0 2237 | 2238 | '@types/node-forge@1.3.11': 2239 | dependencies: 2240 | '@types/node': 20.8.3 2241 | 2242 | '@types/node@20.8.3': {} 2243 | 2244 | '@types/service-worker-mock@2.0.4': {} 2245 | 2246 | '@types/stack-utils@2.0.3': {} 2247 | 2248 | '@types/yargs-parser@21.0.3': {} 2249 | 2250 | '@types/yargs@17.0.33': 2251 | dependencies: 2252 | '@types/yargs-parser': 21.0.3 2253 | 2254 | acorn-walk@8.3.4: 2255 | dependencies: 2256 | acorn: 8.14.0 2257 | 2258 | acorn@8.14.0: {} 2259 | 2260 | ansi-escapes@4.3.2: 2261 | dependencies: 2262 | type-fest: 0.21.3 2263 | 2264 | ansi-regex@5.0.1: {} 2265 | 2266 | ansi-styles@4.3.0: 2267 | dependencies: 2268 | color-convert: 2.0.1 2269 | 2270 | ansi-styles@5.2.0: {} 2271 | 2272 | anymatch@3.1.3: 2273 | dependencies: 2274 | normalize-path: 3.0.0 2275 | picomatch: 2.3.1 2276 | 2277 | arg@4.1.3: {} 2278 | 2279 | argparse@1.0.10: 2280 | dependencies: 2281 | sprintf-js: 1.0.3 2282 | 2283 | argparse@2.0.1: {} 2284 | 2285 | as-table@1.0.55: 2286 | dependencies: 2287 | printable-characters: 1.0.42 2288 | 2289 | async@3.2.6: {} 2290 | 2291 | babel-jest@29.7.0(@babel/core@7.26.0): 2292 | dependencies: 2293 | '@babel/core': 7.26.0 2294 | '@jest/transform': 29.7.0 2295 | '@types/babel__core': 7.20.5 2296 | babel-plugin-istanbul: 6.1.1 2297 | babel-preset-jest: 29.6.3(@babel/core@7.26.0) 2298 | chalk: 4.1.2 2299 | graceful-fs: 4.2.11 2300 | slash: 3.0.0 2301 | transitivePeerDependencies: 2302 | - supports-color 2303 | 2304 | babel-plugin-istanbul@6.1.1: 2305 | dependencies: 2306 | '@babel/helper-plugin-utils': 7.25.9 2307 | '@istanbuljs/load-nyc-config': 1.1.0 2308 | '@istanbuljs/schema': 0.1.3 2309 | istanbul-lib-instrument: 5.2.1 2310 | test-exclude: 6.0.0 2311 | transitivePeerDependencies: 2312 | - supports-color 2313 | 2314 | babel-plugin-jest-hoist@29.6.3: 2315 | dependencies: 2316 | '@babel/template': 7.25.9 2317 | '@babel/types': 7.26.3 2318 | '@types/babel__core': 7.20.5 2319 | '@types/babel__traverse': 7.20.6 2320 | 2321 | babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.0): 2322 | dependencies: 2323 | '@babel/core': 7.26.0 2324 | '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.0) 2325 | '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.0) 2326 | '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.0) 2327 | '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.0) 2328 | '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.0) 2329 | '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.0) 2330 | '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.0) 2331 | '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.0) 2332 | '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.0) 2333 | '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.0) 2334 | '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.0) 2335 | '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.0) 2336 | '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.0) 2337 | '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.0) 2338 | '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.0) 2339 | 2340 | babel-preset-jest@29.6.3(@babel/core@7.26.0): 2341 | dependencies: 2342 | '@babel/core': 7.26.0 2343 | babel-plugin-jest-hoist: 29.6.3 2344 | babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.0) 2345 | 2346 | balanced-match@1.0.2: {} 2347 | 2348 | blake3-wasm@2.1.5: {} 2349 | 2350 | brace-expansion@1.1.11: 2351 | dependencies: 2352 | balanced-match: 1.0.2 2353 | concat-map: 0.0.1 2354 | 2355 | brace-expansion@2.0.1: 2356 | dependencies: 2357 | balanced-match: 1.0.2 2358 | 2359 | braces@3.0.3: 2360 | dependencies: 2361 | fill-range: 7.1.1 2362 | 2363 | browserslist@4.24.3: 2364 | dependencies: 2365 | caniuse-lite: 1.0.30001689 2366 | electron-to-chromium: 1.5.74 2367 | node-releases: 2.0.19 2368 | update-browserslist-db: 1.1.1(browserslist@4.24.3) 2369 | 2370 | bs-logger@0.2.6: 2371 | dependencies: 2372 | fast-json-stable-stringify: 2.1.0 2373 | 2374 | bser@2.1.1: 2375 | dependencies: 2376 | node-int64: 0.4.0 2377 | 2378 | buffer-from@1.1.2: {} 2379 | 2380 | callsites@3.1.0: {} 2381 | 2382 | camelcase@5.3.1: {} 2383 | 2384 | camelcase@6.3.0: {} 2385 | 2386 | caniuse-lite@1.0.30001689: {} 2387 | 2388 | capnp-ts@0.7.0: 2389 | dependencies: 2390 | debug: 4.4.0 2391 | tslib: 2.8.1 2392 | transitivePeerDependencies: 2393 | - supports-color 2394 | 2395 | chalk@4.1.2: 2396 | dependencies: 2397 | ansi-styles: 4.3.0 2398 | supports-color: 7.2.0 2399 | 2400 | chanfana@2.5.1: 2401 | dependencies: 2402 | '@asteasolutions/zod-to-openapi': 7.3.0(zod@3.24.1) 2403 | js-yaml: 4.1.0 2404 | openapi3-ts: 4.4.0 2405 | zod: 3.24.1 2406 | 2407 | char-regex@1.0.2: {} 2408 | 2409 | chokidar@4.0.1: 2410 | dependencies: 2411 | readdirp: 4.0.2 2412 | 2413 | ci-info@3.9.0: {} 2414 | 2415 | cjs-module-lexer@1.4.1: {} 2416 | 2417 | cliui@8.0.1: 2418 | dependencies: 2419 | string-width: 4.2.3 2420 | strip-ansi: 6.0.1 2421 | wrap-ansi: 7.0.0 2422 | 2423 | co@4.6.0: {} 2424 | 2425 | collect-v8-coverage@1.0.2: {} 2426 | 2427 | color-convert@2.0.1: 2428 | dependencies: 2429 | color-name: 1.1.4 2430 | 2431 | color-name@1.1.4: {} 2432 | 2433 | concat-map@0.0.1: {} 2434 | 2435 | convert-source-map@2.0.0: {} 2436 | 2437 | cookie@0.7.2: {} 2438 | 2439 | create-jest@29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)): 2440 | dependencies: 2441 | '@jest/types': 29.6.3 2442 | chalk: 4.1.2 2443 | exit: 0.1.2 2444 | graceful-fs: 4.2.11 2445 | jest-config: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 2446 | jest-util: 29.7.0 2447 | prompts: 2.4.2 2448 | transitivePeerDependencies: 2449 | - '@types/node' 2450 | - babel-plugin-macros 2451 | - supports-color 2452 | - ts-node 2453 | 2454 | create-require@1.1.1: {} 2455 | 2456 | cross-spawn@7.0.6: 2457 | dependencies: 2458 | path-key: 3.1.1 2459 | shebang-command: 2.0.0 2460 | which: 2.0.2 2461 | 2462 | data-uri-to-buffer@2.0.2: {} 2463 | 2464 | date-fns@4.1.0: {} 2465 | 2466 | debug@4.4.0: 2467 | dependencies: 2468 | ms: 2.1.3 2469 | 2470 | dedent@1.5.3: {} 2471 | 2472 | deepmerge@4.3.1: {} 2473 | 2474 | defu@6.1.4: {} 2475 | 2476 | detect-newline@3.1.0: {} 2477 | 2478 | diff-sequences@29.6.3: {} 2479 | 2480 | diff@4.0.2: {} 2481 | 2482 | ejs@3.1.10: 2483 | dependencies: 2484 | jake: 10.9.2 2485 | 2486 | electron-to-chromium@1.5.74: {} 2487 | 2488 | emittery@0.13.1: {} 2489 | 2490 | emoji-regex@8.0.0: {} 2491 | 2492 | error-ex@1.3.2: 2493 | dependencies: 2494 | is-arrayish: 0.2.1 2495 | 2496 | esbuild@0.17.19: 2497 | optionalDependencies: 2498 | '@esbuild/android-arm': 0.17.19 2499 | '@esbuild/android-arm64': 0.17.19 2500 | '@esbuild/android-x64': 0.17.19 2501 | '@esbuild/darwin-arm64': 0.17.19 2502 | '@esbuild/darwin-x64': 0.17.19 2503 | '@esbuild/freebsd-arm64': 0.17.19 2504 | '@esbuild/freebsd-x64': 0.17.19 2505 | '@esbuild/linux-arm': 0.17.19 2506 | '@esbuild/linux-arm64': 0.17.19 2507 | '@esbuild/linux-ia32': 0.17.19 2508 | '@esbuild/linux-loong64': 0.17.19 2509 | '@esbuild/linux-mips64el': 0.17.19 2510 | '@esbuild/linux-ppc64': 0.17.19 2511 | '@esbuild/linux-riscv64': 0.17.19 2512 | '@esbuild/linux-s390x': 0.17.19 2513 | '@esbuild/linux-x64': 0.17.19 2514 | '@esbuild/netbsd-x64': 0.17.19 2515 | '@esbuild/openbsd-x64': 0.17.19 2516 | '@esbuild/sunos-x64': 0.17.19 2517 | '@esbuild/win32-arm64': 0.17.19 2518 | '@esbuild/win32-ia32': 0.17.19 2519 | '@esbuild/win32-x64': 0.17.19 2520 | 2521 | escalade@3.2.0: {} 2522 | 2523 | escape-string-regexp@2.0.0: {} 2524 | 2525 | escape-string-regexp@4.0.0: {} 2526 | 2527 | esprima@4.0.1: {} 2528 | 2529 | estree-walker@0.6.1: {} 2530 | 2531 | execa@5.1.1: 2532 | dependencies: 2533 | cross-spawn: 7.0.6 2534 | get-stream: 6.0.1 2535 | human-signals: 2.1.0 2536 | is-stream: 2.0.1 2537 | merge-stream: 2.0.0 2538 | npm-run-path: 4.0.1 2539 | onetime: 5.1.2 2540 | signal-exit: 3.0.7 2541 | strip-final-newline: 2.0.0 2542 | 2543 | exit-hook@2.2.1: {} 2544 | 2545 | exit@0.1.2: {} 2546 | 2547 | expect@29.7.0: 2548 | dependencies: 2549 | '@jest/expect-utils': 29.7.0 2550 | jest-get-type: 29.6.3 2551 | jest-matcher-utils: 29.7.0 2552 | jest-message-util: 29.7.0 2553 | jest-util: 29.7.0 2554 | 2555 | fast-json-stable-stringify@2.1.0: {} 2556 | 2557 | fb-watchman@2.0.2: 2558 | dependencies: 2559 | bser: 2.1.1 2560 | 2561 | filelist@1.0.4: 2562 | dependencies: 2563 | minimatch: 5.1.6 2564 | 2565 | fill-range@7.1.1: 2566 | dependencies: 2567 | to-regex-range: 5.0.1 2568 | 2569 | find-up@4.1.0: 2570 | dependencies: 2571 | locate-path: 5.0.0 2572 | path-exists: 4.0.0 2573 | 2574 | fs.realpath@1.0.0: {} 2575 | 2576 | fsevents@2.3.3: 2577 | optional: true 2578 | 2579 | function-bind@1.1.2: {} 2580 | 2581 | gensync@1.0.0-beta.2: {} 2582 | 2583 | get-caller-file@2.0.5: {} 2584 | 2585 | get-package-type@0.1.0: {} 2586 | 2587 | get-source@2.0.12: 2588 | dependencies: 2589 | data-uri-to-buffer: 2.0.2 2590 | source-map: 0.6.1 2591 | 2592 | get-stream@6.0.1: {} 2593 | 2594 | glob-to-regexp@0.4.1: {} 2595 | 2596 | glob@7.2.3: 2597 | dependencies: 2598 | fs.realpath: 1.0.0 2599 | inflight: 1.0.6 2600 | inherits: 2.0.4 2601 | minimatch: 3.1.2 2602 | once: 1.4.0 2603 | path-is-absolute: 1.0.1 2604 | 2605 | globals@11.12.0: {} 2606 | 2607 | graceful-fs@4.2.11: {} 2608 | 2609 | has-flag@4.0.0: {} 2610 | 2611 | hasown@2.0.2: 2612 | dependencies: 2613 | function-bind: 1.1.2 2614 | 2615 | hono@4.6.14: {} 2616 | 2617 | html-escaper@2.0.2: {} 2618 | 2619 | human-signals@2.1.0: {} 2620 | 2621 | import-local@3.2.0: 2622 | dependencies: 2623 | pkg-dir: 4.2.0 2624 | resolve-cwd: 3.0.0 2625 | 2626 | imurmurhash@0.1.4: {} 2627 | 2628 | inflight@1.0.6: 2629 | dependencies: 2630 | once: 1.4.0 2631 | wrappy: 1.0.2 2632 | 2633 | inherits@2.0.4: {} 2634 | 2635 | is-arrayish@0.2.1: {} 2636 | 2637 | is-core-module@2.16.0: 2638 | dependencies: 2639 | hasown: 2.0.2 2640 | 2641 | is-fullwidth-code-point@3.0.0: {} 2642 | 2643 | is-generator-fn@2.1.0: {} 2644 | 2645 | is-number@7.0.0: {} 2646 | 2647 | is-stream@2.0.1: {} 2648 | 2649 | isexe@2.0.0: {} 2650 | 2651 | istanbul-lib-coverage@3.2.2: {} 2652 | 2653 | istanbul-lib-instrument@5.2.1: 2654 | dependencies: 2655 | '@babel/core': 7.26.0 2656 | '@babel/parser': 7.26.3 2657 | '@istanbuljs/schema': 0.1.3 2658 | istanbul-lib-coverage: 3.2.2 2659 | semver: 6.3.1 2660 | transitivePeerDependencies: 2661 | - supports-color 2662 | 2663 | istanbul-lib-instrument@6.0.3: 2664 | dependencies: 2665 | '@babel/core': 7.26.0 2666 | '@babel/parser': 7.26.3 2667 | '@istanbuljs/schema': 0.1.3 2668 | istanbul-lib-coverage: 3.2.2 2669 | semver: 7.6.3 2670 | transitivePeerDependencies: 2671 | - supports-color 2672 | 2673 | istanbul-lib-report@3.0.1: 2674 | dependencies: 2675 | istanbul-lib-coverage: 3.2.2 2676 | make-dir: 4.0.0 2677 | supports-color: 7.2.0 2678 | 2679 | istanbul-lib-source-maps@4.0.1: 2680 | dependencies: 2681 | debug: 4.4.0 2682 | istanbul-lib-coverage: 3.2.2 2683 | source-map: 0.6.1 2684 | transitivePeerDependencies: 2685 | - supports-color 2686 | 2687 | istanbul-reports@3.1.7: 2688 | dependencies: 2689 | html-escaper: 2.0.2 2690 | istanbul-lib-report: 3.0.1 2691 | 2692 | itty-time@1.0.6: {} 2693 | 2694 | jake@10.9.2: 2695 | dependencies: 2696 | async: 3.2.6 2697 | chalk: 4.1.2 2698 | filelist: 1.0.4 2699 | minimatch: 3.1.2 2700 | 2701 | jest-changed-files@29.7.0: 2702 | dependencies: 2703 | execa: 5.1.1 2704 | jest-util: 29.7.0 2705 | p-limit: 3.1.0 2706 | 2707 | jest-circus@29.7.0: 2708 | dependencies: 2709 | '@jest/environment': 29.7.0 2710 | '@jest/expect': 29.7.0 2711 | '@jest/test-result': 29.7.0 2712 | '@jest/types': 29.6.3 2713 | '@types/node': 20.8.3 2714 | chalk: 4.1.2 2715 | co: 4.6.0 2716 | dedent: 1.5.3 2717 | is-generator-fn: 2.1.0 2718 | jest-each: 29.7.0 2719 | jest-matcher-utils: 29.7.0 2720 | jest-message-util: 29.7.0 2721 | jest-runtime: 29.7.0 2722 | jest-snapshot: 29.7.0 2723 | jest-util: 29.7.0 2724 | p-limit: 3.1.0 2725 | pretty-format: 29.7.0 2726 | pure-rand: 6.1.0 2727 | slash: 3.0.0 2728 | stack-utils: 2.0.6 2729 | transitivePeerDependencies: 2730 | - babel-plugin-macros 2731 | - supports-color 2732 | 2733 | jest-cli@29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)): 2734 | dependencies: 2735 | '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 2736 | '@jest/test-result': 29.7.0 2737 | '@jest/types': 29.6.3 2738 | chalk: 4.1.2 2739 | create-jest: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 2740 | exit: 0.1.2 2741 | import-local: 3.2.0 2742 | jest-config: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 2743 | jest-util: 29.7.0 2744 | jest-validate: 29.7.0 2745 | yargs: 17.7.2 2746 | transitivePeerDependencies: 2747 | - '@types/node' 2748 | - babel-plugin-macros 2749 | - supports-color 2750 | - ts-node 2751 | 2752 | jest-config@29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)): 2753 | dependencies: 2754 | '@babel/core': 7.26.0 2755 | '@jest/test-sequencer': 29.7.0 2756 | '@jest/types': 29.6.3 2757 | babel-jest: 29.7.0(@babel/core@7.26.0) 2758 | chalk: 4.1.2 2759 | ci-info: 3.9.0 2760 | deepmerge: 4.3.1 2761 | glob: 7.2.3 2762 | graceful-fs: 4.2.11 2763 | jest-circus: 29.7.0 2764 | jest-environment-node: 29.7.0 2765 | jest-get-type: 29.6.3 2766 | jest-regex-util: 29.6.3 2767 | jest-resolve: 29.7.0 2768 | jest-runner: 29.7.0 2769 | jest-util: 29.7.0 2770 | jest-validate: 29.7.0 2771 | micromatch: 4.0.8 2772 | parse-json: 5.2.0 2773 | pretty-format: 29.7.0 2774 | slash: 3.0.0 2775 | strip-json-comments: 3.1.1 2776 | optionalDependencies: 2777 | '@types/node': 20.8.3 2778 | ts-node: 10.9.2(@types/node@20.8.3)(typescript@5.7.2) 2779 | transitivePeerDependencies: 2780 | - babel-plugin-macros 2781 | - supports-color 2782 | 2783 | jest-diff@29.7.0: 2784 | dependencies: 2785 | chalk: 4.1.2 2786 | diff-sequences: 29.6.3 2787 | jest-get-type: 29.6.3 2788 | pretty-format: 29.7.0 2789 | 2790 | jest-docblock@29.7.0: 2791 | dependencies: 2792 | detect-newline: 3.1.0 2793 | 2794 | jest-each@29.7.0: 2795 | dependencies: 2796 | '@jest/types': 29.6.3 2797 | chalk: 4.1.2 2798 | jest-get-type: 29.6.3 2799 | jest-util: 29.7.0 2800 | pretty-format: 29.7.0 2801 | 2802 | jest-environment-node@29.7.0: 2803 | dependencies: 2804 | '@jest/environment': 29.7.0 2805 | '@jest/fake-timers': 29.7.0 2806 | '@jest/types': 29.6.3 2807 | '@types/node': 20.8.3 2808 | jest-mock: 29.7.0 2809 | jest-util: 29.7.0 2810 | 2811 | jest-get-type@29.6.3: {} 2812 | 2813 | jest-haste-map@29.7.0: 2814 | dependencies: 2815 | '@jest/types': 29.6.3 2816 | '@types/graceful-fs': 4.1.9 2817 | '@types/node': 20.8.3 2818 | anymatch: 3.1.3 2819 | fb-watchman: 2.0.2 2820 | graceful-fs: 4.2.11 2821 | jest-regex-util: 29.6.3 2822 | jest-util: 29.7.0 2823 | jest-worker: 29.7.0 2824 | micromatch: 4.0.8 2825 | walker: 1.0.8 2826 | optionalDependencies: 2827 | fsevents: 2.3.3 2828 | 2829 | jest-leak-detector@29.7.0: 2830 | dependencies: 2831 | jest-get-type: 29.6.3 2832 | pretty-format: 29.7.0 2833 | 2834 | jest-matcher-utils@29.7.0: 2835 | dependencies: 2836 | chalk: 4.1.2 2837 | jest-diff: 29.7.0 2838 | jest-get-type: 29.6.3 2839 | pretty-format: 29.7.0 2840 | 2841 | jest-message-util@29.7.0: 2842 | dependencies: 2843 | '@babel/code-frame': 7.26.2 2844 | '@jest/types': 29.6.3 2845 | '@types/stack-utils': 2.0.3 2846 | chalk: 4.1.2 2847 | graceful-fs: 4.2.11 2848 | micromatch: 4.0.8 2849 | pretty-format: 29.7.0 2850 | slash: 3.0.0 2851 | stack-utils: 2.0.6 2852 | 2853 | jest-mock@29.7.0: 2854 | dependencies: 2855 | '@jest/types': 29.6.3 2856 | '@types/node': 20.8.3 2857 | jest-util: 29.7.0 2858 | 2859 | jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): 2860 | optionalDependencies: 2861 | jest-resolve: 29.7.0 2862 | 2863 | jest-regex-util@29.6.3: {} 2864 | 2865 | jest-resolve-dependencies@29.7.0: 2866 | dependencies: 2867 | jest-regex-util: 29.6.3 2868 | jest-snapshot: 29.7.0 2869 | transitivePeerDependencies: 2870 | - supports-color 2871 | 2872 | jest-resolve@29.7.0: 2873 | dependencies: 2874 | chalk: 4.1.2 2875 | graceful-fs: 4.2.11 2876 | jest-haste-map: 29.7.0 2877 | jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) 2878 | jest-util: 29.7.0 2879 | jest-validate: 29.7.0 2880 | resolve: 1.22.9 2881 | resolve.exports: 2.0.3 2882 | slash: 3.0.0 2883 | 2884 | jest-runner@29.7.0: 2885 | dependencies: 2886 | '@jest/console': 29.7.0 2887 | '@jest/environment': 29.7.0 2888 | '@jest/test-result': 29.7.0 2889 | '@jest/transform': 29.7.0 2890 | '@jest/types': 29.6.3 2891 | '@types/node': 20.8.3 2892 | chalk: 4.1.2 2893 | emittery: 0.13.1 2894 | graceful-fs: 4.2.11 2895 | jest-docblock: 29.7.0 2896 | jest-environment-node: 29.7.0 2897 | jest-haste-map: 29.7.0 2898 | jest-leak-detector: 29.7.0 2899 | jest-message-util: 29.7.0 2900 | jest-resolve: 29.7.0 2901 | jest-runtime: 29.7.0 2902 | jest-util: 29.7.0 2903 | jest-watcher: 29.7.0 2904 | jest-worker: 29.7.0 2905 | p-limit: 3.1.0 2906 | source-map-support: 0.5.13 2907 | transitivePeerDependencies: 2908 | - supports-color 2909 | 2910 | jest-runtime@29.7.0: 2911 | dependencies: 2912 | '@jest/environment': 29.7.0 2913 | '@jest/fake-timers': 29.7.0 2914 | '@jest/globals': 29.7.0 2915 | '@jest/source-map': 29.6.3 2916 | '@jest/test-result': 29.7.0 2917 | '@jest/transform': 29.7.0 2918 | '@jest/types': 29.6.3 2919 | '@types/node': 20.8.3 2920 | chalk: 4.1.2 2921 | cjs-module-lexer: 1.4.1 2922 | collect-v8-coverage: 1.0.2 2923 | glob: 7.2.3 2924 | graceful-fs: 4.2.11 2925 | jest-haste-map: 29.7.0 2926 | jest-message-util: 29.7.0 2927 | jest-mock: 29.7.0 2928 | jest-regex-util: 29.6.3 2929 | jest-resolve: 29.7.0 2930 | jest-snapshot: 29.7.0 2931 | jest-util: 29.7.0 2932 | slash: 3.0.0 2933 | strip-bom: 4.0.0 2934 | transitivePeerDependencies: 2935 | - supports-color 2936 | 2937 | jest-snapshot@29.7.0: 2938 | dependencies: 2939 | '@babel/core': 7.26.0 2940 | '@babel/generator': 7.26.3 2941 | '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) 2942 | '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) 2943 | '@babel/types': 7.26.3 2944 | '@jest/expect-utils': 29.7.0 2945 | '@jest/transform': 29.7.0 2946 | '@jest/types': 29.6.3 2947 | babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.0) 2948 | chalk: 4.1.2 2949 | expect: 29.7.0 2950 | graceful-fs: 4.2.11 2951 | jest-diff: 29.7.0 2952 | jest-get-type: 29.6.3 2953 | jest-matcher-utils: 29.7.0 2954 | jest-message-util: 29.7.0 2955 | jest-util: 29.7.0 2956 | natural-compare: 1.4.0 2957 | pretty-format: 29.7.0 2958 | semver: 7.6.3 2959 | transitivePeerDependencies: 2960 | - supports-color 2961 | 2962 | jest-util@29.7.0: 2963 | dependencies: 2964 | '@jest/types': 29.6.3 2965 | '@types/node': 20.8.3 2966 | chalk: 4.1.2 2967 | ci-info: 3.9.0 2968 | graceful-fs: 4.2.11 2969 | picomatch: 2.3.1 2970 | 2971 | jest-validate@29.7.0: 2972 | dependencies: 2973 | '@jest/types': 29.6.3 2974 | camelcase: 6.3.0 2975 | chalk: 4.1.2 2976 | jest-get-type: 29.6.3 2977 | leven: 3.1.0 2978 | pretty-format: 29.7.0 2979 | 2980 | jest-watcher@29.7.0: 2981 | dependencies: 2982 | '@jest/test-result': 29.7.0 2983 | '@jest/types': 29.6.3 2984 | '@types/node': 20.8.3 2985 | ansi-escapes: 4.3.2 2986 | chalk: 4.1.2 2987 | emittery: 0.13.1 2988 | jest-util: 29.7.0 2989 | string-length: 4.0.2 2990 | 2991 | jest-worker@29.7.0: 2992 | dependencies: 2993 | '@types/node': 20.8.3 2994 | jest-util: 29.7.0 2995 | merge-stream: 2.0.0 2996 | supports-color: 8.1.1 2997 | 2998 | jest@29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)): 2999 | dependencies: 3000 | '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 3001 | '@jest/types': 29.6.3 3002 | import-local: 3.2.0 3003 | jest-cli: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 3004 | transitivePeerDependencies: 3005 | - '@types/node' 3006 | - babel-plugin-macros 3007 | - supports-color 3008 | - ts-node 3009 | 3010 | js-tokens@4.0.0: {} 3011 | 3012 | js-yaml@3.14.1: 3013 | dependencies: 3014 | argparse: 1.0.10 3015 | esprima: 4.0.1 3016 | 3017 | js-yaml@4.1.0: 3018 | dependencies: 3019 | argparse: 2.0.1 3020 | 3021 | jsesc@3.1.0: {} 3022 | 3023 | json-parse-even-better-errors@2.3.1: {} 3024 | 3025 | json5@2.2.3: {} 3026 | 3027 | kleur@3.0.3: {} 3028 | 3029 | leven@3.1.0: {} 3030 | 3031 | lines-and-columns@1.2.4: {} 3032 | 3033 | locate-path@5.0.0: 3034 | dependencies: 3035 | p-locate: 4.1.0 3036 | 3037 | lodash.memoize@4.1.2: {} 3038 | 3039 | lru-cache@5.1.1: 3040 | dependencies: 3041 | yallist: 3.1.1 3042 | 3043 | magic-string@0.25.9: 3044 | dependencies: 3045 | sourcemap-codec: 1.4.8 3046 | 3047 | make-dir@4.0.0: 3048 | dependencies: 3049 | semver: 7.6.3 3050 | 3051 | make-error@1.3.6: {} 3052 | 3053 | makeerror@1.0.12: 3054 | dependencies: 3055 | tmpl: 1.0.5 3056 | 3057 | merge-stream@2.0.0: {} 3058 | 3059 | micromatch@4.0.8: 3060 | dependencies: 3061 | braces: 3.0.3 3062 | picomatch: 2.3.1 3063 | 3064 | mime@3.0.0: {} 3065 | 3066 | mimic-fn@2.1.0: {} 3067 | 3068 | miniflare@3.20241205.0: 3069 | dependencies: 3070 | '@cspotcode/source-map-support': 0.8.1 3071 | acorn: 8.14.0 3072 | acorn-walk: 8.3.4 3073 | capnp-ts: 0.7.0 3074 | exit-hook: 2.2.1 3075 | glob-to-regexp: 0.4.1 3076 | stoppable: 1.1.0 3077 | undici: 5.28.4 3078 | workerd: 1.20241205.0 3079 | ws: 8.18.0 3080 | youch: 3.3.4 3081 | zod: 3.24.1 3082 | transitivePeerDependencies: 3083 | - bufferutil 3084 | - supports-color 3085 | - utf-8-validate 3086 | 3087 | minimatch@3.1.2: 3088 | dependencies: 3089 | brace-expansion: 1.1.11 3090 | 3091 | minimatch@5.1.6: 3092 | dependencies: 3093 | brace-expansion: 2.0.1 3094 | 3095 | ms@2.1.3: {} 3096 | 3097 | mustache@4.2.0: {} 3098 | 3099 | nanoid@3.3.7: {} 3100 | 3101 | natural-compare@1.4.0: {} 3102 | 3103 | node-forge@1.3.1: {} 3104 | 3105 | node-int64@0.4.0: {} 3106 | 3107 | node-releases@2.0.19: {} 3108 | 3109 | normalize-path@3.0.0: {} 3110 | 3111 | npm-run-path@4.0.1: 3112 | dependencies: 3113 | path-key: 3.1.1 3114 | 3115 | ohash@1.1.4: {} 3116 | 3117 | once@1.4.0: 3118 | dependencies: 3119 | wrappy: 1.0.2 3120 | 3121 | onetime@5.1.2: 3122 | dependencies: 3123 | mimic-fn: 2.1.0 3124 | 3125 | openapi3-ts@4.4.0: 3126 | dependencies: 3127 | yaml: 2.6.1 3128 | 3129 | p-limit@2.3.0: 3130 | dependencies: 3131 | p-try: 2.2.0 3132 | 3133 | p-limit@3.1.0: 3134 | dependencies: 3135 | yocto-queue: 0.1.0 3136 | 3137 | p-locate@4.1.0: 3138 | dependencies: 3139 | p-limit: 2.3.0 3140 | 3141 | p-try@2.2.0: {} 3142 | 3143 | parse-json@5.2.0: 3144 | dependencies: 3145 | '@babel/code-frame': 7.26.2 3146 | error-ex: 1.3.2 3147 | json-parse-even-better-errors: 2.3.1 3148 | lines-and-columns: 1.2.4 3149 | 3150 | path-exists@4.0.0: {} 3151 | 3152 | path-is-absolute@1.0.1: {} 3153 | 3154 | path-key@3.1.1: {} 3155 | 3156 | path-parse@1.0.7: {} 3157 | 3158 | path-to-regexp@6.3.0: {} 3159 | 3160 | pathe@1.1.2: {} 3161 | 3162 | picocolors@1.1.1: {} 3163 | 3164 | picomatch@2.3.1: {} 3165 | 3166 | pirates@4.0.6: {} 3167 | 3168 | pkg-dir@4.2.0: 3169 | dependencies: 3170 | find-up: 4.1.0 3171 | 3172 | pretty-format@29.7.0: 3173 | dependencies: 3174 | '@jest/schemas': 29.6.3 3175 | ansi-styles: 5.2.0 3176 | react-is: 18.3.1 3177 | 3178 | printable-characters@1.0.42: {} 3179 | 3180 | prompts@2.4.2: 3181 | dependencies: 3182 | kleur: 3.0.3 3183 | sisteransi: 1.0.5 3184 | 3185 | pure-rand@6.1.0: {} 3186 | 3187 | react-is@18.3.1: {} 3188 | 3189 | readdirp@4.0.2: {} 3190 | 3191 | require-directory@2.1.1: {} 3192 | 3193 | resolve-cwd@3.0.0: 3194 | dependencies: 3195 | resolve-from: 5.0.0 3196 | 3197 | resolve-from@5.0.0: {} 3198 | 3199 | resolve.exports@2.0.3: {} 3200 | 3201 | resolve@1.22.9: 3202 | dependencies: 3203 | is-core-module: 2.16.0 3204 | path-parse: 1.0.7 3205 | supports-preserve-symlinks-flag: 1.0.0 3206 | 3207 | rollup-plugin-inject@3.0.2: 3208 | dependencies: 3209 | estree-walker: 0.6.1 3210 | magic-string: 0.25.9 3211 | rollup-pluginutils: 2.8.2 3212 | 3213 | rollup-plugin-node-polyfills@0.2.1: 3214 | dependencies: 3215 | rollup-plugin-inject: 3.0.2 3216 | 3217 | rollup-pluginutils@2.8.2: 3218 | dependencies: 3219 | estree-walker: 0.6.1 3220 | 3221 | selfsigned@2.4.1: 3222 | dependencies: 3223 | '@types/node-forge': 1.3.11 3224 | node-forge: 1.3.1 3225 | 3226 | semver@6.3.1: {} 3227 | 3228 | semver@7.6.3: {} 3229 | 3230 | shebang-command@2.0.0: 3231 | dependencies: 3232 | shebang-regex: 3.0.0 3233 | 3234 | shebang-regex@3.0.0: {} 3235 | 3236 | signal-exit@3.0.7: {} 3237 | 3238 | sisteransi@1.0.5: {} 3239 | 3240 | slash@3.0.0: {} 3241 | 3242 | source-map-support@0.5.13: 3243 | dependencies: 3244 | buffer-from: 1.1.2 3245 | source-map: 0.6.1 3246 | 3247 | source-map@0.6.1: {} 3248 | 3249 | sourcemap-codec@1.4.8: {} 3250 | 3251 | sprintf-js@1.0.3: {} 3252 | 3253 | stack-utils@2.0.6: 3254 | dependencies: 3255 | escape-string-regexp: 2.0.0 3256 | 3257 | stacktracey@2.1.8: 3258 | dependencies: 3259 | as-table: 1.0.55 3260 | get-source: 2.0.12 3261 | 3262 | stoppable@1.1.0: {} 3263 | 3264 | string-length@4.0.2: 3265 | dependencies: 3266 | char-regex: 1.0.2 3267 | strip-ansi: 6.0.1 3268 | 3269 | string-width@4.2.3: 3270 | dependencies: 3271 | emoji-regex: 8.0.0 3272 | is-fullwidth-code-point: 3.0.0 3273 | strip-ansi: 6.0.1 3274 | 3275 | strip-ansi@6.0.1: 3276 | dependencies: 3277 | ansi-regex: 5.0.1 3278 | 3279 | strip-bom@4.0.0: {} 3280 | 3281 | strip-final-newline@2.0.0: {} 3282 | 3283 | strip-json-comments@3.1.1: {} 3284 | 3285 | supports-color@7.2.0: 3286 | dependencies: 3287 | has-flag: 4.0.0 3288 | 3289 | supports-color@8.1.1: 3290 | dependencies: 3291 | has-flag: 4.0.0 3292 | 3293 | supports-preserve-symlinks-flag@1.0.0: {} 3294 | 3295 | test-exclude@6.0.0: 3296 | dependencies: 3297 | '@istanbuljs/schema': 0.1.3 3298 | glob: 7.2.3 3299 | minimatch: 3.1.2 3300 | 3301 | tmpl@1.0.5: {} 3302 | 3303 | to-regex-range@5.0.1: 3304 | dependencies: 3305 | is-number: 7.0.0 3306 | 3307 | ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.17.19)(jest@29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)))(typescript@5.7.2): 3308 | dependencies: 3309 | bs-logger: 0.2.6 3310 | ejs: 3.1.10 3311 | fast-json-stable-stringify: 2.1.0 3312 | jest: 29.7.0(@types/node@20.8.3)(ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2)) 3313 | jest-util: 29.7.0 3314 | json5: 2.2.3 3315 | lodash.memoize: 4.1.2 3316 | make-error: 1.3.6 3317 | semver: 7.6.3 3318 | typescript: 5.7.2 3319 | yargs-parser: 21.1.1 3320 | optionalDependencies: 3321 | '@babel/core': 7.26.0 3322 | '@jest/transform': 29.7.0 3323 | '@jest/types': 29.6.3 3324 | babel-jest: 29.7.0(@babel/core@7.26.0) 3325 | esbuild: 0.17.19 3326 | 3327 | ts-node@10.9.2(@types/node@20.8.3)(typescript@5.7.2): 3328 | dependencies: 3329 | '@cspotcode/source-map-support': 0.8.1 3330 | '@tsconfig/node10': 1.0.11 3331 | '@tsconfig/node12': 1.0.11 3332 | '@tsconfig/node14': 1.0.3 3333 | '@tsconfig/node16': 1.0.4 3334 | '@types/node': 20.8.3 3335 | acorn: 8.14.0 3336 | acorn-walk: 8.3.4 3337 | arg: 4.1.3 3338 | create-require: 1.1.1 3339 | diff: 4.0.2 3340 | make-error: 1.3.6 3341 | typescript: 5.7.2 3342 | v8-compile-cache-lib: 3.0.1 3343 | yn: 3.1.1 3344 | 3345 | tslib@2.8.1: {} 3346 | 3347 | type-detect@4.0.8: {} 3348 | 3349 | type-fest@0.21.3: {} 3350 | 3351 | typescript@5.7.2: {} 3352 | 3353 | ufo@1.5.4: {} 3354 | 3355 | undici@5.28.4: 3356 | dependencies: 3357 | '@fastify/busboy': 2.1.1 3358 | 3359 | unenv-nightly@2.0.0-20241204-140205-a5d5190: 3360 | dependencies: 3361 | defu: 6.1.4 3362 | ohash: 1.1.4 3363 | pathe: 1.1.2 3364 | ufo: 1.5.4 3365 | 3366 | update-browserslist-db@1.1.1(browserslist@4.24.3): 3367 | dependencies: 3368 | browserslist: 4.24.3 3369 | escalade: 3.2.0 3370 | picocolors: 1.1.1 3371 | 3372 | v8-compile-cache-lib@3.0.1: {} 3373 | 3374 | v8-to-istanbul@9.3.0: 3375 | dependencies: 3376 | '@jridgewell/trace-mapping': 0.3.25 3377 | '@types/istanbul-lib-coverage': 2.0.6 3378 | convert-source-map: 2.0.0 3379 | 3380 | walker@1.0.8: 3381 | dependencies: 3382 | makeerror: 1.0.12 3383 | 3384 | which@2.0.2: 3385 | dependencies: 3386 | isexe: 2.0.0 3387 | 3388 | workerd@1.20241205.0: 3389 | optionalDependencies: 3390 | '@cloudflare/workerd-darwin-64': 1.20241205.0 3391 | '@cloudflare/workerd-darwin-arm64': 1.20241205.0 3392 | '@cloudflare/workerd-linux-64': 1.20241205.0 3393 | '@cloudflare/workerd-linux-arm64': 1.20241205.0 3394 | '@cloudflare/workerd-windows-64': 1.20241205.0 3395 | 3396 | wrangler@3.95.0(@cloudflare/workers-types@4.20241205.0): 3397 | dependencies: 3398 | '@cloudflare/kv-asset-handler': 0.3.4 3399 | '@cloudflare/workers-shared': 0.11.0 3400 | '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) 3401 | '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) 3402 | blake3-wasm: 2.1.5 3403 | chokidar: 4.0.1 3404 | date-fns: 4.1.0 3405 | esbuild: 0.17.19 3406 | itty-time: 1.0.6 3407 | miniflare: 3.20241205.0 3408 | nanoid: 3.3.7 3409 | path-to-regexp: 6.3.0 3410 | resolve: 1.22.9 3411 | selfsigned: 2.4.1 3412 | source-map: 0.6.1 3413 | unenv: unenv-nightly@2.0.0-20241204-140205-a5d5190 3414 | workerd: 1.20241205.0 3415 | xxhash-wasm: 1.1.0 3416 | optionalDependencies: 3417 | '@cloudflare/workers-types': 4.20241205.0 3418 | fsevents: 2.3.3 3419 | transitivePeerDependencies: 3420 | - bufferutil 3421 | - supports-color 3422 | - utf-8-validate 3423 | 3424 | wrap-ansi@7.0.0: 3425 | dependencies: 3426 | ansi-styles: 4.3.0 3427 | string-width: 4.2.3 3428 | strip-ansi: 6.0.1 3429 | 3430 | wrappy@1.0.2: {} 3431 | 3432 | write-file-atomic@4.0.2: 3433 | dependencies: 3434 | imurmurhash: 0.1.4 3435 | signal-exit: 3.0.7 3436 | 3437 | ws@8.18.0: {} 3438 | 3439 | xxhash-wasm@1.1.0: {} 3440 | 3441 | y18n@5.0.8: {} 3442 | 3443 | yallist@3.1.1: {} 3444 | 3445 | yaml@2.6.1: {} 3446 | 3447 | yargs-parser@21.1.1: {} 3448 | 3449 | yargs@17.7.2: 3450 | dependencies: 3451 | cliui: 8.0.1 3452 | escalade: 3.2.0 3453 | get-caller-file: 2.0.5 3454 | require-directory: 2.1.1 3455 | string-width: 4.2.3 3456 | y18n: 5.0.8 3457 | yargs-parser: 21.1.1 3458 | 3459 | yn@3.1.1: {} 3460 | 3461 | yocto-queue@0.1.0: {} 3462 | 3463 | youch@3.3.4: 3464 | dependencies: 3465 | cookie: 0.7.2 3466 | mustache: 4.2.0 3467 | stacktracey: 2.1.8 3468 | 3469 | zod@3.24.1: {} 3470 | -------------------------------------------------------------------------------- /src/application/endpoints/documentEndpoints.ts: -------------------------------------------------------------------------------- 1 | import { Context } from 'hono' 2 | import { DocumentService } from '../../services/documentService' 3 | 4 | export class DocumentEndpoints { 5 | constructor(private service: DocumentService) {} 6 | 7 | indexDocument = async (c: Context) => { 8 | try { 9 | const document = await c.req.json() 10 | const documentId = await this.service.indexDocument(document) 11 | return c.json({ id: documentId }, 200 as const) 12 | } catch (error) { 13 | return c.json({ error: error instanceof Error ? error.message : 'Unknown error' }, 400 as const) 14 | } 15 | } 16 | 17 | getDocument = async (c: Context) => { 18 | try { 19 | const { id } = c.req.param() 20 | const document = await this.service.getDocument(id) 21 | if (!document) { 22 | return c.json({ error: 'Document not found' }, 404 as const) 23 | } 24 | return c.json(document, 200 as const) 25 | } catch (error) { 26 | return c.json({ error: error instanceof Error ? error.message : 'Unknown error' }, 404 as const) 27 | } 28 | } 29 | 30 | deleteDocument = async (c: Context) => { 31 | try { 32 | const { id } = c.req.param() 33 | const deleted = await this.service.deleteDocument(id) 34 | if (!deleted) { 35 | return c.json({ error: 'Document not found' }, 404 as const) 36 | } 37 | return c.json({ success: true }, 200 as const) 38 | } catch (error) { 39 | return c.json({ error: error instanceof Error ? error.message : 'Unknown error' }, 400 as const) 40 | } 41 | } 42 | 43 | searchDocuments = async (c: Context) => { 44 | try { 45 | const { query, limit } = await c.req.json() 46 | if (!query) { 47 | return c.json({ error: 'Query is required' }, 400 as const) 48 | } 49 | const results = await this.service.searchDocuments(query, limit) 50 | return c.json({ results }, 200 as const) 51 | } catch (error) { 52 | return c.json({ error: error instanceof Error ? error.message : 'Unknown error' }, 400 as const) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/domain/document.ts: -------------------------------------------------------------------------------- 1 | export interface Document { 2 | id: string 3 | text: string 4 | metadata?: Record 5 | } 6 | 7 | export interface SearchQuery { 8 | query: string 9 | limit?: number 10 | } 11 | 12 | export interface SearchResult { 13 | document: Document 14 | score: number 15 | } 16 | 17 | export interface DocumentRepository { 18 | save(indexName: string, document: Document): Promise 19 | findById(indexName: string, id: string): Promise 20 | delete(indexName: string, id: string): Promise 21 | search(indexName: string, query: SearchQuery): Promise 22 | } 23 | -------------------------------------------------------------------------------- /src/domain/documentRepository.ts: -------------------------------------------------------------------------------- 1 | import { Document } from './document' 2 | 3 | export interface DocumentRepository { 4 | indexDocument(document: Document): Promise 5 | getDocument(id: string): Promise 6 | deleteDocuments(ids: string[]): Promise 7 | deleteDocument(id: string): Promise 8 | searchDocuments(query: string, limit?: number): Promise> 9 | } 10 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { OpenAPIHono } from '@hono/zod-openapi' 2 | import { cors } from 'hono/cors' 3 | import { swaggerUI } from '@hono/swagger-ui' 4 | import { createRoute } from '@hono/zod-openapi' 5 | import { z } from 'zod' 6 | import { DocumentEndpoints } from './application/endpoints/documentEndpoints' 7 | import { DocumentService } from './services/documentService' 8 | import { CloudflareDocumentRepository } from './infrastructure/semanticSearch/cloudflareDocumentRepository' 9 | import { auth } from './middleware/auth' 10 | import { Env } from './types' 11 | 12 | const app = new OpenAPIHono<{ Bindings: Env }>() 13 | 14 | const createDependencies = (env: Env) => { 15 | const repository = new CloudflareDocumentRepository(env) 16 | const service = new DocumentService(repository) 17 | return new DocumentEndpoints(service) 18 | } 19 | 20 | app.use('/*', cors()) 21 | 22 | app.use('/v1/*', auth()) 23 | 24 | const documentSchema = z.object({ 25 | id: z.string().optional(), 26 | text: z.string(), 27 | metadata: z.record(z.any()).optional() 28 | }) 29 | 30 | const searchQuerySchema = z.object({ 31 | query: z.string(), 32 | limit: z.number().optional() 33 | }) 34 | 35 | const searchResultSchema = z.object({ 36 | results: z.array(z.object({ 37 | document: documentSchema, 38 | score: z.number() 39 | })) 40 | }) 41 | 42 | const indexRoute = createRoute({ 43 | method: 'post', 44 | path: '/v1/documents', 45 | request: { 46 | body: { 47 | content: { 48 | 'application/json': { 49 | schema: documentSchema 50 | } 51 | } 52 | } 53 | }, 54 | responses: { 55 | 200: { 56 | content: { 57 | 'application/json': { 58 | schema: z.object({ 59 | id: z.string() 60 | }) 61 | } 62 | }, 63 | description: 'Document indexed successfully' 64 | }, 65 | 400: { 66 | content: { 67 | 'application/json': { 68 | schema: z.object({ 69 | error: z.string() 70 | }) 71 | } 72 | }, 73 | description: 'Bad request' 74 | } 75 | } 76 | }) 77 | 78 | const getDocumentRoute = createRoute({ 79 | method: 'get', 80 | path: '/v1/documents/:id', 81 | request: { 82 | params: z.object({ 83 | id: z.string() 84 | }) 85 | }, 86 | responses: { 87 | 200: { 88 | content: { 89 | 'application/json': { 90 | schema: documentSchema 91 | } 92 | }, 93 | description: 'Document retrieved successfully' 94 | }, 95 | 404: { 96 | content: { 97 | 'application/json': { 98 | schema: z.object({ 99 | error: z.string() 100 | }) 101 | } 102 | }, 103 | description: 'Document not found' 104 | } 105 | } 106 | }) 107 | 108 | const deleteDocumentRoute = createRoute({ 109 | method: 'delete', 110 | path: '/v1/documents/:id', 111 | request: { 112 | params: z.object({ 113 | id: z.string() 114 | }) 115 | }, 116 | responses: { 117 | 200: { 118 | content: { 119 | 'application/json': { 120 | schema: z.object({ 121 | success: z.boolean() 122 | }) 123 | } 124 | }, 125 | description: 'Document deleted successfully' 126 | }, 127 | 404: { 128 | content: { 129 | 'application/json': { 130 | schema: z.object({ 131 | error: z.string() 132 | }) 133 | } 134 | }, 135 | description: 'Document not found' 136 | }, 137 | 400: { 138 | content: { 139 | 'application/json': { 140 | schema: z.object({ 141 | error: z.string() 142 | }) 143 | } 144 | }, 145 | description: 'Bad request' 146 | } 147 | } 148 | }) 149 | 150 | const searchRoute = createRoute({ 151 | method: 'post', 152 | path: '/v1/search', 153 | request: { 154 | body: { 155 | content: { 156 | 'application/json': { 157 | schema: searchQuerySchema 158 | } 159 | } 160 | } 161 | }, 162 | responses: { 163 | 200: { 164 | content: { 165 | 'application/json': { 166 | schema: searchResultSchema 167 | } 168 | }, 169 | description: 'Search completed successfully' 170 | }, 171 | 400: { 172 | content: { 173 | 'application/json': { 174 | schema: z.object({ 175 | error: z.string() 176 | }) 177 | } 178 | }, 179 | description: 'Bad request' 180 | } 181 | } 182 | }) 183 | 184 | app.openapi(indexRoute, async (c) => { 185 | const currentEnv = c.env 186 | const documentEndpoints = createDependencies(currentEnv) 187 | const result = await documentEndpoints.indexDocument(c) 188 | return result 189 | }) 190 | 191 | app.openapi(getDocumentRoute, async (c) => { 192 | const currentEnv = c.env 193 | const documentEndpoints = createDependencies(currentEnv) 194 | const result = await documentEndpoints.getDocument(c) 195 | return result 196 | }) 197 | 198 | app.openapi(deleteDocumentRoute, async (c) => { 199 | const currentEnv = c.env 200 | const documentEndpoints = createDependencies(currentEnv) 201 | const result = await documentEndpoints.deleteDocument(c) 202 | return result 203 | }) 204 | 205 | app.openapi(searchRoute, async (c) => { 206 | const currentEnv = c.env 207 | const documentEndpoints = createDependencies(currentEnv) 208 | const result = await documentEndpoints.searchDocuments(c) 209 | return result 210 | }) 211 | 212 | // Add Swagger UI 213 | app.doc('/swagger.json', { 214 | openapi: '3.0.0', 215 | info: { 216 | title: 'Semantic Search API', 217 | version: '1.0.0', 218 | description: 'API for semantic search functionality' 219 | } 220 | }) 221 | 222 | app.get('/', swaggerUI({ url: '/swagger.json' })) 223 | 224 | export default app 225 | -------------------------------------------------------------------------------- /src/infrastructure/semanticSearch/__tests__/cloudflareAdapter.test.ts: -------------------------------------------------------------------------------- 1 | import { CloudflareSemanticSearchAdapter } from '../cloudflareAdapter' 2 | import { Env } from '../../../types' 3 | 4 | describe('CloudflareSemanticSearchAdapter', () => { 5 | let adapter: CloudflareSemanticSearchAdapter 6 | let mockEnv: jest.Mocked 7 | 8 | beforeEach(() => { 9 | mockEnv = { 10 | VECTORIZE: { 11 | insert: jest.fn(), 12 | upsert: jest.fn(), 13 | query: jest.fn(), 14 | getByIds: jest.fn(), 15 | deleteByIds: jest.fn() 16 | } as any, 17 | AI: { 18 | run: jest.fn() 19 | } as any 20 | } as jest.Mocked 21 | 22 | adapter = new CloudflareSemanticSearchAdapter(mockEnv) 23 | 24 | }) 25 | 26 | describe('generateEmbedding', () => { 27 | it('should generate embedding for text', async () => { 28 | const text = 'test text' 29 | const embedding = [0.1, 0.2, 0.3] 30 | const mockRun = mockEnv.AI.run as jest.Mock 31 | mockRun.mockResolvedValue({ data: [embedding] }) 32 | 33 | const result = await adapter.generateEmbedding(text) 34 | 35 | expect(result).toEqual(embedding) 36 | expect(mockRun).toHaveBeenCalledWith('@cf/baai/bge-small-en-v1.5', { text: [text] }) 37 | }) 38 | 39 | it('should handle invalid AI response', async () => { 40 | const mockRun = mockEnv.AI.run as jest.Mock 41 | mockRun.mockResolvedValue({ data: 'invalid' }) 42 | 43 | const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) 44 | 45 | await expect(adapter.generateEmbedding('test')).rejects.toThrow('Invalid response from AI.run') 46 | 47 | consoleErrorSpy.mockRestore() 48 | }) 49 | }) 50 | 51 | describe('upsertVector', () => { 52 | it('should upsert vector with metadata', async () => { 53 | const mockUpsert = mockEnv.VECTORIZE.upsert as jest.Mock 54 | mockUpsert.mockResolvedValue(undefined) 55 | 56 | const id = 'test-id' 57 | const vector = [0.1, 0.2, 0.3] 58 | const metadata = { key: 'value' } 59 | 60 | await adapter.upsertVector(id, vector, metadata) 61 | 62 | expect(mockUpsert).toHaveBeenCalledWith([{ 63 | id, 64 | values: vector, 65 | metadata 66 | }]) 67 | }) 68 | 69 | it('should handle upsert errors', async () => { 70 | const mockUpsert = mockEnv.VECTORIZE.upsert as jest.Mock 71 | mockUpsert.mockRejectedValue(new Error('Upsert error')) 72 | 73 | const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) 74 | 75 | await expect(adapter.upsertVector('test-id', [0.1])).rejects.toThrow('Failed to upsert vector') 76 | 77 | consoleErrorSpy.mockRestore() 78 | }) 79 | }) 80 | 81 | describe('deleteVector', () => { 82 | it('should delete vector by id', async () => { 83 | const mockDeleteByIds = mockEnv.VECTORIZE.deleteByIds as jest.Mock 84 | mockDeleteByIds.mockResolvedValue(undefined) 85 | 86 | await adapter.deleteVector('test-id') 87 | 88 | expect(mockDeleteByIds).toHaveBeenCalledWith(['test-id']) 89 | }) 90 | 91 | it('should handle delete errors', async () => { 92 | const mockDeleteByIds = mockEnv.VECTORIZE.deleteByIds as jest.Mock 93 | mockDeleteByIds.mockRejectedValue(new Error('Delete error')) 94 | 95 | await expect(adapter.deleteVector('test-id')).rejects.toThrow('Failed to delete vector') 96 | }) 97 | }) 98 | 99 | describe('queryById', () => { 100 | it('should return vector by id', async () => { 101 | const vector = { 102 | id: 'test-id', 103 | values: [0.1, 0.2, 0.3], 104 | metadata: { key: 'value' } 105 | } 106 | const mockGetByIds = mockEnv.VECTORIZE.getByIds as jest.Mock 107 | mockGetByIds.mockResolvedValue([vector]) 108 | 109 | const result = await adapter.queryById('test-id') 110 | 111 | expect(result).toEqual({ 112 | id: vector.id, 113 | score: 1.0, 114 | metadata: vector.metadata 115 | }) 116 | expect(mockGetByIds).toHaveBeenCalledWith(['test-id']) 117 | }) 118 | 119 | it('should return null if vector not found', async () => { 120 | const mockGetByIds = mockEnv.VECTORIZE.getByIds as jest.Mock 121 | mockGetByIds.mockResolvedValue([]) 122 | 123 | const result = await adapter.queryById('test-id') 124 | 125 | expect(result).toBeNull() 126 | expect(mockGetByIds).toHaveBeenCalledWith(['test-id']) 127 | }) 128 | 129 | it('should handle query errors', async () => { 130 | const mockGetByIds = mockEnv.VECTORIZE.getByIds as jest.Mock 131 | mockGetByIds.mockRejectedValue(new Error('Query error')) 132 | 133 | const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) 134 | 135 | await expect(adapter.queryById('test-id')).rejects.toThrow('Failed to query vector by ID') 136 | 137 | consoleErrorSpy.mockRestore() 138 | }) 139 | }) 140 | 141 | describe('query', () => { 142 | it('should query vectors with limit', async () => { 143 | const queryVector = [0.1, 0.2, 0.3] 144 | const matches = [ 145 | { id: 'id1', score: 0.9, metadata: { key: 'value1' } }, 146 | { id: 'id2', score: 0.8, metadata: { key: 'value2' } } 147 | ] 148 | const mockQuery = mockEnv.VECTORIZE.query as jest.Mock 149 | mockQuery.mockResolvedValue({ matches }) 150 | 151 | const result = await adapter.query(queryVector, 2) 152 | 153 | expect(result).toEqual(matches) 154 | expect(mockQuery).toHaveBeenCalledWith(queryVector, { topK: 2, returnMetadata: "all" }) 155 | }) 156 | 157 | it('should handle query errors', async () => { 158 | const mockQuery = mockEnv.VECTORIZE.query as jest.Mock 159 | mockQuery.mockRejectedValue(new Error('Query error')) 160 | 161 | const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) 162 | 163 | await expect(adapter.query([0.1])).rejects.toThrow('Failed to query vectors') 164 | 165 | consoleErrorSpy.mockRestore() 166 | }) 167 | }) 168 | }) 169 | -------------------------------------------------------------------------------- /src/infrastructure/semanticSearch/__tests__/cloudflareDocumentRepository.test.ts: -------------------------------------------------------------------------------- 1 | import { CloudflareDocumentRepository } from '../cloudflareDocumentRepository' 2 | import { CloudflareSemanticSearchAdapter } from '../cloudflareAdapter' 3 | import { Document } from '../../../domain/document' 4 | import { Env } from '../../../types' 5 | 6 | jest.mock('../cloudflareAdapter') 7 | 8 | describe('CloudflareDocumentRepository', () => { 9 | let repository: CloudflareDocumentRepository 10 | let mockAdapter: CloudflareSemanticSearchAdapter 11 | 12 | beforeEach(() => { 13 | mockAdapter = new CloudflareSemanticSearchAdapter({} as Env) 14 | jest.spyOn(mockAdapter, 'generateEmbedding').mockImplementation(jest.fn()) 15 | jest.spyOn(mockAdapter, 'upsertVector').mockImplementation(jest.fn()) 16 | jest.spyOn(mockAdapter, 'deleteByIds').mockImplementation(jest.fn()) 17 | jest.spyOn(mockAdapter, 'query').mockImplementation(jest.fn()) 18 | jest.spyOn(mockAdapter, 'queryById').mockImplementation(jest.fn()) 19 | 20 | repository = new CloudflareDocumentRepository(mockAdapter) 21 | }) 22 | 23 | describe('indexDocument', () => { 24 | it('should index document and return id', async () => { 25 | const document: Document = { 26 | id: 'test-id', 27 | text: 'test text' 28 | } 29 | 30 | const embedding = [0.1, 0.2, 0.3] 31 | jest.spyOn(mockAdapter, 'generateEmbedding').mockResolvedValue(embedding) 32 | 33 | const result = await repository.indexDocument(document) 34 | 35 | expect(result).toBe(document.id) 36 | expect(mockAdapter.generateEmbedding).toHaveBeenCalledWith(document.text) 37 | expect(mockAdapter.upsertVector).toHaveBeenCalledWith(document.id, embedding, { 38 | _ss_text: document.text 39 | }) 40 | }) 41 | 42 | it('should handle adapter errors', async () => { 43 | const document: Document = { 44 | id: 'test-id', 45 | text: 'test text' 46 | } 47 | 48 | const error = new Error('Adapter error') 49 | jest.spyOn(mockAdapter, 'generateEmbedding').mockRejectedValue(error) 50 | 51 | await expect(repository.indexDocument(document)).rejects.toThrow('Adapter error') 52 | }) 53 | }) 54 | 55 | describe('getDocument', () => { 56 | it('should return document if exists', async () => { 57 | const document = { 58 | id: 'test-id', 59 | text: 'test text' 60 | } 61 | 62 | ;(mockAdapter.queryById as jest.Mock).mockResolvedValue({ 63 | id: document.id, 64 | score: 1, 65 | metadata: { 66 | _ss_text: document.text 67 | } 68 | }) 69 | 70 | const result = await repository.getDocument(document.id) 71 | expect(result).toEqual({ 72 | id: document.id, 73 | text: document.text, 74 | metadata: {} 75 | }) 76 | expect(mockAdapter.queryById).toHaveBeenCalledWith(document.id) 77 | }) 78 | 79 | it('should return null if document does not exist', async () => { 80 | jest.spyOn(mockAdapter, 'queryById').mockResolvedValue(null) 81 | 82 | const result = await repository.getDocument('non-existent-id') 83 | expect(result).toBeNull() 84 | expect(mockAdapter.queryById).toHaveBeenCalledWith('non-existent-id') 85 | }) 86 | }) 87 | 88 | describe('deleteDocument', () => { 89 | it('should delete document and return true', async () => { 90 | const document = { id: 'test-id', text: 'test text' } 91 | ;(mockAdapter.deleteByIds as jest.Mock).mockResolvedValue(undefined) 92 | 93 | const result = await repository.deleteDocument(document.id) 94 | 95 | expect(result).toBe(true) 96 | expect(mockAdapter.deleteByIds).toHaveBeenCalledWith([document.id]) 97 | }) 98 | 99 | it('should return false if adapter throws error', async () => { 100 | ;(mockAdapter.deleteByIds as jest.Mock).mockRejectedValue(new Error('Delete error')) 101 | const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) 102 | 103 | const result = await repository.deleteDocument('non-existent-id') 104 | expect(result).toBe(false) 105 | expect(mockAdapter.deleteByIds).toHaveBeenCalledWith(['non-existent-id']) 106 | 107 | consoleErrorSpy.mockRestore() 108 | }) 109 | }) 110 | 111 | describe('searchDocuments', () => { 112 | it('should search documents and return results', async () => { 113 | const documents = [ 114 | { id: 'doc1', text: 'first document' }, 115 | { id: 'doc2', text: 'second document' } 116 | ] 117 | 118 | const queryEmbedding = [0.1, 0.2, 0.3] 119 | jest.spyOn(mockAdapter, 'generateEmbedding').mockResolvedValue(queryEmbedding) 120 | 121 | ;(mockAdapter.query as jest.Mock).mockResolvedValue([ 122 | { 123 | id: documents[0].id, 124 | score: 0.9, 125 | metadata: { 126 | _ss_text: documents[0].text 127 | } 128 | }, 129 | { 130 | id: documents[1].id, 131 | score: 0.8, 132 | metadata: { 133 | _ss_text: documents[1].text 134 | } 135 | } 136 | ]) 137 | 138 | const results = await repository.searchDocuments('search query', 2) 139 | 140 | expect(mockAdapter.generateEmbedding).toHaveBeenCalledWith('search query') 141 | expect(mockAdapter.query).toHaveBeenCalledWith(queryEmbedding, 2) 142 | expect(results).toHaveLength(2) 143 | expect(results[0]).toEqual({ 144 | document: { 145 | id: documents[0].id, 146 | text: documents[0].text, 147 | metadata: {} 148 | }, 149 | score: 0.9 150 | }) 151 | expect(results[1]).toEqual({ 152 | document: { 153 | id: documents[1].id, 154 | text: documents[1].text, 155 | metadata: {} 156 | }, 157 | score: 0.8 158 | }) 159 | }) 160 | 161 | it('should handle adapter errors', async () => { 162 | const error = new Error('Search error') 163 | jest.spyOn(mockAdapter, 'generateEmbedding').mockRejectedValue(error) 164 | 165 | const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) 166 | 167 | await expect(repository.searchDocuments('search query')).rejects.toThrow('Search error') 168 | 169 | consoleErrorSpy.mockRestore() 170 | }) 171 | }) 172 | }) 173 | -------------------------------------------------------------------------------- /src/infrastructure/semanticSearch/cloudflareAdapter.ts: -------------------------------------------------------------------------------- 1 | import { Env } from '../../types' 2 | 3 | interface VectorizeMatch { 4 | id: string 5 | score: number 6 | metadata?: Record 7 | } 8 | 9 | export class CloudflareSemanticSearchAdapter { 10 | private readonly env: Env 11 | private readonly modelName = '@cf/baai/bge-small-en-v1.5' 12 | private readonly dimension = 384 // bge-small-en-v1.5 embedding dimension 13 | 14 | constructor(env: Env) { 15 | this.env = env 16 | } 17 | 18 | async generateEmbedding(text: string): Promise { 19 | try { 20 | if (typeof this.env.AI.run !== 'function') { 21 | throw new Error(`AI.run is not a function. AI binding type: ${typeof this.env.AI}, available properties: ${Object.keys(this.env.AI)}`) 22 | } 23 | 24 | const response = await this.env.AI.run(this.modelName, { text: [text] }) 25 | 26 | if (!response || !response.data || !Array.isArray(response.data)) { 27 | throw new Error(`Invalid response from AI.run: ${JSON.stringify(response)}`) 28 | } 29 | 30 | return response.data[0] 31 | } catch (error) { 32 | console.error('Embedding generation error:', error) 33 | const message = error instanceof Error 34 | ? `${error.message}\n${error.stack}` 35 | : String(error) 36 | throw new Error(`Failed to generate embedding: ${message}`) 37 | } 38 | } 39 | 40 | async upsertVector(id: string, vector: number[], metadata?: Record): Promise { 41 | try { 42 | await this.env.VECTORIZE.upsert([{ 43 | id, 44 | values: vector, 45 | metadata 46 | }]) 47 | } catch (error) { 48 | throw new Error(`Failed to upsert vector: ${error instanceof Error ? error.message : String(error)}`) 49 | } 50 | } 51 | 52 | async deleteByIds(ids: string[]): Promise { 53 | try { 54 | await this.env.VECTORIZE.deleteByIds(ids) 55 | } catch (error) { 56 | throw new Error(`Failed to delete vectors: ${error instanceof Error ? error.message : String(error)}`) 57 | } 58 | } 59 | 60 | async deleteVector(id: string): Promise { 61 | try { 62 | await this.deleteByIds([id]) 63 | } catch (error) { 64 | throw new Error(`Failed to delete vector: ${error instanceof Error ? error.message : String(error)}`) 65 | } 66 | } 67 | 68 | async queryById(id: string): Promise { 69 | try { 70 | const result = await this.env.VECTORIZE.getByIds([id]) 71 | if (!result || !Array.isArray(result) || result.length === 0) { 72 | return null 73 | } 74 | const vector = result[0] 75 | return { 76 | id: vector.id, 77 | score: 1.0, // For getByIds, we return perfect score since it's an exact match 78 | metadata: vector.metadata 79 | } 80 | } catch (error) { 81 | throw new Error(`Failed to query vector by ID: ${error instanceof Error ? error.message : String(error)}`) 82 | } 83 | } 84 | 85 | async query(queryVector: number[], limit: number = 10): Promise { 86 | try { 87 | const result = await this.env.VECTORIZE.query(queryVector, { topK: limit, returnMetadata: "all" }) 88 | return result.matches 89 | } catch (error) { 90 | throw new Error(`Failed to query vectors: ${error instanceof Error ? error.message : String(error)}`) 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/infrastructure/semanticSearch/cloudflareDocumentRepository.ts: -------------------------------------------------------------------------------- 1 | import { Document } from '../../domain/document' 2 | import { DocumentRepository } from '../../domain/documentRepository' 3 | import { Env } from '../../types' 4 | import { CloudflareSemanticSearchAdapter } from './cloudflareAdapter' 5 | 6 | export class CloudflareDocumentRepository implements DocumentRepository { 7 | private readonly adapter: CloudflareSemanticSearchAdapter 8 | 9 | constructor(envOrAdapter: Env | CloudflareSemanticSearchAdapter) { 10 | this.adapter = envOrAdapter instanceof CloudflareSemanticSearchAdapter 11 | ? envOrAdapter 12 | : new CloudflareSemanticSearchAdapter(envOrAdapter) 13 | } 14 | 15 | async indexDocument(document: Document): Promise { 16 | // Generate embedding for the document 17 | const embedding = await this.adapter.generateEmbedding(document.text) 18 | 19 | // Prepare flattened metadata with _ss_text 20 | const flatMetadata = { 21 | _ss_text: document.text, 22 | ...document.metadata 23 | } 24 | 25 | // Store document in vector store 26 | await this.adapter.upsertVector(document.id, embedding, flatMetadata) 27 | 28 | return document.id 29 | } 30 | 31 | async deleteDocuments(ids: string[]): Promise { 32 | try { 33 | await this.adapter.deleteByIds(ids) 34 | return ids.map(() => true) 35 | } catch (error) { 36 | // eslint-disable-next-line no-console 37 | console.error('Error deleting documents:', error) 38 | return ids.map(() => false) 39 | } 40 | } 41 | 42 | async deleteDocument(id: string): Promise { 43 | const results = await this.deleteDocuments([id]) 44 | return results[0] 45 | } 46 | 47 | async getDocument(id: string): Promise { 48 | const result = await this.adapter.queryById(id) 49 | if (!result || !result.metadata) { 50 | return null 51 | } 52 | 53 | const { _ss_text, ...metadata } = result.metadata 54 | return { 55 | id: result.id, 56 | text: _ss_text, 57 | metadata 58 | } 59 | } 60 | 61 | async searchDocuments(query: string, limit?: number): Promise> { 62 | // Generate embedding for the query 63 | const queryEmbedding = await this.adapter.generateEmbedding(query) 64 | 65 | // Search for similar documents 66 | const matches = await this.adapter.query(queryEmbedding, limit) 67 | 68 | // Map results to documents 69 | return matches.map(match => { 70 | if (!match.metadata) { 71 | return { 72 | document: { 73 | id: match.id, 74 | text: '', 75 | metadata: {} 76 | }, 77 | score: match.score 78 | } 79 | } 80 | const { _ss_text, ...metadata } = match.metadata 81 | return { 82 | document: { 83 | id: match.id, 84 | text: _ss_text, 85 | metadata 86 | }, 87 | score: match.score 88 | } 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/middleware/__tests__/auth.test.ts: -------------------------------------------------------------------------------- 1 | import { Context } from 'hono' 2 | import { auth } from '../auth' 3 | 4 | describe('Auth Middleware', () => { 5 | let mockContext: Partial 6 | const env = { API_KEY: 'test-api-key' } 7 | 8 | beforeEach(() => { 9 | mockContext = { 10 | env, 11 | req: { 12 | header: jest.fn() 13 | } as any, 14 | json: jest.fn(), 15 | } 16 | }) 17 | 18 | it('should allow request with valid bearer token', async () => { 19 | ;(mockContext.req!.header as jest.Mock).mockReturnValue(`Bearer ${env.API_KEY}`) 20 | const next = jest.fn() 21 | 22 | await auth()(mockContext as Context, next) 23 | 24 | expect(next).toHaveBeenCalled() 25 | expect(mockContext.json).not.toHaveBeenCalled() 26 | }) 27 | 28 | it('should reject request with invalid bearer token', async () => { 29 | ;(mockContext.req!.header as jest.Mock).mockReturnValue('Bearer invalid-token') 30 | const next = jest.fn() 31 | 32 | await auth()(mockContext as Context, next) 33 | 34 | expect(next).not.toHaveBeenCalled() 35 | expect(mockContext.json).toHaveBeenCalledWith( 36 | { error: 'Unauthorized' }, 37 | 401 38 | ) 39 | }) 40 | 41 | it('should reject request with missing authorization header', async () => { 42 | ;(mockContext.req!.header as jest.Mock).mockReturnValue(null) 43 | const next = jest.fn() 44 | 45 | await auth()(mockContext as Context, next) 46 | 47 | expect(next).not.toHaveBeenCalled() 48 | expect(mockContext.json).toHaveBeenCalledWith( 49 | { error: 'Unauthorized' }, 50 | 401 51 | ) 52 | }) 53 | 54 | it('should reject request with non-bearer authorization', async () => { 55 | ;(mockContext.req!.header as jest.Mock).mockReturnValue('Basic sometoken') 56 | const next = jest.fn() 57 | 58 | await auth()(mockContext as Context, next) 59 | 60 | expect(next).not.toHaveBeenCalled() 61 | expect(mockContext.json).toHaveBeenCalledWith( 62 | { error: 'Unauthorized' }, 63 | 401 64 | ) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /src/middleware/auth.ts: -------------------------------------------------------------------------------- 1 | import { Context, MiddlewareHandler } from 'hono' 2 | 3 | export const auth = (): MiddlewareHandler => { 4 | return async (c: Context, next) => { 5 | const authHeader = c.req.header('Authorization') 6 | 7 | if (!authHeader) { 8 | return c.json({ error: 'Unauthorized' }, 401) 9 | } 10 | 11 | const [scheme, token] = authHeader.split(' ') 12 | 13 | if (scheme !== 'Bearer') { 14 | return c.json({ error: 'Unauthorized' }, 401) 15 | } 16 | 17 | const apiKey = c.env.API_KEY 18 | if (!apiKey || token !== apiKey) { 19 | return c.json({ error: 'Unauthorized' }, 401) 20 | } 21 | 22 | await next() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/services/__tests__/documentService.test.ts: -------------------------------------------------------------------------------- 1 | import { DocumentService } from '../documentService' 2 | import { Document } from '../../domain/document' 3 | import { DocumentRepository } from '../../domain/documentRepository' 4 | 5 | describe('DocumentService', () => { 6 | let service: DocumentService 7 | let mockRepository: jest.Mocked 8 | 9 | beforeEach(() => { 10 | mockRepository = { 11 | indexDocument: jest.fn(), 12 | getDocument: jest.fn(), 13 | deleteDocument: jest.fn(), 14 | deleteDocuments: jest.fn(), 15 | searchDocuments: jest.fn() 16 | } 17 | service = new DocumentService(mockRepository) 18 | }) 19 | 20 | describe('indexDocument', () => { 21 | it('should index document with generated id', async () => { 22 | const data = { 23 | text: 'test document' 24 | } 25 | 26 | mockRepository.indexDocument.mockResolvedValue('generated-id') 27 | 28 | const id = await service.indexDocument(data) 29 | 30 | expect(id).toBe('generated-id') 31 | expect(mockRepository.indexDocument).toHaveBeenCalledWith(expect.objectContaining({ 32 | text: data.text 33 | })) 34 | }) 35 | 36 | it('should use provided id if available', async () => { 37 | const data = { 38 | id: 'custom-id', 39 | text: 'test document' 40 | } 41 | 42 | mockRepository.indexDocument.mockResolvedValue(data.id) 43 | 44 | const id = await service.indexDocument(data) 45 | 46 | expect(id).toBe(data.id) 47 | expect(mockRepository.indexDocument).toHaveBeenCalledWith(expect.objectContaining({ 48 | id: data.id, 49 | text: data.text 50 | })) 51 | }) 52 | 53 | it('should throw error if text is missing', async () => { 54 | const data = { 55 | id: 'test-id' 56 | } 57 | 58 | await expect(service.indexDocument(data)).rejects.toThrow('Document text is required') 59 | expect(mockRepository.indexDocument).not.toHaveBeenCalled() 60 | }) 61 | }) 62 | 63 | describe('getDocument', () => { 64 | it('should return document if exists', async () => { 65 | const document: Document = { 66 | id: 'test-id', 67 | text: 'test document' 68 | } 69 | 70 | mockRepository.getDocument.mockResolvedValue(document) 71 | 72 | const result = await service.getDocument('test-id') 73 | 74 | expect(result).toEqual(document) 75 | expect(mockRepository.getDocument).toHaveBeenCalledWith('test-id') 76 | }) 77 | 78 | it('should return null if document does not exist', async () => { 79 | mockRepository.getDocument.mockResolvedValue(null) 80 | 81 | const result = await service.getDocument('non-existent') 82 | 83 | expect(result).toBeNull() 84 | expect(mockRepository.getDocument).toHaveBeenCalledWith('non-existent') 85 | }) 86 | }) 87 | 88 | describe('deleteDocument', () => { 89 | it('should delete document and return true', async () => { 90 | mockRepository.deleteDocument.mockResolvedValue(true) 91 | 92 | const result = await service.deleteDocument('test-id') 93 | 94 | expect(result).toBe(true) 95 | expect(mockRepository.deleteDocument).toHaveBeenCalledWith('test-id') 96 | }) 97 | 98 | it('should return false if document does not exist', async () => { 99 | mockRepository.deleteDocument.mockResolvedValue(false) 100 | 101 | const result = await service.deleteDocument('non-existent') 102 | 103 | expect(result).toBe(false) 104 | expect(mockRepository.deleteDocument).toHaveBeenCalledWith('non-existent') 105 | }) 106 | }) 107 | 108 | describe('searchDocuments', () => { 109 | it('should search documents with limit', async () => { 110 | const documents = [ 111 | { id: 'doc1', text: 'first document' }, 112 | { id: 'doc2', text: 'second document' } 113 | ] 114 | 115 | const searchResults = documents.map((document, index) => ({ 116 | document, 117 | score: 1 - index * 0.1 118 | })) 119 | 120 | mockRepository.searchDocuments.mockResolvedValue(searchResults) 121 | 122 | const results = await service.searchDocuments('test query', 5) 123 | 124 | expect(results).toEqual(searchResults) 125 | expect(mockRepository.searchDocuments).toHaveBeenCalledWith('test query', 5) 126 | }) 127 | 128 | it('should search documents without limit', async () => { 129 | mockRepository.searchDocuments.mockResolvedValue([]) 130 | 131 | await service.searchDocuments('test query') 132 | 133 | expect(mockRepository.searchDocuments).toHaveBeenCalledWith('test query', undefined) 134 | }) 135 | }) 136 | }) 137 | -------------------------------------------------------------------------------- /src/services/documentService.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto' 2 | import { Document } from '../domain/document' 3 | import { DocumentRepository } from '../domain/documentRepository' 4 | 5 | export class DocumentService { 6 | constructor(private repository: DocumentRepository) {} 7 | 8 | async indexDocument(data: Partial): Promise { 9 | if (!data.text) { 10 | throw new Error('Document text is required') 11 | } 12 | 13 | const document: Document = { 14 | id: data.id || crypto.randomUUID(), 15 | text: data.text, 16 | metadata: data.metadata, 17 | } 18 | 19 | return await this.repository.indexDocument(document) 20 | } 21 | 22 | async getDocument(id: string): Promise { 23 | return await this.repository.getDocument(id) 24 | } 25 | 26 | async deleteDocuments(ids: string[]): Promise { 27 | return await this.repository.deleteDocuments(ids) 28 | } 29 | 30 | async deleteDocument(id: string): Promise { 31 | return await this.repository.deleteDocument(id) 32 | } 33 | 34 | async searchDocuments(query: string, limit?: number): Promise> { 35 | return await this.repository.searchDocuments(query, limit) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Env { 2 | AI: Ai; 3 | VECTORIZE: Vectorize; 4 | API_KEY: string; 5 | [key: string]: unknown; 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true, 5 | "baseUrl": "src", 6 | "declaration": true, 7 | "sourceMap": true, 8 | "esModuleInterop": true, 9 | "inlineSourceMap": false, 10 | "lib": ["es2021"], 11 | "listEmittedFiles": false, 12 | "listFiles": false, 13 | "moduleResolution": "node", 14 | "noFallthroughCasesInSwitch": true, 15 | "pretty": true, 16 | "resolveJsonModule": true, 17 | "rootDir": ".", 18 | "skipLibCheck": true, 19 | "strict": true, 20 | "traceResolution": false, 21 | "outDir": "", 22 | "target": "es2021", 23 | "module": "es2022", 24 | "jsx": "react", 25 | "types": [ 26 | "@cloudflare/workers-types", 27 | "jest", 28 | "@types/node" 29 | ], 30 | "checkJs": false, 31 | "noEmit": true, 32 | "isolatedModules": true, 33 | "forceConsistentCasingInFileNames": true 34 | }, 35 | "exclude": ["node_modules", "dist", "tests"], 36 | "include": ["src", "scripts"] 37 | } 38 | -------------------------------------------------------------------------------- /worker-configuration.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by Wrangler by running `wrangler types` 2 | 3 | interface Env { 4 | API_KEY: string; 5 | VECTORIZE: Vectorize; 6 | AI: Ai; 7 | } 8 | -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | #:schema node_modules/wrangler/config-schema.json 2 | name = "semanticsearch-demo" 3 | main = "src/index.ts" 4 | compatibility_date = "2024-12-05" 5 | compatibility_flags = ["nodejs_compat"] 6 | 7 | # Workers Logs 8 | # Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ 9 | # Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs 10 | [observability] 11 | enabled = true 12 | 13 | # Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) 14 | # Docs: 15 | # - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables 16 | # Note: Use secrets to store sensitive data. 17 | # - https://developers.cloudflare.com/workers/configuration/secrets/ 18 | 19 | [vars] 20 | API_KEY = "YOUR_API_KEY" 21 | 22 | # Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network 23 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai 24 | [ai] 25 | binding = "AI" 26 | 27 | # Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. 28 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes 29 | [[vectorize]] 30 | binding = "VECTORIZE" 31 | index_name = "semantic-search" 32 | 33 | # Automatically place your workloads in an optimal location to minimize latency. 34 | # If you are running back-end logic in a Worker, running it closer to your back-end infrastructure 35 | # rather than the end user may result in better performance. 36 | # Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement 37 | # [placement] 38 | # mode = "smart" 39 | 40 | # Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. 41 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets 42 | # [[analytics_engine_datasets]] 43 | # binding = "MY_DATASET" 44 | 45 | # Bind a headless browser instance running on Cloudflare's global network. 46 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering 47 | # [browser] 48 | # binding = "MY_BROWSER" 49 | 50 | # Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. 51 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases 52 | # [[d1_databases]] 53 | # binding = "MY_DB" 54 | # database_name = "my-database" 55 | # database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 56 | 57 | # Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. 58 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms 59 | # [[dispatch_namespaces]] 60 | # binding = "MY_DISPATCHER" 61 | # namespace = "my-namespace" 62 | 63 | # Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. 64 | # Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. 65 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects 66 | # [[durable_objects.bindings]] 67 | # name = "MY_DURABLE_OBJECT" 68 | # class_name = "MyDurableObject" 69 | 70 | # Durable Object migrations. 71 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations 72 | # [[migrations]] 73 | # tag = "v1" 74 | # new_classes = ["MyDurableObject"] 75 | 76 | # Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. 77 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive 78 | # [[hyperdrive]] 79 | # binding = "MY_HYPERDRIVE" 80 | # id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 81 | 82 | # Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. 83 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces 84 | # [[kv_namespaces]] 85 | # binding = "MY_KV_NAMESPACE" 86 | # id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 87 | 88 | # Bind an mTLS certificate. Use to present a client certificate when communicating with another service. 89 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates 90 | # [[mtls_certificates]] 91 | # binding = "MY_CERTIFICATE" 92 | # certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 93 | 94 | # Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. 95 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues 96 | # [[queues.producers]] 97 | # binding = "MY_QUEUE" 98 | # queue = "my-queue" 99 | 100 | # Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. 101 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues 102 | # [[queues.consumers]] 103 | # queue = "my-queue" 104 | 105 | # Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. 106 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets 107 | # [[r2_buckets]] 108 | # binding = "MY_BUCKET" 109 | # bucket_name = "my-bucket" 110 | 111 | # Bind another Worker service. Use this binding to call another Worker without network overhead. 112 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings 113 | # [[services]] 114 | # binding = "MY_SERVICE" 115 | # service = "my-service" 116 | --------------------------------------------------------------------------------