From fd066d1a943a9c470009b995421a4054c26cde9e Mon Sep 17 00:00:00 2001 From: madkarmaa Date: Sun, 22 Mar 2026 19:58:04 +0100 Subject: [PATCH 1/6] feat: add TypeScript client generation --- .gitignore | 1 + bun.lock | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++-- package.json | 6 ++-- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 71b026d2..3dc48fe7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules/ .dev.vars .env about.json +openapi-ts-error-*.log \ No newline at end of file diff --git a/bun.lock b/bun.lock index ba8ee245..44857dd5 100644 --- a/bun.lock +++ b/bun.lock @@ -13,6 +13,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20260317.1", + "@hey-api/openapi-ts": "0.94.4", "@kilianpaquier/semantic-release-backmerge": "^1.7.3", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", @@ -35,7 +36,7 @@ "@actions/io": ["@actions/io@3.0.2", "", {}, "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="], - "@asteasolutions/zod-to-openapi": ["@asteasolutions/zod-to-openapi@8.4.3", "", { "dependencies": { "openapi3-ts": "^4.1.2" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-lwfMTN7kDbFDwMniYZUebiGGHxVGBw9ZSI4IBYjm6Ey22Kd5z/fsQb2k+Okr8WMbCCC553vi/ZM9utl5/XcvuQ=="], + "@asteasolutions/zod-to-openapi": ["@asteasolutions/zod-to-openapi@8.5.0", "", { "dependencies": { "openapi3-ts": "^4.1.2" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-SABbKiObg5dLRiTFnqiW1WWwGcg1BJfmHtT2asIBnBHg6Smy/Ms2KHc650+JI4Hw7lSkdiNebEGXpwoxfben8Q=="], "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], @@ -121,9 +122,19 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@hey-api/codegen-core": ["@hey-api/codegen-core@0.7.4", "", { "dependencies": { "@hey-api/types": "0.1.4", "ansi-colors": "4.1.3", "c12": "3.3.3", "color-support": "1.1.3" } }, "sha512-DGd9yeSQzflOWO3Y5mt1GRXkXH9O/yIMgbxPjwLI3jwu/3nAjoXXD26lEeFb6tclYlg0JAqTIs5d930G/qxHeA=="], + + "@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.3.1", "", { "dependencies": { "@jsdevtools/ono": "7.1.3", "@types/json-schema": "7.0.15", "js-yaml": "4.1.1" } }, "sha512-7atnpUkT8TyUPHYPLk91j/GyaqMuwTEHanLOe50Dlx0EEvNuQqFD52Yjg8x4KU0UFL1mWlyhE+sUE/wAtQ1N2A=="], + + "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.94.4", "", { "dependencies": { "@hey-api/codegen-core": "0.7.4", "@hey-api/json-schema-ref-parser": "1.3.1", "@hey-api/shared": "0.2.5", "@hey-api/types": "0.1.4", "ansi-colors": "4.1.3", "color-support": "1.1.3", "commander": "14.0.3", "get-tsconfig": "4.13.6" }, "peerDependencies": { "typescript": ">=5.5.3 || 6.0.1-rc" }, "bin": { "openapi-ts": "bin/run.js" } }, "sha512-943f7wlLAQ0KHVx8CeD3xYJzBsCRQYtr+lgMYrAdfV48j32loqsqiMAM4fsMxvSO7mkz0lqcJkIb+YZIXO8Ubg=="], + + "@hey-api/shared": ["@hey-api/shared@0.2.5", "", { "dependencies": { "@hey-api/codegen-core": "0.7.4", "@hey-api/json-schema-ref-parser": "1.3.1", "@hey-api/types": "0.1.4", "ansi-colors": "4.1.3", "cross-spawn": "7.0.6", "open": "11.0.0", "semver": "7.7.3" } }, "sha512-NS57dHXxhwBtenPWAzljA0I493ZxzjcZZtr8KFr8SsLboofdjcAbVRFAfOQ0iv2JMhOe9oyiWEEc1QOJ/9WWaw=="], + + "@hey-api/types": ["@hey-api/types@0.1.4", "", {}, "sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg=="], + "@hono/swagger-ui": ["@hono/swagger-ui@0.6.1", "", { "peerDependencies": { "hono": ">=4.0.0" } }, "sha512-sJTvldu1GPeEPfyeLG7gRj+W4vEuD+JDi+JjJ3TJs/DvMUtBLs0KJO5yokGegWWdy5qrbdnQGekbhgNRmPmYKQ=="], - "@hono/zod-openapi": ["@hono/zod-openapi@1.2.2", "", { "dependencies": { "@asteasolutions/zod-to-openapi": "^8.4.1", "@hono/zod-validator": "^0.7.6", "openapi3-ts": "^4.5.0" }, "peerDependencies": { "hono": ">=4.3.6", "zod": "^4.0.0" } }, "sha512-va6vsL23wCJ1d0Vd+vGL1XOt+wPwItxirYafuhlW9iC2MstYr2FvsI7mctb45eBTjZfkqB/3LYDJEppPjOEiHw=="], + "@hono/zod-openapi": ["@hono/zod-openapi@1.2.3", "", { "dependencies": { "@asteasolutions/zod-to-openapi": "^8.5.0", "@hono/zod-validator": "^0.7.6", "openapi3-ts": "^4.5.0" }, "peerDependencies": { "hono": ">=4.3.6", "zod": "^4.0.0" } }, "sha512-zAviC3ApRAYGUiGWZiW/mrK/UBqkTi9BKQxn1IvwYyp2kS+k1tlnwut59DfEInpcsq1347zAYOqYI+obMy4vzQ=="], "@hono/zod-validator": ["@hono/zod-validator@0.7.6", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Io1B6d011Gj1KknV4rXYz4le5+5EubcWEU/speUjuw9XMMIaP3n78yXLhjd2A3PXaXaUwEAluOiAyLqhBEJgsw=="], @@ -183,6 +194,8 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], + "@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="], + "@kilianpaquier/semantic-release-backmerge": ["@kilianpaquier/semantic-release-backmerge@1.7.3", "", { "dependencies": { "@octokit/core": "7.0.6", "@semantic-release/error": "4.0.0", "aggregate-error": "5.0.0", "debug": "4.4.3", "execa": "9.6.1", "git-up": "8.1.1", "git-url-parse": "16.1.0", "lodash": "4.17.23", "node-fetch": "3.3.2", "semantic-release": "25.0.3", "semver": "7.7.4", "url-join": "5.0.0" } }, "sha512-H18O9omYVo925KF2sanfi5TnQ5Fh1jtsPIX7s+lC9CfWlWXJ4nywvCOY6ax+hYFZR/AFTG9zgHwD6AZL4HambA=="], "@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], @@ -243,6 +256,8 @@ "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], @@ -253,6 +268,8 @@ "aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], @@ -277,12 +294,20 @@ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], + + "c12": ["c12@3.3.3", "", { "dependencies": { "chokidar": "^5.0.0", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^17.2.3", "exsolve": "^1.0.8", "giget": "^2.0.0", "jiti": "^2.6.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "*" }, "optionalPeers": ["magicast"] }, "sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q=="], + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], + "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + + "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], + "clean-stack": ["clean-stack@5.3.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg=="], "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], @@ -295,10 +320,18 @@ "color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + "color-support": ["color-support@1.1.3", "", { "bin": { "color-support": "bin.js" } }, "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="], + + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], + "confbox": ["confbox@0.2.4", "", {}, "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ=="], + "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], + "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], + "conventional-changelog-angular": ["conventional-changelog-angular@8.2.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-4YB1zEXqB17oBI8yRsAs1T+ZhbdsOgJqkl6Trz+GXt/eKf1e4jnA0oW+sOd9BEENzEViuNW0DNoFFjSf3CeC5Q=="], "conventional-changelog-writer": ["conventional-changelog-writer@8.3.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", "semver": "^7.5.2" }, "bin": "dist/cli/index.js" }, "sha512-l5hDOHjcTUVtnZJapoqXMCJ3IbyF6oV/vnxKL13AHulFH7mDp4PMJARxI7LWzob6UDDvhxIUWGTNUPW84JabQg=="], @@ -325,12 +358,24 @@ "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], + "default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="], + + "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="], + + "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], + + "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], + + "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], + "dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="], + "drizzle-kit": ["drizzle-kit@0.31.10", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "tsx": "^4.21.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw=="], "drizzle-orm": ["drizzle-orm@0.45.1", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA=="], @@ -359,6 +404,8 @@ "execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="], + "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], + "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], @@ -393,6 +440,8 @@ "get-tsconfig": ["get-tsconfig@4.13.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="], + "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="], + "git-log-parser": ["git-log-parser@1.2.1", "", { "dependencies": { "argv-formatter": "~1.0.0", "spawn-error-forwarder": "~1.0.0", "split2": "~1.0.0", "stream-combiner2": "~1.1.1", "through2": "~2.0.0", "traverse": "0.6.8" } }, "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ=="], "git-up": ["git-up@8.1.1", "", { "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^9.2.0" } }, "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g=="], @@ -437,8 +486,14 @@ "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="], + + "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], @@ -451,6 +506,8 @@ "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], + "is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], @@ -459,6 +516,8 @@ "java-properties": ["java-properties@1.0.2", "", {}, "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ=="], + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], @@ -529,6 +588,8 @@ "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + "normalize-package-data": ["normalize-package-data@8.0.0", "", { "dependencies": { "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ=="], "normalize-url": ["normalize-url@9.0.0", "", {}, "sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ=="], @@ -537,10 +598,16 @@ "npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], + "nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + "open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], + "openapi3-ts": ["openapi3-ts@4.5.0", "", { "dependencies": { "yaml": "^2.8.0" } }, "sha512-jaL+HgTq2Gj5jRcfdutgRGLosCy/hT8sQf6VOy+P+g36cZOjI1iukdPnijC+4CmeRzg/jEllJUboEic2FhxhtQ=="], "p-each-series": ["p-each-series@3.0.0", "", {}, "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw=="], @@ -587,6 +654,8 @@ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="], + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -595,6 +664,10 @@ "pkg-conf": ["pkg-conf@2.1.0", "", { "dependencies": { "find-up": "^2.0.0", "load-json-file": "^4.0.0" } }, "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g=="], + "pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], + + "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], + "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], "pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="], @@ -607,12 +680,16 @@ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "read-package-up": ["read-package-up@12.0.0", "", { "dependencies": { "find-up-simple": "^1.0.1", "read-pkg": "^10.0.0", "type-fest": "^5.2.0" } }, "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw=="], "read-pkg": ["read-pkg@10.1.0", "", { "dependencies": { "@types/normalize-package-data": "^2.4.4", "normalize-package-data": "^8.0.0", "parse-json": "^8.3.0", "type-fest": "^5.4.4", "unicorn-magic": "^0.4.0" } }, "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg=="], "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + "registry-auth-token": ["registry-auth-token@5.1.1", "", { "dependencies": { "@pnpm/npm-conf": "^3.0.2" } }, "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q=="], "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], @@ -621,6 +698,8 @@ "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], + "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "semantic-release": ["semantic-release@25.0.3", "", { "dependencies": { "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^12.0.0", "@semantic-release/npm": "^13.1.1", "@semantic-release/release-notes-generator": "^14.1.0", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^4.0.0", "hosted-git-info": "^9.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^15.0.0", "marked-terminal": "^7.3.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", "read-package-up": "^12.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "signale": "^1.2.1", "yargs": "^18.0.0" }, "bin": "bin/semantic-release.js" }, "sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA=="], @@ -691,6 +770,8 @@ "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], + "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], @@ -747,6 +828,8 @@ "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], @@ -769,6 +852,8 @@ "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": "bin/esbuild" }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], + "@hey-api/shared/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], "@poppinss/dumper/@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], @@ -817,6 +902,8 @@ "npm-run-path/unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], + "nypm/citty": ["citty@0.2.1", "", {}, "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg=="], + "parse-json/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="], diff --git a/package.json b/package.json index a5e7f76a..09f36087 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "format": "prettier --write --ignore-unknown .", "db:create": "wrangler d1 create revanced-api", "db:migration:generate": "drizzle-kit generate", - "db:migration:apply": "wrangler d1 migrations apply revanced-api" + "db:migration:apply": "wrangler d1 migrations apply revanced-api", + "build:client:ts": "openapi-ts -o ./src/client -i" }, "keywords": [ "revanced", @@ -20,13 +21,14 @@ "license": "AGPL-3.0", "dependencies": { "@hono/swagger-ui": "^0.6.1", - "@hono/zod-openapi": "^1.2.2", + "@hono/zod-openapi": "^1.2.3", "drizzle-orm": "^0.45.1", "hono": "^4.12.8", "zod": "^4.3.6" }, "devDependencies": { "@cloudflare/workers-types": "^4.20260317.1", + "@hey-api/openapi-ts": "0.94.4", "@kilianpaquier/semantic-release-backmerge": "^1.7.3", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", From a49a732833179006aeac2eda15863c58bafa15dc Mon Sep 17 00:00:00 2001 From: madkarmaa Date: Sun, 22 Mar 2026 19:58:38 +0100 Subject: [PATCH 2/6] chore: generate client --- src/client/client.gen.ts | 16 + src/client/client/client.gen.ts | 290 ++++++++ src/client/client/index.ts | 25 + src/client/client/types.gen.ts | 214 ++++++ src/client/client/utils.gen.ts | 316 +++++++++ src/client/core/auth.gen.ts | 41 ++ src/client/core/bodySerializer.gen.ts | 82 +++ src/client/core/params.gen.ts | 169 +++++ src/client/core/pathSerializer.gen.ts | 171 +++++ src/client/core/queryKeySerializer.gen.ts | 117 +++ src/client/core/serverSentEvents.gen.ts | 243 +++++++ src/client/core/types.gen.ts | 104 +++ src/client/core/utils.gen.ts | 140 ++++ src/client/index.ts | 4 + src/client/sdk.gen.ts | 221 ++++++ src/client/types.gen.ts | 827 ++++++++++++++++++++++ 16 files changed, 2980 insertions(+) create mode 100644 src/client/client.gen.ts create mode 100644 src/client/client/client.gen.ts create mode 100644 src/client/client/index.ts create mode 100644 src/client/client/types.gen.ts create mode 100644 src/client/client/utils.gen.ts create mode 100644 src/client/core/auth.gen.ts create mode 100644 src/client/core/bodySerializer.gen.ts create mode 100644 src/client/core/params.gen.ts create mode 100644 src/client/core/pathSerializer.gen.ts create mode 100644 src/client/core/queryKeySerializer.gen.ts create mode 100644 src/client/core/serverSentEvents.gen.ts create mode 100644 src/client/core/types.gen.ts create mode 100644 src/client/core/utils.gen.ts create mode 100644 src/client/index.ts create mode 100644 src/client/sdk.gen.ts create mode 100644 src/client/types.gen.ts diff --git a/src/client/client.gen.ts b/src/client/client.gen.ts new file mode 100644 index 00000000..04353756 --- /dev/null +++ b/src/client/client.gen.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { type ClientOptions, type Config, createClient, createConfig } from './client'; +import type { ClientOptions as ClientOptions2 } from './types.gen'; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = (override?: Config) => Config & T>; + +export const client = createClient(createConfig({ baseUrl: 'https://api.revanced.app' })); diff --git a/src/client/client/client.gen.ts b/src/client/client/client.gen.ts new file mode 100644 index 00000000..14dc0a0e --- /dev/null +++ b/src/client/client/client.gen.ts @@ -0,0 +1,290 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import { getValidRequestBody } from '../core/utils.gen'; +import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen'; +import { + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from './utils.gen'; + +type ReqInit = Omit & { + body?: any; + headers: ReturnType; +}; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; + + const interceptors = createInterceptors(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined as string | undefined, + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body !== undefined && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined; + } + + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.body === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: getValidRequestBody(opts), + }; + + let request = new Request(url, requestInit); + + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } + } + + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response: Response; + + try { + response = await _fetch(request); + } catch (error) { + // Handle fetch exceptions (AbortError, network errors, etc.) + let finalError = error; + + for (const fn of interceptors.error.fns) { + if (fn) { + finalError = (await fn(error, undefined as any, request, opts)) as unknown; + } + } + + finalError = finalError || ({} as unknown); + + if (opts.throwOnError) { + throw finalError; + } + + // Return error response + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + request, + response: undefined as any, + }; + } + + for (const fn of interceptors.response.fns) { + if (fn) { + response = await fn(response, request, opts); + } + } + + const result = { + request, + response, + }; + + if (response.ok) { + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + if (response.status === 204 || response.headers.get('Content-Length') === '0') { + let emptyData: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'text': + emptyData = await response[parseAs](); + break; + case 'formData': + emptyData = new FormData(); + break; + case 'stream': + emptyData = response.body; + break; + case 'json': + default: + emptyData = {}; + break; + } + return opts.responseStyle === 'data' + ? emptyData + : { + data: emptyData, + ...result, + }; + } + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'text': + data = await response[parseAs](); + break; + case 'json': { + // Some servers return 200 with no Content-Length and empty body. + // response.json() would throw; read as text and parse if non-empty. + const text = await response.text(); + data = text ? JSON.parse(text) : {}; + break; + } + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result, + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result, + }; + } + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop + } + + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error.fns) { + if (fn) { + finalError = (await fn(error, response, request, opts)) as string; + } + } + + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; + } + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result, + }; + }; + + const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + onRequest: async (url, init) => { + let request = new Request(url, init); + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } + } + return request; + }, + serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined, + url, + }); + }; + + const _buildUrl: Client['buildUrl'] = (options) => buildUrl({ ..._config, ...options }); + + return { + buildUrl: _buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/src/client/client/index.ts b/src/client/client/index.ts new file mode 100644 index 00000000..b295edec --- /dev/null +++ b/src/client/client/index.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { serializeQueryKeyValue } from '../core/queryKeySerializer.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape, +} from './types.gen'; +export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/src/client/client/types.gen.ts b/src/client/client/types.gen.ts new file mode 100644 index 00000000..a3f86165 --- /dev/null +++ b/src/client/client/types.gen.ts @@ -0,0 +1,214 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen'; +import type { Middleware } from './utils.gen'; + +export type ResponseStyle = 'data' | 'fields'; + +export interface Config + extends Omit, CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> + extends + Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onRequest' + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = ThrowOnError extends true + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record ? TData[keyof TData] : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? (TData extends Record ? TData[keyof TData] : TData) | undefined + : ( + | { + data: TData extends Record ? TData[keyof TData] : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record ? TError[keyof TError] : TError; + } + ) & { + request: Request; + response: Response; + } + >; + +export interface ClientOptions { + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => RequestResult; + +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'> & + Pick>, 'method'>, +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: TData & Options, +) => string; + +export type Client = CoreClient & { + interceptors: Middleware; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys = Pick>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields', +> = OmitKeys< + RequestOptions, + 'body' | 'path' | 'query' | 'url' +> & + ([TData] extends [never] ? unknown : Omit); diff --git a/src/client/client/utils.gen.ts b/src/client/client/utils.gen.ts new file mode 100644 index 00000000..b4bd2435 --- /dev/null +++ b/src/client/client/utils.gen.ts @@ -0,0 +1,316 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { jsonBodySerializer } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = ({ + parameters = {}, + ...args +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + const options = parameters[name] || args; + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'form', + value, + ...options.array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...options.object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved: options.allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +/** + * Infers parseAs value from provided Content-Type header. + */ +export const getParseAs = (contentType: string | null): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } + + const cleanContent = contentType.split(';')[0]?.trim(); + + if (!cleanContent) { + return; + } + + if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { + return 'json'; + } + + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } + + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) + ) { + return 'blob'; + } + + if (cleanContent.startsWith('text/')) { + return 'text'; + } + + return; +}; + +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick, 'security'> & + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +const headersEntries = (headers: Headers): Array<[string, string]> => { + const entries: Array<[string, string]> = []; + headers.forEach((value, key) => { + entries.push([key, value]); + }); + return entries; +}; + +export const mergeHeaders = ( + ...headers: Array['headers'] | undefined> +): Headers => { + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header) { + continue; + } + + const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' ? JSON.stringify(value) : (value as string), + ); + } + } + } + return mergedHeaders; +}; + +type ErrInterceptor = ( + error: Err, + response: Res, + request: Req, + options: Options, +) => Err | Promise; + +type ReqInterceptor = (request: Req, options: Options) => Req | Promise; + +type ResInterceptor = ( + response: Res, + request: Req, + options: Options, +) => Res | Promise; + +class Interceptors { + fns: Array = []; + + clear(): void { + this.fns = []; + } + + eject(id: number | Interceptor): void { + const index = this.getInterceptorIndex(id); + if (this.fns[index]) { + this.fns[index] = null; + } + } + + exists(id: number | Interceptor): boolean { + const index = this.getInterceptorIndex(id); + return Boolean(this.fns[index]); + } + + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this.fns[id] ? id : -1; + } + return this.fns.indexOf(id); + } + + update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { + const index = this.getInterceptorIndex(id); + if (this.fns[index]) { + this.fns[index] = fn; + return id; + } + return false; + } + + use(fn: Interceptor): number { + this.fns.push(fn); + return this.fns.length - 1; + } +} + +export interface Middleware { + error: Interceptors>; + request: Interceptors>; + response: Interceptors>; +} + +export const createInterceptors = (): Middleware< + Req, + Res, + Err, + Options +> => ({ + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>(), +}); + +const defaultQuerySerializer = createQuerySerializer({ + allowReserved: false, + array: { + explode: true, + style: 'form', + }, + object: { + explode: true, + style: 'deepObject', + }, +}); + +const defaultHeaders = { + 'Content-Type': 'application/json', +}; + +export const createConfig = ( + override: Config & T> = {}, +): Config & T> => ({ + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override, +}); diff --git a/src/client/core/auth.gen.ts b/src/client/core/auth.gen.ts new file mode 100644 index 00000000..3ebf9947 --- /dev/null +++ b/src/client/core/auth.gen.ts @@ -0,0 +1,41 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, +): Promise => { + const token = typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/src/client/core/bodySerializer.gen.ts b/src/client/core/bodySerializer.gen.ts new file mode 100644 index 00000000..67daca60 --- /dev/null +++ b/src/client/core/bodySerializer.gen.ts @@ -0,0 +1,82 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record) => string; + +export type BodySerializer = (body: unknown) => unknown; + +type QuerySerializerOptionsObject = { + allowReserved?: boolean; + array?: Partial>; + object?: Partial>; +}; + +export type QuerySerializerOptions = QuerySerializerOptionsObject & { + /** + * Per-parameter serialization overrides. When provided, these settings + * override the global array/object settings for specific parameter names. + */ + parameters?: Record; +}; + +const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: (body: unknown): FormData => { + const data = new FormData(); + + Object.entries(body as Record).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: (body: unknown): string => + JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: (body: unknown): string => { + const data = new URLSearchParams(); + + Object.entries(body as Record).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/src/client/core/params.gen.ts b/src/client/core/params.gen.ts new file mode 100644 index 00000000..7955601a --- /dev/null +++ b/src/client/core/params.gen.ts @@ -0,0 +1,169 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + } + | { + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If `in` is omitted, `map` aliases `key` to the transport layer. + */ + map: Slot; + }; + +export interface Fields { + allowExtra?: Partial>; + args?: ReadonlyArray; +} + +export type FieldsConfig = ReadonlyArray; + +const extraPrefixesMap: Record = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + | { + in: Slot; + map?: string; + } + | { + in?: never; + map: Slot; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if ('key' in config) { + map.set(config.key, { + map: config.map, + }); + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record; + path: Record; + query: Record; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Array.isArray(value) && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + if (field.in) { + (params[field.in] as Record)[name] = arg; + } + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + if (field.in) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + params[field.map] = value; + } + } else { + const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[key.slice(prefix.length)] = value; + } else if ('allowExtra' in config && config.allowExtra) { + for (const [slot, allowed] of Object.entries(config.allowExtra)) { + if (allowed) { + (params[slot as Slot] as Record)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/src/client/core/pathSerializer.gen.ts b/src/client/core/pathSerializer.gen.ts new file mode 100644 index 00000000..994b2848 --- /dev/null +++ b/src/client/core/pathSerializer.gen.ts @@ -0,0 +1,171 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions & { + value: Record | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; +}; diff --git a/src/client/core/queryKeySerializer.gen.ts b/src/client/core/queryKeySerializer.gen.ts new file mode 100644 index 00000000..5000df60 --- /dev/null +++ b/src/client/core/queryKeySerializer.gen.ts @@ -0,0 +1,117 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * JSON-friendly union that mirrors what Pinia Colada can hash. + */ +export type JsonValue = + | null + | string + | number + | boolean + | JsonValue[] + | { [key: string]: JsonValue }; + +/** + * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes. + */ +export const queryKeyJsonReplacer = (_key: string, value: unknown) => { + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined; + } + if (typeof value === 'bigint') { + return value.toString(); + } + if (value instanceof Date) { + return value.toISOString(); + } + return value; +}; + +/** + * Safely stringifies a value and parses it back into a JsonValue. + */ +export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => { + try { + const json = JSON.stringify(input, queryKeyJsonReplacer); + if (json === undefined) { + return undefined; + } + return JSON.parse(json) as JsonValue; + } catch { + return undefined; + } +}; + +/** + * Detects plain objects (including objects with a null prototype). + */ +const isPlainObject = (value: unknown): value is Record => { + if (value === null || typeof value !== 'object') { + return false; + } + const prototype = Object.getPrototypeOf(value as object); + return prototype === Object.prototype || prototype === null; +}; + +/** + * Turns URLSearchParams into a sorted JSON object for deterministic keys. + */ +const serializeSearchParams = (params: URLSearchParams): JsonValue => { + const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b)); + const result: Record = {}; + + for (const [key, value] of entries) { + const existing = result[key]; + if (existing === undefined) { + result[key] = value; + continue; + } + + if (Array.isArray(existing)) { + (existing as string[]).push(value); + } else { + result[key] = [existing, value]; + } + } + + return result; +}; + +/** + * Normalizes any accepted value into a JSON-friendly shape for query keys. + */ +export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => { + if (value === null) { + return null; + } + + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + return value; + } + + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined; + } + + if (typeof value === 'bigint') { + return value.toString(); + } + + if (value instanceof Date) { + return value.toISOString(); + } + + if (Array.isArray(value)) { + return stringifyToJsonValue(value); + } + + if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) { + return serializeSearchParams(value); + } + + if (isPlainObject(value)) { + return stringifyToJsonValue(value); + } + + return undefined; +}; diff --git a/src/client/core/serverSentEvents.gen.ts b/src/client/core/serverSentEvents.gen.ts new file mode 100644 index 00000000..6aa6cf02 --- /dev/null +++ b/src/client/core/serverSentEvents.gen.ts @@ -0,0 +1,243 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit & + Pick & { + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Implementing clients can call request interceptors inside this hook. + */ + onRequest?: (url: string, init: RequestInit) => Promise; + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + serializedBody?: RequestInit['body']; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onRequest, + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const requestInit: RequestInit = { + redirect: 'follow', + ...options, + body: options.serializedBody, + headers, + signal, + }; + let request = new Request(url, requestInit); + if (onRequest) { + request = await onRequest(url, requestInit); + } + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = options.fetch ?? globalThis.fetch; + const response = await _fetch(request); + + if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + // Normalize line endings: CRLF -> LF, then CR -> LF + buffer = buffer.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/src/client/core/types.gen.ts b/src/client/core/types.gen.ts new file mode 100644 index 00000000..97463257 --- /dev/null +++ b/src/client/core/types.gen.ts @@ -0,0 +1,104 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + string | number | boolean | (string | number | boolean)[] | null | undefined | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; +} + +type IsExactlyNeverOrNeverUndefined = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K]; +}; diff --git a/src/client/core/utils.gen.ts b/src/client/core/utils.gen.ts new file mode 100644 index 00000000..e7ddbe35 --- /dev/null +++ b/src/client/core/utils.gen.ts @@ -0,0 +1,140 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { BodySerializer, QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace(match, serializeArrayParam({ explode, name, style, value })); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; + +export function getValidRequestBody(options: { + body?: unknown; + bodySerializer?: BodySerializer | null; + serializedBody?: unknown; +}) { + const hasBody = options.body !== undefined; + const isSerializedBody = hasBody && options.bodySerializer; + + if (isSerializedBody) { + if ('serializedBody' in options) { + const hasSerializedBody = + options.serializedBody !== undefined && options.serializedBody !== ''; + + return hasSerializedBody ? options.serializedBody : null; + } + + // not all clients implement a serializedBody property (i.e. client-axios) + return options.body !== '' ? options.body : null; + } + + // plain/text body + if (hasBody) { + return options.body; + } + + // no body was provided + return undefined; +} diff --git a/src/client/index.ts b/src/client/index.ts new file mode 100644 index 00000000..e7628069 --- /dev/null +++ b/src/client/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export { deleteV5AnnouncementsById, getV5About, getV5Announcements, getV5AnnouncementsLatest, getV5AnnouncementsLatestId, getV5Contributors, getV5Manager, getV5ManagerDownloaders, getV5ManagerDownloadersPrerelease, getV5ManagerDownloadersVersion, getV5ManagerDownloadersVersionPrerelease, getV5ManagerHistory, getV5ManagerHistoryPrerelease, getV5ManagerPrerelease, getV5ManagerVersion, getV5ManagerVersionPrerelease, getV5Patches, getV5PatchesHistory, getV5PatchesHistoryPrerelease, getV5PatchesKeys, getV5PatchesPrerelease, getV5PatchesVersion, getV5PatchesVersionPrerelease, getV5Team, type Options, patchV5AnnouncementsById, postV5Announcements } from './sdk.gen'; +export type { About, Announcement, ClientOptions, Contributable, CreateAnnouncement, DeleteV5AnnouncementsByIdData, DeleteV5AnnouncementsByIdError, DeleteV5AnnouncementsByIdErrors, DeleteV5AnnouncementsByIdResponse, DeleteV5AnnouncementsByIdResponses, GetV5AboutData, GetV5AboutResponse, GetV5AboutResponses, GetV5AnnouncementsData, GetV5AnnouncementsLatestData, GetV5AnnouncementsLatestIdData, GetV5AnnouncementsLatestIdResponse, GetV5AnnouncementsLatestIdResponses, GetV5AnnouncementsLatestResponse, GetV5AnnouncementsLatestResponses, GetV5AnnouncementsResponse, GetV5AnnouncementsResponses, GetV5ContributorsData, GetV5ContributorsError, GetV5ContributorsErrors, GetV5ContributorsResponse, GetV5ContributorsResponses, GetV5ManagerData, GetV5ManagerDownloadersData, GetV5ManagerDownloadersError, GetV5ManagerDownloadersErrors, GetV5ManagerDownloadersPrereleaseData, GetV5ManagerDownloadersPrereleaseError, GetV5ManagerDownloadersPrereleaseErrors, GetV5ManagerDownloadersPrereleaseResponse, GetV5ManagerDownloadersPrereleaseResponses, GetV5ManagerDownloadersResponse, GetV5ManagerDownloadersResponses, GetV5ManagerDownloadersVersionData, GetV5ManagerDownloadersVersionError, GetV5ManagerDownloadersVersionErrors, GetV5ManagerDownloadersVersionPrereleaseData, GetV5ManagerDownloadersVersionPrereleaseError, GetV5ManagerDownloadersVersionPrereleaseErrors, GetV5ManagerDownloadersVersionPrereleaseResponse, GetV5ManagerDownloadersVersionPrereleaseResponses, GetV5ManagerDownloadersVersionResponse, GetV5ManagerDownloadersVersionResponses, GetV5ManagerError, GetV5ManagerErrors, GetV5ManagerHistoryData, GetV5ManagerHistoryError, GetV5ManagerHistoryErrors, GetV5ManagerHistoryPrereleaseData, GetV5ManagerHistoryPrereleaseError, GetV5ManagerHistoryPrereleaseErrors, GetV5ManagerHistoryPrereleaseResponse, GetV5ManagerHistoryPrereleaseResponses, GetV5ManagerHistoryResponse, GetV5ManagerHistoryResponses, GetV5ManagerPrereleaseData, GetV5ManagerPrereleaseError, GetV5ManagerPrereleaseErrors, GetV5ManagerPrereleaseResponse, GetV5ManagerPrereleaseResponses, GetV5ManagerResponse, GetV5ManagerResponses, GetV5ManagerVersionData, GetV5ManagerVersionError, GetV5ManagerVersionErrors, GetV5ManagerVersionPrereleaseData, GetV5ManagerVersionPrereleaseError, GetV5ManagerVersionPrereleaseErrors, GetV5ManagerVersionPrereleaseResponse, GetV5ManagerVersionPrereleaseResponses, GetV5ManagerVersionResponse, GetV5ManagerVersionResponses, GetV5PatchesData, GetV5PatchesError, GetV5PatchesErrors, GetV5PatchesHistoryData, GetV5PatchesHistoryError, GetV5PatchesHistoryErrors, GetV5PatchesHistoryPrereleaseData, GetV5PatchesHistoryPrereleaseError, GetV5PatchesHistoryPrereleaseErrors, GetV5PatchesHistoryPrereleaseResponse, GetV5PatchesHistoryPrereleaseResponses, GetV5PatchesHistoryResponse, GetV5PatchesHistoryResponses, GetV5PatchesKeysData, GetV5PatchesKeysResponse, GetV5PatchesKeysResponses, GetV5PatchesPrereleaseData, GetV5PatchesPrereleaseError, GetV5PatchesPrereleaseErrors, GetV5PatchesPrereleaseResponse, GetV5PatchesPrereleaseResponses, GetV5PatchesResponse, GetV5PatchesResponses, GetV5PatchesVersionData, GetV5PatchesVersionError, GetV5PatchesVersionErrors, GetV5PatchesVersionPrereleaseData, GetV5PatchesVersionPrereleaseError, GetV5PatchesVersionPrereleaseErrors, GetV5PatchesVersionPrereleaseResponse, GetV5PatchesVersionPrereleaseResponses, GetV5PatchesVersionResponse, GetV5PatchesVersionResponses, GetV5TeamData, GetV5TeamError, GetV5TeamErrors, GetV5TeamResponse, GetV5TeamResponses, LatestAnnouncementEntry, LatestAnnouncementIdEntry, LatestAnnouncementIdsByTag, LatestAnnouncementsByTag, PatchV5AnnouncementsByIdData, PatchV5AnnouncementsByIdError, PatchV5AnnouncementsByIdErrors, PatchV5AnnouncementsByIdResponse, PatchV5AnnouncementsByIdResponses, PostV5AnnouncementsData, PostV5AnnouncementsError, PostV5AnnouncementsErrors, PostV5AnnouncementsResponse, PostV5AnnouncementsResponses, PublicKey, Release, ReleaseSimple, TeamMember, UpdateAnnouncement, Version } from './types.gen'; diff --git a/src/client/sdk.gen.ts b/src/client/sdk.gen.ts new file mode 100644 index 00000000..4642e937 --- /dev/null +++ b/src/client/sdk.gen.ts @@ -0,0 +1,221 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Client, Options as Options2, TDataShape } from './client'; +import { client } from './client.gen'; +import type { DeleteV5AnnouncementsByIdData, DeleteV5AnnouncementsByIdErrors, DeleteV5AnnouncementsByIdResponses, GetV5AboutData, GetV5AboutResponses, GetV5AnnouncementsData, GetV5AnnouncementsLatestData, GetV5AnnouncementsLatestIdData, GetV5AnnouncementsLatestIdResponses, GetV5AnnouncementsLatestResponses, GetV5AnnouncementsResponses, GetV5ContributorsData, GetV5ContributorsErrors, GetV5ContributorsResponses, GetV5ManagerData, GetV5ManagerDownloadersData, GetV5ManagerDownloadersErrors, GetV5ManagerDownloadersPrereleaseData, GetV5ManagerDownloadersPrereleaseErrors, GetV5ManagerDownloadersPrereleaseResponses, GetV5ManagerDownloadersResponses, GetV5ManagerDownloadersVersionData, GetV5ManagerDownloadersVersionErrors, GetV5ManagerDownloadersVersionPrereleaseData, GetV5ManagerDownloadersVersionPrereleaseErrors, GetV5ManagerDownloadersVersionPrereleaseResponses, GetV5ManagerDownloadersVersionResponses, GetV5ManagerErrors, GetV5ManagerHistoryData, GetV5ManagerHistoryErrors, GetV5ManagerHistoryPrereleaseData, GetV5ManagerHistoryPrereleaseErrors, GetV5ManagerHistoryPrereleaseResponses, GetV5ManagerHistoryResponses, GetV5ManagerPrereleaseData, GetV5ManagerPrereleaseErrors, GetV5ManagerPrereleaseResponses, GetV5ManagerResponses, GetV5ManagerVersionData, GetV5ManagerVersionErrors, GetV5ManagerVersionPrereleaseData, GetV5ManagerVersionPrereleaseErrors, GetV5ManagerVersionPrereleaseResponses, GetV5ManagerVersionResponses, GetV5PatchesData, GetV5PatchesErrors, GetV5PatchesHistoryData, GetV5PatchesHistoryErrors, GetV5PatchesHistoryPrereleaseData, GetV5PatchesHistoryPrereleaseErrors, GetV5PatchesHistoryPrereleaseResponses, GetV5PatchesHistoryResponses, GetV5PatchesKeysData, GetV5PatchesKeysResponses, GetV5PatchesPrereleaseData, GetV5PatchesPrereleaseErrors, GetV5PatchesPrereleaseResponses, GetV5PatchesResponses, GetV5PatchesVersionData, GetV5PatchesVersionErrors, GetV5PatchesVersionPrereleaseData, GetV5PatchesVersionPrereleaseErrors, GetV5PatchesVersionPrereleaseResponses, GetV5PatchesVersionResponses, GetV5TeamData, GetV5TeamErrors, GetV5TeamResponses, PatchV5AnnouncementsByIdData, PatchV5AnnouncementsByIdErrors, PatchV5AnnouncementsByIdResponses, PostV5AnnouncementsData, PostV5AnnouncementsErrors, PostV5AnnouncementsResponses } from './types.gen'; + +export type Options = Options2 & { + /** + * You can provide a client instance returned by `createClient()` instead of + * individual options. This might be also useful if you want to implement a + * custom client. + */ + client?: Client; + /** + * You can pass arbitrary values through the `meta` object. This can be + * used to access values that aren't defined as part of the SDK function. + */ + meta?: Record; +}; + +/** + * Get current patches release + * + * Get the current stable patches release. + */ +export const getV5Patches = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches', ...options }); + +/** + * Get current patches prerelease + * + * Get the current patches prerelease. + */ +export const getV5PatchesPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/prerelease', ...options }); + +/** + * Get current patches release version + * + * Get the current stable patches release version. + */ +export const getV5PatchesVersion = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/version', ...options }); + +/** + * Get current patches prerelease version + * + * Get the current patches prerelease version. + */ +export const getV5PatchesVersionPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/version/prerelease', ...options }); + +/** + * Get patches release history + * + * Get the stable patches release history. + */ +export const getV5PatchesHistory = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/history', ...options }); + +/** + * Get patches prerelease history + * + * Get the patches prerelease history. + */ +export const getV5PatchesHistoryPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/history/prerelease', ...options }); + +/** + * Get patches public keys + * + * Get the public keys for verifying patches assets. + */ +export const getV5PatchesKeys = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/keys', ...options }); + +/** + * Get current manager release + * + * Get the current stable manager release. + */ +export const getV5Manager = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager', ...options }); + +/** + * Get current manager prerelease + * + * Get the current manager prerelease. + */ +export const getV5ManagerPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/prerelease', ...options }); + +/** + * Get current manager release version + * + * Get the current stable manager release version. + */ +export const getV5ManagerVersion = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/version', ...options }); + +/** + * Get current manager prerelease version + * + * Get the current manager prerelease version. + */ +export const getV5ManagerVersionPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/version/prerelease', ...options }); + +/** + * Get manager release history + * + * Get the stable manager release history. + */ +export const getV5ManagerHistory = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/history', ...options }); + +/** + * Get manager prerelease history + * + * Get the manager prerelease history. + */ +export const getV5ManagerHistoryPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/history/prerelease', ...options }); + +/** + * Get current manager downloaders release + * + * Get the current stable manager downloaders release. + */ +export const getV5ManagerDownloaders = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders', ...options }); + +/** + * Get current manager downloaders prerelease + * + * Get the current manager downloaders prerelease. + */ +export const getV5ManagerDownloadersPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders/prerelease', ...options }); + +/** + * Get current manager downloaders release version + * + * Get the current stable manager downloaders release version. + */ +export const getV5ManagerDownloadersVersion = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders/version', ...options }); + +/** + * Get current manager downloaders prerelease version + * + * Get the current manager downloaders prerelease version. + */ +export const getV5ManagerDownloadersVersionPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders/version/prerelease', ...options }); + +/** + * Get all announcements + * + * Get all announcements ordered by newest first. + */ +export const getV5Announcements = (options?: Options) => (options?.client ?? client).get({ url: '/v5/announcements', ...options }); + +/** + * Create an announcement + * + * Create a new announcement. Requires bearer token authentication. + */ +export const postV5Announcements = (options?: Options) => (options?.client ?? client).post({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v5/announcements', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options?.headers + } +}); + +/** + * Get the latest announcement for each tag + * + * Get the newest announcement for every available announcement tag. + */ +export const getV5AnnouncementsLatest = (options?: Options) => (options?.client ?? client).get({ url: '/v5/announcements/latest', ...options }); + +/** + * Get the latest announcement ID for each tag + * + * Get the ID of the newest announcement for every available announcement tag. + */ +export const getV5AnnouncementsLatestId = (options?: Options) => (options?.client ?? client).get({ url: '/v5/announcements/latest/id', ...options }); + +/** + * Delete an announcement + * + * Delete an announcement. Requires bearer token authentication. + */ +export const deleteV5AnnouncementsById = (options: Options) => (options.client ?? client).delete({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v5/announcements/{id}', + ...options +}); + +/** + * Update an announcement + * + * Update an existing announcement. Requires bearer token authentication. + */ +export const patchV5AnnouncementsById = (options: Options) => (options.client ?? client).patch({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v5/announcements/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get contributors + * + * Get the list of contributors for each configured repository. + */ +export const getV5Contributors = (options?: Options) => (options?.client ?? client).get({ url: '/v5/contributors', ...options }); + +/** + * Get team members + * + * Get the list of team members from the organization. + */ +export const getV5Team = (options?: Options) => (options?.client ?? client).get({ url: '/v5/team', ...options }); + +/** + * Get about + * + * Get information about the API. + */ +export const getV5About = (options?: Options) => (options?.client ?? client).get({ url: '/v5/about', ...options }); diff --git a/src/client/types.gen.ts b/src/client/types.gen.ts new file mode 100644 index 00000000..5a79aeed --- /dev/null +++ b/src/client/types.gen.ts @@ -0,0 +1,827 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: 'https://api.revanced.app' | `${string}://{customServer}` | (string & {}); +}; + +export type Release = { + version: string; + created_at: string; + description: string; + download_url: string; + signature_download_url?: string; +}; + +export type Version = { + version: string; +}; + +export type ReleaseSimple = { + version: string; + created_at: string; + description: string; +}; + +export type PublicKey = { + /** + * The PGP public key for verifying patches assets. + */ + patches_public_key: string; +}; + +export type Announcement = { + id: number; + author: string; + title: string; + content: string; + tags: Array; + created_at: string; + archived_at: string; + level: number; +}; + +export type LatestAnnouncementsByTag = Array; + +export type LatestAnnouncementEntry = { + tag: string; + announcement: Announcement; +}; + +export type LatestAnnouncementIdsByTag = Array; + +export type LatestAnnouncementIdEntry = { + tag: string; + id: number; +}; + +export type CreateAnnouncement = { + author?: string; + title: string; + content?: string; + tags: Array; + /** + * UTC timestamp. Defaults to current time if omitted. + */ + created_at?: string; + /** + * UTC timestamp. + */ + archived_at?: string; + level?: number; +}; + +export type UpdateAnnouncement = { + author?: string; + title: string; + content?: string; + tags: Array; + /** + * UTC timestamp. + */ + created_at?: string; + /** + * UTC timestamp. + */ + archived_at?: string; + level?: number; +}; + +export type Contributable = { + name: string; + url: string; + contributors: Array<{ + name: string; + avatar_url: string; + url: string; + contributions: number; + }>; +}; + +export type TeamMember = { + name: string; + avatar_url: string; + url: string; + bio: string; + gpg_key: { + id: string; + url: string; + }; +}; + +export type About = { + name: string; + about: string; + keys: string; + branding?: { + logo: string; + }; + status: string; + contact?: { + email: string; + }; + socials?: Array<{ + name: string; + url: string; + preferred?: boolean; + }>; + donations?: { + wallets?: Array<{ + network: string; + currency_code: string; + address: string; + preferred?: boolean; + }>; + links?: Array<{ + name: string; + url: string; + preferred?: boolean; + }>; + }; +}; + +export type GetV5PatchesData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches'; +}; + +export type GetV5PatchesErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5PatchesError = GetV5PatchesErrors[keyof GetV5PatchesErrors]; + +export type GetV5PatchesResponses = { + /** + * The current patches release. + */ + 200: Release; +}; + +export type GetV5PatchesResponse = GetV5PatchesResponses[keyof GetV5PatchesResponses]; + +export type GetV5PatchesPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches/prerelease'; +}; + +export type GetV5PatchesPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5PatchesPrereleaseError = GetV5PatchesPrereleaseErrors[keyof GetV5PatchesPrereleaseErrors]; + +export type GetV5PatchesPrereleaseResponses = { + /** + * The current patches prerelease. + */ + 200: Release; +}; + +export type GetV5PatchesPrereleaseResponse = GetV5PatchesPrereleaseResponses[keyof GetV5PatchesPrereleaseResponses]; + +export type GetV5PatchesVersionData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches/version'; +}; + +export type GetV5PatchesVersionErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5PatchesVersionError = GetV5PatchesVersionErrors[keyof GetV5PatchesVersionErrors]; + +export type GetV5PatchesVersionResponses = { + /** + * The current patches release version. + */ + 200: Version; +}; + +export type GetV5PatchesVersionResponse = GetV5PatchesVersionResponses[keyof GetV5PatchesVersionResponses]; + +export type GetV5PatchesVersionPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches/version/prerelease'; +}; + +export type GetV5PatchesVersionPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5PatchesVersionPrereleaseError = GetV5PatchesVersionPrereleaseErrors[keyof GetV5PatchesVersionPrereleaseErrors]; + +export type GetV5PatchesVersionPrereleaseResponses = { + /** + * The current patches prerelease version. + */ + 200: Version; +}; + +export type GetV5PatchesVersionPrereleaseResponse = GetV5PatchesVersionPrereleaseResponses[keyof GetV5PatchesVersionPrereleaseResponses]; + +export type GetV5PatchesHistoryData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches/history'; +}; + +export type GetV5PatchesHistoryErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5PatchesHistoryError = GetV5PatchesHistoryErrors[keyof GetV5PatchesHistoryErrors]; + +export type GetV5PatchesHistoryResponses = { + /** + * The patches release history. + */ + 200: Array; +}; + +export type GetV5PatchesHistoryResponse = GetV5PatchesHistoryResponses[keyof GetV5PatchesHistoryResponses]; + +export type GetV5PatchesHistoryPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches/history/prerelease'; +}; + +export type GetV5PatchesHistoryPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5PatchesHistoryPrereleaseError = GetV5PatchesHistoryPrereleaseErrors[keyof GetV5PatchesHistoryPrereleaseErrors]; + +export type GetV5PatchesHistoryPrereleaseResponses = { + /** + * The patches prerelease history. + */ + 200: Array; +}; + +export type GetV5PatchesHistoryPrereleaseResponse = GetV5PatchesHistoryPrereleaseResponses[keyof GetV5PatchesHistoryPrereleaseResponses]; + +export type GetV5PatchesKeysData = { + body?: never; + path?: never; + query?: never; + url: '/v5/patches/keys'; +}; + +export type GetV5PatchesKeysResponses = { + /** + * The public keys. + */ + 200: PublicKey; +}; + +export type GetV5PatchesKeysResponse = GetV5PatchesKeysResponses[keyof GetV5PatchesKeysResponses]; + +export type GetV5ManagerData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager'; +}; + +export type GetV5ManagerErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerError = GetV5ManagerErrors[keyof GetV5ManagerErrors]; + +export type GetV5ManagerResponses = { + /** + * The latest manager release. + */ + 200: Release; +}; + +export type GetV5ManagerResponse = GetV5ManagerResponses[keyof GetV5ManagerResponses]; + +export type GetV5ManagerPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/prerelease'; +}; + +export type GetV5ManagerPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerPrereleaseError = GetV5ManagerPrereleaseErrors[keyof GetV5ManagerPrereleaseErrors]; + +export type GetV5ManagerPrereleaseResponses = { + /** + * The latest manager prerelease. + */ + 200: Release; +}; + +export type GetV5ManagerPrereleaseResponse = GetV5ManagerPrereleaseResponses[keyof GetV5ManagerPrereleaseResponses]; + +export type GetV5ManagerVersionData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/version'; +}; + +export type GetV5ManagerVersionErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerVersionError = GetV5ManagerVersionErrors[keyof GetV5ManagerVersionErrors]; + +export type GetV5ManagerVersionResponses = { + /** + * The current manager release version. + */ + 200: Version; +}; + +export type GetV5ManagerVersionResponse = GetV5ManagerVersionResponses[keyof GetV5ManagerVersionResponses]; + +export type GetV5ManagerVersionPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/version/prerelease'; +}; + +export type GetV5ManagerVersionPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerVersionPrereleaseError = GetV5ManagerVersionPrereleaseErrors[keyof GetV5ManagerVersionPrereleaseErrors]; + +export type GetV5ManagerVersionPrereleaseResponses = { + /** + * The current manager prerelease version. + */ + 200: Version; +}; + +export type GetV5ManagerVersionPrereleaseResponse = GetV5ManagerVersionPrereleaseResponses[keyof GetV5ManagerVersionPrereleaseResponses]; + +export type GetV5ManagerHistoryData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/history'; +}; + +export type GetV5ManagerHistoryErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerHistoryError = GetV5ManagerHistoryErrors[keyof GetV5ManagerHistoryErrors]; + +export type GetV5ManagerHistoryResponses = { + /** + * The manager release history. + */ + 200: Array; +}; + +export type GetV5ManagerHistoryResponse = GetV5ManagerHistoryResponses[keyof GetV5ManagerHistoryResponses]; + +export type GetV5ManagerHistoryPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/history/prerelease'; +}; + +export type GetV5ManagerHistoryPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerHistoryPrereleaseError = GetV5ManagerHistoryPrereleaseErrors[keyof GetV5ManagerHistoryPrereleaseErrors]; + +export type GetV5ManagerHistoryPrereleaseResponses = { + /** + * The manager prerelease history. + */ + 200: Array; +}; + +export type GetV5ManagerHistoryPrereleaseResponse = GetV5ManagerHistoryPrereleaseResponses[keyof GetV5ManagerHistoryPrereleaseResponses]; + +export type GetV5ManagerDownloadersData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/downloaders'; +}; + +export type GetV5ManagerDownloadersErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerDownloadersError = GetV5ManagerDownloadersErrors[keyof GetV5ManagerDownloadersErrors]; + +export type GetV5ManagerDownloadersResponses = { + /** + * The latest manager downloaders release. + */ + 200: Release; +}; + +export type GetV5ManagerDownloadersResponse = GetV5ManagerDownloadersResponses[keyof GetV5ManagerDownloadersResponses]; + +export type GetV5ManagerDownloadersPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/downloaders/prerelease'; +}; + +export type GetV5ManagerDownloadersPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerDownloadersPrereleaseError = GetV5ManagerDownloadersPrereleaseErrors[keyof GetV5ManagerDownloadersPrereleaseErrors]; + +export type GetV5ManagerDownloadersPrereleaseResponses = { + /** + * The latest manager downloaders prerelease. + */ + 200: Release; +}; + +export type GetV5ManagerDownloadersPrereleaseResponse = GetV5ManagerDownloadersPrereleaseResponses[keyof GetV5ManagerDownloadersPrereleaseResponses]; + +export type GetV5ManagerDownloadersVersionData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/downloaders/version'; +}; + +export type GetV5ManagerDownloadersVersionErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerDownloadersVersionError = GetV5ManagerDownloadersVersionErrors[keyof GetV5ManagerDownloadersVersionErrors]; + +export type GetV5ManagerDownloadersVersionResponses = { + /** + * The current manager downloaders release version. + */ + 200: Version; +}; + +export type GetV5ManagerDownloadersVersionResponse = GetV5ManagerDownloadersVersionResponses[keyof GetV5ManagerDownloadersVersionResponses]; + +export type GetV5ManagerDownloadersVersionPrereleaseData = { + body?: never; + path?: never; + query?: never; + url: '/v5/manager/downloaders/version/prerelease'; +}; + +export type GetV5ManagerDownloadersVersionPrereleaseErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ManagerDownloadersVersionPrereleaseError = GetV5ManagerDownloadersVersionPrereleaseErrors[keyof GetV5ManagerDownloadersVersionPrereleaseErrors]; + +export type GetV5ManagerDownloadersVersionPrereleaseResponses = { + /** + * The current manager downloaders prerelease version. + */ + 200: Version; +}; + +export type GetV5ManagerDownloadersVersionPrereleaseResponse = GetV5ManagerDownloadersVersionPrereleaseResponses[keyof GetV5ManagerDownloadersVersionPrereleaseResponses]; + +export type GetV5AnnouncementsData = { + body?: never; + path?: never; + query?: never; + url: '/v5/announcements'; +}; + +export type GetV5AnnouncementsResponses = { + /** + * All announcements. + */ + 200: Array; +}; + +export type GetV5AnnouncementsResponse = GetV5AnnouncementsResponses[keyof GetV5AnnouncementsResponses]; + +export type PostV5AnnouncementsData = { + body?: CreateAnnouncement; + path?: never; + query?: never; + url: '/v5/announcements'; +}; + +export type PostV5AnnouncementsErrors = { + /** + * Unauthorized. + */ + 401: { + error: string; + }; + /** + * Forbidden. + */ + 403: { + error: string; + }; +}; + +export type PostV5AnnouncementsError = PostV5AnnouncementsErrors[keyof PostV5AnnouncementsErrors]; + +export type PostV5AnnouncementsResponses = { + /** + * The created announcement. + */ + 201: Announcement; +}; + +export type PostV5AnnouncementsResponse = PostV5AnnouncementsResponses[keyof PostV5AnnouncementsResponses]; + +export type GetV5AnnouncementsLatestData = { + body?: never; + path?: never; + query?: never; + url: '/v5/announcements/latest'; +}; + +export type GetV5AnnouncementsLatestResponses = { + /** + * The newest announcement for each tag. + */ + 200: LatestAnnouncementsByTag; +}; + +export type GetV5AnnouncementsLatestResponse = GetV5AnnouncementsLatestResponses[keyof GetV5AnnouncementsLatestResponses]; + +export type GetV5AnnouncementsLatestIdData = { + body?: never; + path?: never; + query?: never; + url: '/v5/announcements/latest/id'; +}; + +export type GetV5AnnouncementsLatestIdResponses = { + /** + * The newest announcement ID for each tag. + */ + 200: LatestAnnouncementIdsByTag; +}; + +export type GetV5AnnouncementsLatestIdResponse = GetV5AnnouncementsLatestIdResponses[keyof GetV5AnnouncementsLatestIdResponses]; + +export type DeleteV5AnnouncementsByIdData = { + body?: never; + path: { + /** + * Announcement ID. + */ + id: number; + }; + query?: never; + url: '/v5/announcements/{id}'; +}; + +export type DeleteV5AnnouncementsByIdErrors = { + /** + * Unauthorized. + */ + 401: { + error: string; + }; + /** + * Forbidden. + */ + 403: { + error: string; + }; + /** + * Announcement not found. + */ + 404: { + error: string; + }; +}; + +export type DeleteV5AnnouncementsByIdError = DeleteV5AnnouncementsByIdErrors[keyof DeleteV5AnnouncementsByIdErrors]; + +export type DeleteV5AnnouncementsByIdResponses = { + /** + * Announcement deleted. + */ + 204: void; +}; + +export type DeleteV5AnnouncementsByIdResponse = DeleteV5AnnouncementsByIdResponses[keyof DeleteV5AnnouncementsByIdResponses]; + +export type PatchV5AnnouncementsByIdData = { + body?: UpdateAnnouncement; + path: { + /** + * Announcement ID. + */ + id: number; + }; + query?: never; + url: '/v5/announcements/{id}'; +}; + +export type PatchV5AnnouncementsByIdErrors = { + /** + * Unauthorized. + */ + 401: { + error: string; + }; + /** + * Forbidden. + */ + 403: { + error: string; + }; + /** + * Announcement not found. + */ + 404: { + error: string; + }; +}; + +export type PatchV5AnnouncementsByIdError = PatchV5AnnouncementsByIdErrors[keyof PatchV5AnnouncementsByIdErrors]; + +export type PatchV5AnnouncementsByIdResponses = { + /** + * The updated announcement. + */ + 200: Announcement; +}; + +export type PatchV5AnnouncementsByIdResponse = PatchV5AnnouncementsByIdResponses[keyof PatchV5AnnouncementsByIdResponses]; + +export type GetV5ContributorsData = { + body?: never; + path?: never; + query?: never; + url: '/v5/contributors'; +}; + +export type GetV5ContributorsErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5ContributorsError = GetV5ContributorsErrors[keyof GetV5ContributorsErrors]; + +export type GetV5ContributorsResponses = { + /** + * The list of contributors. + */ + 200: Array; +}; + +export type GetV5ContributorsResponse = GetV5ContributorsResponses[keyof GetV5ContributorsResponses]; + +export type GetV5TeamData = { + body?: never; + path?: never; + query?: never; + url: '/v5/team'; +}; + +export type GetV5TeamErrors = { + /** + * GitHub API error. + */ + 500: { + error: string; + }; +}; + +export type GetV5TeamError = GetV5TeamErrors[keyof GetV5TeamErrors]; + +export type GetV5TeamResponses = { + /** + * The list of team members. + */ + 200: Array; +}; + +export type GetV5TeamResponse = GetV5TeamResponses[keyof GetV5TeamResponses]; + +export type GetV5AboutData = { + body?: never; + path?: never; + query?: never; + url: '/v5/about'; +}; + +export type GetV5AboutResponses = { + /** + * Information about the API. + */ + 200: About; +}; + +export type GetV5AboutResponse = GetV5AboutResponses[keyof GetV5AboutResponses]; From 01ac4d48df30e37395421c6a1d3a7da22b569b5d Mon Sep 17 00:00:00 2001 From: madkarmaa Date: Mon, 23 Mar 2026 10:30:48 +0100 Subject: [PATCH 3/6] refactor: move client to a different location --- {src/client => client/ts}/client.gen.ts | 0 {src/client => client/ts}/client/client.gen.ts | 0 {src/client => client/ts}/client/index.ts | 0 {src/client => client/ts}/client/types.gen.ts | 0 {src/client => client/ts}/client/utils.gen.ts | 0 {src/client => client/ts}/core/auth.gen.ts | 0 {src/client => client/ts}/core/bodySerializer.gen.ts | 0 {src/client => client/ts}/core/params.gen.ts | 0 {src/client => client/ts}/core/pathSerializer.gen.ts | 0 {src/client => client/ts}/core/queryKeySerializer.gen.ts | 0 {src/client => client/ts}/core/serverSentEvents.gen.ts | 0 {src/client => client/ts}/core/types.gen.ts | 0 {src/client => client/ts}/core/utils.gen.ts | 0 {src/client => client/ts}/index.ts | 0 {src/client => client/ts}/sdk.gen.ts | 0 {src/client => client/ts}/types.gen.ts | 0 package.json | 2 +- 17 files changed, 1 insertion(+), 1 deletion(-) rename {src/client => client/ts}/client.gen.ts (100%) rename {src/client => client/ts}/client/client.gen.ts (100%) rename {src/client => client/ts}/client/index.ts (100%) rename {src/client => client/ts}/client/types.gen.ts (100%) rename {src/client => client/ts}/client/utils.gen.ts (100%) rename {src/client => client/ts}/core/auth.gen.ts (100%) rename {src/client => client/ts}/core/bodySerializer.gen.ts (100%) rename {src/client => client/ts}/core/params.gen.ts (100%) rename {src/client => client/ts}/core/pathSerializer.gen.ts (100%) rename {src/client => client/ts}/core/queryKeySerializer.gen.ts (100%) rename {src/client => client/ts}/core/serverSentEvents.gen.ts (100%) rename {src/client => client/ts}/core/types.gen.ts (100%) rename {src/client => client/ts}/core/utils.gen.ts (100%) rename {src/client => client/ts}/index.ts (100%) rename {src/client => client/ts}/sdk.gen.ts (100%) rename {src/client => client/ts}/types.gen.ts (100%) diff --git a/src/client/client.gen.ts b/client/ts/client.gen.ts similarity index 100% rename from src/client/client.gen.ts rename to client/ts/client.gen.ts diff --git a/src/client/client/client.gen.ts b/client/ts/client/client.gen.ts similarity index 100% rename from src/client/client/client.gen.ts rename to client/ts/client/client.gen.ts diff --git a/src/client/client/index.ts b/client/ts/client/index.ts similarity index 100% rename from src/client/client/index.ts rename to client/ts/client/index.ts diff --git a/src/client/client/types.gen.ts b/client/ts/client/types.gen.ts similarity index 100% rename from src/client/client/types.gen.ts rename to client/ts/client/types.gen.ts diff --git a/src/client/client/utils.gen.ts b/client/ts/client/utils.gen.ts similarity index 100% rename from src/client/client/utils.gen.ts rename to client/ts/client/utils.gen.ts diff --git a/src/client/core/auth.gen.ts b/client/ts/core/auth.gen.ts similarity index 100% rename from src/client/core/auth.gen.ts rename to client/ts/core/auth.gen.ts diff --git a/src/client/core/bodySerializer.gen.ts b/client/ts/core/bodySerializer.gen.ts similarity index 100% rename from src/client/core/bodySerializer.gen.ts rename to client/ts/core/bodySerializer.gen.ts diff --git a/src/client/core/params.gen.ts b/client/ts/core/params.gen.ts similarity index 100% rename from src/client/core/params.gen.ts rename to client/ts/core/params.gen.ts diff --git a/src/client/core/pathSerializer.gen.ts b/client/ts/core/pathSerializer.gen.ts similarity index 100% rename from src/client/core/pathSerializer.gen.ts rename to client/ts/core/pathSerializer.gen.ts diff --git a/src/client/core/queryKeySerializer.gen.ts b/client/ts/core/queryKeySerializer.gen.ts similarity index 100% rename from src/client/core/queryKeySerializer.gen.ts rename to client/ts/core/queryKeySerializer.gen.ts diff --git a/src/client/core/serverSentEvents.gen.ts b/client/ts/core/serverSentEvents.gen.ts similarity index 100% rename from src/client/core/serverSentEvents.gen.ts rename to client/ts/core/serverSentEvents.gen.ts diff --git a/src/client/core/types.gen.ts b/client/ts/core/types.gen.ts similarity index 100% rename from src/client/core/types.gen.ts rename to client/ts/core/types.gen.ts diff --git a/src/client/core/utils.gen.ts b/client/ts/core/utils.gen.ts similarity index 100% rename from src/client/core/utils.gen.ts rename to client/ts/core/utils.gen.ts diff --git a/src/client/index.ts b/client/ts/index.ts similarity index 100% rename from src/client/index.ts rename to client/ts/index.ts diff --git a/src/client/sdk.gen.ts b/client/ts/sdk.gen.ts similarity index 100% rename from src/client/sdk.gen.ts rename to client/ts/sdk.gen.ts diff --git a/src/client/types.gen.ts b/client/ts/types.gen.ts similarity index 100% rename from src/client/types.gen.ts rename to client/ts/types.gen.ts diff --git a/package.json b/package.json index 09f36087..8a2f67d3 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "db:create": "wrangler d1 create revanced-api", "db:migration:generate": "drizzle-kit generate", "db:migration:apply": "wrangler d1 migrations apply revanced-api", - "build:client:ts": "openapi-ts -o ./src/client -i" + "build:client:ts": "openapi-ts -o ./client/ts -i" }, "keywords": [ "revanced", From d3a82fcae0f5180a1d5ebbcbe672a15c048ca65a Mon Sep 17 00:00:00 2001 From: madkarmaa Date: Mon, 23 Mar 2026 10:32:37 +0100 Subject: [PATCH 4/6] refactor: format --- client/ts/client.gen.ts | 15 +- client/ts/client/client.gen.ts | 539 ++++++++++++----------- client/ts/client/index.ts | 26 +- client/ts/client/types.gen.ts | 339 +++++++------- client/ts/client/utils.gen.ts | 477 ++++++++++---------- client/ts/core/auth.gen.ts | 55 +-- client/ts/core/bodySerializer.gen.ts | 126 +++--- client/ts/core/params.gen.ts | 274 ++++++------ client/ts/core/pathSerializer.gen.ts | 267 +++++------ client/ts/core/queryKeySerializer.gen.ts | 161 ++++--- client/ts/core/serverSentEvents.gen.ts | 465 ++++++++++--------- client/ts/core/types.gen.ts | 188 ++++---- client/ts/core/utils.gen.ts | 228 +++++----- client/ts/index.ts | 168 ++++++- client/ts/sdk.gen.ts | 372 ++++++++++++++-- client/ts/types.gen.ts | 131 ++++-- src/schemas/contributors.ts | 16 +- 17 files changed, 2274 insertions(+), 1573 deletions(-) diff --git a/client/ts/client.gen.ts b/client/ts/client.gen.ts index 04353756..41bfa80d 100644 --- a/client/ts/client.gen.ts +++ b/client/ts/client.gen.ts @@ -1,6 +1,11 @@ // This file is auto-generated by @hey-api/openapi-ts -import { type ClientOptions, type Config, createClient, createConfig } from './client'; +import { + type ClientOptions, + type Config, + createClient, + createConfig +} from './client'; import type { ClientOptions as ClientOptions2 } from './types.gen'; /** @@ -11,6 +16,10 @@ import type { ClientOptions as ClientOptions2 } from './types.gen'; * `setConfig()`. This is useful for example if you're using Next.js * to ensure your client always has the correct values. */ -export type CreateClientConfig = (override?: Config) => Config & T>; +export type CreateClientConfig = ( + override?: Config +) => Config & T>; -export const client = createClient(createConfig({ baseUrl: 'https://api.revanced.app' })); +export const client = createClient( + createConfig({ baseUrl: 'https://api.revanced.app' }) +); diff --git a/client/ts/client/client.gen.ts b/client/ts/client/client.gen.ts index 14dc0a0e..330ab4a4 100644 --- a/client/ts/client/client.gen.ts +++ b/client/ts/client/client.gen.ts @@ -3,288 +3,319 @@ import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; import { getValidRequestBody } from '../core/utils.gen'; -import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions +} from './types.gen'; import { - buildUrl, - createConfig, - createInterceptors, - getParseAs, - mergeConfigs, - mergeHeaders, - setAuthParams, + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams } from './utils.gen'; type ReqInit = Omit & { - body?: any; - headers: ReturnType; + body?: any; + headers: ReturnType; }; export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config); + let _config = mergeConfigs(createConfig(), config); - const getConfig = (): Config => ({ ..._config }); + const getConfig = (): Config => ({ ..._config }); - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config); - return getConfig(); - }; + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; - const interceptors = createInterceptors(); + const interceptors = createInterceptors< + Request, + Response, + unknown, + ResolvedRequestOptions + >(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined as string | undefined + }; - const beforeRequest = async (options: RequestOptions) => { - const opts = { - ..._config, - ...options, - fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), - serializedBody: undefined as string | undefined, - }; + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security + }); + } - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security, - }); - } - - if (opts.requestValidator) { - await opts.requestValidator(opts); - } - - if (opts.body !== undefined && opts.bodySerializer) { - opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined; - } - - // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.serializedBody === '') { - opts.headers.delete('Content-Type'); - } - - const url = buildUrl(opts); - - return { opts, url }; - }; - - const request: Client['request'] = async (options) => { - // @ts-expect-error - const { opts, url } = await beforeRequest(options); - const requestInit: ReqInit = { - redirect: 'follow', - ...opts, - body: getValidRequestBody(opts), - }; + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body !== undefined && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body) as + | string + | undefined; + } - let request = new Request(url, requestInit); + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.body === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts); - } - } + return { opts, url }; + }; - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = opts.fetch!; - let response: Response; + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: getValidRequestBody(opts) + }; - try { - response = await _fetch(request); - } catch (error) { - // Handle fetch exceptions (AbortError, network errors, etc.) - let finalError = error; + let request = new Request(url, requestInit); - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, undefined as any, request, opts)) as unknown; + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } } - } - finalError = finalError || ({} as unknown); + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response: Response; + + try { + response = await _fetch(request); + } catch (error) { + // Handle fetch exceptions (AbortError, network errors, etc.) + let finalError = error; + + for (const fn of interceptors.error.fns) { + if (fn) { + finalError = (await fn( + error, + undefined as any, + request, + opts + )) as unknown; + } + } + + finalError = finalError || ({} as unknown); + + if (opts.throwOnError) { + throw finalError; + } + + // Return error response + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + request, + response: undefined as any + }; + } - if (opts.throwOnError) { - throw finalError; - } + for (const fn of interceptors.response.fns) { + if (fn) { + response = await fn(response, request, opts); + } + } - // Return error response - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, + const result = { request, - response: undefined as any, - }; - } - - for (const fn of interceptors.response.fns) { - if (fn) { - response = await fn(response, request, opts); - } - } - - const result = { - request, - response, - }; + response + }; - if (response.ok) { - const parseAs = - (opts.parseAs === 'auto' - ? getParseAs(response.headers.get('Content-Type')) - : opts.parseAs) ?? 'json'; - - if (response.status === 204 || response.headers.get('Content-Length') === '0') { - let emptyData: any; - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'text': - emptyData = await response[parseAs](); - break; - case 'formData': - emptyData = new FormData(); - break; - case 'stream': - emptyData = response.body; - break; - case 'json': - default: - emptyData = {}; - break; + if (response.ok) { + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + if ( + response.status === 204 || + response.headers.get('Content-Length') === '0' + ) { + let emptyData: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'text': + emptyData = await response[parseAs](); + break; + case 'formData': + emptyData = new FormData(); + break; + case 'stream': + emptyData = response.body; + break; + case 'json': + default: + emptyData = {}; + break; + } + return opts.responseStyle === 'data' + ? emptyData + : { + data: emptyData, + ...result + }; + } + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'text': + data = await response[parseAs](); + break; + case 'json': { + // Some servers return 200 with no Content-Length and empty body. + // response.json() would throw; read as text and parse if non-empty. + const text = await response.text(); + data = text ? JSON.parse(text) : {}; + break; + } + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result + }; } - return opts.responseStyle === 'data' - ? emptyData - : { - data: emptyData, - ...result, - }; - } - - let data: any; - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'formData': - case 'text': - data = await response[parseAs](); - break; - case 'json': { - // Some servers return 200 with no Content-Length and empty body. - // response.json() would throw; read as text and parse if non-empty. - const text = await response.text(); - data = text ? JSON.parse(text) : {}; - break; + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop } - case 'stream': - return opts.responseStyle === 'data' - ? response.body - : { - data: response.body, - ...result, - }; - } - if (parseAs === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data); + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error.fns) { + if (fn) { + finalError = (await fn( + error, + response, + request, + opts + )) as string; + } } - if (opts.responseTransformer) { - data = await opts.responseTransformer(data); + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; } - } - - return opts.responseStyle === 'data' - ? data - : { - data, - ...result, - }; - } - - const textError = await response.text(); - let jsonError: unknown; - - try { - jsonError = JSON.parse(textError); - } catch { - // noop - } - - const error = jsonError ?? textError; - let finalError = error; - - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, response, request, opts)) as string; - } - } - - finalError = finalError || ({} as string); - - if (opts.throwOnError) { - throw finalError; - } - - // TODO: we probably want to return error and improve types - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, - ...result, + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result + }; + }; + + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + onRequest: async (url, init) => { + let request = new Request(url, init); + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } + } + return request; + }, + serializedBody: getValidRequestBody(opts) as + | BodyInit + | null + | undefined, + url + }); }; - }; - - const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => - request({ ...options, method }); - - const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { opts, url } = await beforeRequest(options); - return createSseClient({ - ...opts, - body: opts.body as BodyInit | null | undefined, - headers: opts.headers as unknown as Record, - method, - onRequest: async (url, init) => { - let request = new Request(url, init); - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts); - } - } - return request; - }, - serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined, - url, - }); - }; - - const _buildUrl: Client['buildUrl'] = (options) => buildUrl({ ..._config, ...options }); - - return { - buildUrl: _buildUrl, - connect: makeMethodFn('CONNECT'), - delete: makeMethodFn('DELETE'), - get: makeMethodFn('GET'), - getConfig, - head: makeMethodFn('HEAD'), - interceptors, - options: makeMethodFn('OPTIONS'), - patch: makeMethodFn('PATCH'), - post: makeMethodFn('POST'), - put: makeMethodFn('PUT'), - request, - setConfig, - sse: { - connect: makeSseFn('CONNECT'), - delete: makeSseFn('DELETE'), - get: makeSseFn('GET'), - head: makeSseFn('HEAD'), - options: makeSseFn('OPTIONS'), - patch: makeSseFn('PATCH'), - post: makeSseFn('POST'), - put: makeSseFn('PUT'), - trace: makeSseFn('TRACE'), - }, - trace: makeMethodFn('TRACE'), - } as Client; + + const _buildUrl: Client['buildUrl'] = (options) => + buildUrl({ ..._config, ...options }); + + return { + buildUrl: _buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE') + }, + trace: makeMethodFn('TRACE') + } as Client; }; diff --git a/client/ts/client/index.ts b/client/ts/client/index.ts index b295edec..8ed2a0aa 100644 --- a/client/ts/client/index.ts +++ b/client/ts/client/index.ts @@ -3,23 +3,23 @@ export type { Auth } from '../core/auth.gen'; export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; export { - formDataBodySerializer, - jsonBodySerializer, - urlSearchParamsBodySerializer, + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer } from '../core/bodySerializer.gen'; export { buildClientParams } from '../core/params.gen'; export { serializeQueryKeyValue } from '../core/queryKeySerializer.gen'; export { createClient } from './client.gen'; export type { - Client, - ClientOptions, - Config, - CreateClientConfig, - Options, - RequestOptions, - RequestResult, - ResolvedRequestOptions, - ResponseStyle, - TDataShape, + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape } from './types.gen'; export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/client/ts/client/types.gen.ts b/client/ts/client/types.gen.ts index a3f86165..0711cc36 100644 --- a/client/ts/client/types.gen.ts +++ b/client/ts/client/types.gen.ts @@ -2,182 +2,219 @@ import type { Auth } from '../core/auth.gen'; import type { - ServerSentEventsOptions, - ServerSentEventsResult, + ServerSentEventsOptions, + ServerSentEventsResult } from '../core/serverSentEvents.gen'; -import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen'; +import type { + Client as CoreClient, + Config as CoreConfig +} from '../core/types.gen'; import type { Middleware } from './utils.gen'; export type ResponseStyle = 'data' | 'fields'; export interface Config - extends Omit, CoreConfig { - /** - * Base URL for all requests made by this client. - */ - baseUrl?: T['baseUrl']; - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch; - /** - * Please don't use the Fetch client for Next.js applications. The `next` - * options won't have any effect. - * - * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. - */ - next?: never; - /** - * Return the response data parsed in a specified format. By default, `auto` - * will infer the appropriate method from the `Content-Type` response header. - * You can override this behavior with any of the {@link Body} methods. - * Select `stream` if you don't want to parse response data at all. - * - * @default 'auto' - */ - parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text'; - /** - * Should we return only data or multiple fields (data, error, response, etc.)? - * - * @default 'fields' - */ - responseStyle?: ResponseStyle; - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError']; + extends Omit, CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: + | 'arrayBuffer' + | 'auto' + | 'blob' + | 'formData' + | 'json' + | 'stream' + | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; } export interface RequestOptions< - TData = unknown, - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string, + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string > - extends - Config<{ - responseStyle: TResponseStyle; - throwOnError: ThrowOnError; - }>, - Pick< - ServerSentEventsOptions, - | 'onRequest' - | 'onSseError' - | 'onSseEvent' - | 'sseDefaultRetryDelay' - | 'sseMaxRetryAttempts' - | 'sseMaxRetryDelay' - > { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown; - path?: Record; - query?: Record; - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray; - url: Url; + extends + Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onRequest' + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; } export interface ResolvedRequestOptions< - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string > extends RequestOptions { - serializedBody?: string; + serializedBody?: string; } export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields', + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields' > = ThrowOnError extends true - ? Promise< - TResponseStyle extends 'data' - ? TData extends Record - ? TData[keyof TData] - : TData - : { - data: TData extends Record ? TData[keyof TData] : TData; - request: Request; - response: Response; - } - > - : Promise< - TResponseStyle extends 'data' - ? (TData extends Record ? TData[keyof TData] : TData) | undefined - : ( - | { - data: TData extends Record ? TData[keyof TData] : TData; - error: undefined; - } - | { - data: undefined; - error: TError extends Record ? TError[keyof TError] : TError; - } - ) & { - request: Request; - response: Response; - } - >; + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record + ? TData[keyof TData] + : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? + | (TData extends Record + ? TData[keyof TData] + : TData) + | undefined + : ( + | { + data: TData extends Record + ? TData[keyof TData] + : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record + ? TError[keyof TError] + : TError; + } + ) & { + request: Request; + response: Response; + } + >; export interface ClientOptions { - baseUrl?: string; - responseStyle?: ResponseStyle; - throwOnError?: boolean; + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; } type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields', + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields' >( - options: Omit, 'method'>, + options: Omit, 'method'> ) => RequestResult; type SseFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields', + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields' >( - options: Omit, 'method'>, + options: Omit, 'method'> ) => Promise>; type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields', + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields' >( - options: Omit, 'method'> & - Pick>, 'method'>, + options: Omit< + RequestOptions, + 'method' + > & + Pick< + Required>, + 'method' + > ) => RequestResult; type BuildUrlFn = < - TData extends { - body?: unknown; - path?: Record; - query?: Record; - url: string; - }, + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + } >( - options: TData & Options, + options: TData & Options ) => string; -export type Client = CoreClient & { - interceptors: Middleware; +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { + interceptors: Middleware< + Request, + Response, + unknown, + ResolvedRequestOptions + >; }; /** @@ -189,26 +226,26 @@ export type Client = CoreClient * to ensure your client always has the correct values. */ export type CreateClientConfig = ( - override?: Config, + override?: Config ) => Config & T>; export interface TDataShape { - body?: unknown; - headers?: unknown; - path?: unknown; - query?: unknown; - url: string; + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; } type OmitKeys = Pick>; export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, - TResponse = unknown, - TResponseStyle extends ResponseStyle = 'fields', + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields' > = OmitKeys< - RequestOptions, - 'body' | 'path' | 'query' | 'url' + RequestOptions, + 'body' | 'path' | 'query' | 'url' > & - ([TData] extends [never] ? unknown : Omit); + ([TData] extends [never] ? unknown : Omit); diff --git a/client/ts/client/utils.gen.ts b/client/ts/client/utils.gen.ts index b4bd2435..34048244 100644 --- a/client/ts/client/utils.gen.ts +++ b/client/ts/client/utils.gen.ts @@ -4,313 +4,336 @@ import { getAuthToken } from '../core/auth.gen'; import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; import { jsonBodySerializer } from '../core/bodySerializer.gen'; import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam } from '../core/pathSerializer.gen'; import { getUrl } from '../core/utils.gen'; -import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; +import type { + Client, + ClientOptions, + Config, + RequestOptions +} from './types.gen'; export const createQuerySerializer = ({ - parameters = {}, - ...args + parameters = {}, + ...args }: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = []; - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name]; - - if (value === undefined || value === null) { - continue; + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + const options = parameters[name] || args; + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'form', + value, + ...options.array + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...options.object + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved: options.allowReserved, + name, + value: value as string + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } } - - const options = parameters[name] || args; - - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved: options.allowReserved, - explode: true, - name, - style: 'form', - value, - ...options.array, - }); - if (serializedArray) search.push(serializedArray); - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved: options.allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...options.object, - }); - if (serializedObject) search.push(serializedObject); - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved: options.allowReserved, - name, - value: value as string, - }); - if (serializedPrimitive) search.push(serializedPrimitive); - } - } - } - return search.join('&'); - }; - return querySerializer; + return search.join('&'); + }; + return querySerializer; }; /** * Infers parseAs value from provided Content-Type header. */ -export const getParseAs = (contentType: string | null): Exclude => { - if (!contentType) { - // If no Content-Type header is provided, the best we can do is return the raw response body, - // which is effectively the same as the 'stream' option. - return 'stream'; - } +export const getParseAs = ( + contentType: string | null +): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } - const cleanContent = contentType.split(';')[0]?.trim(); + const cleanContent = contentType.split(';')[0]?.trim(); - if (!cleanContent) { - return; - } + if (!cleanContent) { + return; + } - if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { - return 'json'; - } + if ( + cleanContent.startsWith('application/json') || + cleanContent.endsWith('+json') + ) { + return 'json'; + } - if (cleanContent === 'multipart/form-data') { - return 'formData'; - } + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } - if ( - ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) - ) { - return 'blob'; - } + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => + cleanContent.startsWith(type) + ) + ) { + return 'blob'; + } - if (cleanContent.startsWith('text/')) { - return 'text'; - } + if (cleanContent.startsWith('text/')) { + return 'text'; + } - return; + return; }; const checkForExistence = ( - options: Pick & { - headers: Headers; - }, - name?: string, + options: Pick & { + headers: Headers; + }, + name?: string ): boolean => { - if (!name) { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } return false; - } - if ( - options.headers.has(name) || - options.query?.[name] || - options.headers.get('Cookie')?.includes(`${name}=`) - ) { - return true; - } - return false; }; export const setAuthParams = async ({ - security, - ...options + security, + ...options }: Pick, 'security'> & - Pick & { - headers: Headers; - }) => { - for (const auth of security) { - if (checkForExistence(options, auth.name)) { - continue; - } + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } - const token = await getAuthToken(auth, options.auth); + const token = await getAuthToken(auth, options.auth); - if (!token) { - continue; - } - - const name = auth.name ?? 'Authorization'; + if (!token) { + continue; + } - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {}; + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; } - options.query[name] = token; - break; - case 'cookie': - options.headers.append('Cookie', `${name}=${token}`); - break; - case 'header': - default: - options.headers.set(name, token); - break; } - } }; export const buildUrl: Client['buildUrl'] = (options) => - getUrl({ - baseUrl: options.baseUrl as string, - path: options.path, - query: options.query, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url, - }); + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url + }); export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b }; - if (config.baseUrl?.endsWith('/')) { - config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); - } - config.headers = mergeHeaders(a.headers, b.headers); - return config; + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; }; const headersEntries = (headers: Headers): Array<[string, string]> => { - const entries: Array<[string, string]> = []; - headers.forEach((value, key) => { - entries.push([key, value]); - }); - return entries; + const entries: Array<[string, string]> = []; + headers.forEach((value, key) => { + entries.push([key, value]); + }); + return entries; }; export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> + ...headers: Array['headers'] | undefined> ): Headers => { - const mergedHeaders = new Headers(); - for (const header of headers) { - if (!header) { - continue; - } - - const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header); + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header) { + continue; + } - for (const [key, value] of iterator) { - if (value === null) { - mergedHeaders.delete(key); - } else if (Array.isArray(value)) { - for (const v of value) { - mergedHeaders.append(key, v as string); + const iterator = + header instanceof Headers + ? headersEntries(header) + : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' + ? JSON.stringify(value) + : (value as string) + ); + } } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders.set( - key, - typeof value === 'object' ? JSON.stringify(value) : (value as string), - ); - } } - } - return mergedHeaders; + return mergedHeaders; }; type ErrInterceptor = ( - error: Err, - response: Res, - request: Req, - options: Options, + error: Err, + response: Res, + request: Req, + options: Options ) => Err | Promise; -type ReqInterceptor = (request: Req, options: Options) => Req | Promise; +type ReqInterceptor = ( + request: Req, + options: Options +) => Req | Promise; type ResInterceptor = ( - response: Res, - request: Req, - options: Options, + response: Res, + request: Req, + options: Options ) => Res | Promise; class Interceptors { - fns: Array = []; + fns: Array = []; - clear(): void { - this.fns = []; - } + clear(): void { + this.fns = []; + } - eject(id: number | Interceptor): void { - const index = this.getInterceptorIndex(id); - if (this.fns[index]) { - this.fns[index] = null; + eject(id: number | Interceptor): void { + const index = this.getInterceptorIndex(id); + if (this.fns[index]) { + this.fns[index] = null; + } } - } - exists(id: number | Interceptor): boolean { - const index = this.getInterceptorIndex(id); - return Boolean(this.fns[index]); - } + exists(id: number | Interceptor): boolean { + const index = this.getInterceptorIndex(id); + return Boolean(this.fns[index]); + } - getInterceptorIndex(id: number | Interceptor): number { - if (typeof id === 'number') { - return this.fns[id] ? id : -1; + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this.fns[id] ? id : -1; + } + return this.fns.indexOf(id); } - return this.fns.indexOf(id); - } - - update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { - const index = this.getInterceptorIndex(id); - if (this.fns[index]) { - this.fns[index] = fn; - return id; + + update( + id: number | Interceptor, + fn: Interceptor + ): number | Interceptor | false { + const index = this.getInterceptorIndex(id); + if (this.fns[index]) { + this.fns[index] = fn; + return id; + } + return false; } - return false; - } - use(fn: Interceptor): number { - this.fns.push(fn); - return this.fns.length - 1; - } + use(fn: Interceptor): number { + this.fns.push(fn); + return this.fns.length - 1; + } } export interface Middleware { - error: Interceptors>; - request: Interceptors>; - response: Interceptors>; + error: Interceptors>; + request: Interceptors>; + response: Interceptors>; } export const createInterceptors = (): Middleware< - Req, - Res, - Err, - Options + Req, + Res, + Err, + Options > => ({ - error: new Interceptors>(), - request: new Interceptors>(), - response: new Interceptors>(), + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>() }); const defaultQuerySerializer = createQuerySerializer({ - allowReserved: false, - array: { - explode: true, - style: 'form', - }, - object: { - explode: true, - style: 'deepObject', - }, + allowReserved: false, + array: { + explode: true, + style: 'form' + }, + object: { + explode: true, + style: 'deepObject' + } }); const defaultHeaders = { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }; export const createConfig = ( - override: Config & T> = {}, + override: Config & T> = {} ): Config & T> => ({ - ...jsonBodySerializer, - headers: defaultHeaders, - parseAs: 'auto', - querySerializer: defaultQuerySerializer, - ...override, + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override }); diff --git a/client/ts/core/auth.gen.ts b/client/ts/core/auth.gen.ts index 3ebf9947..247a1f97 100644 --- a/client/ts/core/auth.gen.ts +++ b/client/ts/core/auth.gen.ts @@ -3,39 +3,40 @@ export type AuthToken = string | undefined; export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie'; - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string; - scheme?: 'basic' | 'bearer'; - type: 'apiKey' | 'http'; + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; } export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken ): Promise => { - const token = typeof callback === 'function' ? await callback(auth) : callback; + const token = + typeof callback === 'function' ? await callback(auth) : callback; - if (!token) { - return; - } + if (!token) { + return; + } - if (auth.scheme === 'bearer') { - return `Bearer ${token}`; - } + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}`; - } + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } - return token; + return token; }; diff --git a/client/ts/core/bodySerializer.gen.ts b/client/ts/core/bodySerializer.gen.ts index 67daca60..4fca82ee 100644 --- a/client/ts/core/bodySerializer.gen.ts +++ b/client/ts/core/bodySerializer.gen.ts @@ -1,82 +1,102 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen'; +import type { + ArrayStyle, + ObjectStyle, + SerializerOptions +} from './pathSerializer.gen'; export type QuerySerializer = (query: Record) => string; export type BodySerializer = (body: unknown) => unknown; type QuerySerializerOptionsObject = { - allowReserved?: boolean; - array?: Partial>; - object?: Partial>; + allowReserved?: boolean; + array?: Partial>; + object?: Partial>; }; export type QuerySerializerOptions = QuerySerializerOptionsObject & { - /** - * Per-parameter serialization overrides. When provided, these settings - * override the global array/object settings for specific parameter names. - */ - parameters?: Record; + /** + * Per-parameter serialization overrides. When provided, these settings + * override the global array/object settings for specific parameter names. + */ + parameters?: Record; }; -const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value); - } else if (value instanceof Date) { - data.append(key, value.toISOString()); - } else { - data.append(key, JSON.stringify(value)); - } +const serializeFormDataPair = ( + data: FormData, + key: string, + value: unknown +): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } }; -const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { - if (typeof value === 'string') { - data.append(key, value); - } else { - data.append(key, JSON.stringify(value)); - } +const serializeUrlSearchParamsPair = ( + data: URLSearchParams, + key: string, + value: unknown +): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } }; export const formDataBodySerializer = { - bodySerializer: (body: unknown): FormData => { - const data = new FormData(); + bodySerializer: (body: unknown): FormData => { + const data = new FormData(); - Object.entries(body as Record).forEach(([key, value]) => { - if (value === undefined || value === null) { - return; - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)); - } else { - serializeFormDataPair(data, key, value); - } - }); + Object.entries(body as Record).forEach( + ([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + } + ); - return data; - }, + return data; + } }; export const jsonBodySerializer = { - bodySerializer: (body: unknown): string => - JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)), + bodySerializer: (body: unknown): string => + JSON.stringify(body, (_key, value) => + typeof value === 'bigint' ? value.toString() : value + ) }; export const urlSearchParamsBodySerializer = { - bodySerializer: (body: unknown): string => { - const data = new URLSearchParams(); + bodySerializer: (body: unknown): string => { + const data = new URLSearchParams(); - Object.entries(body as Record).forEach(([key, value]) => { - if (value === undefined || value === null) { - return; - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); - } else { - serializeUrlSearchParamsPair(data, key, value); - } - }); + Object.entries(body as Record).forEach( + ([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => + serializeUrlSearchParamsPair(data, key, v) + ); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + } + ); - return data.toString(); - }, + return data.toString(); + } }; diff --git a/client/ts/core/params.gen.ts b/client/ts/core/params.gen.ts index 7955601a..12729eca 100644 --- a/client/ts/core/params.gen.ts +++ b/client/ts/core/params.gen.ts @@ -3,167 +3,187 @@ type Slot = 'body' | 'headers' | 'path' | 'query'; export type Field = - | { - in: Exclude; - /** - * Field name. This is the name we want the user to see and use. - */ - key: string; - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string; - } - | { - in: Extract; - /** - * Key isn't required for bodies. - */ - key?: string; - map?: string; - } - | { - /** - * Field name. This is the name we want the user to see and use. - */ - key: string; - /** - * Field mapped name. This is the name we want to use in the request. - * If `in` is omitted, `map` aliases `key` to the transport layer. - */ - map: Slot; - }; + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + } + | { + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If `in` is omitted, `map` aliases `key` to the transport layer. + */ + map: Slot; + }; export interface Fields { - allowExtra?: Partial>; - args?: ReadonlyArray; + allowExtra?: Partial>; + args?: ReadonlyArray; } export type FieldsConfig = ReadonlyArray; const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query', + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query' }; const extraPrefixes = Object.entries(extraPrefixesMap); type KeyMap = Map< - string, - | { - in: Slot; - map?: string; - } - | { - in?: never; - map: Slot; - } + string, + | { + in: Slot; + map?: string; + } + | { + in?: never; + map: Slot; + } >; const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map(); - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map, - }); - } - } else if ('key' in config) { - map.set(config.key, { - map: config.map, - }); - } else if (config.args) { - buildKeyMap(config.args, map); + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map + }); + } + } else if ('key' in config) { + map.set(config.key, { + map: config.map + }); + } else if (config.args) { + buildKeyMap(config.args, map); + } } - } - return map; + return map; }; interface Params { - body: unknown; - headers: Record; - path: Record; - query: Record; + body: unknown; + headers: Record; + path: Record; + query: Record; } const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Array.isArray(value) && !Object.keys(value).length) { - delete params[slot as Slot]; + for (const [slot, value] of Object.entries(params)) { + if ( + value && + typeof value === 'object' && + !Array.isArray(value) && + !Object.keys(value).length + ) { + delete params[slot as Slot]; + } } - } }; -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {}, - }; - - const map = buildKeyMap(fields); +export const buildClientParams = ( + args: ReadonlyArray, + fields: FieldsConfig +) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {} + }; - let config: FieldsConfig[number] | undefined; + const map = buildKeyMap(fields); - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index]; - } + let config: FieldsConfig[number] | undefined; - if (!config) { - continue; - } + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)!; - const name = field.map || config.key; - if (field.in) { - (params[field.in] as Record)[name] = arg; + if (!config) { + continue; } - } else { - params.body = arg; - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key); - - if (field) { - if (field.in) { - const name = field.map || key; - (params[field.in] as Record)[name] = value; - } else { - params[field.map] = value; - } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + if (field.in) { + (params[field.in] as Record)[name] = arg; + } + } else { + params.body = arg; + } } else { - const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)); - - if (extra) { - const [prefix, slot] = extra; - (params[slot] as Record)[key.slice(prefix.length)] = value; - } else if ('allowExtra' in config && config.allowExtra) { - for (const [slot, allowed] of Object.entries(config.allowExtra)) { - if (allowed) { - (params[slot as Slot] as Record)[key] = value; - break; - } + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + if (field.in) { + const name = field.map || key; + (params[field.in] as Record)[name] = + value; + } else { + params[field.map] = value; + } + } else { + const extra = extraPrefixes.find(([prefix]) => + key.startsWith(prefix) + ); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[ + key.slice(prefix.length) + ] = value; + } else if ('allowExtra' in config && config.allowExtra) { + for (const [slot, allowed] of Object.entries( + config.allowExtra + )) { + if (allowed) { + ( + params[slot as Slot] as Record< + string, + unknown + > + )[key] = value; + break; + } + } + } + } } - } } - } } - } - stripEmptySlots(params); + stripEmptySlots(params); - return params; + return params; }; diff --git a/client/ts/core/pathSerializer.gen.ts b/client/ts/core/pathSerializer.gen.ts index 994b2848..a36b7d62 100644 --- a/client/ts/core/pathSerializer.gen.ts +++ b/client/ts/core/pathSerializer.gen.ts @@ -1,18 +1,19 @@ // This file is auto-generated by @hey-api/openapi-ts -interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} +interface SerializeOptions + extends SerializePrimitiveOptions, SerializerOptions {} interface SerializePrimitiveOptions { - allowReserved?: boolean; - name: string; + allowReserved?: boolean; + name: string; } export interface SerializerOptions { - /** - * @default true - */ - explode: boolean; - style: T; + /** + * @default true + */ + explode: boolean; + style: T; } export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; @@ -22,150 +23,162 @@ export type ObjectStyle = 'form' | 'deepObject'; type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string; + value: string; } export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.'; - case 'matrix': - return ';'; - case 'simple': - return ','; - default: - return '&'; - } + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } }; export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ','; - case 'pipeDelimited': - return '|'; - case 'spaceDelimited': - return '%20'; - default: - return ','; - } + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } }; export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.'; - case 'matrix': - return ';'; - case 'simple': - return ','; - default: - return '&'; - } + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } }; export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value, + allowReserved, + explode, + name, + style, + value }: SerializeOptions & { - value: unknown[]; + value: unknown[]; }) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)); - switch (style) { - case 'label': - return `.${joinedValues}`; - case 'matrix': - return `;${name}=${joinedValues}`; - case 'simple': - return joinedValues; - default: - return `${name}=${joinedValues}`; + if (!explode) { + const joinedValues = ( + allowReserved + ? value + : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } } - } - - const separator = separatorArrayExplode(style); - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string); - } - - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string, - }); - }) - .join(separator); - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; }; export const serializePrimitiveParam = ({ - allowReserved, - name, - value, + allowReserved, + name, + value }: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return ''; - } + if (value === undefined || value === null) { + return ''; + } - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', - ); - } + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.' + ); + } - return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; }; export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly, + allowReserved, + explode, + name, + style, + value, + valueOnly }: SerializeOptions & { - value: Record | Date; - valueOnly?: boolean; + value: Record | Date; + valueOnly?: boolean; }) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = []; - Object.entries(value).forEach(([key, v]) => { - values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)]; - }); - const joinedValues = values.join(','); - switch (style) { - case 'form': - return `${name}=${joinedValues}`; - case 'label': - return `.${joinedValues}`; - case 'matrix': - return `;${name}=${joinedValues}`; - default: - return joinedValues; + if (value instanceof Date) { + return valueOnly + ? value.toISOString() + : `${name}=${value.toISOString()}`; } - } - - const separator = separatorObjectExplode(style); - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string, - }), - ) - .join(separator); - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [ + ...values, + key, + allowReserved ? (v as string) : encodeURIComponent(v as string) + ]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string + }) + ) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; }; diff --git a/client/ts/core/queryKeySerializer.gen.ts b/client/ts/core/queryKeySerializer.gen.ts index 5000df60..13eedb3d 100644 --- a/client/ts/core/queryKeySerializer.gen.ts +++ b/client/ts/core/queryKeySerializer.gen.ts @@ -4,114 +4,133 @@ * JSON-friendly union that mirrors what Pinia Colada can hash. */ export type JsonValue = - | null - | string - | number - | boolean - | JsonValue[] - | { [key: string]: JsonValue }; + | null + | string + | number + | boolean + | JsonValue[] + | { [key: string]: JsonValue }; /** * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes. */ export const queryKeyJsonReplacer = (_key: string, value: unknown) => { - if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { - return undefined; - } - if (typeof value === 'bigint') { - return value.toString(); - } - if (value instanceof Date) { - return value.toISOString(); - } - return value; + if ( + value === undefined || + typeof value === 'function' || + typeof value === 'symbol' + ) { + return undefined; + } + if (typeof value === 'bigint') { + return value.toString(); + } + if (value instanceof Date) { + return value.toISOString(); + } + return value; }; /** * Safely stringifies a value and parses it back into a JsonValue. */ export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => { - try { - const json = JSON.stringify(input, queryKeyJsonReplacer); - if (json === undefined) { - return undefined; + try { + const json = JSON.stringify(input, queryKeyJsonReplacer); + if (json === undefined) { + return undefined; + } + return JSON.parse(json) as JsonValue; + } catch { + return undefined; } - return JSON.parse(json) as JsonValue; - } catch { - return undefined; - } }; /** * Detects plain objects (including objects with a null prototype). */ const isPlainObject = (value: unknown): value is Record => { - if (value === null || typeof value !== 'object') { - return false; - } - const prototype = Object.getPrototypeOf(value as object); - return prototype === Object.prototype || prototype === null; + if (value === null || typeof value !== 'object') { + return false; + } + const prototype = Object.getPrototypeOf(value as object); + return prototype === Object.prototype || prototype === null; }; /** * Turns URLSearchParams into a sorted JSON object for deterministic keys. */ const serializeSearchParams = (params: URLSearchParams): JsonValue => { - const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b)); - const result: Record = {}; - - for (const [key, value] of entries) { - const existing = result[key]; - if (existing === undefined) { - result[key] = value; - continue; + const entries = Array.from(params.entries()).sort(([a], [b]) => + a.localeCompare(b) + ); + const result: Record = {}; + + for (const [key, value] of entries) { + const existing = result[key]; + if (existing === undefined) { + result[key] = value; + continue; + } + + if (Array.isArray(existing)) { + (existing as string[]).push(value); + } else { + result[key] = [existing, value]; + } } - if (Array.isArray(existing)) { - (existing as string[]).push(value); - } else { - result[key] = [existing, value]; - } - } - - return result; + return result; }; /** * Normalizes any accepted value into a JSON-friendly shape for query keys. */ -export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => { - if (value === null) { - return null; - } +export const serializeQueryKeyValue = ( + value: unknown +): JsonValue | undefined => { + if (value === null) { + return null; + } - if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { - return value; - } + if ( + typeof value === 'string' || + typeof value === 'number' || + typeof value === 'boolean' + ) { + return value; + } - if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { - return undefined; - } + if ( + value === undefined || + typeof value === 'function' || + typeof value === 'symbol' + ) { + return undefined; + } - if (typeof value === 'bigint') { - return value.toString(); - } + if (typeof value === 'bigint') { + return value.toString(); + } - if (value instanceof Date) { - return value.toISOString(); - } + if (value instanceof Date) { + return value.toISOString(); + } - if (Array.isArray(value)) { - return stringifyToJsonValue(value); - } + if (Array.isArray(value)) { + return stringifyToJsonValue(value); + } - if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) { - return serializeSearchParams(value); - } + if ( + typeof URLSearchParams !== 'undefined' && + value instanceof URLSearchParams + ) { + return serializeSearchParams(value); + } - if (isPlainObject(value)) { - return stringifyToJsonValue(value); - } + if (isPlainObject(value)) { + return stringifyToJsonValue(value); + } - return undefined; + return undefined; }; diff --git a/client/ts/core/serverSentEvents.gen.ts b/client/ts/core/serverSentEvents.gen.ts index 6aa6cf02..b94f1435 100644 --- a/client/ts/core/serverSentEvents.gen.ts +++ b/client/ts/core/serverSentEvents.gen.ts @@ -2,242 +2,271 @@ import type { Config } from './types.gen'; -export type ServerSentEventsOptions = Omit & - Pick & { - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch; - /** - * Implementing clients can call request interceptors inside this hook. - */ - onRequest?: (url: string, init: RequestInit) => Promise; - /** - * Callback invoked when a network or parsing error occurs during streaming. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param error The error that occurred. - */ - onSseError?: (error: unknown) => void; - /** - * Callback invoked when an event is streamed from the server. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param event Event streamed from the server. - * @returns Nothing (void). - */ - onSseEvent?: (event: StreamEvent) => void; - serializedBody?: RequestInit['body']; - /** - * Default retry delay in milliseconds. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 3000 - */ - sseDefaultRetryDelay?: number; - /** - * Maximum number of retry attempts before giving up. - */ - sseMaxRetryAttempts?: number; - /** - * Maximum retry delay in milliseconds. - * - * Applies only when exponential backoff is used. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 30000 - */ - sseMaxRetryDelay?: number; - /** - * Optional sleep function for retry backoff. - * - * Defaults to using `setTimeout`. - */ - sseSleepFn?: (ms: number) => Promise; - url: string; - }; +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Implementing clients can call request interceptors inside this hook. + */ + onRequest?: (url: string, init: RequestInit) => Promise; + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + serializedBody?: RequestInit['body']; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; export interface StreamEvent { - data: TData; - event?: string; - id?: string; - retry?: number; + data: TData; + event?: string; + id?: string; + retry?: number; } -export type ServerSentEventsResult = { - stream: AsyncGenerator< - TData extends Record ? TData[keyof TData] : TData, - TReturn, - TNext - >; +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; }; export const createSseClient = ({ - onRequest, - onSseError, - onSseEvent, - responseTransformer, - responseValidator, - sseDefaultRetryDelay, - sseMaxRetryAttempts, - sseMaxRetryDelay, - sseSleepFn, - url, - ...options + onRequest, + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options }: ServerSentEventsOptions): ServerSentEventsResult => { - let lastEventId: string | undefined; - - const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); - - const createStream = async function* () { - let retryDelay: number = sseDefaultRetryDelay ?? 3000; - let attempt = 0; - const signal = options.signal ?? new AbortController().signal; - - while (true) { - if (signal.aborted) break; - - attempt++; - - const headers = - options.headers instanceof Headers - ? options.headers - : new Headers(options.headers as Record | undefined); - - if (lastEventId !== undefined) { - headers.set('Last-Event-ID', lastEventId); - } - - try { - const requestInit: RequestInit = { - redirect: 'follow', - ...options, - body: options.serializedBody, - headers, - signal, - }; - let request = new Request(url, requestInit); - if (onRequest) { - request = await onRequest(url, requestInit); - } - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = options.fetch ?? globalThis.fetch; - const response = await _fetch(request); - - if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`); - - if (!response.body) throw new Error('No body in SSE response'); - - const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); - - let buffer = ''; - - const abortHandler = () => { - try { - reader.cancel(); - } catch { - // noop - } - }; - - signal.addEventListener('abort', abortHandler); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - buffer += value; - // Normalize line endings: CRLF -> LF, then CR -> LF - buffer = buffer.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); - - const chunks = buffer.split('\n\n'); - buffer = chunks.pop() ?? ''; - - for (const chunk of chunks) { - const lines = chunk.split('\n'); - const dataLines: Array = []; - let eventName: string | undefined; - - for (const line of lines) { - if (line.startsWith('data:')) { - dataLines.push(line.replace(/^data:\s*/, '')); - } else if (line.startsWith('event:')) { - eventName = line.replace(/^event:\s*/, ''); - } else if (line.startsWith('id:')) { - lastEventId = line.replace(/^id:\s*/, ''); - } else if (line.startsWith('retry:')) { - const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10); - if (!Number.isNaN(parsed)) { - retryDelay = parsed; - } + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers( + options.headers as Record | undefined + ); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const requestInit: RequestInit = { + redirect: 'follow', + ...options, + body: options.serializedBody, + headers, + signal + }; + let request = new Request(url, requestInit); + if (onRequest) { + request = await onRequest(url, requestInit); } - } + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = options.fetch ?? globalThis.fetch; + const response = await _fetch(request); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}` + ); - let data: unknown; - let parsedJson = false; + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); - if (dataLines.length) { - const rawData = dataLines.join('\n'); try { - data = JSON.parse(rawData); - parsedJson = true; - } catch { - data = rawData; + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + // Normalize line endings: CRLF -> LF, then CR -> LF + buffer = buffer + .replace(/\r\n/g, '\n') + .replace(/\r/g, '\n'); + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push( + line.replace(/^data:\s*/, '') + ); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10 + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); } - } - if (parsedJson) { - if (responseValidator) { - await responseValidator(data); - } + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); - if (responseTransformer) { - data = await responseTransformer(data); + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error } - } - - onSseEvent?.({ - data, - event: eventName, - id: lastEventId, - retry: retryDelay, - }); - - if (dataLines.length) { - yield data as any; - } - } - } - } finally { - signal.removeEventListener('abort', abortHandler); - reader.releaseLock(); - } - - break; // exit loop on normal completion - } catch (error) { - // connection failed or aborted; retry after delay - onSseError?.(error); - if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { - break; // stop after firing error + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000 + ); + await sleep(backoff); + } } + }; - // exponential backoff: double retry each attempt, cap at 30s - const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000); - await sleep(backoff); - } - } - }; - - const stream = createStream(); + const stream = createStream(); - return { stream }; + return { stream }; }; diff --git a/client/ts/core/types.gen.ts b/client/ts/core/types.gen.ts index 97463257..75b20331 100644 --- a/client/ts/core/types.gen.ts +++ b/client/ts/core/types.gen.ts @@ -1,104 +1,118 @@ // This file is auto-generated by @hey-api/openapi-ts import type { Auth, AuthToken } from './auth.gen'; -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen'; +import type { + BodySerializer, + QuerySerializer, + QuerySerializerOptions +} from './bodySerializer.gen'; export type HttpMethod = - | 'connect' - | 'delete' - | 'get' - | 'head' - | 'options' - | 'patch' - | 'post' - | 'put' - | 'trace'; + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; export type Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, - SseFn = never, + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never > = { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn; - getConfig: () => Config; - request: RequestFn; - setConfig: (config: Config) => Config; + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; } & { - [K in HttpMethod]: MethodFn; -} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }); + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null; - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - string | number | boolean | (string | number | boolean)[] | null | undefined | unknown - >; - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: Uppercase; - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions; - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise; - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise; - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise; + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; } type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false; + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K]; + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true + ? never + : K]: T[K]; }; diff --git a/client/ts/core/utils.gen.ts b/client/ts/core/utils.gen.ts index e7ddbe35..881dd87b 100644 --- a/client/ts/core/utils.gen.ts +++ b/client/ts/core/utils.gen.ts @@ -2,139 +2,143 @@ import type { BodySerializer, QuerySerializer } from './bodySerializer.gen'; import { - type ArraySeparatorStyle, - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam, + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam } from './pathSerializer.gen'; export interface PathSerializer { - path: Record; - url: string; + path: Record; + url: string; } export const PATH_PARAM_RE = /\{[^{}]+\}/g; export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url; - const matches = _url.match(PATH_PARAM_RE); - if (matches) { - for (const match of matches) { - let explode = false; - let name = match.substring(1, match.length - 1); - let style: ArraySeparatorStyle = 'simple'; - - if (name.endsWith('*')) { - explode = true; - name = name.substring(0, name.length - 1); - } - - if (name.startsWith('.')) { - name = name.substring(1); - style = 'label'; - } else if (name.startsWith(';')) { - name = name.substring(1); - style = 'matrix'; - } - - const value = path[name]; - - if (value === undefined || value === null) { - continue; - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })); - continue; - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true, - }), - ); - continue; - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string, - })}`, - ); - continue; - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string), - ); - url = url.replace(match, replaceValue); + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }) + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true + }) + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string + })}` + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string) + ); + url = url.replace(match, replaceValue); + } } - } - return url; + return url; }; export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url, + baseUrl, + path, + query, + querySerializer, + url: _url }: { - baseUrl?: string; - path?: Record; - query?: Record; - querySerializer: QuerySerializer; - url: string; + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; }) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; - let url = (baseUrl ?? '') + pathUrl; - if (path) { - url = defaultPathSerializer({ path, url }); - } - let search = query ? querySerializer(query) : ''; - if (search.startsWith('?')) { - search = search.substring(1); - } - if (search) { - url += `?${search}`; - } - return url; + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; }; export function getValidRequestBody(options: { - body?: unknown; - bodySerializer?: BodySerializer | null; - serializedBody?: unknown; + body?: unknown; + bodySerializer?: BodySerializer | null; + serializedBody?: unknown; }) { - const hasBody = options.body !== undefined; - const isSerializedBody = hasBody && options.bodySerializer; + const hasBody = options.body !== undefined; + const isSerializedBody = hasBody && options.bodySerializer; - if (isSerializedBody) { - if ('serializedBody' in options) { - const hasSerializedBody = - options.serializedBody !== undefined && options.serializedBody !== ''; + if (isSerializedBody) { + if ('serializedBody' in options) { + const hasSerializedBody = + options.serializedBody !== undefined && + options.serializedBody !== ''; - return hasSerializedBody ? options.serializedBody : null; - } + return hasSerializedBody ? options.serializedBody : null; + } - // not all clients implement a serializedBody property (i.e. client-axios) - return options.body !== '' ? options.body : null; - } + // not all clients implement a serializedBody property (i.e. client-axios) + return options.body !== '' ? options.body : null; + } - // plain/text body - if (hasBody) { - return options.body; - } + // plain/text body + if (hasBody) { + return options.body; + } - // no body was provided - return undefined; + // no body was provided + return undefined; } diff --git a/client/ts/index.ts b/client/ts/index.ts index e7628069..696f87ef 100644 --- a/client/ts/index.ts +++ b/client/ts/index.ts @@ -1,4 +1,168 @@ // This file is auto-generated by @hey-api/openapi-ts -export { deleteV5AnnouncementsById, getV5About, getV5Announcements, getV5AnnouncementsLatest, getV5AnnouncementsLatestId, getV5Contributors, getV5Manager, getV5ManagerDownloaders, getV5ManagerDownloadersPrerelease, getV5ManagerDownloadersVersion, getV5ManagerDownloadersVersionPrerelease, getV5ManagerHistory, getV5ManagerHistoryPrerelease, getV5ManagerPrerelease, getV5ManagerVersion, getV5ManagerVersionPrerelease, getV5Patches, getV5PatchesHistory, getV5PatchesHistoryPrerelease, getV5PatchesKeys, getV5PatchesPrerelease, getV5PatchesVersion, getV5PatchesVersionPrerelease, getV5Team, type Options, patchV5AnnouncementsById, postV5Announcements } from './sdk.gen'; -export type { About, Announcement, ClientOptions, Contributable, CreateAnnouncement, DeleteV5AnnouncementsByIdData, DeleteV5AnnouncementsByIdError, DeleteV5AnnouncementsByIdErrors, DeleteV5AnnouncementsByIdResponse, DeleteV5AnnouncementsByIdResponses, GetV5AboutData, GetV5AboutResponse, GetV5AboutResponses, GetV5AnnouncementsData, GetV5AnnouncementsLatestData, GetV5AnnouncementsLatestIdData, GetV5AnnouncementsLatestIdResponse, GetV5AnnouncementsLatestIdResponses, GetV5AnnouncementsLatestResponse, GetV5AnnouncementsLatestResponses, GetV5AnnouncementsResponse, GetV5AnnouncementsResponses, GetV5ContributorsData, GetV5ContributorsError, GetV5ContributorsErrors, GetV5ContributorsResponse, GetV5ContributorsResponses, GetV5ManagerData, GetV5ManagerDownloadersData, GetV5ManagerDownloadersError, GetV5ManagerDownloadersErrors, GetV5ManagerDownloadersPrereleaseData, GetV5ManagerDownloadersPrereleaseError, GetV5ManagerDownloadersPrereleaseErrors, GetV5ManagerDownloadersPrereleaseResponse, GetV5ManagerDownloadersPrereleaseResponses, GetV5ManagerDownloadersResponse, GetV5ManagerDownloadersResponses, GetV5ManagerDownloadersVersionData, GetV5ManagerDownloadersVersionError, GetV5ManagerDownloadersVersionErrors, GetV5ManagerDownloadersVersionPrereleaseData, GetV5ManagerDownloadersVersionPrereleaseError, GetV5ManagerDownloadersVersionPrereleaseErrors, GetV5ManagerDownloadersVersionPrereleaseResponse, GetV5ManagerDownloadersVersionPrereleaseResponses, GetV5ManagerDownloadersVersionResponse, GetV5ManagerDownloadersVersionResponses, GetV5ManagerError, GetV5ManagerErrors, GetV5ManagerHistoryData, GetV5ManagerHistoryError, GetV5ManagerHistoryErrors, GetV5ManagerHistoryPrereleaseData, GetV5ManagerHistoryPrereleaseError, GetV5ManagerHistoryPrereleaseErrors, GetV5ManagerHistoryPrereleaseResponse, GetV5ManagerHistoryPrereleaseResponses, GetV5ManagerHistoryResponse, GetV5ManagerHistoryResponses, GetV5ManagerPrereleaseData, GetV5ManagerPrereleaseError, GetV5ManagerPrereleaseErrors, GetV5ManagerPrereleaseResponse, GetV5ManagerPrereleaseResponses, GetV5ManagerResponse, GetV5ManagerResponses, GetV5ManagerVersionData, GetV5ManagerVersionError, GetV5ManagerVersionErrors, GetV5ManagerVersionPrereleaseData, GetV5ManagerVersionPrereleaseError, GetV5ManagerVersionPrereleaseErrors, GetV5ManagerVersionPrereleaseResponse, GetV5ManagerVersionPrereleaseResponses, GetV5ManagerVersionResponse, GetV5ManagerVersionResponses, GetV5PatchesData, GetV5PatchesError, GetV5PatchesErrors, GetV5PatchesHistoryData, GetV5PatchesHistoryError, GetV5PatchesHistoryErrors, GetV5PatchesHistoryPrereleaseData, GetV5PatchesHistoryPrereleaseError, GetV5PatchesHistoryPrereleaseErrors, GetV5PatchesHistoryPrereleaseResponse, GetV5PatchesHistoryPrereleaseResponses, GetV5PatchesHistoryResponse, GetV5PatchesHistoryResponses, GetV5PatchesKeysData, GetV5PatchesKeysResponse, GetV5PatchesKeysResponses, GetV5PatchesPrereleaseData, GetV5PatchesPrereleaseError, GetV5PatchesPrereleaseErrors, GetV5PatchesPrereleaseResponse, GetV5PatchesPrereleaseResponses, GetV5PatchesResponse, GetV5PatchesResponses, GetV5PatchesVersionData, GetV5PatchesVersionError, GetV5PatchesVersionErrors, GetV5PatchesVersionPrereleaseData, GetV5PatchesVersionPrereleaseError, GetV5PatchesVersionPrereleaseErrors, GetV5PatchesVersionPrereleaseResponse, GetV5PatchesVersionPrereleaseResponses, GetV5PatchesVersionResponse, GetV5PatchesVersionResponses, GetV5TeamData, GetV5TeamError, GetV5TeamErrors, GetV5TeamResponse, GetV5TeamResponses, LatestAnnouncementEntry, LatestAnnouncementIdEntry, LatestAnnouncementIdsByTag, LatestAnnouncementsByTag, PatchV5AnnouncementsByIdData, PatchV5AnnouncementsByIdError, PatchV5AnnouncementsByIdErrors, PatchV5AnnouncementsByIdResponse, PatchV5AnnouncementsByIdResponses, PostV5AnnouncementsData, PostV5AnnouncementsError, PostV5AnnouncementsErrors, PostV5AnnouncementsResponse, PostV5AnnouncementsResponses, PublicKey, Release, ReleaseSimple, TeamMember, UpdateAnnouncement, Version } from './types.gen'; +export { + deleteV5AnnouncementsById, + getV5About, + getV5Announcements, + getV5AnnouncementsLatest, + getV5AnnouncementsLatestId, + getV5Contributors, + getV5Manager, + getV5ManagerDownloaders, + getV5ManagerDownloadersPrerelease, + getV5ManagerDownloadersVersion, + getV5ManagerDownloadersVersionPrerelease, + getV5ManagerHistory, + getV5ManagerHistoryPrerelease, + getV5ManagerPrerelease, + getV5ManagerVersion, + getV5ManagerVersionPrerelease, + getV5Patches, + getV5PatchesHistory, + getV5PatchesHistoryPrerelease, + getV5PatchesKeys, + getV5PatchesPrerelease, + getV5PatchesVersion, + getV5PatchesVersionPrerelease, + getV5Team, + type Options, + patchV5AnnouncementsById, + postV5Announcements +} from './sdk.gen'; +export type { + About, + Announcement, + ClientOptions, + Contributable, + CreateAnnouncement, + DeleteV5AnnouncementsByIdData, + DeleteV5AnnouncementsByIdError, + DeleteV5AnnouncementsByIdErrors, + DeleteV5AnnouncementsByIdResponse, + DeleteV5AnnouncementsByIdResponses, + GetV5AboutData, + GetV5AboutResponse, + GetV5AboutResponses, + GetV5AnnouncementsData, + GetV5AnnouncementsLatestData, + GetV5AnnouncementsLatestIdData, + GetV5AnnouncementsLatestIdResponse, + GetV5AnnouncementsLatestIdResponses, + GetV5AnnouncementsLatestResponse, + GetV5AnnouncementsLatestResponses, + GetV5AnnouncementsResponse, + GetV5AnnouncementsResponses, + GetV5ContributorsData, + GetV5ContributorsError, + GetV5ContributorsErrors, + GetV5ContributorsResponse, + GetV5ContributorsResponses, + GetV5ManagerData, + GetV5ManagerDownloadersData, + GetV5ManagerDownloadersError, + GetV5ManagerDownloadersErrors, + GetV5ManagerDownloadersPrereleaseData, + GetV5ManagerDownloadersPrereleaseError, + GetV5ManagerDownloadersPrereleaseErrors, + GetV5ManagerDownloadersPrereleaseResponse, + GetV5ManagerDownloadersPrereleaseResponses, + GetV5ManagerDownloadersResponse, + GetV5ManagerDownloadersResponses, + GetV5ManagerDownloadersVersionData, + GetV5ManagerDownloadersVersionError, + GetV5ManagerDownloadersVersionErrors, + GetV5ManagerDownloadersVersionPrereleaseData, + GetV5ManagerDownloadersVersionPrereleaseError, + GetV5ManagerDownloadersVersionPrereleaseErrors, + GetV5ManagerDownloadersVersionPrereleaseResponse, + GetV5ManagerDownloadersVersionPrereleaseResponses, + GetV5ManagerDownloadersVersionResponse, + GetV5ManagerDownloadersVersionResponses, + GetV5ManagerError, + GetV5ManagerErrors, + GetV5ManagerHistoryData, + GetV5ManagerHistoryError, + GetV5ManagerHistoryErrors, + GetV5ManagerHistoryPrereleaseData, + GetV5ManagerHistoryPrereleaseError, + GetV5ManagerHistoryPrereleaseErrors, + GetV5ManagerHistoryPrereleaseResponse, + GetV5ManagerHistoryPrereleaseResponses, + GetV5ManagerHistoryResponse, + GetV5ManagerHistoryResponses, + GetV5ManagerPrereleaseData, + GetV5ManagerPrereleaseError, + GetV5ManagerPrereleaseErrors, + GetV5ManagerPrereleaseResponse, + GetV5ManagerPrereleaseResponses, + GetV5ManagerResponse, + GetV5ManagerResponses, + GetV5ManagerVersionData, + GetV5ManagerVersionError, + GetV5ManagerVersionErrors, + GetV5ManagerVersionPrereleaseData, + GetV5ManagerVersionPrereleaseError, + GetV5ManagerVersionPrereleaseErrors, + GetV5ManagerVersionPrereleaseResponse, + GetV5ManagerVersionPrereleaseResponses, + GetV5ManagerVersionResponse, + GetV5ManagerVersionResponses, + GetV5PatchesData, + GetV5PatchesError, + GetV5PatchesErrors, + GetV5PatchesHistoryData, + GetV5PatchesHistoryError, + GetV5PatchesHistoryErrors, + GetV5PatchesHistoryPrereleaseData, + GetV5PatchesHistoryPrereleaseError, + GetV5PatchesHistoryPrereleaseErrors, + GetV5PatchesHistoryPrereleaseResponse, + GetV5PatchesHistoryPrereleaseResponses, + GetV5PatchesHistoryResponse, + GetV5PatchesHistoryResponses, + GetV5PatchesKeysData, + GetV5PatchesKeysResponse, + GetV5PatchesKeysResponses, + GetV5PatchesPrereleaseData, + GetV5PatchesPrereleaseError, + GetV5PatchesPrereleaseErrors, + GetV5PatchesPrereleaseResponse, + GetV5PatchesPrereleaseResponses, + GetV5PatchesResponse, + GetV5PatchesResponses, + GetV5PatchesVersionData, + GetV5PatchesVersionError, + GetV5PatchesVersionErrors, + GetV5PatchesVersionPrereleaseData, + GetV5PatchesVersionPrereleaseError, + GetV5PatchesVersionPrereleaseErrors, + GetV5PatchesVersionPrereleaseResponse, + GetV5PatchesVersionPrereleaseResponses, + GetV5PatchesVersionResponse, + GetV5PatchesVersionResponses, + GetV5TeamData, + GetV5TeamError, + GetV5TeamErrors, + GetV5TeamResponse, + GetV5TeamResponses, + LatestAnnouncementEntry, + LatestAnnouncementIdEntry, + LatestAnnouncementIdsByTag, + LatestAnnouncementsByTag, + PatchV5AnnouncementsByIdData, + PatchV5AnnouncementsByIdError, + PatchV5AnnouncementsByIdErrors, + PatchV5AnnouncementsByIdResponse, + PatchV5AnnouncementsByIdResponses, + PostV5AnnouncementsData, + PostV5AnnouncementsError, + PostV5AnnouncementsErrors, + PostV5AnnouncementsResponse, + PostV5AnnouncementsResponses, + PublicKey, + Release, + ReleaseSimple, + TeamMember, + UpdateAnnouncement, + Version +} from './types.gen'; diff --git a/client/ts/sdk.gen.ts b/client/ts/sdk.gen.ts index 4642e937..51222357 100644 --- a/client/ts/sdk.gen.ts +++ b/client/ts/sdk.gen.ts @@ -2,9 +2,86 @@ import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; -import type { DeleteV5AnnouncementsByIdData, DeleteV5AnnouncementsByIdErrors, DeleteV5AnnouncementsByIdResponses, GetV5AboutData, GetV5AboutResponses, GetV5AnnouncementsData, GetV5AnnouncementsLatestData, GetV5AnnouncementsLatestIdData, GetV5AnnouncementsLatestIdResponses, GetV5AnnouncementsLatestResponses, GetV5AnnouncementsResponses, GetV5ContributorsData, GetV5ContributorsErrors, GetV5ContributorsResponses, GetV5ManagerData, GetV5ManagerDownloadersData, GetV5ManagerDownloadersErrors, GetV5ManagerDownloadersPrereleaseData, GetV5ManagerDownloadersPrereleaseErrors, GetV5ManagerDownloadersPrereleaseResponses, GetV5ManagerDownloadersResponses, GetV5ManagerDownloadersVersionData, GetV5ManagerDownloadersVersionErrors, GetV5ManagerDownloadersVersionPrereleaseData, GetV5ManagerDownloadersVersionPrereleaseErrors, GetV5ManagerDownloadersVersionPrereleaseResponses, GetV5ManagerDownloadersVersionResponses, GetV5ManagerErrors, GetV5ManagerHistoryData, GetV5ManagerHistoryErrors, GetV5ManagerHistoryPrereleaseData, GetV5ManagerHistoryPrereleaseErrors, GetV5ManagerHistoryPrereleaseResponses, GetV5ManagerHistoryResponses, GetV5ManagerPrereleaseData, GetV5ManagerPrereleaseErrors, GetV5ManagerPrereleaseResponses, GetV5ManagerResponses, GetV5ManagerVersionData, GetV5ManagerVersionErrors, GetV5ManagerVersionPrereleaseData, GetV5ManagerVersionPrereleaseErrors, GetV5ManagerVersionPrereleaseResponses, GetV5ManagerVersionResponses, GetV5PatchesData, GetV5PatchesErrors, GetV5PatchesHistoryData, GetV5PatchesHistoryErrors, GetV5PatchesHistoryPrereleaseData, GetV5PatchesHistoryPrereleaseErrors, GetV5PatchesHistoryPrereleaseResponses, GetV5PatchesHistoryResponses, GetV5PatchesKeysData, GetV5PatchesKeysResponses, GetV5PatchesPrereleaseData, GetV5PatchesPrereleaseErrors, GetV5PatchesPrereleaseResponses, GetV5PatchesResponses, GetV5PatchesVersionData, GetV5PatchesVersionErrors, GetV5PatchesVersionPrereleaseData, GetV5PatchesVersionPrereleaseErrors, GetV5PatchesVersionPrereleaseResponses, GetV5PatchesVersionResponses, GetV5TeamData, GetV5TeamErrors, GetV5TeamResponses, PatchV5AnnouncementsByIdData, PatchV5AnnouncementsByIdErrors, PatchV5AnnouncementsByIdResponses, PostV5AnnouncementsData, PostV5AnnouncementsErrors, PostV5AnnouncementsResponses } from './types.gen'; +import type { + DeleteV5AnnouncementsByIdData, + DeleteV5AnnouncementsByIdErrors, + DeleteV5AnnouncementsByIdResponses, + GetV5AboutData, + GetV5AboutResponses, + GetV5AnnouncementsData, + GetV5AnnouncementsLatestData, + GetV5AnnouncementsLatestIdData, + GetV5AnnouncementsLatestIdResponses, + GetV5AnnouncementsLatestResponses, + GetV5AnnouncementsResponses, + GetV5ContributorsData, + GetV5ContributorsErrors, + GetV5ContributorsResponses, + GetV5ManagerData, + GetV5ManagerDownloadersData, + GetV5ManagerDownloadersErrors, + GetV5ManagerDownloadersPrereleaseData, + GetV5ManagerDownloadersPrereleaseErrors, + GetV5ManagerDownloadersPrereleaseResponses, + GetV5ManagerDownloadersResponses, + GetV5ManagerDownloadersVersionData, + GetV5ManagerDownloadersVersionErrors, + GetV5ManagerDownloadersVersionPrereleaseData, + GetV5ManagerDownloadersVersionPrereleaseErrors, + GetV5ManagerDownloadersVersionPrereleaseResponses, + GetV5ManagerDownloadersVersionResponses, + GetV5ManagerErrors, + GetV5ManagerHistoryData, + GetV5ManagerHistoryErrors, + GetV5ManagerHistoryPrereleaseData, + GetV5ManagerHistoryPrereleaseErrors, + GetV5ManagerHistoryPrereleaseResponses, + GetV5ManagerHistoryResponses, + GetV5ManagerPrereleaseData, + GetV5ManagerPrereleaseErrors, + GetV5ManagerPrereleaseResponses, + GetV5ManagerResponses, + GetV5ManagerVersionData, + GetV5ManagerVersionErrors, + GetV5ManagerVersionPrereleaseData, + GetV5ManagerVersionPrereleaseErrors, + GetV5ManagerVersionPrereleaseResponses, + GetV5ManagerVersionResponses, + GetV5PatchesData, + GetV5PatchesErrors, + GetV5PatchesHistoryData, + GetV5PatchesHistoryErrors, + GetV5PatchesHistoryPrereleaseData, + GetV5PatchesHistoryPrereleaseErrors, + GetV5PatchesHistoryPrereleaseResponses, + GetV5PatchesHistoryResponses, + GetV5PatchesKeysData, + GetV5PatchesKeysResponses, + GetV5PatchesPrereleaseData, + GetV5PatchesPrereleaseErrors, + GetV5PatchesPrereleaseResponses, + GetV5PatchesResponses, + GetV5PatchesVersionData, + GetV5PatchesVersionErrors, + GetV5PatchesVersionPrereleaseData, + GetV5PatchesVersionPrereleaseErrors, + GetV5PatchesVersionPrereleaseResponses, + GetV5PatchesVersionResponses, + GetV5TeamData, + GetV5TeamErrors, + GetV5TeamResponses, + PatchV5AnnouncementsByIdData, + PatchV5AnnouncementsByIdErrors, + PatchV5AnnouncementsByIdResponses, + PostV5AnnouncementsData, + PostV5AnnouncementsErrors, + PostV5AnnouncementsResponses +} from './types.gen'; -export type Options = Options2 & { +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean +> = Options2 & { /** * You can provide a client instance returned by `createClient()` instead of * individual options. This might be also useful if you want to implement a @@ -23,199 +100,398 @@ export type Options(options?: Options) => (options?.client ?? client).get({ url: '/v5/patches', ...options }); +export const getV5Patches = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesResponses, + GetV5PatchesErrors, + ThrowOnError + >({ url: '/v5/patches', ...options }); /** * Get current patches prerelease * * Get the current patches prerelease. */ -export const getV5PatchesPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/prerelease', ...options }); +export const getV5PatchesPrerelease = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesPrereleaseResponses, + GetV5PatchesPrereleaseErrors, + ThrowOnError + >({ url: '/v5/patches/prerelease', ...options }); /** * Get current patches release version * * Get the current stable patches release version. */ -export const getV5PatchesVersion = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/version', ...options }); +export const getV5PatchesVersion = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesVersionResponses, + GetV5PatchesVersionErrors, + ThrowOnError + >({ url: '/v5/patches/version', ...options }); /** * Get current patches prerelease version * * Get the current patches prerelease version. */ -export const getV5PatchesVersionPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/version/prerelease', ...options }); +export const getV5PatchesVersionPrerelease = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesVersionPrereleaseResponses, + GetV5PatchesVersionPrereleaseErrors, + ThrowOnError + >({ url: '/v5/patches/version/prerelease', ...options }); /** * Get patches release history * * Get the stable patches release history. */ -export const getV5PatchesHistory = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/history', ...options }); +export const getV5PatchesHistory = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesHistoryResponses, + GetV5PatchesHistoryErrors, + ThrowOnError + >({ url: '/v5/patches/history', ...options }); /** * Get patches prerelease history * * Get the patches prerelease history. */ -export const getV5PatchesHistoryPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/history/prerelease', ...options }); +export const getV5PatchesHistoryPrerelease = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesHistoryPrereleaseResponses, + GetV5PatchesHistoryPrereleaseErrors, + ThrowOnError + >({ url: '/v5/patches/history/prerelease', ...options }); /** * Get patches public keys * * Get the public keys for verifying patches assets. */ -export const getV5PatchesKeys = (options?: Options) => (options?.client ?? client).get({ url: '/v5/patches/keys', ...options }); +export const getV5PatchesKeys = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5PatchesKeysResponses, + unknown, + ThrowOnError + >({ url: '/v5/patches/keys', ...options }); /** * Get current manager release * * Get the current stable manager release. */ -export const getV5Manager = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager', ...options }); +export const getV5Manager = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerResponses, + GetV5ManagerErrors, + ThrowOnError + >({ url: '/v5/manager', ...options }); /** * Get current manager prerelease * * Get the current manager prerelease. */ -export const getV5ManagerPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/prerelease', ...options }); +export const getV5ManagerPrerelease = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerPrereleaseResponses, + GetV5ManagerPrereleaseErrors, + ThrowOnError + >({ url: '/v5/manager/prerelease', ...options }); /** * Get current manager release version * * Get the current stable manager release version. */ -export const getV5ManagerVersion = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/version', ...options }); +export const getV5ManagerVersion = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerVersionResponses, + GetV5ManagerVersionErrors, + ThrowOnError + >({ url: '/v5/manager/version', ...options }); /** * Get current manager prerelease version * * Get the current manager prerelease version. */ -export const getV5ManagerVersionPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/version/prerelease', ...options }); +export const getV5ManagerVersionPrerelease = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerVersionPrereleaseResponses, + GetV5ManagerVersionPrereleaseErrors, + ThrowOnError + >({ url: '/v5/manager/version/prerelease', ...options }); /** * Get manager release history * * Get the stable manager release history. */ -export const getV5ManagerHistory = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/history', ...options }); +export const getV5ManagerHistory = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerHistoryResponses, + GetV5ManagerHistoryErrors, + ThrowOnError + >({ url: '/v5/manager/history', ...options }); /** * Get manager prerelease history * * Get the manager prerelease history. */ -export const getV5ManagerHistoryPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/history/prerelease', ...options }); +export const getV5ManagerHistoryPrerelease = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerHistoryPrereleaseResponses, + GetV5ManagerHistoryPrereleaseErrors, + ThrowOnError + >({ url: '/v5/manager/history/prerelease', ...options }); /** * Get current manager downloaders release * * Get the current stable manager downloaders release. */ -export const getV5ManagerDownloaders = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders', ...options }); +export const getV5ManagerDownloaders = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerDownloadersResponses, + GetV5ManagerDownloadersErrors, + ThrowOnError + >({ url: '/v5/manager/downloaders', ...options }); /** * Get current manager downloaders prerelease * * Get the current manager downloaders prerelease. */ -export const getV5ManagerDownloadersPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders/prerelease', ...options }); +export const getV5ManagerDownloadersPrerelease = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerDownloadersPrereleaseResponses, + GetV5ManagerDownloadersPrereleaseErrors, + ThrowOnError + >({ url: '/v5/manager/downloaders/prerelease', ...options }); /** * Get current manager downloaders release version * * Get the current stable manager downloaders release version. */ -export const getV5ManagerDownloadersVersion = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders/version', ...options }); +export const getV5ManagerDownloadersVersion = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5ManagerDownloadersVersionResponses, + GetV5ManagerDownloadersVersionErrors, + ThrowOnError + >({ url: '/v5/manager/downloaders/version', ...options }); /** * Get current manager downloaders prerelease version * * Get the current manager downloaders prerelease version. */ -export const getV5ManagerDownloadersVersionPrerelease = (options?: Options) => (options?.client ?? client).get({ url: '/v5/manager/downloaders/version/prerelease', ...options }); +export const getV5ManagerDownloadersVersionPrerelease = < + ThrowOnError extends boolean = false +>( + options?: Options< + GetV5ManagerDownloadersVersionPrereleaseData, + ThrowOnError + > +) => + (options?.client ?? client).get< + GetV5ManagerDownloadersVersionPrereleaseResponses, + GetV5ManagerDownloadersVersionPrereleaseErrors, + ThrowOnError + >({ url: '/v5/manager/downloaders/version/prerelease', ...options }); /** * Get all announcements * * Get all announcements ordered by newest first. */ -export const getV5Announcements = (options?: Options) => (options?.client ?? client).get({ url: '/v5/announcements', ...options }); +export const getV5Announcements = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5AnnouncementsResponses, + unknown, + ThrowOnError + >({ url: '/v5/announcements', ...options }); /** * Create an announcement * * Create a new announcement. Requires bearer token authentication. */ -export const postV5Announcements = (options?: Options) => (options?.client ?? client).post({ - security: [{ scheme: 'bearer', type: 'http' }], - url: '/v5/announcements', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } -}); +export const postV5Announcements = ( + options?: Options +) => + (options?.client ?? client).post< + PostV5AnnouncementsResponses, + PostV5AnnouncementsErrors, + ThrowOnError + >({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v5/announcements', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options?.headers + } + }); /** * Get the latest announcement for each tag * * Get the newest announcement for every available announcement tag. */ -export const getV5AnnouncementsLatest = (options?: Options) => (options?.client ?? client).get({ url: '/v5/announcements/latest', ...options }); +export const getV5AnnouncementsLatest = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5AnnouncementsLatestResponses, + unknown, + ThrowOnError + >({ url: '/v5/announcements/latest', ...options }); /** * Get the latest announcement ID for each tag * * Get the ID of the newest announcement for every available announcement tag. */ -export const getV5AnnouncementsLatestId = (options?: Options) => (options?.client ?? client).get({ url: '/v5/announcements/latest/id', ...options }); +export const getV5AnnouncementsLatestId = < + ThrowOnError extends boolean = false +>( + options?: Options +) => + (options?.client ?? client).get< + GetV5AnnouncementsLatestIdResponses, + unknown, + ThrowOnError + >({ url: '/v5/announcements/latest/id', ...options }); /** * Delete an announcement * * Delete an announcement. Requires bearer token authentication. */ -export const deleteV5AnnouncementsById = (options: Options) => (options.client ?? client).delete({ - security: [{ scheme: 'bearer', type: 'http' }], - url: '/v5/announcements/{id}', - ...options -}); +export const deleteV5AnnouncementsById = ( + options: Options +) => + (options.client ?? client).delete< + DeleteV5AnnouncementsByIdResponses, + DeleteV5AnnouncementsByIdErrors, + ThrowOnError + >({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v5/announcements/{id}', + ...options + }); /** * Update an announcement * * Update an existing announcement. Requires bearer token authentication. */ -export const patchV5AnnouncementsById = (options: Options) => (options.client ?? client).patch({ - security: [{ scheme: 'bearer', type: 'http' }], - url: '/v5/announcements/{id}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } -}); +export const patchV5AnnouncementsById = ( + options: Options +) => + (options.client ?? client).patch< + PatchV5AnnouncementsByIdResponses, + PatchV5AnnouncementsByIdErrors, + ThrowOnError + >({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v5/announcements/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } + }); /** * Get contributors * * Get the list of contributors for each configured repository. */ -export const getV5Contributors = (options?: Options) => (options?.client ?? client).get({ url: '/v5/contributors', ...options }); +export const getV5Contributors = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5ContributorsResponses, + GetV5ContributorsErrors, + ThrowOnError + >({ url: '/v5/contributors', ...options }); /** * Get team members * * Get the list of team members from the organization. */ -export const getV5Team = (options?: Options) => (options?.client ?? client).get({ url: '/v5/team', ...options }); +export const getV5Team = ( + options?: Options +) => + (options?.client ?? client).get< + GetV5TeamResponses, + GetV5TeamErrors, + ThrowOnError + >({ url: '/v5/team', ...options }); /** * Get about * * Get information about the API. */ -export const getV5About = (options?: Options) => (options?.client ?? client).get({ url: '/v5/about', ...options }); +export const getV5About = ( + options?: Options +) => + (options?.client ?? client).get( + { url: '/v5/about', ...options } + ); diff --git a/client/ts/types.gen.ts b/client/ts/types.gen.ts index 5a79aeed..ba7a7d8b 100644 --- a/client/ts/types.gen.ts +++ b/client/ts/types.gen.ts @@ -1,7 +1,10 @@ // This file is auto-generated by @hey-api/openapi-ts export type ClientOptions = { - baseUrl: 'https://api.revanced.app' | `${string}://{customServer}` | (string & {}); + baseUrl: + | 'https://api.revanced.app' + | `${string}://{customServer}` + | (string & {}); }; export type Release = { @@ -164,7 +167,8 @@ export type GetV5PatchesResponses = { 200: Release; }; -export type GetV5PatchesResponse = GetV5PatchesResponses[keyof GetV5PatchesResponses]; +export type GetV5PatchesResponse = + GetV5PatchesResponses[keyof GetV5PatchesResponses]; export type GetV5PatchesPrereleaseData = { body?: never; @@ -182,7 +186,8 @@ export type GetV5PatchesPrereleaseErrors = { }; }; -export type GetV5PatchesPrereleaseError = GetV5PatchesPrereleaseErrors[keyof GetV5PatchesPrereleaseErrors]; +export type GetV5PatchesPrereleaseError = + GetV5PatchesPrereleaseErrors[keyof GetV5PatchesPrereleaseErrors]; export type GetV5PatchesPrereleaseResponses = { /** @@ -191,7 +196,8 @@ export type GetV5PatchesPrereleaseResponses = { 200: Release; }; -export type GetV5PatchesPrereleaseResponse = GetV5PatchesPrereleaseResponses[keyof GetV5PatchesPrereleaseResponses]; +export type GetV5PatchesPrereleaseResponse = + GetV5PatchesPrereleaseResponses[keyof GetV5PatchesPrereleaseResponses]; export type GetV5PatchesVersionData = { body?: never; @@ -209,7 +215,8 @@ export type GetV5PatchesVersionErrors = { }; }; -export type GetV5PatchesVersionError = GetV5PatchesVersionErrors[keyof GetV5PatchesVersionErrors]; +export type GetV5PatchesVersionError = + GetV5PatchesVersionErrors[keyof GetV5PatchesVersionErrors]; export type GetV5PatchesVersionResponses = { /** @@ -218,7 +225,8 @@ export type GetV5PatchesVersionResponses = { 200: Version; }; -export type GetV5PatchesVersionResponse = GetV5PatchesVersionResponses[keyof GetV5PatchesVersionResponses]; +export type GetV5PatchesVersionResponse = + GetV5PatchesVersionResponses[keyof GetV5PatchesVersionResponses]; export type GetV5PatchesVersionPrereleaseData = { body?: never; @@ -236,7 +244,8 @@ export type GetV5PatchesVersionPrereleaseErrors = { }; }; -export type GetV5PatchesVersionPrereleaseError = GetV5PatchesVersionPrereleaseErrors[keyof GetV5PatchesVersionPrereleaseErrors]; +export type GetV5PatchesVersionPrereleaseError = + GetV5PatchesVersionPrereleaseErrors[keyof GetV5PatchesVersionPrereleaseErrors]; export type GetV5PatchesVersionPrereleaseResponses = { /** @@ -245,7 +254,8 @@ export type GetV5PatchesVersionPrereleaseResponses = { 200: Version; }; -export type GetV5PatchesVersionPrereleaseResponse = GetV5PatchesVersionPrereleaseResponses[keyof GetV5PatchesVersionPrereleaseResponses]; +export type GetV5PatchesVersionPrereleaseResponse = + GetV5PatchesVersionPrereleaseResponses[keyof GetV5PatchesVersionPrereleaseResponses]; export type GetV5PatchesHistoryData = { body?: never; @@ -263,7 +273,8 @@ export type GetV5PatchesHistoryErrors = { }; }; -export type GetV5PatchesHistoryError = GetV5PatchesHistoryErrors[keyof GetV5PatchesHistoryErrors]; +export type GetV5PatchesHistoryError = + GetV5PatchesHistoryErrors[keyof GetV5PatchesHistoryErrors]; export type GetV5PatchesHistoryResponses = { /** @@ -272,7 +283,8 @@ export type GetV5PatchesHistoryResponses = { 200: Array; }; -export type GetV5PatchesHistoryResponse = GetV5PatchesHistoryResponses[keyof GetV5PatchesHistoryResponses]; +export type GetV5PatchesHistoryResponse = + GetV5PatchesHistoryResponses[keyof GetV5PatchesHistoryResponses]; export type GetV5PatchesHistoryPrereleaseData = { body?: never; @@ -290,7 +302,8 @@ export type GetV5PatchesHistoryPrereleaseErrors = { }; }; -export type GetV5PatchesHistoryPrereleaseError = GetV5PatchesHistoryPrereleaseErrors[keyof GetV5PatchesHistoryPrereleaseErrors]; +export type GetV5PatchesHistoryPrereleaseError = + GetV5PatchesHistoryPrereleaseErrors[keyof GetV5PatchesHistoryPrereleaseErrors]; export type GetV5PatchesHistoryPrereleaseResponses = { /** @@ -299,7 +312,8 @@ export type GetV5PatchesHistoryPrereleaseResponses = { 200: Array; }; -export type GetV5PatchesHistoryPrereleaseResponse = GetV5PatchesHistoryPrereleaseResponses[keyof GetV5PatchesHistoryPrereleaseResponses]; +export type GetV5PatchesHistoryPrereleaseResponse = + GetV5PatchesHistoryPrereleaseResponses[keyof GetV5PatchesHistoryPrereleaseResponses]; export type GetV5PatchesKeysData = { body?: never; @@ -315,7 +329,8 @@ export type GetV5PatchesKeysResponses = { 200: PublicKey; }; -export type GetV5PatchesKeysResponse = GetV5PatchesKeysResponses[keyof GetV5PatchesKeysResponses]; +export type GetV5PatchesKeysResponse = + GetV5PatchesKeysResponses[keyof GetV5PatchesKeysResponses]; export type GetV5ManagerData = { body?: never; @@ -342,7 +357,8 @@ export type GetV5ManagerResponses = { 200: Release; }; -export type GetV5ManagerResponse = GetV5ManagerResponses[keyof GetV5ManagerResponses]; +export type GetV5ManagerResponse = + GetV5ManagerResponses[keyof GetV5ManagerResponses]; export type GetV5ManagerPrereleaseData = { body?: never; @@ -360,7 +376,8 @@ export type GetV5ManagerPrereleaseErrors = { }; }; -export type GetV5ManagerPrereleaseError = GetV5ManagerPrereleaseErrors[keyof GetV5ManagerPrereleaseErrors]; +export type GetV5ManagerPrereleaseError = + GetV5ManagerPrereleaseErrors[keyof GetV5ManagerPrereleaseErrors]; export type GetV5ManagerPrereleaseResponses = { /** @@ -369,7 +386,8 @@ export type GetV5ManagerPrereleaseResponses = { 200: Release; }; -export type GetV5ManagerPrereleaseResponse = GetV5ManagerPrereleaseResponses[keyof GetV5ManagerPrereleaseResponses]; +export type GetV5ManagerPrereleaseResponse = + GetV5ManagerPrereleaseResponses[keyof GetV5ManagerPrereleaseResponses]; export type GetV5ManagerVersionData = { body?: never; @@ -387,7 +405,8 @@ export type GetV5ManagerVersionErrors = { }; }; -export type GetV5ManagerVersionError = GetV5ManagerVersionErrors[keyof GetV5ManagerVersionErrors]; +export type GetV5ManagerVersionError = + GetV5ManagerVersionErrors[keyof GetV5ManagerVersionErrors]; export type GetV5ManagerVersionResponses = { /** @@ -396,7 +415,8 @@ export type GetV5ManagerVersionResponses = { 200: Version; }; -export type GetV5ManagerVersionResponse = GetV5ManagerVersionResponses[keyof GetV5ManagerVersionResponses]; +export type GetV5ManagerVersionResponse = + GetV5ManagerVersionResponses[keyof GetV5ManagerVersionResponses]; export type GetV5ManagerVersionPrereleaseData = { body?: never; @@ -414,7 +434,8 @@ export type GetV5ManagerVersionPrereleaseErrors = { }; }; -export type GetV5ManagerVersionPrereleaseError = GetV5ManagerVersionPrereleaseErrors[keyof GetV5ManagerVersionPrereleaseErrors]; +export type GetV5ManagerVersionPrereleaseError = + GetV5ManagerVersionPrereleaseErrors[keyof GetV5ManagerVersionPrereleaseErrors]; export type GetV5ManagerVersionPrereleaseResponses = { /** @@ -423,7 +444,8 @@ export type GetV5ManagerVersionPrereleaseResponses = { 200: Version; }; -export type GetV5ManagerVersionPrereleaseResponse = GetV5ManagerVersionPrereleaseResponses[keyof GetV5ManagerVersionPrereleaseResponses]; +export type GetV5ManagerVersionPrereleaseResponse = + GetV5ManagerVersionPrereleaseResponses[keyof GetV5ManagerVersionPrereleaseResponses]; export type GetV5ManagerHistoryData = { body?: never; @@ -441,7 +463,8 @@ export type GetV5ManagerHistoryErrors = { }; }; -export type GetV5ManagerHistoryError = GetV5ManagerHistoryErrors[keyof GetV5ManagerHistoryErrors]; +export type GetV5ManagerHistoryError = + GetV5ManagerHistoryErrors[keyof GetV5ManagerHistoryErrors]; export type GetV5ManagerHistoryResponses = { /** @@ -450,7 +473,8 @@ export type GetV5ManagerHistoryResponses = { 200: Array; }; -export type GetV5ManagerHistoryResponse = GetV5ManagerHistoryResponses[keyof GetV5ManagerHistoryResponses]; +export type GetV5ManagerHistoryResponse = + GetV5ManagerHistoryResponses[keyof GetV5ManagerHistoryResponses]; export type GetV5ManagerHistoryPrereleaseData = { body?: never; @@ -468,7 +492,8 @@ export type GetV5ManagerHistoryPrereleaseErrors = { }; }; -export type GetV5ManagerHistoryPrereleaseError = GetV5ManagerHistoryPrereleaseErrors[keyof GetV5ManagerHistoryPrereleaseErrors]; +export type GetV5ManagerHistoryPrereleaseError = + GetV5ManagerHistoryPrereleaseErrors[keyof GetV5ManagerHistoryPrereleaseErrors]; export type GetV5ManagerHistoryPrereleaseResponses = { /** @@ -477,7 +502,8 @@ export type GetV5ManagerHistoryPrereleaseResponses = { 200: Array; }; -export type GetV5ManagerHistoryPrereleaseResponse = GetV5ManagerHistoryPrereleaseResponses[keyof GetV5ManagerHistoryPrereleaseResponses]; +export type GetV5ManagerHistoryPrereleaseResponse = + GetV5ManagerHistoryPrereleaseResponses[keyof GetV5ManagerHistoryPrereleaseResponses]; export type GetV5ManagerDownloadersData = { body?: never; @@ -495,7 +521,8 @@ export type GetV5ManagerDownloadersErrors = { }; }; -export type GetV5ManagerDownloadersError = GetV5ManagerDownloadersErrors[keyof GetV5ManagerDownloadersErrors]; +export type GetV5ManagerDownloadersError = + GetV5ManagerDownloadersErrors[keyof GetV5ManagerDownloadersErrors]; export type GetV5ManagerDownloadersResponses = { /** @@ -504,7 +531,8 @@ export type GetV5ManagerDownloadersResponses = { 200: Release; }; -export type GetV5ManagerDownloadersResponse = GetV5ManagerDownloadersResponses[keyof GetV5ManagerDownloadersResponses]; +export type GetV5ManagerDownloadersResponse = + GetV5ManagerDownloadersResponses[keyof GetV5ManagerDownloadersResponses]; export type GetV5ManagerDownloadersPrereleaseData = { body?: never; @@ -522,7 +550,8 @@ export type GetV5ManagerDownloadersPrereleaseErrors = { }; }; -export type GetV5ManagerDownloadersPrereleaseError = GetV5ManagerDownloadersPrereleaseErrors[keyof GetV5ManagerDownloadersPrereleaseErrors]; +export type GetV5ManagerDownloadersPrereleaseError = + GetV5ManagerDownloadersPrereleaseErrors[keyof GetV5ManagerDownloadersPrereleaseErrors]; export type GetV5ManagerDownloadersPrereleaseResponses = { /** @@ -531,7 +560,8 @@ export type GetV5ManagerDownloadersPrereleaseResponses = { 200: Release; }; -export type GetV5ManagerDownloadersPrereleaseResponse = GetV5ManagerDownloadersPrereleaseResponses[keyof GetV5ManagerDownloadersPrereleaseResponses]; +export type GetV5ManagerDownloadersPrereleaseResponse = + GetV5ManagerDownloadersPrereleaseResponses[keyof GetV5ManagerDownloadersPrereleaseResponses]; export type GetV5ManagerDownloadersVersionData = { body?: never; @@ -549,7 +579,8 @@ export type GetV5ManagerDownloadersVersionErrors = { }; }; -export type GetV5ManagerDownloadersVersionError = GetV5ManagerDownloadersVersionErrors[keyof GetV5ManagerDownloadersVersionErrors]; +export type GetV5ManagerDownloadersVersionError = + GetV5ManagerDownloadersVersionErrors[keyof GetV5ManagerDownloadersVersionErrors]; export type GetV5ManagerDownloadersVersionResponses = { /** @@ -558,7 +589,8 @@ export type GetV5ManagerDownloadersVersionResponses = { 200: Version; }; -export type GetV5ManagerDownloadersVersionResponse = GetV5ManagerDownloadersVersionResponses[keyof GetV5ManagerDownloadersVersionResponses]; +export type GetV5ManagerDownloadersVersionResponse = + GetV5ManagerDownloadersVersionResponses[keyof GetV5ManagerDownloadersVersionResponses]; export type GetV5ManagerDownloadersVersionPrereleaseData = { body?: never; @@ -576,7 +608,8 @@ export type GetV5ManagerDownloadersVersionPrereleaseErrors = { }; }; -export type GetV5ManagerDownloadersVersionPrereleaseError = GetV5ManagerDownloadersVersionPrereleaseErrors[keyof GetV5ManagerDownloadersVersionPrereleaseErrors]; +export type GetV5ManagerDownloadersVersionPrereleaseError = + GetV5ManagerDownloadersVersionPrereleaseErrors[keyof GetV5ManagerDownloadersVersionPrereleaseErrors]; export type GetV5ManagerDownloadersVersionPrereleaseResponses = { /** @@ -585,7 +618,8 @@ export type GetV5ManagerDownloadersVersionPrereleaseResponses = { 200: Version; }; -export type GetV5ManagerDownloadersVersionPrereleaseResponse = GetV5ManagerDownloadersVersionPrereleaseResponses[keyof GetV5ManagerDownloadersVersionPrereleaseResponses]; +export type GetV5ManagerDownloadersVersionPrereleaseResponse = + GetV5ManagerDownloadersVersionPrereleaseResponses[keyof GetV5ManagerDownloadersVersionPrereleaseResponses]; export type GetV5AnnouncementsData = { body?: never; @@ -601,7 +635,8 @@ export type GetV5AnnouncementsResponses = { 200: Array; }; -export type GetV5AnnouncementsResponse = GetV5AnnouncementsResponses[keyof GetV5AnnouncementsResponses]; +export type GetV5AnnouncementsResponse = + GetV5AnnouncementsResponses[keyof GetV5AnnouncementsResponses]; export type PostV5AnnouncementsData = { body?: CreateAnnouncement; @@ -625,7 +660,8 @@ export type PostV5AnnouncementsErrors = { }; }; -export type PostV5AnnouncementsError = PostV5AnnouncementsErrors[keyof PostV5AnnouncementsErrors]; +export type PostV5AnnouncementsError = + PostV5AnnouncementsErrors[keyof PostV5AnnouncementsErrors]; export type PostV5AnnouncementsResponses = { /** @@ -634,7 +670,8 @@ export type PostV5AnnouncementsResponses = { 201: Announcement; }; -export type PostV5AnnouncementsResponse = PostV5AnnouncementsResponses[keyof PostV5AnnouncementsResponses]; +export type PostV5AnnouncementsResponse = + PostV5AnnouncementsResponses[keyof PostV5AnnouncementsResponses]; export type GetV5AnnouncementsLatestData = { body?: never; @@ -650,7 +687,8 @@ export type GetV5AnnouncementsLatestResponses = { 200: LatestAnnouncementsByTag; }; -export type GetV5AnnouncementsLatestResponse = GetV5AnnouncementsLatestResponses[keyof GetV5AnnouncementsLatestResponses]; +export type GetV5AnnouncementsLatestResponse = + GetV5AnnouncementsLatestResponses[keyof GetV5AnnouncementsLatestResponses]; export type GetV5AnnouncementsLatestIdData = { body?: never; @@ -666,7 +704,8 @@ export type GetV5AnnouncementsLatestIdResponses = { 200: LatestAnnouncementIdsByTag; }; -export type GetV5AnnouncementsLatestIdResponse = GetV5AnnouncementsLatestIdResponses[keyof GetV5AnnouncementsLatestIdResponses]; +export type GetV5AnnouncementsLatestIdResponse = + GetV5AnnouncementsLatestIdResponses[keyof GetV5AnnouncementsLatestIdResponses]; export type DeleteV5AnnouncementsByIdData = { body?: never; @@ -701,7 +740,8 @@ export type DeleteV5AnnouncementsByIdErrors = { }; }; -export type DeleteV5AnnouncementsByIdError = DeleteV5AnnouncementsByIdErrors[keyof DeleteV5AnnouncementsByIdErrors]; +export type DeleteV5AnnouncementsByIdError = + DeleteV5AnnouncementsByIdErrors[keyof DeleteV5AnnouncementsByIdErrors]; export type DeleteV5AnnouncementsByIdResponses = { /** @@ -710,7 +750,8 @@ export type DeleteV5AnnouncementsByIdResponses = { 204: void; }; -export type DeleteV5AnnouncementsByIdResponse = DeleteV5AnnouncementsByIdResponses[keyof DeleteV5AnnouncementsByIdResponses]; +export type DeleteV5AnnouncementsByIdResponse = + DeleteV5AnnouncementsByIdResponses[keyof DeleteV5AnnouncementsByIdResponses]; export type PatchV5AnnouncementsByIdData = { body?: UpdateAnnouncement; @@ -745,7 +786,8 @@ export type PatchV5AnnouncementsByIdErrors = { }; }; -export type PatchV5AnnouncementsByIdError = PatchV5AnnouncementsByIdErrors[keyof PatchV5AnnouncementsByIdErrors]; +export type PatchV5AnnouncementsByIdError = + PatchV5AnnouncementsByIdErrors[keyof PatchV5AnnouncementsByIdErrors]; export type PatchV5AnnouncementsByIdResponses = { /** @@ -754,7 +796,8 @@ export type PatchV5AnnouncementsByIdResponses = { 200: Announcement; }; -export type PatchV5AnnouncementsByIdResponse = PatchV5AnnouncementsByIdResponses[keyof PatchV5AnnouncementsByIdResponses]; +export type PatchV5AnnouncementsByIdResponse = + PatchV5AnnouncementsByIdResponses[keyof PatchV5AnnouncementsByIdResponses]; export type GetV5ContributorsData = { body?: never; @@ -772,7 +815,8 @@ export type GetV5ContributorsErrors = { }; }; -export type GetV5ContributorsError = GetV5ContributorsErrors[keyof GetV5ContributorsErrors]; +export type GetV5ContributorsError = + GetV5ContributorsErrors[keyof GetV5ContributorsErrors]; export type GetV5ContributorsResponses = { /** @@ -781,7 +825,8 @@ export type GetV5ContributorsResponses = { 200: Array; }; -export type GetV5ContributorsResponse = GetV5ContributorsResponses[keyof GetV5ContributorsResponses]; +export type GetV5ContributorsResponse = + GetV5ContributorsResponses[keyof GetV5ContributorsResponses]; export type GetV5TeamData = { body?: never; diff --git a/src/schemas/contributors.ts b/src/schemas/contributors.ts index 247130bd..5bcfe643 100644 --- a/src/schemas/contributors.ts +++ b/src/schemas/contributors.ts @@ -12,11 +12,9 @@ export const ContributorSchema = z.object({ export const ContributableSchema = z .object({ name: z.string().openapi({ example: 'ReVanced Patches' }), - url: z - .url() - .openapi({ - example: 'https://github.com/revanced/revanced-patches' - }), + url: z.url().openapi({ + example: 'https://github.com/revanced/revanced-patches' + }), contributors: z.array(ContributorSchema) }) .openapi('Contributable'); @@ -33,11 +31,9 @@ export const GpgKeySchema = z export const TeamMemberSchema = z .object({ name: z.string().openapi({ example: 'oSumAtrIX' }), - avatar_url: z - .url() - .openapi({ - example: 'https://avatars.githubusercontent.com/u/...' - }), + avatar_url: z.url().openapi({ + example: 'https://avatars.githubusercontent.com/u/...' + }), url: z.url().openapi({ example: 'https://github.com/oSumAtrIX' }), bio: z.string().nullable().openapi({ example: 'Some bio text' }), gpg_key: GpgKeySchema From 027b861490314e22deac87452616284e9836213a Mon Sep 17 00:00:00 2001 From: madkarmaa Date: Mon, 23 Mar 2026 11:14:25 +0100 Subject: [PATCH 5/6] feat: make the ts client an npm package --- .prettierignore | 5 +- bun.lock | 350 ++++++++++++++++++++++++++++++++++++---- client/ts/.gitignore | 34 ++++ client/ts/package.json | 26 +++ client/ts/tsconfig.json | 32 ++++ package.json | 8 +- 6 files changed, 424 insertions(+), 31 deletions(-) create mode 100644 client/ts/.gitignore create mode 100644 client/ts/package.json create mode 100644 client/ts/tsconfig.json diff --git a/.prettierignore b/.prettierignore index 9b2d3386..a1948592 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,7 @@ drizzle/ bun.lock node_modules/ -*.md \ No newline at end of file +*.md +dist/ +build/ +out/ \ No newline at end of file diff --git a/bun.lock b/bun.lock index 44857dd5..b707b925 100644 --- a/bun.lock +++ b/bun.lock @@ -1,12 +1,12 @@ { "lockfileVersion": 1, - "configVersion": 0, + "configVersion": 1, "workspaces": { "": { "name": "revanced-api", "dependencies": { "@hono/swagger-ui": "^0.6.1", - "@hono/zod-openapi": "^1.2.2", + "@hono/zod-openapi": "^1.2.3", "drizzle-orm": "^0.45.1", "hono": "^4.12.8", "zod": "^4.3.6", @@ -26,6 +26,12 @@ "wrangler": "^4.76.0", }, }, + "client/ts": { + "name": "@revanced/api-client", + "peerDependencies": { + "typescript": "^5.9.3", + }, + }, }, "packages": { "@actions/core": ["@actions/core@3.0.0", "", { "dependencies": { "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0" } }, "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg=="], @@ -64,7 +70,7 @@ "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="], - "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="], @@ -232,6 +238,8 @@ "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], + "@revanced/api-client": ["@revanced/api-client@workspace:client/ts"], + "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], "@semantic-release/changelog": ["@semantic-release/changelog@6.0.3", "", { "dependencies": { "@semantic-release/error": "^3.0.0", "aggregate-error": "^3.0.0", "fs-extra": "^11.0.0", "lodash": "^4.17.4" }, "peerDependencies": { "semantic-release": ">=18.0.0" } }, "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag=="], @@ -254,7 +262,7 @@ "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], - "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], + "@speed-highlight/core": ["@speed-highlight/core@1.2.15", "", {}, "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw=="], "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], @@ -262,7 +270,7 @@ "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], - "@types/parse-path": ["@types/parse-path@7.0.3", "", {}, "sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg=="], + "@types/parse-path": ["@types/parse-path@7.1.0", "", { "dependencies": { "parse-path": "*" } }, "sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q=="], "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], @@ -332,13 +340,13 @@ "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], - "conventional-changelog-angular": ["conventional-changelog-angular@8.2.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-4YB1zEXqB17oBI8yRsAs1T+ZhbdsOgJqkl6Trz+GXt/eKf1e4jnA0oW+sOd9BEENzEViuNW0DNoFFjSf3CeC5Q=="], + "conventional-changelog-angular": ["conventional-changelog-angular@8.3.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA=="], - "conventional-changelog-writer": ["conventional-changelog-writer@8.3.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", "semver": "^7.5.2" }, "bin": "dist/cli/index.js" }, "sha512-l5hDOHjcTUVtnZJapoqXMCJ3IbyF6oV/vnxKL13AHulFH7mDp4PMJARxI7LWzob6UDDvhxIUWGTNUPW84JabQg=="], + "conventional-changelog-writer": ["conventional-changelog-writer@8.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", "semver": "^7.5.2" }, "bin": { "conventional-changelog-writer": "dist/cli/index.js" } }, "sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g=="], "conventional-commits-filter": ["conventional-commits-filter@5.0.0", "", {}, "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q=="], - "conventional-commits-parser": ["conventional-commits-parser@6.3.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": "dist/cli/index.js" }, "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg=="], + "conventional-commits-parser": ["conventional-commits-parser@6.3.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg=="], "convert-hrtime": ["convert-hrtime@5.0.0", "", {}, "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg=="], @@ -346,7 +354,7 @@ "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], - "cosmiconfig": ["cosmiconfig@9.0.1", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" } }, "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ=="], + "cosmiconfig": ["cosmiconfig@9.0.1", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], @@ -408,7 +416,7 @@ "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], @@ -450,7 +458,7 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": "bin/handlebars" }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], + "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], @@ -520,13 +528,13 @@ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], "json-parse-better-errors": ["json-parse-better-errors@1.0.2", "", {}, "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="], "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], - "json-with-bigint": ["json-with-bigint@3.5.7", "", {}, "sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw=="], + "json-with-bigint": ["json-with-bigint@3.5.8", "", {}, "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw=="], "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], @@ -552,11 +560,11 @@ "lodash.uniqby": ["lodash.uniqby@4.7.0", "", {}, "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww=="], - "lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="], + "lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], "make-asynchronous": ["make-asynchronous@1.1.0", "", { "dependencies": { "p-event": "^6.0.0", "type-fest": "^4.6.0", "web-worker": "^1.5.0" } }, "sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg=="], - "marked": ["marked@15.0.12", "", { "bin": "bin/marked.js" }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], + "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], "marked-terminal": ["marked-terminal@7.3.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "peerDependencies": { "marked": ">=1 <16" } }, "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw=="], @@ -566,7 +574,7 @@ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - "mime": ["mime@4.1.0", "", { "bin": "bin/cli.js" }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="], + "mime": ["mime@4.1.0", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="], "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], @@ -594,7 +602,7 @@ "normalize-url": ["normalize-url@9.0.0", "", {}, "sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ=="], - "npm": ["npm@11.11.0", "", { "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" } }, "sha512-82gRxKrh/eY5UnNorkTFcdBQAGpgjWehkfGVqAGlJjejEtJZGGJUqjo3mbBTNbc5BTnPKGVtGPBZGhElujX5cw=="], + "npm": ["npm@11.12.0", "", { "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^9.4.2", "@npmcli/config": "^10.8.0", "@npmcli/fs": "^5.0.0", "@npmcli/map-workspaces": "^5.0.3", "@npmcli/metavuln-calculator": "^9.0.3", "@npmcli/package-json": "^7.0.5", "@npmcli/promise-spawn": "^9.0.1", "@npmcli/redact": "^4.0.0", "@npmcli/run-script": "^10.0.4", "@sigstore/tuf": "^4.0.2", "abbrev": "^4.0.0", "archy": "~1.0.0", "cacache": "^20.0.4", "chalk": "^5.6.2", "ci-info": "^4.4.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^13.0.6", "graceful-fs": "^4.2.11", "hosted-git-info": "^9.0.2", "ini": "^6.0.0", "init-package-json": "^8.2.5", "is-cidr": "^6.0.3", "json-parse-even-better-errors": "^5.0.0", "libnpmaccess": "^10.0.3", "libnpmdiff": "^8.1.5", "libnpmexec": "^10.2.5", "libnpmfund": "^7.0.19", "libnpmorg": "^8.0.1", "libnpmpack": "^9.1.5", "libnpmpublish": "^11.1.3", "libnpmsearch": "^9.0.1", "libnpmteam": "^8.0.2", "libnpmversion": "^8.0.3", "make-fetch-happen": "^15.0.5", "minimatch": "^10.2.4", "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^12.2.0", "nopt": "^9.0.0", "npm-audit-report": "^7.0.0", "npm-install-checks": "^8.0.0", "npm-package-arg": "^13.0.2", "npm-pick-manifest": "^11.0.3", "npm-profile": "^12.0.1", "npm-registry-fetch": "^19.1.1", "npm-user-validate": "^4.0.0", "p-map": "^7.0.4", "pacote": "^21.5.0", "parse-conflict-json": "^5.0.1", "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", "read": "^5.0.1", "semver": "^7.7.4", "spdx-expression-parse": "^4.0.0", "ssri": "^13.0.1", "supports-color": "^10.2.2", "tar": "^7.5.11", "text-table": "~0.2.0", "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", "validate-npm-package-name": "^7.0.2", "which": "^6.0.1" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" } }, "sha512-xPhOap4ZbJWyd7DAOukP564WFwNSGu/2FeTRFHhiiKthcauxhH/NpkJAQm24xD+cAn8av5tQ00phi98DqtfLsg=="], "npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], @@ -678,7 +686,7 @@ "protocols": ["protocols@2.0.2", "", {}, "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ=="], - "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], @@ -702,9 +710,9 @@ "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], - "semantic-release": ["semantic-release@25.0.3", "", { "dependencies": { "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^12.0.0", "@semantic-release/npm": "^13.1.1", "@semantic-release/release-notes-generator": "^14.1.0", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^4.0.0", "hosted-git-info": "^9.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^15.0.0", "marked-terminal": "^7.3.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", "read-package-up": "^12.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "signale": "^1.2.1", "yargs": "^18.0.0" }, "bin": "bin/semantic-release.js" }, "sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA=="], + "semantic-release": ["semantic-release@25.0.3", "", { "dependencies": { "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^12.0.0", "@semantic-release/npm": "^13.1.1", "@semantic-release/release-notes-generator": "^14.1.0", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^4.0.0", "hosted-git-info": "^9.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^15.0.0", "marked-terminal": "^7.3.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", "read-package-up": "^12.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "signale": "^1.2.1", "yargs": "^18.0.0" }, "bin": { "semantic-release": "bin/semantic-release.js" } }, "sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA=="], - "semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="], @@ -784,13 +792,13 @@ "tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="], - "type-fest": ["type-fest@5.4.4", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw=="], + "type-fest": ["type-fest@5.5.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], - "undici": ["undici@7.22.0", "", {}, "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg=="], + "undici": ["undici@7.24.5", "", {}, "sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q=="], "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], @@ -816,7 +824,7 @@ "web-worker": ["web-worker@1.5.0", "", {}, "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw=="], - "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], @@ -834,7 +842,7 @@ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], - "yaml": ["yaml@2.8.2", "", { "bin": "bin.mjs" }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], + "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], @@ -848,9 +856,9 @@ "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "@actions/http-client/undici": ["undici@6.23.0", "", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="], + "@actions/http-client/undici": ["undici@6.24.1", "", {}, "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA=="], - "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": "bin/esbuild" }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], + "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], "@hey-api/shared/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -888,8 +896,6 @@ "execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - "fdir/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "load-json-file/parse-json": ["parse-json@4.0.0", "", { "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw=="], @@ -898,6 +904,286 @@ "miniflare/undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="], + "npm/@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], + + "npm/@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "npm/@isaacs/string-locale-compare": ["@isaacs/string-locale-compare@1.1.0", "", { "bundled": true }, "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ=="], + + "npm/@npmcli/agent": ["@npmcli/agent@4.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^11.2.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA=="], + + "npm/@npmcli/arborist": ["@npmcli/arborist@9.4.2", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^5.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/map-workspaces": "^5.0.0", "@npmcli/metavuln-calculator": "^9.0.2", "@npmcli/name-from-folder": "^4.0.0", "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/query": "^5.0.0", "@npmcli/redact": "^4.0.0", "@npmcli/run-script": "^10.0.0", "bin-links": "^6.0.0", "cacache": "^20.0.1", "common-ancestor-path": "^2.0.0", "hosted-git-info": "^9.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^11.2.1", "minimatch": "^10.0.3", "nopt": "^9.0.0", "npm-install-checks": "^8.0.0", "npm-package-arg": "^13.0.0", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "pacote": "^21.0.2", "parse-conflict-json": "^5.0.1", "proc-log": "^6.0.0", "proggy": "^4.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", "semver": "^7.3.7", "ssri": "^13.0.0", "treeverse": "^3.0.0", "walk-up-path": "^4.0.0" }, "bundled": true, "bin": { "arborist": "bin/index.js" } }, "sha512-omJgPyzt11cEGrxzgrECoOyxAunmPMgBFTcAB/FbaB+9iOYhGmRdsQqySV8o0LWQ/l2kTeASUIMR4xJufVwmtw=="], + + "npm/@npmcli/config": ["@npmcli/config@10.8.0", "", { "dependencies": { "@npmcli/map-workspaces": "^5.0.0", "@npmcli/package-json": "^7.0.0", "ci-info": "^4.0.0", "ini": "^6.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "walk-up-path": "^4.0.0" }, "bundled": true }, "sha512-YkhoXZQU7zxyGi3V7J0zdK2pghzF9YXHiRdpRX8QNhsefk/zAJZJjRsbbw1hD67hlMp2gSygUGgW4y7FlrUThw=="], + + "npm/@npmcli/fs": ["@npmcli/fs@5.0.0", "", { "dependencies": { "semver": "^7.3.5" }, "bundled": true }, "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og=="], + + "npm/@npmcli/git": ["@npmcli/git@7.0.2", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/promise-spawn": "^9.0.0", "ini": "^6.0.0", "lru-cache": "^11.2.1", "npm-pick-manifest": "^11.0.1", "proc-log": "^6.0.0", "semver": "^7.3.5", "which": "^6.0.0" } }, "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg=="], + + "npm/@npmcli/installed-package-contents": ["@npmcli/installed-package-contents@4.0.0", "", { "dependencies": { "npm-bundled": "^5.0.0", "npm-normalize-package-bin": "^5.0.0" }, "bin": { "installed-package-contents": "bin/index.js" } }, "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA=="], + + "npm/@npmcli/map-workspaces": ["@npmcli/map-workspaces@5.0.3", "", { "dependencies": { "@npmcli/name-from-folder": "^4.0.0", "@npmcli/package-json": "^7.0.0", "glob": "^13.0.0", "minimatch": "^10.0.3" }, "bundled": true }, "sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw=="], + + "npm/@npmcli/metavuln-calculator": ["@npmcli/metavuln-calculator@9.0.3", "", { "dependencies": { "cacache": "^20.0.0", "json-parse-even-better-errors": "^5.0.0", "pacote": "^21.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5" }, "bundled": true }, "sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg=="], + + "npm/@npmcli/name-from-folder": ["@npmcli/name-from-folder@4.0.0", "", {}, "sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg=="], + + "npm/@npmcli/node-gyp": ["@npmcli/node-gyp@5.0.0", "", {}, "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ=="], + + "npm/@npmcli/package-json": ["@npmcli/package-json@7.0.5", "", { "dependencies": { "@npmcli/git": "^7.0.0", "glob": "^13.0.0", "hosted-git-info": "^9.0.0", "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.5.3", "spdx-expression-parse": "^4.0.0" }, "bundled": true }, "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ=="], + + "npm/@npmcli/promise-spawn": ["@npmcli/promise-spawn@9.0.1", "", { "dependencies": { "which": "^6.0.0" }, "bundled": true }, "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q=="], + + "npm/@npmcli/query": ["@npmcli/query@5.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ=="], + + "npm/@npmcli/redact": ["@npmcli/redact@4.0.0", "", { "bundled": true }, "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q=="], + + "npm/@npmcli/run-script": ["@npmcli/run-script@10.0.4", "", { "dependencies": { "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "node-gyp": "^12.1.0", "proc-log": "^6.0.0" }, "bundled": true }, "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg=="], + + "npm/@sigstore/bundle": ["@sigstore/bundle@4.0.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A=="], + + "npm/@sigstore/core": ["@sigstore/core@3.2.0", "", {}, "sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA=="], + + "npm/@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.5.0", "", {}, "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA=="], + + "npm/@sigstore/sign": ["@sigstore/sign@4.1.1", "", { "dependencies": { "@gar/promise-retry": "^1.0.2", "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.0", "@sigstore/protobuf-specs": "^0.5.0", "make-fetch-happen": "^15.0.4", "proc-log": "^6.1.0" } }, "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ=="], + + "npm/@sigstore/tuf": ["@sigstore/tuf@4.0.2", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" }, "bundled": true }, "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ=="], + + "npm/@sigstore/verify": ["@sigstore/verify@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag=="], + + "npm/@tufjs/canonical-json": ["@tufjs/canonical-json@2.0.0", "", {}, "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA=="], + + "npm/@tufjs/models": ["@tufjs/models@4.1.0", "", { "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^10.1.1" } }, "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww=="], + + "npm/abbrev": ["abbrev@4.0.0", "", { "bundled": true }, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="], + + "npm/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "npm/aproba": ["aproba@2.1.0", "", {}, "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew=="], + + "npm/archy": ["archy@1.0.0", "", { "bundled": true }, "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw=="], + + "npm/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "npm/bin-links": ["bin-links@6.0.0", "", { "dependencies": { "cmd-shim": "^8.0.0", "npm-normalize-package-bin": "^5.0.0", "proc-log": "^6.0.0", "read-cmd-shim": "^6.0.0", "write-file-atomic": "^7.0.0" } }, "sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w=="], + + "npm/binary-extensions": ["binary-extensions@3.1.0", "", {}, "sha512-Jvvd9hy1w+xUad8+ckQsWA/V1AoyubOvqn0aygjMOVM4BfIaRav1NFS3LsTSDaV4n4FtcCtQXvzep1E6MboqwQ=="], + + "npm/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + + "npm/cacache": ["cacache@20.0.4", "", { "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", "glob": "^13.0.0", "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^13.0.0" }, "bundled": true }, "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA=="], + + "npm/chalk": ["chalk@5.6.2", "", { "bundled": true }, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "npm/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "npm/ci-info": ["ci-info@4.4.0", "", { "bundled": true }, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "npm/cidr-regex": ["cidr-regex@5.0.3", "", {}, "sha512-zfPT2uurEroxXqefaL2L7/fT5ED2XTutC6UwFbSZfqSOk1vk5VFY6xa6/R6pBxB4Uc8MNPbRW5ykqutFG5P5ww=="], + + "npm/cmd-shim": ["cmd-shim@8.0.0", "", {}, "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA=="], + + "npm/common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], + + "npm/cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "npm/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "npm/diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], + + "npm/env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "npm/exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + + "npm/fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", { "bundled": true }, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="], + + "npm/fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "npm/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], + + "npm/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" }, "bundled": true }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "npm/graceful-fs": ["graceful-fs@4.2.11", "", { "bundled": true }, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "npm/hosted-git-info": ["hosted-git-info@9.0.2", "", { "dependencies": { "lru-cache": "^11.1.0" }, "bundled": true }, "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg=="], + + "npm/http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], + + "npm/http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "npm/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "npm/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "npm/ignore-walk": ["ignore-walk@8.0.0", "", { "dependencies": { "minimatch": "^10.0.3" } }, "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A=="], + + "npm/ini": ["ini@6.0.0", "", { "bundled": true }, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], + + "npm/init-package-json": ["init-package-json@8.2.5", "", { "dependencies": { "@npmcli/package-json": "^7.0.0", "npm-package-arg": "^13.0.0", "promzard": "^3.0.1", "read": "^5.0.1", "semver": "^7.7.2", "validate-npm-package-name": "^7.0.0" }, "bundled": true }, "sha512-IknQ+upLuJU6t3p0uo9wS3GjFD/1GtxIwcIGYOWR8zL2HxQeJwvxYTgZr9brJ8pyZ4kvpkebM8ZKcyqOeLOHSg=="], + + "npm/ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], + + "npm/is-cidr": ["is-cidr@6.0.3", "", { "dependencies": { "cidr-regex": "^5.0.1" }, "bundled": true }, "sha512-tPdsizbDiISrc4PoII6ZfpmAokx0oDKeYqAUp5bXOfznauOFXfEeosKBRrl0o0SriE4xoRR05Czn4YPCFMjSHA=="], + + "npm/isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], + + "npm/json-parse-even-better-errors": ["json-parse-even-better-errors@5.0.0", "", { "bundled": true }, "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ=="], + + "npm/json-stringify-nice": ["json-stringify-nice@1.1.4", "", {}, "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw=="], + + "npm/jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], + + "npm/just-diff": ["just-diff@6.0.2", "", {}, "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA=="], + + "npm/just-diff-apply": ["just-diff-apply@5.5.0", "", {}, "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw=="], + + "npm/libnpmaccess": ["libnpmaccess@10.0.3", "", { "dependencies": { "npm-package-arg": "^13.0.0", "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-JPHTfWJxIK+NVPdNMNGnkz4XGX56iijPbe0qFWbdt68HL+kIvSzh+euBL8npLZvl2fpaxo+1eZSdoG15f5YdIQ=="], + + "npm/libnpmdiff": ["libnpmdiff@8.1.5", "", { "dependencies": { "@npmcli/arborist": "^9.4.2", "@npmcli/installed-package-contents": "^4.0.0", "binary-extensions": "^3.0.0", "diff": "^8.0.2", "minimatch": "^10.0.3", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2", "tar": "^7.5.1" }, "bundled": true }, "sha512-3tknN/GosDOpIYjBplXpr7WVjpBDodAxXkZEtv410XlIsfMD+v/6mt9sYe/s/x+TRmmCRpzP/bxfhUorvV6Cqg=="], + + "npm/libnpmexec": ["libnpmexec@10.2.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/arborist": "^9.4.2", "@npmcli/package-json": "^7.0.0", "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2", "proc-log": "^6.0.0", "read": "^5.0.1", "semver": "^7.3.7", "signal-exit": "^4.1.0", "walk-up-path": "^4.0.0" }, "bundled": true }, "sha512-ayouyoml/4NmcgH+nWzK6QB5w0gKrftsYB8TAHu5TB5v6Nj3fgz8ZBK9FsG2A1SNuHZVTjvrNMDyF2VzDih/bA=="], + + "npm/libnpmfund": ["libnpmfund@7.0.19", "", { "dependencies": { "@npmcli/arborist": "^9.4.2" }, "bundled": true }, "sha512-RNyp5gnjVXaqlx0asRLmAOrFkTwANntzqkRyTT6Iu2nUt1F2eiMZNMOpO2HNfA7/NceBVBk/xsrzas3miCz9oQ=="], + + "npm/libnpmorg": ["libnpmorg@8.0.1", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-/QeyXXg4hqMw0ESM7pERjIT2wbR29qtFOWIOug/xO4fRjS3jJJhoAPQNsnHtdwnCqgBdFpGQ45aIdFFZx2YhTA=="], + + "npm/libnpmpack": ["libnpmpack@9.1.5", "", { "dependencies": { "@npmcli/arborist": "^9.4.2", "@npmcli/run-script": "^10.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2" }, "bundled": true }, "sha512-H1IX364ZwpeRfrL6UYSuxFNgP16/TvlwtCm8ZallbB7/1FZ3h1FBZHamQtv7PqcZUTWE27mygdQ4wCCW2BmVlg=="], + + "npm/libnpmpublish": ["libnpmpublish@11.1.3", "", { "dependencies": { "@npmcli/package-json": "^7.0.0", "ci-info": "^4.0.0", "npm-package-arg": "^13.0.0", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "semver": "^7.3.7", "sigstore": "^4.0.0", "ssri": "^13.0.0" }, "bundled": true }, "sha512-NVPTth/71cfbdYHqypcO9Lt5WFGTzFEcx81lWd7GDJIgZ95ERdYHGUfCtFejHCyqodKsQkNEx2JCkMpreDty/A=="], + + "npm/libnpmsearch": ["libnpmsearch@9.0.1", "", { "dependencies": { "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-oKw58X415ERY/BOGV3jQPVMcep8YeMRWMzuuqB0BAIM5VxicOU1tQt19ExCu4SV77SiTOEoziHxGEgJGw3FBYQ=="], + + "npm/libnpmteam": ["libnpmteam@8.0.2", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-ypLrDUQoi8EhG+gzx5ENMcYq23YjPV17Mfvx4nOnQiHOi8vp47+4GvZBrMsEM4yeHPwxguF/HZoXH4rJfHdH/w=="], + + "npm/libnpmversion": ["libnpmversion@8.0.3", "", { "dependencies": { "@npmcli/git": "^7.0.0", "@npmcli/run-script": "^10.0.0", "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.3.7" }, "bundled": true }, "sha512-Avj1GG3DT6MGzWOOk3yA7rORcMDUPizkIGbI8glHCO7WoYn3NYNmskLDwxg2NMY1Tyf2vrHAqTuSG58uqd1lJg=="], + + "npm/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + + "npm/make-fetch-happen": ["make-fetch-happen@15.0.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "ssri": "^13.0.0" }, "bundled": true }, "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg=="], + + "npm/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" }, "bundled": true }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "npm/minipass": ["minipass@7.1.3", "", { "bundled": true }, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "npm/minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], + + "npm/minipass-fetch": ["minipass-fetch@5.0.2", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "iconv-lite": "^0.7.2" } }, "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ=="], + + "npm/minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], + + "npm/minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" }, "bundled": true }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "npm/minipass-sized": ["minipass-sized@2.0.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA=="], + + "npm/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "npm/ms": ["ms@2.1.3", "", { "bundled": true }, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "npm/mute-stream": ["mute-stream@3.0.0", "", {}, "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw=="], + + "npm/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "npm/node-gyp": ["node-gyp@12.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "which": "^6.0.0" }, "bundled": true, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ=="], + + "npm/nopt": ["nopt@9.0.0", "", { "dependencies": { "abbrev": "^4.0.0" }, "bundled": true, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw=="], + + "npm/npm-audit-report": ["npm-audit-report@7.0.0", "", { "bundled": true }, "sha512-bluLL4xwGr/3PERYz50h2Upco0TJMDcLcymuFnfDWeGO99NqH724MNzhWi5sXXuXf2jbytFF0LyR8W+w1jTI6A=="], + + "npm/npm-bundled": ["npm-bundled@5.0.0", "", { "dependencies": { "npm-normalize-package-bin": "^5.0.0" } }, "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw=="], + + "npm/npm-install-checks": ["npm-install-checks@8.0.0", "", { "dependencies": { "semver": "^7.1.1" }, "bundled": true }, "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA=="], + + "npm/npm-normalize-package-bin": ["npm-normalize-package-bin@5.0.0", "", {}, "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag=="], + + "npm/npm-package-arg": ["npm-package-arg@13.0.2", "", { "dependencies": { "hosted-git-info": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^7.0.0" }, "bundled": true }, "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA=="], + + "npm/npm-packlist": ["npm-packlist@10.0.4", "", { "dependencies": { "ignore-walk": "^8.0.0", "proc-log": "^6.0.0" } }, "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng=="], + + "npm/npm-pick-manifest": ["npm-pick-manifest@11.0.3", "", { "dependencies": { "npm-install-checks": "^8.0.0", "npm-normalize-package-bin": "^5.0.0", "npm-package-arg": "^13.0.0", "semver": "^7.3.5" }, "bundled": true }, "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ=="], + + "npm/npm-profile": ["npm-profile@12.0.1", "", { "dependencies": { "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0" }, "bundled": true }, "sha512-Xs1mejJ1/9IKucCxdFMkiBJUre0xaxfCpbsO7DB7CadITuT4k68eI05HBlw4kj+Em1rsFMgeFNljFPYvPETbVQ=="], + + "npm/npm-registry-fetch": ["npm-registry-fetch@19.1.1", "", { "dependencies": { "@npmcli/redact": "^4.0.0", "jsonparse": "^1.3.1", "make-fetch-happen": "^15.0.0", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^13.0.0", "proc-log": "^6.0.0" }, "bundled": true }, "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw=="], + + "npm/npm-user-validate": ["npm-user-validate@4.0.0", "", { "bundled": true }, "sha512-TP+Ziq/qPi/JRdhaEhnaiMkqfMGjhDLoh/oRfW+t5aCuIfJxIUxvwk6Sg/6ZJ069N/Be6gs00r+aZeJTfS9uHQ=="], + + "npm/p-map": ["p-map@7.0.4", "", { "bundled": true }, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], + + "npm/pacote": ["pacote@21.5.0", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "@npmcli/run-script": "^10.0.0", "cacache": "^20.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^13.0.0", "npm-packlist": "^10.0.1", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" }, "bundled": true, "bin": { "pacote": "bin/index.js" } }, "sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ=="], + + "npm/parse-conflict-json": ["parse-conflict-json@5.0.1", "", { "dependencies": { "json-parse-even-better-errors": "^5.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "bundled": true }, "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ=="], + + "npm/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "npm/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "npm/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + + "npm/proc-log": ["proc-log@6.1.0", "", { "bundled": true }, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="], + + "npm/proggy": ["proggy@4.0.0", "", {}, "sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ=="], + + "npm/promise-all-reject-late": ["promise-all-reject-late@1.0.1", "", {}, "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw=="], + + "npm/promise-call-limit": ["promise-call-limit@3.0.2", "", {}, "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw=="], + + "npm/promzard": ["promzard@3.0.1", "", { "dependencies": { "read": "^5.0.0" } }, "sha512-M5mHhWh+Adz0BIxgSrqcc6GTCSconR7zWQV9vnOSptNtr6cSFlApLc28GbQhuN6oOWBQeV2C0bNE47JCY/zu3Q=="], + + "npm/qrcode-terminal": ["qrcode-terminal@0.12.0", "", { "bundled": true, "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ=="], + + "npm/read": ["read@5.0.1", "", { "dependencies": { "mute-stream": "^3.0.0" }, "bundled": true }, "sha512-+nsqpqYkkpet2UVPG8ZiuE8d113DK4vHYEoEhcrXBAlPiq6di7QRTuNiKQAbaRYegobuX2BpZ6QjanKOXnJdTA=="], + + "npm/read-cmd-shim": ["read-cmd-shim@6.0.0", "", {}, "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A=="], + + "npm/safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "npm/semver": ["semver@7.7.4", "", { "bundled": true, "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "npm/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "npm/sigstore": ["sigstore@4.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.0", "@sigstore/tuf": "^4.0.1", "@sigstore/verify": "^3.1.0" } }, "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA=="], + + "npm/smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], + + "npm/socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], + + "npm/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + + "npm/spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "npm/spdx-expression-parse": ["spdx-expression-parse@4.0.0", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" }, "bundled": true }, "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ=="], + + "npm/spdx-license-ids": ["spdx-license-ids@3.0.23", "", {}, "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw=="], + + "npm/ssri": ["ssri@13.0.1", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ=="], + + "npm/supports-color": ["supports-color@10.2.2", "", { "bundled": true }, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + + "npm/tar": ["tar@7.5.12", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "bundled": true }, "sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw=="], + + "npm/text-table": ["text-table@0.2.0", "", { "bundled": true }, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], + + "npm/tiny-relative-date": ["tiny-relative-date@2.0.2", "", { "bundled": true }, "sha512-rGxAbeL9z3J4pI2GtBEoFaavHdO4RKAU54hEuOef5kfx5aPqiQtbhYktMOTL5OA33db8BjsDcLXuNp+/v19PHw=="], + + "npm/tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "npm/treeverse": ["treeverse@3.0.0", "", { "bundled": true }, "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ=="], + + "npm/tuf-js": ["tuf-js@4.1.0", "", { "dependencies": { "@tufjs/models": "4.1.0", "debug": "^4.4.3", "make-fetch-happen": "^15.0.1" } }, "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ=="], + + "npm/util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "npm/validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", { "bundled": true }, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="], + + "npm/walk-up-path": ["walk-up-path@4.0.0", "", {}, "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A=="], + + "npm/which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bundled": true, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], + + "npm/write-file-atomic": ["write-file-atomic@7.0.1", "", { "dependencies": { "signal-exit": "^4.0.1" } }, "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg=="], + + "npm/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], "npm-run-path/unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], @@ -1016,6 +1302,10 @@ "env-ci/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], + "npm/minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], @@ -1146,6 +1436,10 @@ "env-ci/execa/onetime/mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], + "npm/minipass-flush/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "npm/minipass-pipeline/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], "@semantic-release/release-notes-generator/read-package-up/read-pkg/normalize-package-data/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], diff --git a/client/ts/.gitignore b/client/ts/.gitignore new file mode 100644 index 00000000..a14702c4 --- /dev/null +++ b/client/ts/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/client/ts/package.json b/client/ts/package.json new file mode 100644 index 00000000..98a496c4 --- /dev/null +++ b/client/ts/package.json @@ -0,0 +1,26 @@ +{ + "name": "@revanced/api-client", + "module": "./dist/index.js", + "peerDependencies": { + "typescript": "^5.9.3" + }, + "exports": { + ".": { + "default": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./client": { + "default": "./dist/client.gen.js", + "types": "./dist/client.gen.d.ts" + }, + "./package.json": "./package.json" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsc", + "dev": "tsc --watch" + }, + "type": "module" +} diff --git a/client/ts/tsconfig.json b/client/ts/tsconfig.json new file mode 100644 index 00000000..49181152 --- /dev/null +++ b/client/ts/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + "outDir": "dist", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + }, + "exclude": ["dist"] +} diff --git a/package.json b/package.json index 8a2f67d3..6b17f67c 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "db:create": "wrangler d1 create revanced-api", "db:migration:generate": "drizzle-kit generate", "db:migration:apply": "wrangler d1 migrations apply revanced-api", - "build:client:ts": "openapi-ts -o ./client/ts -i" + "gen:client:ts": "openapi-ts -o ./client/ts -i", + "build:client:ts": "bun run --filter ./client/ts build" }, "keywords": [ "revanced", @@ -39,5 +40,8 @@ "semantic-release": "^25.0.3", "typescript": "^5.9.3", "wrangler": "^4.76.0" - } + }, + "workspaces": [ + "client/ts" + ] } From 46349d1e1cdb694ec21ac3eb3b845456c3b0a2bb Mon Sep 17 00:00:00 2001 From: madkarmaa Date: Mon, 23 Mar 2026 11:24:01 +0100 Subject: [PATCH 6/6] fix: add version field in client package --- client/ts/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ts/package.json b/client/ts/package.json index 98a496c4..cede5a8d 100644 --- a/client/ts/package.json +++ b/client/ts/package.json @@ -1,5 +1,6 @@ { "name": "@revanced/api-client", + "version": "0.0.1", "module": "./dist/index.js", "peerDependencies": { "typescript": "^5.9.3"