diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 904cd7b..78ef5b3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -50,7 +50,7 @@ jobs: uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs + publish_dir: ./src/docs/.vitepress/dist user_name: "github-actions[bot]" user_email: "github-actions[bot]@users.noreply.github.com" diff --git a/.gitignore b/.gitignore index 9424ab9..bdaec9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ node_modules/ dist/ coverage/ -docs/ -.env \ No newline at end of file +.env +src/docs/.vitepress/dist/ +src/docs/.vitepress/cache/ +src/docs/api/ diff --git a/.prettierignore b/.prettierignore index 7d7c35f..84aae39 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,5 +2,5 @@ dist node_modules pnpm-lock.yaml CHANGELOG.md -docs +src/docs coverage \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index b53df4a..05f8156 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,7 +4,12 @@ import tseslint from "typescript-eslint"; export default defineConfig([ { - ignores: ["docs/**", "coverage/**", "dist/**", "node_modules/**"], + ignores: [ + "src/docs/.vitepress/**", + "coverage/**", + "dist/**", + "node_modules/**", + ], }, js.configs.recommended, tseslint.configs.recommended, @@ -18,4 +23,27 @@ export default defineConfig([ "no-console": "off", }, }, + { + files: ["scripts/**/*.mjs"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + globals: { + console: "readonly", + process: "readonly", + __dirname: "readonly", + __filename: "readonly", + }, + }, + rules: { + "no-console": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + }, + ], + }, + }, ]); diff --git a/package.json b/package.json index 15de51b..ff44c46 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,11 @@ "format": "prettier --write .", "lint": "eslint .", "lint:format": "prettier --check .", - "docs": "typedoc", - "docs:watch": "typedoc --watch" + "docs": "pnpm run docs:build", + "docs:api": "typedoc && node scripts/generate-api-sidebar.mjs", + "docs:dev": "pnpm run docs:api && vitepress dev src/docs", + "docs:build": "pnpm run docs:api && vitepress build src/docs", + "docs:preview": "vitepress preview src/docs" }, "keywords": [ "roblox", @@ -62,8 +65,11 @@ "semantic-release": "^25.0.1", "tsup": "^8.5.0", "typedoc": "^0.28.14", + "typedoc-plugin-markdown": "^4.9.0", "typescript": "^5.9.3", "typescript-eslint": "^8.46.1", + "vitepress": "^1.6.4", + "vitepress-plugin-group-icons": "^1.6.5", "vitest": "^3.2.4" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8230f7c..38db0af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,12 +44,21 @@ importers: typedoc: specifier: ^0.28.14 version: 0.28.14(typescript@5.9.3) + typedoc-plugin-markdown: + specifier: ^4.9.0 + version: 4.9.0(typedoc@0.28.14(typescript@5.9.3)) typescript: specifier: ^5.9.3 version: 5.9.3 typescript-eslint: specifier: ^8.46.1 version: 8.46.1(eslint@9.38.0)(typescript@5.9.3) + vitepress: + specifier: ^1.6.4 + version: 1.6.4(@algolia/client-search@5.41.0)(@types/node@24.8.1)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3) + vitepress-plugin-group-icons: + specifier: ^1.6.5 + version: 1.6.5(vite@7.1.10(@types/node@24.8.1)(yaml@2.8.1)) vitest: specifier: ^3.2.4 version: 3.2.4(@types/node@24.8.1)(yaml@2.8.1) @@ -68,10 +77,92 @@ packages: '@actions/io@1.1.3': resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==} + '@algolia/abtesting@1.7.0': + resolution: {integrity: sha512-hOEItTFOvNLI6QX6TSGu7VE4XcUcdoKZT8NwDY+5mWwu87rGhkjlY7uesKTInlg6Sh8cyRkDBYRumxbkoBbBhA==} + engines: {node: '>= 14.0.0'} + + '@algolia/autocomplete-core@1.17.7': + resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==} + + '@algolia/autocomplete-plugin-algolia-insights@1.17.7': + resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.17.7': + resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.17.7': + resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.41.0': + resolution: {integrity: sha512-iRuvbEyuHCAhIMkyzG3tfINLxTS7mSKo7q8mQF+FbQpWenlAlrXnfZTN19LRwnVjx0UtAdZq96ThMWGS6cQ61A==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.41.0': + resolution: {integrity: sha512-OIPVbGfx/AO8l1V70xYTPSeTt/GCXPEl6vQICLAXLCk9WOUbcLGcy6t8qv0rO7Z7/M/h9afY6Af8JcnI+FBFdQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.41.0': + resolution: {integrity: sha512-8Mc9niJvfuO8dudWN5vSUlYkz7U3M3X3m1crDLc9N7FZrIVoNGOUETPk3TTHviJIh9y6eKZKbq1hPGoGY9fqPA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.41.0': + resolution: {integrity: sha512-vXzvCGZS6Ixxn+WyzGUVDeR3HO/QO5POeeWy1kjNJbEf6f+tZSI+OiIU9Ha+T3ntV8oXFyBEuweygw4OLmgfiQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.41.0': + resolution: {integrity: sha512-tkymXhmlcc7w/HEvLRiHcpHxLFcUB+0PnE9FcG6hfFZ1ZXiWabH+sX+uukCVnluyhfysU9HRU2kUmUWfucx1Dg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.41.0': + resolution: {integrity: sha512-vyXDoz3kEZnosNeVQQwf0PbBt5IZJoHkozKRIsYfEVm+ylwSDFCW08qy2YIVSHdKy69/rWN6Ue/6W29GgVlmKQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.41.0': + resolution: {integrity: sha512-G9I2atg1ShtFp0t7zwleP6aPS4DcZvsV4uoQOripp16aR6VJzbEnKFPLW4OFXzX7avgZSpYeBAS+Zx4FOgmpPw==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.41.0': + resolution: {integrity: sha512-sxU/ggHbZtmrYzTkueTXXNyifn+ozsLP+Wi9S2hOBVhNWPZ8uRiDTDcFyL7cpCs1q72HxPuhzTP5vn4sUl74cQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.41.0': + resolution: {integrity: sha512-UQ86R6ixraHUpd0hn4vjgTHbViNO8+wA979gJmSIsRI3yli2v89QSFF/9pPcADR6PbtSio/99PmSNxhZy+CR3Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.41.0': + resolution: {integrity: sha512-DxP9P8jJ8whJOnvmyA5mf1wv14jPuI0L25itGfOHSU6d4ZAjduVfPjTS3ROuUN5CJoTdlidYZE+DtfWHxJwyzQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.41.0': + resolution: {integrity: sha512-C21J+LYkE48fDwtLX7YXZd2Fn7Fe0/DOEtvohSfr/ODP8dGDhy9faaYeWB0n1AvmZltugjkjAXT7xk0CYNIXsQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.41.0': + resolution: {integrity: sha512-FhJy/+QJhMx1Hajf2LL8og4J7SqOAHiAuUXq27cct4QnPhSIuIGROzeRpfDNH5BUbq22UlMuGd44SeD4HRAqvA==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.41.0': + resolution: {integrity: sha512-tYv3rGbhBS0eZ5D8oCgV88iuWILROiemk+tQ3YsAKZv2J4kKUNvKkrX/If/SreRy4MGP2uJzMlyKcfSfO2mrsQ==} + engines: {node: '>= 14.0.0'} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@antfu/utils@9.3.0': + resolution: {integrity: sha512-9hFT4RauhcUzqOE4f1+frMKLZrgNog5b06I7VmZQV1BkvwvqrbC8EBZf3L1eEL2AKb6rNKjER0sEvJiSP1FXEA==} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -101,102 +192,227 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@docsearch/css@3.8.2': + resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==} + + '@docsearch/js@3.8.2': + resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==} + + '@docsearch/react@3.8.2': + resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.11': resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.11': resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.11': resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.11': resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.11': resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.11': resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.11': resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.11': resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.11': resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.11': resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.11': resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.11': resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.11': resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.11': resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.11': resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.11': resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.11': resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} engines: {node: '>=18'} @@ -209,6 +425,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.11': resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} engines: {node: '>=18'} @@ -221,6 +443,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.11': resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} engines: {node: '>=18'} @@ -233,24 +461,48 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.11': resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.11': resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.11': resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.11': resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} engines: {node: '>=18'} @@ -318,6 +570,21 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@iconify-json/logos@1.2.10': + resolution: {integrity: sha512-qxaXKJ6fu8jzTMPQdHtNxlfx6tBQ0jXRbHZIYy5Ilh8Lx9US9FsAdzZWUR8MXV8PnWTKGDFO4ZZee9VwerCyMA==} + + '@iconify-json/simple-icons@1.2.56': + resolution: {integrity: sha512-oAvxOzgSjfvdj/Jsi3S7HDUCxO8/n2j8e1w1e/FktHUAXiWjNX00n3Tu3AP+n1ayKrypcUDXCzxn+0ENMl6ouw==} + + '@iconify-json/vscode-icons@1.2.33': + resolution: {integrity: sha512-2lKDybGxXXeLeeqeNT2YVDYXs5va0YMHf06w3GemS22j/0CCTpKwKDK7REaibsCq3bRV8qX0RJDM4AbREE7L+w==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.0.2': + resolution: {integrity: sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -572,15 +839,36 @@ packages: peerDependencies: semantic-release: '>=20.1.0' + '@shikijs/core@2.5.0': + resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==} + + '@shikijs/engine-javascript@2.5.0': + resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==} + + '@shikijs/engine-oniguruma@2.5.0': + resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==} + '@shikijs/engine-oniguruma@3.13.0': resolution: {integrity: sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==} + '@shikijs/langs@2.5.0': + resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==} + '@shikijs/langs@3.13.0': resolution: {integrity: sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==} + '@shikijs/themes@2.5.0': + resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==} + '@shikijs/themes@3.13.0': resolution: {integrity: sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==} + '@shikijs/transformers@2.5.0': + resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==} + + '@shikijs/types@2.5.0': + resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==} + '@shikijs/types@3.13.0': resolution: {integrity: sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==} @@ -616,6 +904,18 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/node@24.8.1': resolution: {integrity: sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q==} @@ -625,6 +925,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + '@typescript-eslint/eslint-plugin@8.46.1': resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -684,6 +987,16 @@ packages: resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + '@vitest/coverage-v8@3.2.4': resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} peerDependencies: @@ -722,6 +1035,94 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vue/compiler-core@3.5.22': + resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} + + '@vue/compiler-dom@3.5.22': + resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} + + '@vue/compiler-sfc@3.5.22': + resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} + + '@vue/compiler-ssr@3.5.22': + resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} + + '@vue/devtools-api@7.7.7': + resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} + + '@vue/devtools-kit@7.7.7': + resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==} + + '@vue/devtools-shared@7.7.7': + resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==} + + '@vue/reactivity@3.5.22': + resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} + + '@vue/runtime-core@3.5.22': + resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} + + '@vue/runtime-dom@3.5.22': + resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} + + '@vue/server-renderer@3.5.22': + resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} + peerDependencies: + vue: 3.5.22 + + '@vue/shared@3.5.22': + resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} + + '@vueuse/core@12.8.2': + resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} + + '@vueuse/integrations@12.8.2': + resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@12.8.2': + resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==} + + '@vueuse/shared@12.8.2': + resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -747,6 +1148,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + algoliasearch@5.41.0: + resolution: {integrity: sha512-9E4b3rJmYbBkn7e3aAPt1as+VVnRhsR4qwRRgOzpeyz4PAOuwKh0HI4AN6mTrqK0S0M9fCCSTOUnuJ8gPY/tvA==} + engines: {node: '>= 14.0.0'} + ansi-escapes@7.1.1: resolution: {integrity: sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==} engines: {node: '>=18'} @@ -796,6 +1201,9 @@ packages: before-after-hook@4.0.0: resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + birpc@2.6.1: + resolution: {integrity: sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==} + bottleneck@2.19.5: resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} @@ -823,6 +1231,9 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -843,6 +1254,12 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -888,6 +1305,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -901,6 +1321,9 @@ packages: confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} @@ -930,6 +1353,10 @@ packages: resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} engines: {node: '>=12'} + copy-anything@4.0.5: + resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} + engines: {node: '>=18'} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -950,6 +1377,9 @@ packages: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} engines: {node: '>=12'} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -970,6 +1400,13 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -984,6 +1421,9 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -1018,6 +1458,11 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.25.11: resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} engines: {node: '>=18'} @@ -1077,6 +1522,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -1100,6 +1548,9 @@ packages: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} + exsolve@1.0.7: + resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} + fast-content-type-parse@3.0.0: resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} @@ -1170,6 +1621,9 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + focus-trap@7.6.6: + resolution: {integrity: sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -1233,6 +1687,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -1255,6 +1713,12 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} @@ -1262,6 +1726,9 @@ packages: resolution: {integrity: sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==} engines: {node: '>=20'} + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + hosted-git-info@7.0.2: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} @@ -1273,6 +1740,9 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -1381,6 +1851,10 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} + engines: {node: '>=18'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -1449,6 +1923,9 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1471,6 +1948,10 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + engines: {node: '>=14'} + locate-path@2.0.0: resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} engines: {node: '>=4'} @@ -1529,6 +2010,9 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + markdown-it@14.1.0: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true @@ -1544,6 +2028,9 @@ packages: engines: {node: '>= 18'} hasBin: true + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} @@ -1558,6 +2045,21 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1589,6 +2091,12 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -1719,6 +2227,9 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + oniguruma-to-es@3.1.1: + resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1770,6 +2281,9 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@1.5.0: + resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1830,6 +2344,9 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1856,6 +2373,9 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -1878,6 +2398,9 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + preact@10.27.2: + resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1894,6 +2417,9 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -1905,6 +2431,9 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -1927,6 +2456,15 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + registry-auth-token@5.1.0: resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} engines: {node: '>=14'} @@ -1947,6 +2485,9 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rollup@4.52.5: resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -1958,6 +2499,9 @@ packages: safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + semantic-release@25.0.1: resolution: {integrity: sha512-0OCYLm0AfVilNGukM+w0C4aptITfuW1Mhvmz8LQliLeYbPOTFRCIJzoltWWx/F5zVFe6np9eNatBUHdAvMFeZg==} engines: {node: ^22.14.0 || >= 24.10.0} @@ -1985,6 +2529,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@2.5.0: + resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -2016,6 +2563,9 @@ packages: engines: {node: '>= 8'} deprecated: The work that was done in this beta branch won't be included in future versions + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spawn-error-forwarder@1.0.0: resolution: {integrity: sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==} @@ -2031,6 +2581,10 @@ packages: spdx-license-ids@3.0.22: resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + split2@1.0.0: resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} @@ -2058,6 +2612,9 @@ packages: string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2102,6 +2659,10 @@ packages: resolution: {integrity: sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==} engines: {node: '>=18'} + superjson@2.2.5: + resolution: {integrity: sha512-zWPTX96LVsA/eVYnqOM2+ofcdPqdS1dAF1LN4TS2/MWuUpfitd9ctTa87wt4xrYnZnkLtS69xpBdSxVBP5Rm6w==} + engines: {node: '>=16'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -2114,6 +2675,9 @@ packages: resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} engines: {node: '>=14.18'} + tabbable@6.3.0: + resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==} + temp-dir@3.0.0: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} @@ -2146,6 +2710,9 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -2177,6 +2744,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -2225,6 +2795,12 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + typedoc-plugin-markdown@4.9.0: + resolution: {integrity: sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + typedoc@0.28.14: resolution: {integrity: sha512-ftJYPvpVfQvFzpkoSfHLkJybdA/geDJ8BGQt/ZnkkhnBYoYW6lBgPQXu6vqLxO4X75dA55hX8Af847H5KXlEFA==} engines: {node: '>= 18', pnpm: '>= 10'} @@ -2278,6 +2854,21 @@ packages: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} engines: {node: '>=12'} + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} @@ -2298,11 +2889,48 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vite@7.1.10: resolution: {integrity: sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2343,6 +2971,26 @@ packages: yaml: optional: true + vitepress-plugin-group-icons@1.6.5: + resolution: {integrity: sha512-+pg4+GKDq2fLqKb1Sat5p1p4SuIZ5tEPxu8HjpwoeecZ/VaXKy6Bdf0wyjedjaTAyZQzXbvyavJegqAcQ+B0VA==} + peerDependencies: + vite: '>=3' + peerDependenciesMeta: + vite: + optional: true + + vitepress@1.6.4: + resolution: {integrity: sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -2371,6 +3019,14 @@ packages: jsdom: optional: true + vue@3.5.22: + resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} @@ -2443,6 +3099,9 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@actions/core@1.11.1': @@ -2461,11 +3120,130 @@ snapshots: '@actions/io@1.1.3': {} + '@algolia/abtesting@1.7.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)': + dependencies: + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0) + '@algolia/client-search': 5.41.0 + algoliasearch: 5.41.0 + + '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)': + dependencies: + '@algolia/client-search': 5.41.0 + algoliasearch: 5.41.0 + + '@algolia/client-abtesting@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/client-analytics@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/client-common@5.41.0': {} + + '@algolia/client-insights@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/client-personalization@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/client-query-suggestions@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/client-search@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/ingestion@1.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/monitoring@1.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/recommend@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + + '@algolia/requester-browser-xhr@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + + '@algolia/requester-fetch@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + + '@algolia/requester-node-http@5.41.0': + dependencies: + '@algolia/client-common': 5.41.0 + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.5.0 + tinyexec: 1.0.1 + + '@antfu/utils@9.3.0': {} + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -2490,81 +3268,174 @@ snapshots: '@colors/colors@1.5.0': optional: true + '@docsearch/css@3.8.2': {} + + '@docsearch/js@3.8.2(@algolia/client-search@5.41.0)(search-insights@2.17.3)': + dependencies: + '@docsearch/react': 3.8.2(@algolia/client-search@5.41.0)(search-insights@2.17.3) + preact: 10.27.2 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.8.2(@algolia/client-search@5.41.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.41.0)(algoliasearch@5.41.0) + '@docsearch/css': 3.8.2 + algoliasearch: 5.41.0 + optionalDependencies: + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.25.11': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.25.11': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.25.11': optional: true - '@esbuild/android-x64@0.25.11': + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.25.11': + optional: true + + '@esbuild/darwin-arm64@0.21.5': optional: true '@esbuild/darwin-arm64@0.25.11': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.25.11': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.25.11': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.25.11': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.25.11': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.25.11': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.25.11': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.25.11': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.25.11': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.25.11': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.25.11': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.25.11': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.25.11': optional: true '@esbuild/netbsd-arm64@0.25.11': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.25.11': optional: true '@esbuild/openbsd-arm64@0.25.11': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.25.11': optional: true '@esbuild/openharmony-arm64@0.25.11': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.25.11': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.25.11': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.25.11': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.25.11': optional: true @@ -2635,6 +3506,33 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@iconify-json/logos@1.2.10': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/simple-icons@1.2.56': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/vscode-icons@1.2.33': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.0.2': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@antfu/utils': 9.3.0 + '@iconify/types': 2.0.0 + debug: 4.4.3 + globals: 15.15.0 + kolorist: 1.8.0 + local-pkg: 1.1.2 + mlly: 1.8.0 + transitivePeerDependencies: + - supports-color + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -2911,19 +3809,57 @@ snapshots: transitivePeerDependencies: - supports-color + '@shikijs/core@2.5.0': + dependencies: + '@shikijs/engine-javascript': 2.5.0 + '@shikijs/engine-oniguruma': 2.5.0 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@2.5.0': + dependencies: + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 3.1.1 + + '@shikijs/engine-oniguruma@2.5.0': + dependencies: + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@shikijs/engine-oniguruma@3.13.0': dependencies: '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 + '@shikijs/langs@2.5.0': + dependencies: + '@shikijs/types': 2.5.0 + '@shikijs/langs@3.13.0': dependencies: '@shikijs/types': 3.13.0 + '@shikijs/themes@2.5.0': + dependencies: + '@shikijs/types': 2.5.0 + '@shikijs/themes@3.13.0': dependencies: '@shikijs/types': 3.13.0 + '@shikijs/transformers@2.5.0': + dependencies: + '@shikijs/core': 2.5.0 + '@shikijs/types': 2.5.0 + + '@shikijs/types@2.5.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + '@shikijs/types@3.13.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 @@ -2956,6 +3892,19 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + '@types/node@24.8.1': dependencies: undici-types: 7.14.0 @@ -2964,6 +3913,8 @@ snapshots: '@types/unist@3.0.3': {} + '@types/web-bluetooth@0.0.21': {} + '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0)(typescript@5.9.3))(eslint@9.38.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -3057,6 +4008,13 @@ snapshots: '@typescript-eslint/types': 8.46.1 eslint-visitor-keys: 4.2.1 + '@ungap/structured-clone@1.3.0': {} + + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@24.8.1))(vue@3.5.22(typescript@5.9.3))': + dependencies: + vite: 5.4.21(@types/node@24.8.1) + vue: 3.5.22(typescript@5.9.3) + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.8.1)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 @@ -3118,6 +4076,105 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 + '@vue/compiler-core@3.5.22': + dependencies: + '@babel/parser': 7.28.4 + '@vue/shared': 3.5.22 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.22': + dependencies: + '@vue/compiler-core': 3.5.22 + '@vue/shared': 3.5.22 + + '@vue/compiler-sfc@3.5.22': + dependencies: + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.5.22 + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + estree-walker: 2.0.2 + magic-string: 0.30.19 + postcss: 8.5.6 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.22': + dependencies: + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 + + '@vue/devtools-api@7.7.7': + dependencies: + '@vue/devtools-kit': 7.7.7 + + '@vue/devtools-kit@7.7.7': + dependencies: + '@vue/devtools-shared': 7.7.7 + birpc: 2.6.1 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.5 + + '@vue/devtools-shared@7.7.7': + dependencies: + rfdc: 1.4.1 + + '@vue/reactivity@3.5.22': + dependencies: + '@vue/shared': 3.5.22 + + '@vue/runtime-core@3.5.22': + dependencies: + '@vue/reactivity': 3.5.22 + '@vue/shared': 3.5.22 + + '@vue/runtime-dom@3.5.22': + dependencies: + '@vue/reactivity': 3.5.22 + '@vue/runtime-core': 3.5.22 + '@vue/shared': 3.5.22 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3))': + dependencies: + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + vue: 3.5.22(typescript@5.9.3) + + '@vue/shared@3.5.22': {} + + '@vueuse/core@12.8.2(typescript@5.9.3)': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 12.8.2 + '@vueuse/shared': 12.8.2(typescript@5.9.3) + vue: 3.5.22(typescript@5.9.3) + transitivePeerDependencies: + - typescript + + '@vueuse/integrations@12.8.2(focus-trap@7.6.6)(typescript@5.9.3)': + dependencies: + '@vueuse/core': 12.8.2(typescript@5.9.3) + '@vueuse/shared': 12.8.2(typescript@5.9.3) + vue: 3.5.22(typescript@5.9.3) + optionalDependencies: + focus-trap: 7.6.6 + transitivePeerDependencies: + - typescript + + '@vueuse/metadata@12.8.2': {} + + '@vueuse/shared@12.8.2(typescript@5.9.3)': + dependencies: + vue: 3.5.22(typescript@5.9.3) + transitivePeerDependencies: + - typescript + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -3143,6 +4200,23 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + algoliasearch@5.41.0: + dependencies: + '@algolia/abtesting': 1.7.0 + '@algolia/client-abtesting': 5.41.0 + '@algolia/client-analytics': 5.41.0 + '@algolia/client-common': 5.41.0 + '@algolia/client-insights': 5.41.0 + '@algolia/client-personalization': 5.41.0 + '@algolia/client-query-suggestions': 5.41.0 + '@algolia/client-search': 5.41.0 + '@algolia/ingestion': 1.41.0 + '@algolia/monitoring': 1.41.0 + '@algolia/recommend': 5.41.0 + '@algolia/requester-browser-xhr': 5.41.0 + '@algolia/requester-fetch': 5.41.0 + '@algolia/requester-node-http': 5.41.0 + ansi-escapes@7.1.1: dependencies: environment: 1.1.0 @@ -3181,6 +4255,8 @@ snapshots: before-after-hook@4.0.0: {} + birpc@2.6.1: {} + bottleneck@2.19.5: {} brace-expansion@1.1.12: @@ -3205,6 +4281,8 @@ snapshots: callsites@3.1.0: {} + ccount@2.0.1: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -3228,6 +4306,10 @@ snapshots: char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + check-error@2.1.1: {} chokidar@4.0.3: @@ -3279,6 +4361,8 @@ snapshots: color-name@1.1.4: {} + comma-separated-tokens@2.0.3: {} + commander@4.1.1: {} compare-func@2.0.0: @@ -3290,6 +4374,8 @@ snapshots: confbox@0.1.8: {} + confbox@0.2.2: {} + config-chain@1.1.13: dependencies: ini: 1.3.8 @@ -3316,6 +4402,10 @@ snapshots: convert-hrtime@5.0.0: {} + copy-anything@4.0.5: + dependencies: + is-what: 5.5.0 + core-util-is@1.0.3: {} cosmiconfig@9.0.0(typescript@5.9.3): @@ -3337,6 +4427,8 @@ snapshots: dependencies: type-fest: 1.4.0 + csstype@3.1.3: {} + debug@4.4.3: dependencies: ms: 2.1.3 @@ -3347,6 +4439,12 @@ snapshots: deep-is@0.1.4: {} + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -3361,6 +4459,8 @@ snapshots: eastasianwidth@0.2.0: {} + emoji-regex-xs@1.0.0: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -3386,6 +4486,32 @@ snapshots: es-module-lexer@1.7.0: {} + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.11: optionalDependencies: '@esbuild/aix-ppc64': 0.25.11 @@ -3487,6 +4613,8 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -3534,6 +4662,8 @@ snapshots: expect-type@1.2.2: {} + exsolve@1.0.7: {} + fast-content-type-parse@3.0.0: {} fast-deep-equal@3.1.3: {} @@ -3603,6 +4733,10 @@ snapshots: flatted@3.3.3: {} + focus-trap@7.6.6: + dependencies: + tabbable: 6.3.0 + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -3667,6 +4801,8 @@ snapshots: globals@14.0.0: {} + globals@15.15.0: {} + graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -3686,10 +4822,30 @@ snapshots: has-flag@4.0.0: {} + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + highlight.js@10.7.3: {} hook-std@4.0.0: {} + hookable@5.5.3: {} + hosted-git-info@7.0.2: dependencies: lru-cache: 10.4.3 @@ -3700,6 +4856,8 @@ snapshots: html-escaper@2.0.2: {} + html-void-elements@3.0.0: {} + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -3779,6 +4937,8 @@ snapshots: is-unicode-supported@2.1.0: {} + is-what@5.5.0: {} + isarray@1.0.0: {} isexe@2.0.0: {} @@ -3850,6 +5010,8 @@ snapshots: dependencies: json-buffer: 3.0.1 + kolorist@1.8.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -3872,6 +5034,12 @@ snapshots: load-tsconfig@0.2.5: {} + local-pkg@1.1.2: + dependencies: + mlly: 1.8.0 + pkg-types: 2.3.0 + quansync: 0.2.11 + locate-path@2.0.0: dependencies: p-locate: 2.0.0 @@ -3921,6 +5089,8 @@ snapshots: dependencies: semver: 7.7.3 + mark.js@8.11.1: {} + markdown-it@14.1.0: dependencies: argparse: 2.0.1 @@ -3943,6 +5113,18 @@ snapshots: marked@15.0.12: {} + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + mdurl@2.0.0: {} meow@13.2.0: {} @@ -3951,6 +5133,23 @@ snapshots: merge2@1.4.1: {} + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -3974,6 +5173,10 @@ snapshots: minipass@7.1.2: {} + minisearch@7.2.0: {} + + mitt@3.0.1: {} + mlly@1.8.0: dependencies: acorn: 8.15.0 @@ -4037,6 +5240,12 @@ snapshots: dependencies: mimic-fn: 4.0.0 + oniguruma-to-es@3.1.1: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 6.0.1 + regex-recursion: 6.0.2 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -4080,6 +5289,8 @@ snapshots: package-json-from-dist@1.0.1: {} + package-manager-detector@1.5.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -4131,6 +5342,8 @@ snapshots: pathval@2.0.1: {} + perfect-debounce@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -4152,6 +5365,12 @@ snapshots: mlly: 1.8.0 pathe: 2.0.3 + pkg-types@2.3.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.7 + pathe: 2.0.3 + postcss-load-config@6.0.1(postcss@8.5.6)(yaml@2.8.1): dependencies: lilconfig: 3.1.3 @@ -4165,6 +5384,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + preact@10.27.2: {} + prelude-ls@1.2.1: {} prettier@3.6.2: {} @@ -4175,12 +5396,16 @@ snapshots: process-nextick-args@2.0.1: {} + property-information@7.1.0: {} + proto-list@1.2.4: {} punycode.js@2.3.1: {} punycode@2.3.1: {} + quansync@0.2.11: {} + queue-microtask@1.2.3: {} rc@1.2.8: @@ -4216,6 +5441,16 @@ snapshots: readdirp@4.1.2: {} + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.0.1: + dependencies: + regex-utilities: 2.3.0 + registry-auth-token@5.1.0: dependencies: '@pnpm/npm-conf': 2.3.1 @@ -4228,6 +5463,8 @@ snapshots: reusify@1.1.0: {} + rfdc@1.4.1: {} + rollup@4.52.5: dependencies: '@types/estree': 1.0.8 @@ -4262,6 +5499,8 @@ snapshots: safe-buffer@5.1.2: {} + search-insights@2.17.3: {} + semantic-release@25.0.1(typescript@5.9.3): dependencies: '@semantic-release/commit-analyzer': 13.0.1(semantic-release@25.0.1(typescript@5.9.3)) @@ -4311,6 +5550,17 @@ snapshots: shebang-regex@3.0.0: {} + shiki@2.5.0: + dependencies: + '@shikijs/core': 2.5.0 + '@shikijs/engine-javascript': 2.5.0 + '@shikijs/engine-oniguruma': 2.5.0 + '@shikijs/langs': 2.5.0 + '@shikijs/themes': 2.5.0 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -4335,6 +5585,8 @@ snapshots: dependencies: whatwg-url: 7.1.0 + space-separated-tokens@2.0.2: {} + spawn-error-forwarder@1.0.0: {} spdx-correct@3.2.0: @@ -4351,6 +5603,8 @@ snapshots: spdx-license-ids@3.0.22: {} + speakingurl@14.0.1: {} + split2@1.0.0: dependencies: through2: 2.0.5 @@ -4386,6 +5640,11 @@ snapshots: dependencies: safe-buffer: 5.1.2 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -4425,6 +5684,10 @@ snapshots: function-timeout: 1.0.2 time-span: 5.1.0 + superjson@2.2.5: + dependencies: + copy-anything: 4.0.5 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -4438,6 +5701,8 @@ snapshots: has-flag: 4.0.0 supports-color: 7.2.0 + tabbable@6.3.0: {} + temp-dir@3.0.0: {} tempy@3.1.0: @@ -4474,6 +5739,8 @@ snapshots: tinyexec@0.3.2: {} + tinyexec@1.0.1: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -4497,6 +5764,8 @@ snapshots: tree-kill@1.2.2: {} + trim-lines@3.0.1: {} + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -4543,6 +5812,10 @@ snapshots: type-fest@4.41.0: {} + typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3)): + dependencies: + typedoc: 0.28.14(typescript@5.9.3) + typedoc@0.28.14(typescript@5.9.3): dependencies: '@gerrit0/mini-shiki': 3.13.1 @@ -4588,6 +5861,29 @@ snapshots: dependencies: crypto-random-string: 4.0.0 + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + universal-user-agent@7.0.3: {} universalify@2.0.1: {} @@ -4605,6 +5901,16 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + vite-node@3.2.4(@types/node@24.8.1)(yaml@2.8.1): dependencies: cac: 6.7.14 @@ -4626,6 +5932,15 @@ snapshots: - tsx - yaml + vite@5.4.21(@types/node@24.8.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.52.5 + optionalDependencies: + '@types/node': 24.8.1 + fsevents: 2.3.3 + vite@7.1.10(@types/node@24.8.1)(yaml@2.8.1): dependencies: esbuild: 0.25.11 @@ -4639,6 +5954,65 @@ snapshots: fsevents: 2.3.3 yaml: 2.8.1 + vitepress-plugin-group-icons@1.6.5(vite@7.1.10(@types/node@24.8.1)(yaml@2.8.1)): + dependencies: + '@iconify-json/logos': 1.2.10 + '@iconify-json/vscode-icons': 1.2.33 + '@iconify/utils': 3.0.2 + optionalDependencies: + vite: 7.1.10(@types/node@24.8.1)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + + vitepress@1.6.4(@algolia/client-search@5.41.0)(@types/node@24.8.1)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3): + dependencies: + '@docsearch/css': 3.8.2 + '@docsearch/js': 3.8.2(@algolia/client-search@5.41.0)(search-insights@2.17.3) + '@iconify-json/simple-icons': 1.2.56 + '@shikijs/core': 2.5.0 + '@shikijs/transformers': 2.5.0 + '@shikijs/types': 2.5.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.2.4(vite@5.4.21(@types/node@24.8.1))(vue@3.5.22(typescript@5.9.3)) + '@vue/devtools-api': 7.7.7 + '@vue/shared': 3.5.22 + '@vueuse/core': 12.8.2(typescript@5.9.3) + '@vueuse/integrations': 12.8.2(focus-trap@7.6.6)(typescript@5.9.3) + focus-trap: 7.6.6 + mark.js: 8.11.1 + minisearch: 7.2.0 + shiki: 2.5.0 + vite: 5.4.21(@types/node@24.8.1) + vue: 3.5.22(typescript@5.9.3) + optionalDependencies: + postcss: 8.5.6 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + vitest@3.2.4(@types/node@24.8.1)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 @@ -4680,6 +6054,16 @@ snapshots: - tsx - yaml + vue@3.5.22(typescript@5.9.3): + dependencies: + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-sfc': 3.5.22 + '@vue/runtime-dom': 3.5.22 + '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.9.3)) + '@vue/shared': 3.5.22 + optionalDependencies: + typescript: 5.9.3 + webidl-conversions@4.0.2: {} whatwg-url@7.1.0: @@ -4751,3 +6135,5 @@ snapshots: yocto-queue@0.1.0: {} yoctocolors@2.1.2: {} + + zwitch@2.0.4: {} diff --git a/scripts/generate-api-sidebar.mjs b/scripts/generate-api-sidebar.mjs new file mode 100644 index 0000000..614e9ef --- /dev/null +++ b/scripts/generate-api-sidebar.mjs @@ -0,0 +1,147 @@ +#!/usr/bin/env node + +import { + writeFileSync, + renameSync, + existsSync, + readFileSync, + readdirSync, +} from "fs"; +import { readdir } from "fs/promises"; +import { join, dirname, extname } from "path"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const API_DOCS_PATH = join(__dirname, "..", "src", "docs", "api"); +const OUTPUT_PATH = join( + __dirname, + "..", + "src", + "docs", + ".vitepress", + "sidebar", + "api.mts", +); + +function fileToDisplayName(filename) { + return filename.replace(".md", ""); +} + +function removeBreadcrumbs(directory) { + const items = readdirSync(directory, { withFileTypes: true }); + + for (const item of items) { + const fullPath = join(directory, item.name); + + if (item.isDirectory()) { + removeBreadcrumbs(fullPath); + } else if (item.isFile() && extname(item.name) === ".md") { + let content = readFileSync(fullPath, "utf-8"); + + content = content.replace(/^\[.*?\]\(.*?README\.md\)\n\n\*\*\*\n\n/m, ""); + + writeFileSync(fullPath, content, "utf-8"); + } + } +} + +async function generateCategoryItems(category, displayName) { + const categoryPath = join(API_DOCS_PATH, category); + + try { + const files = await readdir(categoryPath); + const mdFiles = files.filter((file) => file.endsWith(".md")); + + return { + text: displayName, + collapsed: true, + items: mdFiles + .sort((a, b) => a.localeCompare(b)) + .map((file) => ({ + text: fileToDisplayName(file), + link: `/api/${category}/${file.replace(".md", "")}`, + })), + }; + } catch (error) { + console.warn( + `Warning: Could not read directory ${category}:`, + error.message, + ); + return null; + } +} + +async function generateApiSidebar() { + console.log("๐Ÿ” Analyzing API documentation structure..."); + + const readmePath = join(API_DOCS_PATH, "README.md"); + const indexPath = join(API_DOCS_PATH, "index.md"); + + if (existsSync(readmePath)) { + renameSync(readmePath, indexPath); + console.log("๐Ÿ“ Renamed README.md to index.md"); + } + + console.log("๐Ÿงน Removing breadcrumbs from generated files..."); + removeBreadcrumbs(API_DOCS_PATH); + + const categories = [ + { dir: "classes", name: "Classes" }, + { dir: "interfaces", name: "Interfaces" }, + { dir: "type-aliases", name: "Type Aliases" }, + ]; + + const items = [ + { + text: "Overview", + link: "/api/", + }, + ]; + + for (const category of categories) { + const categoryItems = await generateCategoryItems( + category.dir, + category.name, + ); + if (categoryItems && categoryItems.items.length > 0) { + items.push(categoryItems); + } + } + + const sidebarConfig = { + "/api/": [ + { + text: "API Reference", + items, + }, + ], + }; + + const content = `// This file is auto-generated by scripts/generate-api-sidebar.mjs +// Run 'pnpm docs:api' to regenerate. + +import type { DefaultTheme } from 'vitepress'; + +export const apiSidebar: DefaultTheme.SidebarMulti = ${JSON.stringify( + sidebarConfig, + null, + 2, + ).replace(/"/g, "'")} as const; +`; + + writeFileSync(OUTPUT_PATH, content, "utf-8"); + + console.log("โœ… Generated API sidebar configuration"); + console.log(`๐Ÿ“ Output: ${OUTPUT_PATH}`); + console.log(`๐Ÿ“Š Total categories: ${items.length - 1}`); // -1 for Overview + console.log( + `๐Ÿ“„ Total items: ${items.reduce((acc, item) => acc + (item.items?.length || 0), 0)}`, + ); +} + +generateApiSidebar().catch((error) => { + console.error("โŒ Error generating API sidebar:", error); + process.exit(1); +}); diff --git a/src/docs/.vitepress/config.ts b/src/docs/.vitepress/config.ts new file mode 100644 index 0000000..ea9f6a3 --- /dev/null +++ b/src/docs/.vitepress/config.ts @@ -0,0 +1,69 @@ +import { defineConfig, Plugin } from "vitepress" +import { apiSidebar } from "./sidebar/api.mts" +import { groupIconMdPlugin, groupIconVitePlugin } from "vitepress-plugin-group-icons" + +export default defineConfig({ + title: "OpenCloud", + description: "Typed SDK for Roblox Open Cloud", + lastUpdated: true, + cleanUrls: true, + head: [ + ["link", { rel: "icon", href: "/favicon.ico" }] + ], + + themeConfig: { + logo: "/logo.svg", + siteTitle: false, + nav: [ + { text: "Guide", link: "/guide/getting-started" }, + { text: "API Reference", link: "/api/" }, + ], + sidebar: { + "/guide/": [ + { + text: "Guide", + items: [ + { text: "Getting Started", link: "/guide/getting-started" }, + { text: "Authentication", link: "/guide/authentication" }, + { text: "Error Handling", link: "/guide/error-handling" }, + { text: "Pagination", link: "/guide/pagination" }, + { text: "Rate Limiting", link: "/guide/rate-limiting" }, + { text: "TypeScript", link: "/guide/typescript" }, + { text: "Migration Guide", link: "/guide/migration" }, + ] + }, + { + text: "Resources", + items: [ + { text: "Users", link: "/guide/resources/users" }, + { text: "Groups", link: "/guide/resources/groups" }, + ] + } + ], + ...apiSidebar + }, + outline: [2, 3], + socialLinks: [ + { icon: "github", link: "https://github.com/relatiocc/opencloud" }, + { icon: "discord", link: "https://relatio.cc/discord" } + ], + search: { + provider: "local" + }, + editLink: { + pattern: "https://github.com/relatiocc/opencloud/edit/main/src/docs/:path" + } + }, + markdown: { + theme: { + light: "github-light", + dark: "github-dark" + }, + config(md) { + md.use(groupIconMdPlugin) + } + }, + vite: { + plugins: [groupIconVitePlugin() as Plugin] + } +}) diff --git a/src/docs/.vitepress/sidebar/api.mts b/src/docs/.vitepress/sidebar/api.mts new file mode 100644 index 0000000..f3f0293 --- /dev/null +++ b/src/docs/.vitepress/sidebar/api.mts @@ -0,0 +1,216 @@ +// This file is auto-generated by scripts/generate-api-sidebar.mjs +// Run 'pnpm docs:api' to regenerate. + +import type { DefaultTheme } from 'vitepress'; + +export const apiSidebar: DefaultTheme.SidebarMulti = { + '/api/': [ + { + 'text': 'API Reference', + 'items': [ + { + 'text': 'Overview', + 'link': '/api/' + }, + { + 'text': 'Classes', + 'collapsed': true, + 'items': [ + { + 'text': 'AuthError', + 'link': '/api/classes/AuthError' + }, + { + 'text': 'Groups', + 'link': '/api/classes/Groups' + }, + { + 'text': 'OpenCloud', + 'link': '/api/classes/OpenCloud' + }, + { + 'text': 'OpenCloudError', + 'link': '/api/classes/OpenCloudError' + }, + { + 'text': 'RateLimitError', + 'link': '/api/classes/RateLimitError' + }, + { + 'text': 'Users', + 'link': '/api/classes/Users' + } + ] + }, + { + 'text': 'Interfaces', + 'collapsed': true, + 'items': [ + { + 'text': 'AssetDetails', + 'link': '/api/interfaces/AssetDetails' + }, + { + 'text': 'AssetQuota', + 'link': '/api/interfaces/AssetQuota' + }, + { + 'text': 'BadgeDetails', + 'link': '/api/interfaces/BadgeDetails' + }, + { + 'text': 'CollectibleDetails', + 'link': '/api/interfaces/CollectibleDetails' + }, + { + 'text': 'GamePassDetails', + 'link': '/api/interfaces/GamePassDetails' + }, + { + 'text': 'GenerateThumbnailOptions', + 'link': '/api/interfaces/GenerateThumbnailOptions' + }, + { + 'text': 'Group', + 'link': '/api/interfaces/Group' + }, + { + 'text': 'GroupMembershipItem', + 'link': '/api/interfaces/GroupMembershipItem' + }, + { + 'text': 'GroupPermissions', + 'link': '/api/interfaces/GroupPermissions' + }, + { + 'text': 'GroupRole', + 'link': '/api/interfaces/GroupRole' + }, + { + 'text': 'GroupShout', + 'link': '/api/interfaces/GroupShout' + }, + { + 'text': 'HttpOptions', + 'link': '/api/interfaces/HttpOptions' + }, + { + 'text': 'InventoryItem', + 'link': '/api/interfaces/InventoryItem' + }, + { + 'text': 'JoinRequestItem', + 'link': '/api/interfaces/JoinRequestItem' + }, + { + 'text': 'ListOptions', + 'link': '/api/interfaces/ListOptions' + }, + { + 'text': 'OpenCloudConfig', + 'link': '/api/interfaces/OpenCloudConfig' + }, + { + 'text': 'PrivateServerDetails', + 'link': '/api/interfaces/PrivateServerDetails' + }, + { + 'text': 'User', + 'link': '/api/interfaces/User' + }, + { + 'text': 'UserNotificationBody', + 'link': '/api/interfaces/UserNotificationBody' + }, + { + 'text': 'UserNotificationPayload', + 'link': '/api/interfaces/UserNotificationPayload' + }, + { + 'text': 'UserNotificationResponse', + 'link': '/api/interfaces/UserNotificationResponse' + }, + { + 'text': 'UserNotificationSource', + 'link': '/api/interfaces/UserNotificationSource' + }, + { + 'text': 'UserThumbnail', + 'link': '/api/interfaces/UserThumbnail' + } + ] + }, + { + 'text': 'Type Aliases', + 'collapsed': true, + 'items': [ + { + 'text': 'AssetQuotasPage', + 'link': '/api/type-aliases/AssetQuotasPage' + }, + { + 'text': 'AssetType', + 'link': '/api/type-aliases/AssetType' + }, + { + 'text': 'GroupMembershipItemsPage', + 'link': '/api/type-aliases/GroupMembershipItemsPage' + }, + { + 'text': 'GroupRolesPage', + 'link': '/api/type-aliases/GroupRolesPage' + }, + { + 'text': 'InstanceState', + 'link': '/api/type-aliases/InstanceState' + }, + { + 'text': 'InventoryItemAssetType', + 'link': '/api/type-aliases/InventoryItemAssetType' + }, + { + 'text': 'InventoryItemsPage', + 'link': '/api/type-aliases/InventoryItemsPage' + }, + { + 'text': 'JoinRequestItemsPage', + 'link': '/api/type-aliases/JoinRequestItemsPage' + }, + { + 'text': 'NotificationType', + 'link': '/api/type-aliases/NotificationType' + }, + { + 'text': 'Page', + 'link': '/api/type-aliases/Page' + }, + { + 'text': 'QuotaPeriod', + 'link': '/api/type-aliases/QuotaPeriod' + }, + { + 'text': 'QuotaType', + 'link': '/api/type-aliases/QuotaType' + }, + { + 'text': 'SocialNetworkProfiles', + 'link': '/api/type-aliases/SocialNetworkProfiles' + }, + { + 'text': 'SocialNetworkVisibility', + 'link': '/api/type-aliases/SocialNetworkVisibility' + }, + { + 'text': 'ThumbnailFormat', + 'link': '/api/type-aliases/ThumbnailFormat' + }, + { + 'text': 'ThumbnailShape', + 'link': '/api/type-aliases/ThumbnailShape' + } + ] + } + ] + } + ] +} as const; diff --git a/src/docs/.vitepress/theme/index.ts b/src/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..61abc83 --- /dev/null +++ b/src/docs/.vitepress/theme/index.ts @@ -0,0 +1,5 @@ +import DefaultTheme from "vitepress/theme-without-fonts" +import "./relatio.css" +import "virtual:group-icons.css" + +export default DefaultTheme \ No newline at end of file diff --git a/src/docs/.vitepress/theme/relatio.css b/src/docs/.vitepress/theme/relatio.css new file mode 100644 index 0000000..e01cebf --- /dev/null +++ b/src/docs/.vitepress/theme/relatio.css @@ -0,0 +1,49 @@ +@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap'); + +:root { + --vp-font-family-base: 'Plus Jakarta Sans', sans-serif; + + --vp-sidebar-bg-color: #f9f9f9; + --vp-c-bg: #ffffff; + --vp-c-bg-soft: #f6f6f7; + --vp-c-bg-alt: #f0f0f1; + --vp-c-brand-1: #30BCB5; + --vp-code-block-bg: #f6f6f7; + + --vp-button-alt-bg: #f6f6f7; + --vp-button-alt-text: #476582; + --vp-button-alt-hover-text: #476582; + --vp-button-alt-hover-bg: #e8e8e9; + + --vp-button-brand-bg: #30BCB5; + --vp-button-brand-text: #fff; + --vp-button-brand-hover-text: #fff; + --vp-button-brand-hover-bg: #22a9a3; + + --vp-home-hero-name-color: #30BCB5; + --vp-home-hero-image-background-image: linear-gradient(90deg, rgba(48, 188, 181, 0.6) 0%, rgba(22, 245, 234, 0.6) 100%); + --vp-home-hero-image-filter: blur(246px); +} + +.dark { + --vp-sidebar-bg-color: #030a0aff; + --vp-c-bg: #030a0aff; + --vp-c-bg-soft: #0a1b1bff; + --vp-c-bg-alt: #061313ff; + --vp-c-brand-1: #30BCB5; + --vp-code-block-bg: #0a1b1bff; + + --vp-button-alt-bg: #0d2222ff; + --vp-button-alt-text: #fff; + --vp-button-alt-hover-text: #fff; + --vp-button-alt-hover-bg: #144040ff; + + --vp-button-brand-bg: #30BCB5; + --vp-button-brand-text: #fff; + --vp-button-brand-hover-text: #fff; + --vp-button-brand-hover-bg: #22a9a3; + + --vp-home-hero-name-color: #30BCB5; + --vp-home-hero-image-background-image: linear-gradient(90deg,rgba(48, 188, 181, 1) 0%, rgba(22, 245, 234, 1) 100%); + --vp-home-hero-image-filter: blur(246px); +} \ No newline at end of file diff --git a/src/docs/guide/authentication.md b/src/docs/guide/authentication.md new file mode 100644 index 0000000..410f466 --- /dev/null +++ b/src/docs/guide/authentication.md @@ -0,0 +1,66 @@ +# Authentication + +The OpenCloud SDK requires a Roblox Open Cloud API key for authentication. + +## Getting an API Key + +1. Go to the [Roblox Creator Dashboard](https://create.roblox.com/dashboard/credentials) +2. Click **Create API Key** +3. Configure the permissions your application needs +4. Copy the generated API key + +::: warning +Keep your API key secret! Never commit it to version control or share it publicly. +::: + +## Using the API Key + +Pass your API key when creating the OpenCloud client: + +```typescript +import { OpenCloud } from "@relatiohq/opencloud"; + +const client = new OpenCloud({ + apiKey: "your-api-key-here" +}); +``` + +## Environment Variables + +It's recommended to store your API key in environment variables: + +```typescript +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY! +}); +``` + +### Using .env files + +Create a `.env` file in your project root: + +``` +ROBLOX_API_KEY=your-api-key-here +``` + +Then load it in your application (using a package like `dotenv`): + +```typescript +import "dotenv/config"; +import { OpenCloud } from "@relatiohq/opencloud"; + +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY! +}); +``` + +## Permissions + +When creating your API key, ensure it has the appropriate permissions for the resources you need to access: + +- **Users** - Read user information +- **Groups** - Read group information +- **Assets** - Upload and manage assets +- And more... + +Refer to the [Roblox Open Cloud documentation](https://create.roblox.com/docs/cloud/open-cloud) for the full list of available permissions. diff --git a/src/docs/guide/error-handling.md b/src/docs/guide/error-handling.md new file mode 100644 index 0000000..dc92720 --- /dev/null +++ b/src/docs/guide/error-handling.md @@ -0,0 +1,179 @@ +# Error Handling + +The OpenCloud SDK provides structured error classes to help you handle API failures gracefully. Understanding these error types and how to handle them is crucial for building robust applications. + +## Error Types + +The SDK exports three main error classes: + +### OpenCloudError + +The base error class for all API-related errors. All other error types extend this class. + +```typescript +import { OpenCloudError } from "@relatiohq/opencloud"; + +try { + const user = await client.users.get("invalid-user-id"); +} catch (error) { + if (error instanceof OpenCloudError) { + console.error(`API Error: ${error.message}`); + console.error(`Status: ${error.status}`); + console.error(`Code: ${error.code}`); + console.error(`Details:`, error.details); + } +} +``` + +**Properties:** +- `message` - Human-readable error description +- `status` - HTTP status code (e.g., 404, 500) +- `code` - Error code from the API (e.g., "RESOURCE_NOT_FOUND") +- `details` - Additional error information from the API response + +### RateLimitError + +Thrown when you exceed the API rate limits. This error includes information about when you can retry. + +```typescript +import { RateLimitError } from "@relatiohq/opencloud"; + +try { + const user = await client.users.get("123456789"); +} catch (error) { + if (error instanceof RateLimitError) { + console.error("Rate limit exceeded!"); + if (error.retryAfter) { + console.log(`Retry after ${error.retryAfter} seconds`); + // Wait before retrying + await new Promise(resolve => setTimeout(resolve, error.retryAfter! * 1000)); + // Retry the request + } + } +} +``` + +**Properties:** +- All properties from `OpenCloudError` +- `retryAfter` - Number of seconds to wait before retrying (optional) + +### AuthError + +Thrown when authentication fails, typically due to an invalid or missing API key. + +```typescript +import { AuthError } from "@relatiohq/opencloud"; + +try { + const user = await client.users.get("123456789"); +} catch (error) { + if (error instanceof AuthError) { + console.error("Authentication failed!"); + console.error("Please check your API key and permissions."); + // Log the user out or prompt for new credentials + } +} +``` + +## Common Error Scenarios + +### 404 Not Found + +When a resource doesn't exist (invalid user ID, group ID, etc.): + +```typescript +try { + const user = await client.users.get("999999999999"); +} catch (error) { + if (error instanceof OpenCloudError && error.status === 404) { + console.error("User not found"); + // Handle missing resource + } +} +``` + +### 401 Unauthorized + +When your API key is invalid or missing required permissions: + +```typescript +try { + const group = await client.groups.get("123456789"); +} catch (error) { + if (error instanceof AuthError && error.status === 401) { + console.error("Invalid API key"); + // Prompt user to update credentials + } +} +``` + +### 403 Forbidden + +When you don't have permission to access a resource: + +```typescript +try { + const inventory = await client.users.listInventoryItems("123456789"); +} catch (error) { + if (error instanceof AuthError && error.status === 403) { + console.error("Insufficient permissions"); + console.error("Your API key needs the 'Users' read permission"); + } +} +``` + +### 429 Rate Limited + +When you've made too many requests: + +```typescript +try { + // Making many requests in a loop + for (const userId of userIds) { + await client.users.get(userId); + } +} catch (error) { + if (error instanceof RateLimitError) { + console.error("Rate limit hit!"); + // The SDK automatically retries with exponential backoff + // This error is thrown only after all retry attempts fail + } +} +``` + +## Type Guards + +Use TypeScript type guards to safely check error types: + +```typescript +function isOpenCloudError(error: unknown): error is OpenCloudError { + return error instanceof OpenCloudError; +} + +function isRateLimitError(error: unknown): error is RateLimitError { + return error instanceof RateLimitError; +} + +function isAuthError(error: unknown): error is AuthError { + return error instanceof AuthError; +} + +// Usage +try { + const user = await client.users.get(userId); +} catch (error) { + if (isAuthError(error)) { + // TypeScript knows error is AuthError here + console.error("Auth failed:", error.status); + } else if (isRateLimitError(error)) { + // TypeScript knows error is RateLimitError here + console.error("Rate limited, retry after:", error.retryAfter); + } else if (isOpenCloudError(error)) { + // TypeScript knows error is OpenCloudError here + console.error("API error:", error.code); + } else { + // Unknown error type + console.error("Unexpected error:", error); + } +} +``` \ No newline at end of file diff --git a/src/docs/guide/getting-started.md b/src/docs/guide/getting-started.md new file mode 100644 index 0000000..492c5d7 --- /dev/null +++ b/src/docs/guide/getting-started.md @@ -0,0 +1,88 @@ +# Getting Started + +## Installation + +::: code-group + +```sh [npm] +$ npm install @relatiohq/opencloud +``` + +```sh [pnpm] +$ pnpm add @relatiohq/opencloud +``` + +```sh [yarn] +$ yarn add @relatiohq/opencloud +``` + +```sh [bun] +$ bun add @relatiohq/opencloud +``` + +::: + +## Quick Start + +```typescript +import { OpenCloud } from "@relatiohq/opencloud"; + +// Initialize the client with your API key +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY, +}); + +// Get user information +const user = await client.users.get("123456789"); +console.log(user.displayName); // "John Doe" + +// Get group details +const group = await client.groups.get("987654321"); +console.log(group.displayName); // "My Group" +``` + +## Key Features + +- **๐Ÿ”’ Type-Safe** - Full TypeScript support with autocomplete +- **๐Ÿชถ Lightweight** - Zero dependencies, tree-shakeable +- **๐Ÿ”„ Auto-Retry** - Built-in exponential backoff for failed requests +- **โšก Modern** - Uses native `fetch` API (Node.js 18+) + +## Common Examples + +### Fetch User Inventory + +```typescript +// Get a user's inventory items +const inventory = await client.users.listInventoryItems("123456789", { + maxPageSize: 50, + filter: "inventoryItemAssetTypes=HAT,CLASSIC_PANTS", +}); + +for (const item of inventory.inventoryItems) { + console.log(item.assetDetails.displayName); +} +``` + +### Generate User Thumbnail + +```typescript +const thumbnail = await client.users.generateThumbnail("123456789", { + size: 420, + format: "PNG", + shape: "ROUND", +}); + +console.log(thumbnail.response.imageUri); +``` + +### List Group Members + +```typescript +const members = await client.groups.listGroupMemberships("987654321", { + maxPageSize: 100, + filter: "role == 'groups/987654321/roles/12345678'", +}); + +console.log(`Total members: ${members.groupMemberships.length}`); +``` \ No newline at end of file diff --git a/src/docs/guide/migration.md b/src/docs/guide/migration.md new file mode 100644 index 0000000..c16c066 --- /dev/null +++ b/src/docs/guide/migration.md @@ -0,0 +1,241 @@ +# Migration Guide + +This guide helps you migrate from raw API calls or other solutions to the OpenCloud SDK. + +## From Raw Fetch Calls + +### Before: Manual API Calls + +```typescript +// Manual implementation +const response = await fetch( + `https://apis.roblox.com/cloud/v2/users/${userId}`, + { + headers: { + "x-api-key": process.env.ROBLOX_API_KEY + } + } +); + +if (!response.ok) { + const error = await response.json(); + throw new Error(`API error: ${response.status} - ${error.message}`); +} + +const user = await response.json(); +``` + +### After: Using OpenCloud SDK + +```typescript +import { OpenCloud } from "@relatiohq/opencloud"; + +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY! +}); + +// Automatic error handling, retries, and type safety +const user = await client.users.get(userId); +``` + +## From axios or node-fetch + +### Before: Using axios + +```typescript +import axios from "axios"; + +const client = axios.create({ + baseURL: "https://apis.roblox.com", + headers: { + "x-api-key": process.env.ROBLOX_API_KEY + } +}); + +try { + const response = await client.get(`/cloud/v2/users/${userId}`); + const user = response.data; +} catch (error) { + if (error.response?.status === 429) { + // Handle rate limiting manually + await new Promise(resolve => setTimeout(resolve, 5000)); + // Retry... + } + throw error; +} +``` + +### After: Using OpenCloud SDK + +```typescript +import { OpenCloud } from "@relatiohq/opencloud"; + +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY! +}); + +// Built-in rate limit handling and retries +const user = await client.users.get(userId); +``` + +## Common Migration Patterns + +### Getting User Information + +```typescript +// Before +const response = await fetch( + `https://apis.roblox.com/cloud/v2/users/${userId}` +); +const user = await response.json(); + +// After +const user = await client.users.get(userId); +``` + +### Listing Inventory with Pagination + +```typescript +// Before +let allItems = []; +let pageToken = undefined; + +do { + const url = new URL(`https://apis.roblox.com/cloud/v2/users/${userId}/inventory-items`); + if (pageToken) url.searchParams.set("pageToken", pageToken); + + const response = await fetch(url, { + headers: { "x-api-key": apiKey } + }); + const data = await response.json(); + + allItems.push(...data.inventoryItems); + pageToken = data.nextPageToken; +} while (pageToken); + +// After +let allItems = []; +let pageToken = undefined; + +do { + const page = await client.users.listInventoryItems(userId, { pageToken }); + allItems.push(...page.inventoryItems); + pageToken = page.nextPageToken; +} while (pageToken); +``` + +### Getting Group Members + +```typescript +// Before +const response = await fetch( + `https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships`, + { + headers: { "x-api-key": apiKey } + } +); +const data = await response.json(); +const members = data.groupMemberships; + +// After +const page = await client.groups.listGroupMemberships(groupId); +const members = page.groupMemberships; +``` + +### Accepting Join Requests + +```typescript +// Before +await fetch( + `https://apis.roblox.com/cloud/v2/groups/${groupId}/join-requests/${requestId}:accept`, + { + method: "POST", + headers: { "x-api-key": apiKey } + } +); + +// After +await client.groups.acceptGroupJoinRequest(groupId, requestId); +``` + +## Benefits of Migration + +### 1. Type Safety + +```typescript +// TypeScript knows the exact structure +const user = await client.users.get("123456789"); +user.displayName; // โœ“ Type-safe +user.invalidField; // โœ— TypeScript error +``` + +### 2. Automatic Error Handling + +```typescript +// SDK provides structured error types +import { OpenCloudError, RateLimitError, AuthError } from "@relatiohq/opencloud"; + +try { + const user = await client.users.get("123456789"); +} catch (error) { + if (error instanceof RateLimitError) { + // Handle rate limiting + } else if (error instanceof AuthError) { + // Handle auth issues + } +} +``` + +### 3. Built-in Retries + +```typescript +// No manual retry logic needed +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY!, + retry: { + attempts: 4, + backoff: "exponential" + } +}); +``` + +### 4. Cleaner Code + +```typescript +// Before: Verbose +const url = new URL(`https://apis.roblox.com/cloud/v2/users/${userId}/inventory-items`); +url.searchParams.set("maxPageSize", "50"); +url.searchParams.set("filter", "inventoryItemAssetTypes=HAT"); +const response = await fetch(url, { headers: { "x-api-key": apiKey } }); +const data = await response.json(); + +// After: Concise +const data = await client.users.listInventoryItems(userId, { + maxPageSize: 50, + filter: "inventoryItemAssetTypes=HAT" +}); +``` + +## Installation + +::: code-group + +```sh [npm] +$ npm install @relatiohq/opencloud +``` + +```sh [pnpm] +$ pnpm add @relatiohq/opencloud +``` + +```sh [yarn] +$ yarn add @relatiohq/opencloud +``` + +```sh [bun] +$ bun add @relatiohq/opencloud +``` + +::: + +Then replace your existing API calls with the SDK methods. The SDK is lightweight with zero dependencies, so it won't bloat your project. diff --git a/src/docs/guide/pagination.md b/src/docs/guide/pagination.md new file mode 100644 index 0000000..f8b7bcb --- /dev/null +++ b/src/docs/guide/pagination.md @@ -0,0 +1,116 @@ +# Pagination + +Many Roblox Open Cloud API endpoints return large datasets that are split into pages. The OpenCloud SDK provides consistent pagination handling across all list methods, making it easy to work with large result sets. + +## Understanding Pagination + +Paginated responses follow a consistent structure: + +```typescript +{ + items: [...], // Array of results for current page + nextPageToken?: string // Token to fetch the next page (undefined on last page) +} +``` + +The SDK uses different property names based on the resource type, but the pattern is always the same. + +## Basic Pagination + +### Fetching the First Page + +```typescript +// Get first page of user inventory +const firstPage = await client.users.listInventoryItems("123456789"); + +console.log(`Found ${firstPage.inventoryItems.length} items`); +console.log(`Has more pages: ${!!firstPage.nextPageToken}`); +``` + +### Fetching the Next Page + +Use the `nextPageToken` from the previous response: + +```typescript +const firstPage = await client.users.listInventoryItems("123456789"); + +if (firstPage.nextPageToken) { + const secondPage = await client.users.listInventoryItems("123456789", { + pageToken: firstPage.nextPageToken + }); + + console.log(`Page 2 has ${secondPage.inventoryItems.length} items`); +} +``` + +## Page Size Control + +Control how many items are returned per page using `maxPageSize`: + +```typescript +// Request up to 50 items per page +const page = await client.users.listInventoryItems("123456789", { + maxPageSize: 50 +}); +``` + +::: tip +The API may return fewer items than requested, even if more are available. Always check `nextPageToken` to determine if there are more pages. +::: + +::: warning +The API has maximum limits for `maxPageSize`. If you request too many items, the API will cap the response to its maximum allowed value. +::: + +## Iterating Through All Pages + +### Manual Iteration + +```typescript +let pageToken: string | undefined; +let allItems: InventoryItem[] = []; + +do { + const page = await client.users.listInventoryItems("123456789", { + maxPageSize: 100, + pageToken + }); + + allItems.push(...page.inventoryItems); + pageToken = page.nextPageToken; + + console.log(`Fetched ${allItems.length} items so far...`); +} while (pageToken); + +console.log(`Total items: ${allItems.length}`); +``` + +### Using a Reusable Function + +Create a helper function to fetch all pages: + +```typescript +async function fetchAllPages( + fetchPage: (pageToken?: string) => Promise, + getItems: (page: T) => unknown[] +): Promise { + let allItems: unknown[] = []; + let pageToken: string | undefined; + + do { + const page = await fetchPage(pageToken); + allItems.push(...getItems(page)); + pageToken = page.nextPageToken; + } while (pageToken); + + return allItems; +} + +// Usage +const allInventory = await fetchAllPages( + (pageToken) => client.users.listInventoryItems("123456789", { pageToken }), + (page) => page.inventoryItems +); + +console.log(`Total inventory items: ${allInventory.length}`); +``` \ No newline at end of file diff --git a/src/docs/guide/rate-limiting.md b/src/docs/guide/rate-limiting.md new file mode 100644 index 0000000..18e9f76 --- /dev/null +++ b/src/docs/guide/rate-limiting.md @@ -0,0 +1,167 @@ +# Rate Limiting + +The Roblox Open Cloud API enforces rate limits to ensure fair usage and system stability. The OpenCloud SDK provides automatic retry logic to handle rate limits gracefully. + +## Understanding Rate Limits + +When you exceed the API's rate limits, you'll receive a `429 Too Many Requests` response. The SDK automatically catches these and retries with exponential backoff. + +## Automatic Retry + +The SDK includes built-in retry logic that handles rate limits automatically: + +```typescript +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY!, + retry: { + attempts: 4, // Number of retry attempts (default: 4) + backoff: "exponential" // Exponential backoff strategy (default) + } +}); + +// The SDK will automatically retry if rate limited +const user = await client.users.get("123456789"); +``` + +::: tip +The default retry configuration is suitable for most use cases. The SDK will wait increasingly longer between retries: 1s, 2s, 4s, 8s. +::: + +## Handling Rate Limit Errors + +If all retry attempts are exhausted, the SDK throws a `RateLimitError`: + +```typescript +import { RateLimitError } from "@relatiohq/opencloud"; + +try { + const user = await client.users.get("123456789"); +} catch (error) { + if (error instanceof RateLimitError) { + console.log("Rate limit exceeded after all retries"); + + if (error.retryAfter) { + console.log(`Wait ${error.retryAfter} seconds before retrying`); + + // Wait and retry manually + await new Promise(resolve => setTimeout(resolve, error.retryAfter! * 1000)); + const user = await client.users.get("123456789"); + } + } +} +``` + +## Best Practices + +### 1. Implement Caching + +Avoid making repeated requests for the same data: + +```typescript +const cache = new Map(); + +async function getUserCached(userId: string) { + const cached = cache.get(userId); + + if (cached && Date.now() < cached.expires) { + return cached.data; + } + + const user = await client.users.get(userId); + + // Cache for 5 minutes + cache.set(userId, { + data: user, + expires: Date.now() + 5 * 60 * 1000 + }); + + return user; +} +``` + +### 2. Batch Operations + +When processing multiple items, add delays between requests: + +```typescript +const userIds = ["123", "456", "789", "012"]; + +for (const userId of userIds) { + try { + const user = await client.users.get(userId); + console.log(user.displayName); + + // Small delay between requests + await new Promise(resolve => setTimeout(resolve, 100)); + } catch (error) { + console.error(`Failed to fetch user ${userId}:`, error); + } +} +``` + +### 3. Use Pagination Wisely + +Don't request too many items at once: + +```typescript +// Good: Reasonable page size +const members = await client.groups.listGroupMemberships("123456789", { + maxPageSize: 100 +}); + +// Avoid: Requesting maximum items too frequently +const members = await client.groups.listGroupMemberships("123456789", { + maxPageSize: 1000 +}); +``` + +### 4. Monitor Your Usage + +Keep track of rate limit errors to identify problematic patterns: + +```typescript +let rateLimitCount = 0; + +async function fetchWithMonitoring(userId: string) { + try { + return await client.users.get(userId); + } catch (error) { + if (error instanceof RateLimitError) { + rateLimitCount++; + console.warn(`Rate limit hit ${rateLimitCount} times`); + } + throw error; + } +} +``` + +## Custom Retry Configuration + +You can customize the retry behavior: + +```typescript +// More aggressive retries +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY!, + retry: { + attempts: 6, // More retry attempts + backoff: "exponential" + } +}); + +// Disable retries (not recommended) +const client = new OpenCloud({ + apiKey: process.env.ROBLOX_API_KEY!, + retry: { + attempts: 0 + } +}); +``` + +## Rate Limit Headers + +The Roblox API may include rate limit information in response headers. While the SDK handles retries automatically, you can implement custom logic if needed by catching errors and examining the `retryAfter` property. + +::: warning +Excessive rate limiting may indicate a problem with your implementation. Consider refactoring your code to make fewer requests or implementing caching. +::: diff --git a/src/docs/guide/resources/groups.md b/src/docs/guide/resources/groups.md new file mode 100644 index 0000000..36fe472 --- /dev/null +++ b/src/docs/guide/resources/groups.md @@ -0,0 +1,181 @@ +# Groups Resource + +The Groups resource provides methods to interact with Roblox group data, including group information, members, roles, join requests, and shouts. + +## Getting Group Information + +Retrieve basic group information by group ID: + +```typescript +const group = await client.groups.get("123456789"); + +console.log(group.displayName); // "My Awesome Group" +console.log(group.description); +console.log(group.owner); // "users/987654321" +console.log(group.memberCount); +console.log(group.publicEntryAllowed); +``` + +## Working with Members + +List all members in a group with pagination support: + +```typescript +const members = await client.groups.listGroupMemberships("123456789", { + maxPageSize: 100 +}); + +for (const member of members.groupMemberships) { + console.log(member.user); // "users/987654321" + console.log(member.role); // "groups/123456789/roles/12345" +} +``` + +### Filtering by Role + +Retrieve only members with a specific role: + +```typescript +const admins = await client.groups.listGroupMemberships("123456789", { + filter: "role == 'groups/123456789/roles/12345'" +}); + +console.log(`Admin count: ${admins.groupMemberships.length}`); +``` + +### Updating Member Roles + +Change a member's role in the group: + +```typescript +const updated = await client.groups.updateGroupMembership( + "123456789", // Group ID + "987654321", // Membership ID (user ID) + "12345" // New role ID +); + +console.log(`Updated role: ${updated.role}`); +``` + +## Managing Group Roles + +### Listing All Roles + +Get all roles in a group: + +```typescript +const roles = await client.groups.listGroupRoles("123456789"); + +for (const role of roles.groupRoles) { + console.log(role.displayName); // "Admin", "Member", etc. + console.log(role.rank); // Role rank (0-255) + console.log(role.memberCount); +} +``` + +### Getting a Specific Role + +Retrieve detailed information about a single role: + +```typescript +const role = await client.groups.getGroupRole("123456789", "12345"); + +console.log(role.displayName); +console.log(role.description); +console.log(role.permissions); // Role permissions object +``` + +## Handling Join Requests + +For invite-only groups, manage join requests: + +### Listing Join Requests + +```typescript +const requests = await client.groups.listGroupJoinRequests("123456789", { + maxPageSize: 50 +}); + +for (const request of requests.groupJoinRequests) { + console.log(request.user); // "users/987654321" + console.log(request.createTime); +} +``` + +### Filtering Requests + +Find join requests from a specific user: + +```typescript +const userRequest = await client.groups.listGroupJoinRequests("123456789", { + filter: "user == 'users/987654321'" +}); +``` + +### Accepting Requests + +```typescript +await client.groups.acceptGroupJoinRequest( + "123456789", // Group ID + "555555555" // Join request ID +); + +console.log("Join request accepted"); +``` + +### Declining Requests + +```typescript +await client.groups.declineGroupJoinRequest( + "123456789", // Group ID + "555555555" // Join request ID +); + +console.log("Join request declined"); +``` + +## Working with Group Shouts + +Retrieve the current group shout (announcement): + +```typescript +const shout = await client.groups.getGroupShout("123456789"); + +if (shout.content) { + console.log(shout.content); // Shout message + console.log(shout.poster); // User who posted + console.log(shout.createTime); + console.log(shout.updateTime); +} else { + console.log("No active shout"); +} +``` + +## Complete Example + +Here's a complete example that combines multiple group operations: + +```typescript +// Get group information +const group = await client.groups.get("123456789"); +console.log(`Managing group: ${group.displayName}`); + +// List all roles +const roles = await client.groups.listGroupRoles("123456789"); +console.log(`Total roles: ${roles.groupRoles.length}`); + +// Get admin role +const adminRole = roles.groupRoles.find(r => r.displayName === "Admin"); + +// List members with admin role +if (adminRole) { + const admins = await client.groups.listGroupMemberships("123456789", { + filter: `role == '${adminRole.id}'` + }); + console.log(`Total admins: ${admins.groupMemberships.length}`); +} + +// Check for pending join requests +const requests = await client.groups.listGroupJoinRequests("123456789"); +console.log(`Pending requests: ${requests.groupJoinRequests.length}`); +``` diff --git a/src/docs/guide/resources/users.md b/src/docs/guide/resources/users.md new file mode 100644 index 0000000..7fa509e --- /dev/null +++ b/src/docs/guide/resources/users.md @@ -0,0 +1,130 @@ +# Users Resource + +The Users resource provides methods to interact with Roblox user data, including profile information, inventory, thumbnails, and notifications. + +## Getting User Information + +Retrieve basic user profile information by user ID: + +```typescript +const user = await client.users.get("123456789"); + +console.log(user.displayName); // "John Doe" +console.log(user.name); // "@johndoe" +console.log(user.hasVerifiedBadge); +``` + +## Generating Thumbnails + +Generate avatar thumbnails with customizable size, format, and shape: + +```typescript +const thumbnail = await client.users.generateThumbnail("123456789", { + size: 420, // 48, 50, 60, 75, 100, 110, 150, 180, 352, 420, 720 + format: "PNG", // PNG, JPEG + shape: "ROUND" // ROUND, SQUARE +}); + +console.log(thumbnail.response.imageUri); +``` + +::: tip +The default size is 420px if not specified. This is a good balance between quality and file size. +::: + +## Working with Inventory + +List items in a user's inventory with optional filtering: + +```typescript +// Get all inventory items +const inventory = await client.users.listInventoryItems("123456789"); + +for (const item of inventory.inventoryItems) { + console.log(item.assetDetails.displayName); + console.log(item.assetDetails.assetType); +} +``` + +### Filtering by Asset Type + +Use filters to retrieve specific types of items: + +```typescript +// Get only hats and pants +const items = await client.users.listInventoryItems("123456789", { + filter: "inventoryItemAssetTypes=HAT,CLASSIC_PANTS" +}); +``` + +### Paginating Large Inventories + +For users with many items, use pagination: + +```typescript +let pageToken: string | undefined; +let allItems = []; + +do { + const page = await client.users.listInventoryItems("123456789", { + maxPageSize: 100, + pageToken + }); + + allItems.push(...page.inventoryItems); + pageToken = page.nextPageToken; +} while (pageToken); + +console.log(`Total items: ${allItems.length}`); +``` + +See the [Pagination guide](/guide/pagination) for more details. + +## Checking Asset Quotas + +View upload quotas and usage limits for a user: + +```typescript +const quotas = await client.users.listAssetQuotas("123456789"); + +for (const quota of quotas.assetQuotas) { + console.log(`Asset Type: ${quota.assetType}`); + console.log(`Usage: ${quota.usage}`); + console.log(`Limit: ${quota.quota}`); + console.log(`Resets at: ${quota.usageResetTime}`); +} +``` + +## Sending Notifications + +Send a notification to a user: + +```typescript +await client.users.createNotification("123456789", { + source: { + universe: "universes/96623001" + }, + payload: { + type: "MOMENT", + messageId: "daily-reward", + parameters: { + rewardType: { + stringValue: "coins" + }, + amount: { + int64Value: "1000" + } + }, + joinExperience: { + launchData: "reward_claim" + }, + analyticsData: { + category: "Daily Rewards" + } + } +}); +``` + +::: warning +Notifications require proper API key permissions for the specified universe. +::: diff --git a/src/docs/guide/typescript.md b/src/docs/guide/typescript.md new file mode 100644 index 0000000..42a5ac2 --- /dev/null +++ b/src/docs/guide/typescript.md @@ -0,0 +1,149 @@ +# TypeScript Integration + +The OpenCloud SDK is built with TypeScript and provides full type safety out of the box. This guide shows you how to get the most out of TypeScript features. + +## Type Inference + +The SDK automatically infers types for all API responses: + +```typescript +const user = await client.users.get("123456789"); + +// TypeScript knows the exact structure +user.displayName; // string +user.name; // string +user.hasVerifiedBadge; // boolean +user.created; // string (ISO date) +``` + +## Importing Types + +All types are exported from the main package: + +```typescript +import { + OpenCloud, + User, + Group, + InventoryItem, + GroupRole, + GroupMembershipItem +} from "@relatiohq/opencloud"; +``` + +## Type Guards + +Use type guards to narrow error types: + +```typescript +import { OpenCloudError, RateLimitError, AuthError } from "@relatiohq/opencloud"; + +try { + const user = await client.users.get("123456789"); +} catch (error) { + if (error instanceof RateLimitError) { + // TypeScript knows this is a RateLimitError + console.log(error.retryAfter); // number | undefined + } else if (error instanceof AuthError) { + // TypeScript knows this is an AuthError + console.log(error.status); // number + } else if (error instanceof OpenCloudError) { + // TypeScript knows this is an OpenCloudError + console.log(error.code); // string + } +} +``` + +## Configuration Types + +Type-safe client configuration: + +```typescript +import type { OpenCloudConfig } from "@relatiohq/opencloud"; + +const config: OpenCloudConfig = { + apiKey: process.env.ROBLOX_API_KEY!, + userAgent: "MyApp/1.0", + baseUrl: "https://apis.roblox.com", + retry: { + attempts: 4, + backoff: "exponential" + } +}; + +const client = new OpenCloud(config); +``` + +## Working with Enums + +The SDK exports enums for common values: + +```typescript +import type { AssetType, InventoryItemAssetType } from "@relatiohq/opencloud"; + +// Filter by specific asset types +const items = await client.users.listInventoryItems("123456789", { + filter: "inventoryItemAssetTypes=HAT,CLASSIC_PANTS" +}); + +// TypeScript knows the asset type +items.inventoryItems.forEach(item => { + const assetType: string = item.assetDetails.assetType; + // Could be: "HAT", "CLASSIC_PANTS", "TSHIRT", etc. +}); +``` + +## Strict Mode + +The SDK works great with TypeScript strict mode: + +```json +{ + "compilerOptions": { + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true + } +} +``` + +## Type-Safe Helper Functions + +Create type-safe helper functions using SDK types: + +```typescript +import type { User, Group } from "@relatiohq/opencloud"; + +async function getUsersByIds(userIds: string[]): Promise { + const users: User[] = []; + + for (const userId of userIds) { + const user = await client.users.get(userId); + users.push(user); + } + + return users; +} + +async function getGroupRoleByName( + groupId: string, + roleName: string +): Promise { + const roles = await client.groups.listGroupRoles(groupId); + return roles.groupRoles.find(role => role.displayName === roleName); +} +``` + +## IDE Support + +With full TypeScript support, you get: + +- **Autocomplete** - IntelliSense suggests available methods and properties +- **Type Checking** - Catch errors before runtime +- **Documentation** - Hover over methods to see JSDoc comments +- **Refactoring** - Rename symbols safely across your codebase + +::: tip +Use a TypeScript-aware IDE like VS Code, WebStorm, or Cursor for the best development experience. +::: diff --git a/src/docs/index.md b/src/docs/index.md new file mode 100644 index 0000000..a68b879 --- /dev/null +++ b/src/docs/index.md @@ -0,0 +1,59 @@ +--- + +layout: home +title: Relatio OpenCloud + +hero: + name: Relatio OpenCloud + text: Typed SDK for Roblox Open Cloud + tagline: A modern, fully-typed TypeScript SDK for the Roblox Open Cloud API + image: /cloud.svg + + actions: + - theme: brand + text: Get Started + link: /guide/getting-started + - theme: alt + text: API Reference + link: /api/ + - theme: alt + text: View on GitHub + link: https://github.com/relatiocc/opencloud + +features: + - icon: ๐Ÿ”’ + title: Type-safe + details: Fully typed with TypeScript for excellent IDE support and compile-time safety + - icon: ๐Ÿš€ + title: Modern + details: Built with modern JavaScript/TypeScript features and best practices + - icon: ๐Ÿ“ฆ + title: Easy to use + details: Simple, intuitive API that mirrors the Roblox Open Cloud structure + - icon: ๐Ÿ”„ + title: Auto retry + details: Built-in retry logic with exponential backoff for failed requests + - icon: ๐Ÿ“– + title: Well documented + details: Comprehensive documentation with examples for all features + - icon: โšก + title: Lightweight + details: Minimal dependencies for fast installs and small bundle sizes +--- + +## Quick Start + +```bash +npm install @relatiohq/opencloud +``` + +```typescript +import { OpenCloud } from "@relatiohq/opencloud"; + +const client = new OpenCloud({ + apiKey: "your-api-key" +}); + +const user = await client.users.get("123456789"); +console.log(user.displayName); +``` \ No newline at end of file diff --git a/src/docs/public/cloud.svg b/src/docs/public/cloud.svg new file mode 100644 index 0000000..1da7086 --- /dev/null +++ b/src/docs/public/cloud.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/docs/public/favicon.ico b/src/docs/public/favicon.ico new file mode 100644 index 0000000..20df9e3 Binary files /dev/null and b/src/docs/public/favicon.ico differ diff --git a/src/docs/public/logo.svg b/src/docs/public/logo.svg new file mode 100644 index 0000000..b0d1a8f --- /dev/null +++ b/src/docs/public/logo.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/typedoc.json b/typedoc.json index 84c8f74..7cf7407 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,30 +1,30 @@ { "$schema": "https://typedoc.org/schema.json", - "entryPoints": ["src"], - "entryPointStrategy": "resolve", - "out": "docs", + "entryPoints": ["src/index.ts"], + "entryPointStrategy": "expand", + "out": "src/docs/api", + "plugin": ["typedoc-plugin-markdown"], "excludePrivate": true, "excludeProtected": false, "excludeExternals": true, - "readme": "README.md", + "readme": "none", "name": "@relatiohq/opencloud", "sort": ["source-order"], - "navigation": { - "includeCategories": true, - "includeGroups": true - }, - "navigationLinks": { - "GitHub": "https://github.com/relatiocc/opencloud", - "Discord": "https://relatio.cc/discord" - }, "treatWarningsAsErrors": false, "validation": { "notExported": false, "invalidLink": true, "notDocumented": false }, - "visibilityFilters": {}, "hideGenerator": true, - "hostedBaseUrl": "https://opencloud.relatio.cc", - "cname": "opencloud.relatio.cc" + "hideBreadcrumbs": true, + "outputFileStrategy": "members", + "membersWithOwnFile": ["Class", "Interface", "TypeAlias", "Function", "Enum"], + "flattenOutputFiles": false, + "useCodeBlocks": true, + "expandObjects": true, + "parametersFormat": "table", + "enumMembersFormat": "table", + "typeDeclarationFormat": "table", + "indexFormat": "table" } diff --git a/vitest.config.ts b/vitest.config.ts index ee1ce6c..f83ae66 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,7 +10,8 @@ export default defineConfig({ reporter: ["text", "lcov"], reportsDirectory: "./coverage", exclude: [ - "docs/**", + "src/docs/.vitepress/**", + "scripts/**", "coverage/**", "dist/**", "node_modules/**",